> -----Original Message-----
> From: Shankar, Uma <[email protected]>
> Sent: Thursday, June 11, 2026 11:57 PM
> To: Manna, Animesh <[email protected]>; intel-
> [email protected]; [email protected]
> Cc: Dibin Moolakadan Subrahmanian
> <[email protected]>; [email protected];
> Nikula, Jani <[email protected]>
> Subject: RE: [PATCH v8 18/20] drm/i915/cmtg: Add trigger to enable/disable
> cmtg
>
>
>
> > -----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 18/20] 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]
>
>
> > Signed-off-by: Animesh Manna <[email protected]>
> > ---
> > drivers/gpu/drm/i915/display/intel_cmtg.c | 25 ++++++++++----------
> > drivers/gpu/drm/i915/display/intel_cmtg.h | 4 +---
> > drivers/gpu/drm/i915/display/intel_display.c | 24 +++++++++++++++++++
> > 3 files changed, 38 insertions(+), 15 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.c
> > b/drivers/gpu/drm/i915/display/intel_cmtg.c
> > index 1d63b612c44b..b7f4be33ce2e 100644
> > --- a/drivers/gpu/drm/i915/display/intel_cmtg.c
> > +++ b/drivers/gpu/drm/i915/display/intel_cmtg.c
> > @@ -323,15 +323,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);
> > @@ -342,15 +339,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;
> > @@ -406,7 +400,7 @@ void intel_cmtg_disable_interrupt(const struct
> > intel_crtc_state *crtc_state)
> > #define DC3CO_ENTRY_LATENCY 55
> > #define DC3CO_EXIT_LATENCY 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; @@
> -
> > 415,9 +409,6 @@ void intel_cmtg_set_hwgb(const struct intel_crtc_state
> > *crtc_state)
> > u32 line_time_us = 75;
> > u32 val;
> >
> > - if (!intel_cmtg_is_allowed(crtc_state))
> > - return;
> > -
> > if (crtc_state->linetime)
> > line_time_us = DIV_ROUND_UP(crtc_state->linetime, 8);
> >
> > @@ -433,3 +424,13 @@ 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(const struct intel_crtc_state *crtc_state) {
> > + if (!intel_cmtg_is_allowed(crtc_state))
> > + return;
> > +
> > + intel_cmtg_enable_sync(crtc_state);
> > + intel_cmtg_set_hwgb(crtc_state);
> > + intel_cmtg_enable_ddi(crtc_state);
> > +}
> > diff --git a/drivers/gpu/drm/i915/display/intel_cmtg.h
> > b/drivers/gpu/drm/i915/display/intel_cmtg.h
> > index 2c801a74acf9..51fc3f5a89f4 100644
> > --- a/drivers/gpu/drm/i915/display/intel_cmtg.h
> > +++ b/drivers/gpu/drm/i915/display/intel_cmtg.h
> > @@ -12,8 +12,6 @@ struct intel_display; struct intel_crtc_state;
> >
> > 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); @@
> > -23,6 +21,6 @@ void intel_cmtg_sanitize(struct intel_display
> > *display); bool intel_cmtg_is_allowed(const struct intel_crtc_state
> > *crtc_state); void intel_cmtg_enable_interrupt(const struct
> > intel_crtc_state *crtc_state); void
> > intel_cmtg_disable_interrupt(const struct intel_crtc_state
> > *crtc_state); -void intel_cmtg_set_hwgb(const struct intel_crtc_state
> > *crtc_state);
> > +void intel_cmtg_program(const struct intel_crtc_state *crtc_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 e4763ac81c39..e751a4c37842 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -1790,6 +1790,11 @@ 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) {
>
> In this path we differ from enable where we check for cmtg_is_allowed as
> well.
> We can make both enable and disable consistent.
cmtg_is_allowed() is used inside cmtg functions in both enable and disable
sequence.
Just to double check adding below enable sequence code.
if (modeset && new_crtc_state->hw.active && !crtc->cmtg.enabled) {
intel_cmtg_program(new_crtc_state);
intel_cmtg_enable_interrupt(new_crtc_state);
}
Not sure if I am missing anything please let me know.
>
> > + intel_cmtg_set_clk_select(old_crtc_state);
> > + intel_cmtg_disable(old_crtc_state);
> > + intel_cmtg_disable_interrupt(old_crtc_state);
> > + }
> > /*
> > * FIXME collapse everything to one hook.
> > * Need care with mst->ddi interactions.
> > @@ -6878,6 +6883,12 @@ 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);
> > + intel_cmtg_disable_interrupt(new_crtc_state);
> > + }
> > }
> >
> > static void intel_old_crtc_state_disables(struct intel_atomic_state
> > *state, @@ -
> > 7547,6 +7558,19 @@ static void intel_atomic_commit_tail(struct
> > intel_atomic_state *state)
> > /* FIXME probably need to sequence this properly */
> > intel_program_dpkgc_latency(state);
> >
> > + for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state) {
> > + bool modeset = intel_crtc_needs_modeset(new_crtc_state);
> > +
> > + /*
> > + * TODO: CMTG needs to be restored on DC6 exit and DC3co
> > entry condition
> > + * need to be checked before calling CMTG functions.
> > + */
>
> Assuming this is going to be taken care as part of DC3Co enabling.
Yes.
Regards,
Animesh
>
> With above addressed, this is
> Reviewed-by: Uma Shankar <[email protected]>
>
> > + if (modeset && new_crtc_state->hw.active && !crtc-
> > >cmtg.enabled) {
> > + intel_cmtg_program(new_crtc_state);
> > + intel_cmtg_enable_interrupt(new_crtc_state);
> > + }
> > + }
> > +
> > intel_wait_for_vblank_workers(state);
> >
> > /* FIXME: We should call drm_atomic_helper_commit_hw_done()
> here
> > --
> > 2.29.0