> -----Original Message-----
> From: Manna, Animesh <[email protected]>
> Sent: Tuesday, June 16, 2026 1:34 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 v9 20/22] drm/i915/cmtg: Add trigger to enable/disable cmtg
> 
> Enable CMTG with fixed refresh rate mode and with dynamic dc state enabled.
> 
> Disable CMTG with transcoder disable or if there is a transition to vrr mode 
> from
> fixed refresh rate mode.
> 
> v2:
> - Move the enabled flag update to avoid issue in the disable timeout path. 
> [Uma]
> 
> v3:
> - Introduce intel_cmtg_program() rather calling multiple cmtg functions. 
> [Dibin]
> - Set clock select before cmtg disable as can lost during dc6 entry. [Dibin]
> - Disable cmtg interrupt in crtc-disable(). [Dibin]
> - Got R-b from Uma.
> 
> v4:
> - Simplify the code further by moving for_each_new_intel_crtc_in_state inside
> intel_cmtg.c.

Looks Good to me.
Reviewed-by: Uma Shankar <[email protected]>

> Signed-off-by: Animesh Manna <[email protected]>
> ---
>  drivers/gpu/drm/i915/display/intel_cmtg.c    | 37 +++++++++++++-------
>  drivers/gpu/drm/i915/display/intel_cmtg.h    |  5 ++-
>  drivers/gpu/drm/i915/display/intel_display.c | 14 ++++++++
>  3 files changed, 41 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c
> b/drivers/gpu/drm/i915/display/intel_cmtg.c
> index 96c7608144b9..8684d2ec2f83 100644
> --- a/drivers/gpu/drm/i915/display/intel_cmtg.c
> +++ b/drivers/gpu/drm/i915/display/intel_cmtg.c
> @@ -12,6 +12,7 @@
>  #include "intel_cmtg_regs.h"
>  #include "intel_crtc.h"
>  #include "intel_de.h"
> +#include "intel_display.h"
>  #include "intel_display_device.h"
>  #include "intel_display_power.h"
>  #include "intel_display_regs.h"
> @@ -333,15 +334,12 @@ void intel_cmtg_set_m_n(const struct intel_crtc_state
> *crtc_state)
>       intel_de_write(display, PIPE_LINK_N1(display, cmtg_transcoder), m_n-
> >link_n);  }
> 
> -void intel_cmtg_enable_sync(const struct intel_crtc_state *crtc_state)
> +static void intel_cmtg_enable_sync(const struct intel_crtc_state
> +*crtc_state)
>  {
>       struct intel_display *display = to_intel_display(crtc_state);
>       enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
>       u32 cmtg_ctl;
> 
> -     if (!intel_cmtg_is_allowed(crtc_state))
> -             return;
> -
>       cmtg_ctl = CMTG_SYNC_TO_PORT | CMTG_ENABLE;
> 
>       intel_de_rmw(display, TRANS_CMTG_CTL(cpu_transcoder), 0, cmtg_ctl);
> @@ -352,15 +350,12 @@ void intel_cmtg_enable_sync(const struct
> intel_crtc_state *crtc_state)
>       }
>  }
> 
> -void intel_cmtg_enable_ddi(const struct intel_crtc_state *crtc_state)
> +static void intel_cmtg_enable_ddi(const struct intel_crtc_state
> +*crtc_state)
>  {
>       struct intel_display *display = to_intel_display(crtc_state);
>       struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
>       enum transcoder cpu_transcoder = crtc_state->cpu_transcoder;
> 
> -     if (!intel_cmtg_is_allowed(crtc_state))
> -             return;
> -
>       intel_de_rmw(display, TRANS_DDI_FUNC_CTL2(display,
> cpu_transcoder), 0, CMTG_SECONDARY_MODE);
>       intel_de_rmw(display, CMTG_SCANLINE_GB1(cpu_transcoder), 0,
> CMTG_HW_GB_ENABLE);
>       crtc->cmtg.enabled = true;
> @@ -371,7 +366,7 @@ void intel_cmtg_enable_ddi(const struct intel_crtc_state
> *crtc_state)
>  #define DC3CO_ENTRY_LATENCY_US       55
>  #define DC3CO_EXIT_LATENCY_US        40
> 
> -void intel_cmtg_set_hwgb(const struct intel_crtc_state *crtc_state)
> +static void intel_cmtg_set_hwgb(const struct intel_crtc_state
> +*crtc_state)
>  {
>       struct intel_display *display = to_intel_display(crtc_state);
>       enum transcoder cpu_transcoder = crtc_state->cpu_transcoder; @@ -
> 380,9 +375,6 @@ void intel_cmtg_set_hwgb(const struct intel_crtc_state
> *crtc_state)
>       u32 line_time_us = 75;  /* Max default initialization value */
>       u32 val;
> 
> -     if (!intel_cmtg_is_allowed(crtc_state))
> -             return;
> -
>       if (crtc_state->linetime)
>               line_time_us = DIV_ROUND_UP(crtc_state->linetime, 8);
> 
> @@ -398,3 +390,24 @@ void intel_cmtg_set_hwgb(const struct intel_crtc_state
> *crtc_state)
> 
>       intel_de_write(display, CMTG_HW_GB(cpu_transcoder), val);  }
> +
> +void intel_cmtg_program(struct intel_atomic_state *state) {
> +     struct intel_crtc *crtc;
> +     struct intel_crtc_state *new_crtc_state;
> +
> +     for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
> +             bool modeset = intel_crtc_needs_modeset(new_crtc_state);
> +
> +             if (!intel_cmtg_is_allowed(new_crtc_state))
> +                     continue;
> +             /*
> +              * TODO: CMTG needs to be restored on DC6 exit.
> +              */
> +             if (modeset && new_crtc_state->hw.active && !crtc-
> >cmtg.enabled) {
> +                     intel_cmtg_enable_sync(new_crtc_state);
> +                     intel_cmtg_set_hwgb(new_crtc_state);
> +                     intel_cmtg_enable_ddi(new_crtc_state);
> +             }
> +     }
> +}
> diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.h
> b/drivers/gpu/drm/i915/display/intel_cmtg.h
> index b2b68b38b7e3..a08cb2dcee67 100644
> --- a/drivers/gpu/drm/i915/display/intel_cmtg.h
> +++ b/drivers/gpu/drm/i915/display/intel_cmtg.h
> @@ -8,6 +8,7 @@
> 
>  #include <linux/types.h>
> 
> +struct intel_atomic_state;
>  struct intel_display;
>  struct intel_crtc_state;
> 
> @@ -17,8 +18,6 @@ enum set_timing_type {  };
> 
>  void intel_cmtg_disable(const struct intel_crtc_state *crtc_state); -void
> intel_cmtg_enable_ddi(const struct intel_crtc_state *crtc_state); -void
> intel_cmtg_enable_sync(const struct intel_crtc_state *crtc_state);  void
> intel_cmtg_set_m_n(const struct intel_crtc_state *crtc_state);  void
> intel_cmtg_set_vrr_timings(const struct intel_crtc_state *crtc_state);  void
> intel_cmtg_set_vrr_ctl(const struct intel_crtc_state *crtc_state); @@ -26,6 
> +25,6
> @@ void intel_cmtg_set_timings(const struct intel_crtc_state *crtc_state, enum
> set_  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); -void
> intel_cmtg_set_hwgb(const struct intel_crtc_state *crtc_state);
> +void intel_cmtg_program(struct intel_atomic_state *state);
> 
>  #endif /* __INTEL_CMTG_H__ */
> diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> b/drivers/gpu/drm/i915/display/intel_display.c
> index 62dc2b414f3c..e76aa6c8dab6 100644
> --- a/drivers/gpu/drm/i915/display/intel_display.c
> +++ b/drivers/gpu/drm/i915/display/intel_display.c
> @@ -1790,6 +1790,10 @@ static void hsw_crtc_disable(struct intel_atomic_state
> *state,
>               intel_atomic_get_old_crtc_state(state, crtc);
>       struct intel_crtc *pipe_crtc;
> 
> +     if (crtc->cmtg.enabled) {
> +             intel_cmtg_set_clk_select(old_crtc_state);
> +             intel_cmtg_disable(old_crtc_state);
> +     }
>       /*
>        * FIXME collapse everything to one hook.
>        * Need care with mst->ddi interactions.
> @@ -6898,6 +6902,11 @@ static void intel_update_crtc(struct intel_atomic_state
> *state,
>       if (intel_crtc_needs_fastset(new_crtc_state) &&
>           old_crtc_state->inherited)
>               intel_crtc_arm_fifo_underrun(crtc, new_crtc_state);
> +
> +     if (crtc->cmtg.enabled && (intel_crtc_vrr_enabling(state, crtc))) {
> +             intel_cmtg_set_clk_select(new_crtc_state);
> +             intel_cmtg_disable(new_crtc_state);
> +     }
>  }
> 
>  static void intel_old_crtc_state_disables(struct intel_atomic_state *state, 
> @@ -
> 7567,6 +7576,11 @@ static void intel_atomic_commit_tail(struct
> intel_atomic_state *state)
>       /* FIXME probably need to sequence this properly */
>       intel_program_dpkgc_latency(state);
> 
> +     /*
> +      * TODO: DC3co entry condition need to be checked before calling CMTG
> functions.
> +      */
> +     intel_cmtg_program(state);
> +
>       intel_wait_for_vblank_workers(state);
> 
>       /* FIXME: We should call drm_atomic_helper_commit_hw_done() here
> --
> 2.29.0

Reply via email to