> -----Original Message-----
> From: Manna, Animesh <[email protected]>
> Sent: Thursday, June 4, 2026 1:24 AM
> To: [email protected]; [email protected]
> Cc: Shankar, Uma <[email protected]>; Dibin Moolakadan Subrahmanian
> <[email protected]>; [email protected];
> Nikula, Jani <[email protected]>; Manna, Animesh
> <[email protected]>
> Subject: [PATCH v8 07/20] drm/i915/cmtg: Set timings for CMTG by using
> transcoder timing helpers
> 
> Expose intel_set_transcoder_timings() & intel_set_transcoder_timings_lrr()
> so that they can program timings on any transcoder, and use them from a new
> intel_cmtg_set_timings() helper instead of duplicating the timing register 
> write
> sequence for CMTG.
> 
> intel_cmtg_set_timings() maps the CPU transcoder to the corresponding CMTG
> transcoder (TRANSCODER_A->TRANSCODER_CMTG0, TRANSCODER_B->
> TRANSCODER_CMTG1) and calls the shared helper, gated by
> intel_cmtg_is_allowed(). It is invoked from hsw_configure_cpu_transcoder() for
> the full modeset path and from intel_pipe_fastset() for the LRR update path.
> 
> 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]
> 
> v6:
> - Reuse transcoder timing helpers. [Ville]
> 
> Bspec: 68989
> Signed-off-by: Animesh Manna <[email protected]>
> ---
>  drivers/gpu/drm/i915/display/intel_cmtg.c    | 25 ++++++++++++++++++++
>  drivers/gpu/drm/i915/display/intel_cmtg.h    |  1 +
>  drivers/gpu/drm/i915/display/intel_display.c | 13 +++++-----
> drivers/gpu/drm/i915/display/intel_display.h |  4 ++++
>  4 files changed, 37 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c
> b/drivers/gpu/drm/i915/display/intel_cmtg.c
> index fbc8a4f2b9cb..082c04bec9ee 100644
> --- a/drivers/gpu/drm/i915/display/intel_cmtg.c
> +++ b/drivers/gpu/drm/i915/display/intel_cmtg.c
> @@ -219,3 +219,28 @@ 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) {
> +     enum transcoder cmtg_transcoder =
> +to_cmtg_transcoder(crtc_state->cpu_transcoder);

This can get INVALID_TRANSCODER, we should add protection for it.
Check below should help, but better to add an explicit check.

> +
> +     if (!intel_cmtg_is_allowed(crtc_state))
> +             return;
> +
> +     if (lrr)
> +             intel_set_transcoder_timings_lrr(crtc_state, cmtg_transcoder);
> +     else
> +             intel_set_transcoder_timings(crtc_state, cmtg_transcoder); }
> 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 17621f66501f..a6a1da4bd98d 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"
> @@ -132,8 +133,6 @@
>  #include "vlv_dsi_pll.h"
>  #include "vlv_dsi_regs.h"
> 
> -static void intel_set_transcoder_timings(const struct intel_crtc_state 
> *crtc_state,
> -                                      enum transcoder transcoder);
>  static void intel_set_pipe_src_size(const struct intel_crtc_state 
> *crtc_state);
> static void hsw_set_transconf(const struct intel_crtc_state *crtc_state);  
> static
> void bdw_set_pipe_misc(struct intel_dsb *dsb, @@ -1637,6 +1636,7 @@ static
> void hsw_configure_cpu_transcoder(const struct intel_crtc_state *crtc_sta
>       }
> 
>       intel_set_transcoder_timings(crtc_state, crtc_state->cpu_transcoder);
> +     intel_cmtg_set_timings(crtc_state, false);
> 
>       if (cpu_transcoder != TRANSCODER_EDP)
>               intel_de_write(display, TRANS_MULT(display, cpu_transcoder),
> @@ -2665,8 +2665,8 @@ transcoder_has_vrr(const struct intel_crtc_state
> *crtc_state)
>       return HAS_VRR(display) && !transcoder_is_dsi(cpu_transcoder);
>  }
> 
> -static void intel_set_transcoder_timings(const struct intel_crtc_state 
> *crtc_state,
> -                                      enum transcoder transcoder)
> +void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state,
> +                               enum transcoder transcoder)
>  {
>       struct intel_display *display = to_intel_display(crtc_state);
>       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
> @@ -2777,8 +2777,8 @@ static void intel_set_transcoder_timings(const struct
> intel_crtc_state *crtc_sta
>       }
>  }
> 
> -static void intel_set_transcoder_timings_lrr(const struct intel_crtc_state
> *crtc_state,
> -                                          enum transcoder transcoder)
> +void intel_set_transcoder_timings_lrr(const struct intel_crtc_state 
> *crtc_state,
> +                                   enum transcoder transcoder)
>  {
>       struct intel_display *display = to_intel_display(crtc_state);
>       const struct drm_display_mode *adjusted_mode = &crtc_state-
> >hw.adjusted_mode; @@ -6673,6 +6673,7 @@ static void
> intel_pipe_fastset(const struct intel_crtc_state *old_crtc_state,
> 
>       if (new_crtc_state->update_lrr) {
>               intel_set_transcoder_timings_lrr(new_crtc_state, new_crtc_state-
> >cpu_transcoder);
> +             intel_cmtg_set_timings(new_crtc_state, true);

Maybe instead of true and false here, an enum with explicit names can be
used as argument.

With above fixed, this is
Reviewed-by: Uma Shankar <[email protected]>

>               intel_vrr_set_fixed_rr_timings(new_crtc_state);
>               intel_vrr_transcoder_enable(new_crtc_state);
>       }
> diff --git a/drivers/gpu/drm/i915/display/intel_display.h
> b/drivers/gpu/drm/i915/display/intel_display.h
> index 1963dbc80221..ef7e0506f77f 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.h
> +++ b/drivers/gpu/drm/i915/display/intel_display.h
> @@ -424,6 +424,10 @@ void intel_set_m_n(struct intel_display *display,
>                  const struct intel_link_m_n *m_n,
>                  intel_reg_t data_m_reg, intel_reg_t data_n_reg,
>                  intel_reg_t link_m_reg, intel_reg_t link_n_reg);
> +void intel_set_transcoder_timings(const struct intel_crtc_state *crtc_state,
> +                               enum transcoder transcoder);
> +void intel_set_transcoder_timings_lrr(const struct intel_crtc_state 
> *crtc_state,
> +                                   enum transcoder transcoder);
>  void intel_get_m_n(struct intel_display *display,
>                  struct intel_link_m_n *m_n,
>                  intel_reg_t data_m_reg, intel_reg_t data_n_reg,
> --
> 2.29.0

Reply via email to