From: "Borah, Chaitanya Kumar" <chaitanya.kumar.borah@intel.com>
To: Arun R Murthy <arun.r.murthy@intel.com>,
<intel-gfx@lists.freedesktop.org>,
<intel-xe@lists.freedesktop.org>
Cc: Jani Nikula <jani.nikula@linux.intel.com>,
<uma.shankar@intel.com>, <suraj.kandpal@intel.com>
Subject: Re: [PATCH v4 6/7] drm/i915/display: Program and enable the DP symbol based timing generator
Date: Sun, 15 Nov 2026 17:36:37 +0530 [thread overview]
Message-ID: <c859200e-7972-4a7b-b8ab-fe135cd6428e@intel.com> (raw)
In-Reply-To: <20261103-vlk-64036-dp-symbol-tg-v4-6-6cf8a588b54c@intel.com>
On 11/3/2026 3:28 PM, Arun R Murthy wrote:
> Program the 128 bit LL symbol Data M/N before the LINK_N write which
> arms the double buffered update, the LL symbol HACT/HTOTAL/CHUNK_SIZE
> along with the other transcoder timings, and enable the timing
> generator via TRANSCONF.DP_Symbol_TG_Enable before the transcoder is
> enabled.
>
> v3: Remove redundant HAS_DP_SYMBOL_TG (Jani)
> Use intel_de_read64_2x32()
>
> Bspec: 68849, 68922, 69961
> Signed-off-by: Arun R Murthy <arun.r.murthy@intel.com>
> ---
> drivers/gpu/drm/i915/display/intel_ddi.c | 2 +
> drivers/gpu/drm/i915/display/intel_display.c | 101 ++++++++++++++++++++++++++-
> drivers/gpu/drm/i915/display/intel_display.h | 1 +
> 3 files changed, 101 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
> index a46ab5d3d70fc75c6975f46e14d1b0c24dc1ba5e..c814e0740aa064f56d844e304c0a93d1047475c6 100644
> --- a/drivers/gpu/drm/i915/display/intel_ddi.c
> +++ b/drivers/gpu/drm/i915/display/intel_ddi.c
> @@ -4083,6 +4083,7 @@ static void intel_ddi_read_func_ctl_dp_sst(struct intel_encoder *encoder,
> REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, ddi_func_ctl);
>
> intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder, &crtc_state->dp_m_n);
> + intel_cpu_transcoder_get_llsym_m_n(crtc_state);
> intel_cpu_transcoder_get_m2_n2(crtc, cpu_transcoder, &crtc_state->dp_m2_n2);
>
> crtc_state->enhanced_framing =
> @@ -4119,6 +4120,7 @@ static void intel_ddi_read_func_ctl_dp_mst(struct intel_encoder *encoder,
> REG_FIELD_GET(TRANS_DDI_MST_TRANSPORT_SELECT_MASK, ddi_func_ctl);
>
> intel_cpu_transcoder_get_m1_n1(crtc, cpu_transcoder, &crtc_state->dp_m_n);
> + intel_cpu_transcoder_get_llsym_m_n(crtc_state);
>
> if (DISPLAY_VER(display) >= 11)
> crtc_state->fec_enable =
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
> index 7caf5bee8718729667376b487b0584b47891f05a..71a2f96b5e8f8474fd9ef24ac1c1ac89bcdeff0a 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -521,9 +521,14 @@ void intel_enable_transcoder(const struct intel_crtc_state *new_crtc_state)
> return;
> }
>
> - /* Wa_1409098942:adlp+ */
> - if (DISPLAY_VER(display) >= 13 &&
> - new_crtc_state->dsc.compression_enable) {
> + /* The early pixel count is in symbols with the DP symbol TG, no scaling */
> + if (new_crtc_state->dp_symbol_tg.enable) {
> + val &= ~TRANSCONF_PIXEL_COUNT_SCALING_MASK;
> + val |= REG_FIELD_PREP(TRANSCONF_PIXEL_COUNT_SCALING_MASK,
> + TRANSCONF_PIXEL_COUNT_SCALING_X1);
Bspec specifies the Symbol TG Hblank early setting as a pair: Hblank
Early Count = 96 symbols together with Early Count Scaling = x1. If we
are programming one we should program the other. We are already doing
it for the pixel TG with DSC: Wa_1409098942 sets the x4 scaling and
enable_audio_dsc_wa() programs the matching count.
It has no dependency on audio bandwidth management that is to come later.
> + } else if (DISPLAY_VER(display) >= 13 &&
> + new_crtc_state->dsc.compression_enable) {
> + /* Wa_1409098942:adlp+ */
> val &= ~TRANSCONF_PIXEL_COUNT_SCALING_MASK;
> val |= REG_FIELD_PREP(TRANSCONF_PIXEL_COUNT_SCALING_MASK,
> TRANSCONF_PIXEL_COUNT_SCALING_X4);
> @@ -588,6 +593,14 @@ void intel_disable_transcoder(const struct intel_crtc_state *old_crtc_state)
>
> if ((val & TRANSCONF_ENABLE) == 0)
> intel_wait_for_pipe_off(old_crtc_state);
> +
> + /* Disable the DP symbol based timing generator */
> + if (old_crtc_state->dp_symbol_tg.enable) {
> + intel_de_rmw(display, TRANSCONF(display, cpu_transcoder),
> + TRANSCONF_DP_SYMBOL_TG_ENABLE, 0);
> + intel_de_write(display, TRANS_LLSYM_HACT(display, cpu_transcoder), 0);
> + intel_de_write(display, TRANS_LLSYM_HTOTAL(display, cpu_transcoder), 0);
> + }
> }
>
> u32 intel_plane_fb_max_stride(struct intel_display *display,
> @@ -1683,6 +1696,52 @@ static void hsw_set_frame_start_delay(const struct intel_crtc_state *crtc_state)
> HSW_FRAME_START_DELAY(crtc_state->framestart_delay - 1));
> }
>
> +static void intel_cpu_transcoder_set_llsym_m_n(const struct intel_crtc_state *crtc_state)
> +{
> + struct intel_display *display = to_intel_display(crtc_state);
> + enum transcoder transcoder = crtc_state->cpu_transcoder;
> + const struct intel_dp_symbol_tg *tg = &crtc_state->dp_symbol_tg;
> +
> + if (!tg->enable)
> + return;
> +
> + /*
> + * These are double buffered, updated by the LINK_N write in
> + * intel_set_m_n(), so must be written before that.
> + */
> + intel_de_write(display, DP_LLSYM_DATAM(display, transcoder, 0),
> + lower_32_bits(tg->data_m[0]));
> + intel_de_write(display, DP_LLSYM_DATAM(display, transcoder, 1),
> + upper_32_bits(tg->data_m[0]));
> + intel_de_write(display, DP_LLSYM_DATAM_EXT(display, transcoder, 0),
> + lower_32_bits(tg->data_m[1]));
> + intel_de_write(display, DP_LLSYM_DATAM_EXT(display, transcoder, 1),
> + upper_32_bits(tg->data_m[1]));
> + intel_de_write(display, DP_LLSYM_DATAN(display, transcoder, 0),
> + lower_32_bits(tg->data_n[0]));
> + intel_de_write(display, DP_LLSYM_DATAN(display, transcoder, 1),
> + upper_32_bits(tg->data_n[0]));
> + intel_de_write(display, DP_LLSYM_DATAN_EXT(display, transcoder, 0),
> + lower_32_bits(tg->data_n[1]));
> + intel_de_write(display, DP_LLSYM_DATAN_EXT(display, transcoder, 1),
> + upper_32_bits(tg->data_n[1]));
> +}
> +
> +void intel_cpu_transcoder_get_llsym_m_n(struct intel_crtc_state *crtc_state)
> +{
> + struct intel_display *display = to_intel_display(crtc_state);
> + enum transcoder transcoder = crtc_state->cpu_transcoder;
> + struct intel_dp_symbol_tg *tg = &crtc_state->dp_symbol_tg;
> +
> + if (!tg->enable)
> + return;
> +
> + tg->data_m[0] = intel_de_read64_2x32(display, DP_LLSYM_DATAM(display, transcoder, 0));
> + tg->data_m[1] = intel_de_read64_2x32(display, DP_LLSYM_DATAM_EXT(display, transcoder, 0));
> + tg->data_n[0] = intel_de_read64_2x32(display, DP_LLSYM_DATAN(display, transcoder, 0));
> + tg->data_n[1] = intel_de_read64_2x32(display, DP_LLSYM_DATAN_EXT(display, transcoder, 0));
> +}
> +
> static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_state)
> {
> struct intel_display *display = to_intel_display(crtc_state);
> @@ -1693,6 +1752,7 @@ static void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta
> intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder,
> &crtc_state->fdi_m_n);
> } else if (intel_crtc_has_dp_encoder(crtc_state)) {
> + intel_cpu_transcoder_set_llsym_m_n(crtc_state);
> intel_cpu_transcoder_set_m1_n1(crtc, cpu_transcoder,
> &crtc_state->dp_m_n);
> intel_cpu_transcoder_set_m2_n2(crtc, cpu_transcoder,
> @@ -2929,6 +2989,17 @@ void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state,
> intel_de_write(display, DP_MIN_HBLANK_CTL(transcoder),
> crtc_state->min_hblank);
> }
> +
> + if (crtc_state->dp_symbol_tg.enable) {
> + const struct intel_dp_symbol_tg *tg = &crtc_state->dp_symbol_tg;
> +
> + intel_de_write(display, TRANS_LLSYM_HACT(display, transcoder),
> + TRANS_LLSYM_HACT_VAL(tg->hactive - 1));
> + intel_de_write(display, TRANS_LLSYM_HTOTAL(display, transcoder),
> + TRANS_LLSYM_HTOTAL_VAL(tg->htotal - 1));
> + intel_de_write(display, TRANS_LLSYM_CHUNK_SIZE(display, transcoder),
> + TRANS_LLSYM_CHUNK_SIZE_VAL(tg->chunk_size));
> + }
> }
>
> void intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc_state,
> @@ -3095,6 +3166,26 @@ static void intel_get_transcoder_timings(struct intel_crtc *crtc,
> if (DISPLAY_VER(display) >= 30)
> pipe_config->min_hblank = intel_de_read(display,
> DP_MIN_HBLANK_CTL(cpu_transcoder));
> +
> + if (HAS_DP_SYMBOL_TG(display)) {
> + tmp = intel_de_read(display, TRANSCONF(display, cpu_transcoder));
> +
> + if (tmp & TRANSCONF_DP_SYMBOL_TG_ENABLE) {
> + struct intel_dp_symbol_tg *tg = &pipe_config->dp_symbol_tg;
> + u32 hact, htotal, chunk_size;
> +
> + hact = intel_de_read(display, TRANS_LLSYM_HACT(display, cpu_transcoder));
> + htotal = intel_de_read(display,
> + TRANS_LLSYM_HTOTAL(display, cpu_transcoder));
> + chunk_size = intel_de_read(display,
> + TRANS_LLSYM_CHUNK_SIZE(display, cpu_transcoder));
> +
> + tg->enable = true;
> + tg->hactive = REG_FIELD_GET(TRANS_LLSYM_HACT_MASK, hact) + 1;
> + tg->htotal = REG_FIELD_GET(TRANS_LLSYM_HTOTAL_MASK, htotal) + 1;
> + tg->chunk_size = REG_FIELD_GET(TRANS_LLSYM_CHUNK_SIZE_MASK, chunk_size);
> + }
> + }
> }
>
> static void intel_joiner_adjust_pipe_src(struct intel_crtc_state *crtc_state)
> @@ -3419,6 +3510,10 @@ static void hsw_set_transconf(const struct intel_crtc_state *crtc_state)
> crtc_state->output_format != INTEL_OUTPUT_FORMAT_RGB)
> val |= TRANSCONF_OUTPUT_COLORSPACE_YUV_HSW;
>
> + /* Must be set before the transcoder is enabled, so only on modeset */
> + if (crtc_state->dp_symbol_tg.enable)
> + val |= TRANSCONF_DP_SYMBOL_TG_ENABLE;
> +
> intel_de_write(display, TRANSCONF(display, cpu_transcoder), val);
> intel_de_posting_read(display, TRANSCONF(display, cpu_transcoder));
> }
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h b/drivers/gpu/drm/i915/display/intel_display.h
> index d53b7b4a80e75f8cb3a76d923d05648ffe505e2d..fa9ae8799a1999d9dd6a1f4e4d56983b6536ba26 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -446,6 +446,7 @@ void intel_cpu_transcoder_get_m2_n2(struct intel_crtc *crtc,
> enum transcoder cpu_transcoder,
> struct intel_link_m_n *m_n);
> int intel_dotclock_calculate(int link_freq, const struct intel_link_m_n *m_n);
> +void intel_cpu_transcoder_get_llsym_m_n(struct intel_crtc_state *crtc_state);
> int intel_crtc_dotclock(const struct intel_crtc_state *pipe_config);
> int intel_max_uncompressed_dotclock(struct intel_display *display);
> enum intel_display_power_domain intel_port_to_power_domain(struct intel_digital_port *dig_port);
>
next prev parent reply other threads:[~2026-11-15 12:07 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-03 9:58 [PATCH v4 0/7] drm/i915/dp: Add support for the DP symbol based timing generator Arun R Murthy
2026-11-03 9:58 ` [PATCH v4 1/7] drm/i915/dp: Factor out the DSC slice count and link bpp lookup Arun R Murthy
2026-11-03 9:58 ` [PATCH v4 2/7] drm/i915/display: Add the DP link layer symbol timing generator registers Arun R Murthy
2026-11-03 9:58 ` [PATCH v4 3/7] drm/i915/display: Add the DP symbol timing generator crtc state Arun R Murthy
2026-11-03 9:58 ` [PATCH v4 4/7] drm/i915/display: Add HAS_DP_SYMBOL_TG() Arun R Murthy
2026-11-03 9:58 ` [PATCH v4 5/7] drm/i915/dp: Compute the DP symbol based timing generator parameters Arun R Murthy
2026-11-05 4:32 ` Kandpal, Suraj
2026-11-15 12:06 ` Borah, Chaitanya Kumar
2026-11-03 9:58 ` [PATCH v4 6/7] drm/i915/display: Program and enable the DP symbol based timing generator Arun R Murthy
2026-11-03 10:23 ` sashiko-bot
2026-11-15 12:06 ` Borah, Chaitanya Kumar [this message]
2026-11-03 9:58 ` [PATCH v4 7/7] drm/i915/dp: Don't limit the Link M/N ratio with the symbol " Arun R Murthy
2026-11-04 1:30 ` Kandpal, Suraj
2026-11-15 12:06 ` Borah, Chaitanya Kumar
2026-11-03 10:13 ` ✓ CI.KUnit: success for drm/i915/dp: Add support for the DP symbol based timing generator (rev3) Patchwork
2026-11-03 10:49 ` ✓ Xe.CI.BAT: " Patchwork
2026-11-03 11:21 ` ✓ i915.CI.BAT: " Patchwork
2026-11-03 14:30 ` ✗ i915.CI.Full: failure " Patchwork
2026-11-03 19:18 ` ✗ Xe.CI.FULL: " Patchwork
-- strict thread matches above, loose matches on Subject: below --
2026-11-04 3:24 [PATCH v4 0/7] drm/i915/dp: Add support for the DP symbol based timing generator Arun R Murthy
2026-11-04 3:24 ` [PATCH v4 6/7] drm/i915/display: Program and enable " Arun R Murthy
2026-11-05 4:47 ` Kandpal, Suraj
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c859200e-7972-4a7b-b8ab-fe135cd6428e@intel.com \
--to=chaitanya.kumar.borah@intel.com \
--cc=arun.r.murthy@intel.com \
--cc=intel-gfx@lists.freedesktop.org \
--cc=intel-xe@lists.freedesktop.org \
--cc=jani.nikula@linux.intel.com \
--cc=suraj.kandpal@intel.com \
--cc=uma.shankar@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.