> -----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

Reply via email to