> -----Original Message-----
> From: Manna, Animesh <[email protected]>
> Sent: Monday, June 1, 2026 8:02 PM
> To: Ville Syrjälä <[email protected]>
> Cc: [email protected]; [email protected]; Shankar,
> Uma
> <[email protected]>; Dibin Moolakadan Subrahmanian
> <[email protected]>; Nikula, Jani
> <[email protected]>
> Subject: RE: [PATCH v7 04/15] drm/i915/cmtg: Set timings for CMTG
>
>
>
> > -----Original Message-----
> > From: Ville Syrjälä <[email protected]>
> > Sent: Friday, May 29, 2026 4:29 PM
> > To: Manna, Animesh <[email protected]>
> > Cc: [email protected]; [email protected];
> > Shankar, Uma <[email protected]>; Dibin Moolakadan Subrahmanian
> > <[email protected]>; Nikula, Jani
> > <[email protected]>
> > Subject: Re: [PATCH v7 04/15] drm/i915/cmtg: Set timings for CMTG
> >
> > On Tue, May 26, 2026 at 07:08:00PM +0530, Animesh Manna wrote:
> > > Timing registers are separate for CMTG, read transcoder register and
> > > program cmtg transcoder with those values.
> > >
> > > v2:
> > > - Use sw state instead of reading directly from hardware. [Jani]
> > > - Move set_timing later after encoder enable. [Dibin]
> > >
> > > v3:
> > > - Replace id with trans. [Jani]
> > > - Program cmtg set_timing() along with primary transcoder timing.
> > >
> > > v4:
> > > - Use _MMIO_TRANS() for cmtg registers instead of direct
> > > multiplication. [Jani]
> > >
> > > v5:
> > > - Modify register definition approach and match existing transcoder
> > > definition. [Ville]
> > >
> > > Signed-off-by: Animesh Manna <[email protected]>
> > > ---
> > > drivers/gpu/drm/i915/display/intel_cmtg.c | 74 ++++++++++++++++++++
> > > drivers/gpu/drm/i915/display/intel_cmtg.h | 1 +
> > > drivers/gpu/drm/i915/display/intel_display.c | 4 ++
> > > 3 files changed, 79 insertions(+)
> > >
> > > diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c
> > > b/drivers/gpu/drm/i915/display/intel_cmtg.c
> > > index fbc8a4f2b9cb..0e730afbb4ab 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_cmtg.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_cmtg.c
> > > @@ -219,3 +219,77 @@ void intel_cmtg_set_clk_select(const struct
> > intel_crtc_state *crtc_state)
> > > if (clk_sel_set)
> > > intel_de_rmw(display, CMTG_CLK_SEL, clk_sel_clr,
> > clk_sel_set); }
> > > +
> > > +static inline enum transcoder to_cmtg_transcoder(enum transcoder
> > > +cpu_transcoder) {
> > > + switch (cpu_transcoder) {
> > > + case TRANSCODER_A:
> > > + return TRANSCODER_CMTG0;
> > > + case TRANSCODER_B:
> > > + return TRANSCODER_CMTG1;
> > > + default:
> > > + return INVALID_TRANSCODER;
> > > + }
> > > +}
> > > +
> > > +void intel_cmtg_set_timings(const struct intel_crtc_state
> > > +*crtc_state, bool lrr) {
> > > + struct intel_display *display = to_intel_display(crtc_state);
> > > + const struct drm_display_mode *adjusted_mode = &crtc_state-
> > >hw.adjusted_mode;
> > > + enum transcoder cmtg_transcoder = to_cmtg_transcoder(crtc_state-
> > >cpu_transcoder);
> > > + u32 crtc_vdisplay, crtc_vtotal, crtc_vblank_start,
> > > +crtc_vblank_end;
> > > +
> > > + if (!intel_cmtg_is_allowed(crtc_state))
> > > + return;
> > > +
> > > + crtc_vdisplay = adjusted_mode->crtc_vdisplay;
> > > +
> > > + /*
> > > + * For platforms that always use VRR Timing Generator, the
> > VTOTAL.Vtotal
> > > + * bits are not required. Since the support for these bits is going to
> > > + * be deprecated in upcoming platforms, avoid writing these bits
> > > +for
> > the
> > > + * platforms that do not use legacy Timing Generator.
> > > + */
> > > + crtc_vtotal = 1;
> > > +
> > > + /*
> > > + * VBLANK_START not used by hw, just clear it
> > > + * to make it stand out in register dumps.
> > > + */
> > > + crtc_vblank_start = 1;
> > > +
> > > + crtc_vblank_end = adjusted_mode->crtc_vblank_end;
> > > +
> > > + if (lrr) {
> > > + intel_de_write(display,
> > TRANS_SET_CONTEXT_LATENCY(display, cmtg_transcoder),
> > > + crtc_state->set_context_latency);
> > > + intel_de_write(display, TRANS_VBLANK(display,
> > cmtg_transcoder),
> > > + VBLANK_START(crtc_vblank_start - 1) |
> > > + VBLANK_END(crtc_vblank_end - 1));
> > > + intel_de_write(display, TRANS_VTOTAL(display,
> > cmtg_transcoder),
> > > + VACTIVE(crtc_vdisplay - 1) |
> > > + VTOTAL(crtc_vtotal - 1));
> > > + return;
> > > + }
> > > +
> > > + intel_de_write(display, TRANS_HTOTAL(display, cmtg_transcoder),
> > > + HACTIVE(adjusted_mode->crtc_hdisplay - 1) |
> > > + HTOTAL(adjusted_mode->crtc_htotal - 1));
> > > + intel_de_write(display, TRANS_HBLANK(display, cmtg_transcoder),
> > > + HBLANK_START(adjusted_mode->crtc_hblank_start - 1) |
> > > + HBLANK_END(adjusted_mode->crtc_hblank_end - 1));
> > > + intel_de_write(display, TRANS_HSYNC(display, cmtg_transcoder),
> > > + HSYNC_START(adjusted_mode->crtc_hsync_start - 1) |
> > > + HSYNC_END(adjusted_mode->crtc_hsync_end - 1));
> > > + intel_de_write(display, TRANS_VTOTAL(display, cmtg_transcoder),
> > > + VACTIVE(crtc_vdisplay - 1) |
> > > + VTOTAL(crtc_vtotal - 1));
> > > + intel_de_write(display, TRANS_VBLANK(display, cmtg_transcoder),
> > > + VBLANK_START(crtc_vblank_start - 1) |
> > > + VBLANK_END(crtc_vblank_end - 1));
> > > + intel_de_write(display, TRANS_VSYNC(display, cmtg_transcoder),
> > > + VSYNC_START(adjusted_mode->crtc_vsync_start - 1) |
> > > + VSYNC_END(adjusted_mode->crtc_vsync_end - 1));
> > > + intel_de_write(display, TRANS_SET_CONTEXT_LATENCY(display,
> > cmtg_transcoder),
> > > + crtc_state->set_context_latency); }
> >
> > We already have functions to configure the timing registers. Why can't
> > we just reuse those (as in pass the transcoder from the caller)?
>
> Due to following reasons did not reuse, 1. CMTG will be enabled very specific
> case like single EDP on pipe-A/pipe-B during psr2/lobf/pr-alpm.
> 2. Function prototype of existing functions to configure the timing registers
> need to
> be changed.
> 3. Need condition check for DP_MIN_HBLANK_CTL register programming.
> 4. Two version of set-timings - intel_set_transcoder_timings_lrr() and
> intel_set_transcoder_timings().
> 5. May overload intel_display.c.
>
> I can try to reuse If you have strong objections on current implementation,
> please
> let me know.
> Also is it only for timing registers or same needed for link-m/n and vrr
> registers.
Code duplication for timing registers can be avoided by using a common helper.
Abstract the
logic in helper and use for both CMTG and regular Timing Generator.
Regards,
Uma Shankar
> Regards,
> Animesh
> >
> > > diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.h
> > > b/drivers/gpu/drm/i915/display/intel_cmtg.h
> > > index 87092ce6d67b..53a44f505dd2 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_cmtg.h
> > > +++ b/drivers/gpu/drm/i915/display/intel_cmtg.h
> > > @@ -11,6 +11,7 @@
> > > struct intel_display;
> > > struct intel_crtc_state;
> > >
> > > +void intel_cmtg_set_timings(const struct intel_crtc_state
> > > +*crtc_state, bool lrr);
> > > void intel_cmtg_set_clk_select(const struct intel_crtc_state
> > > *crtc_state); void intel_cmtg_sanitize(struct intel_display
> > > *display); bool intel_cmtg_is_allowed(const struct intel_crtc_state
> > > *crtc_state); diff --git
> > > a/drivers/gpu/drm/i915/display/intel_display.c
> > > b/drivers/gpu/drm/i915/display/intel_display.c
> > > index 6c8935f69db1..f8bcd1fcddca 100644
> > > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > > @@ -60,6 +60,7 @@
> > > #include "intel_bw.h"
> > > #include "intel_cdclk.h"
> > > #include "intel_clock_gating.h"
> > > +#include "intel_cmtg.h"
> > > #include "intel_color.h"
> > > #include "intel_crt.h"
> > > #include "intel_crtc.h"
> > > @@ -2753,6 +2754,8 @@ static void intel_set_transcoder_timings(const
> > struct intel_crtc_state *crtc_sta
> > > intel_de_write(display,
> > DP_MIN_HBLANK_CTL(cpu_transcoder),
> > > crtc_state->min_hblank);
> > > }
> > > +
> > > + intel_cmtg_set_timings(crtc_state, false);
> > > }
> > >
> > > static void intel_set_transcoder_timings_lrr(const struct
> > > intel_crtc_state *crtc_state) @@ -2814,6 +2817,7 @@ static void
> > intel_set_transcoder_timings_lrr(const struct intel_crtc_state *crtc
> > > VACTIVE(crtc_vdisplay - 1) |
> > > VTOTAL(crtc_vtotal - 1));
> > >
> > > + intel_cmtg_set_timings(crtc_state, true);
> > > intel_vrr_set_fixed_rr_timings(crtc_state);
> > > intel_vrr_transcoder_enable(crtc_state);
> > > }
> > > --
> > > 2.29.0
> >
> > --
> > Ville Syrjälä
> > Intel