> -----Original Message-----
> From: Dibin Moolakadan Subrahmanian
> <[email protected]>
> Sent: Thursday, May 21, 2026 5:17 PM
> To: Manna, Animesh <[email protected]>; intel-
> [email protected]; [email protected]
> Cc: Shankar, Uma <[email protected]>; [email protected];
> Nikula, Jani <[email protected]>
> Subject: Re: [PATCH v6 15/16] drm/i915/cmtg: Restore CMTG after DC6 entry
> 
> 
> On 13-05-2026 22:08, Animesh Manna wrote:
> > Restore CMTG registers after DC6 exit, as they lose their values in
> > the low-power state.
> >
> > Signed-off-by: Animesh Manna <[email protected]>
> > ---
> >   drivers/gpu/drm/i915/display/intel_display.c  | 12 ++++++++-
> >   .../drm/i915/display/intel_display_power.c    | 25 +++++++++++++++++++
> >   .../drm/i915/display/intel_display_power.h    |  3 +++
> >   3 files changed, 39 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/gpu/drm/i915/display/intel_display.c
> > b/drivers/gpu/drm/i915/display/intel_display.c
> > index 6dc561713c35..324a2c722422 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display.c
> > @@ -7544,9 +7544,19 @@ static void intel_atomic_commit_tail(struct
> > intel_atomic_state *state)
> >
> >     for_each_new_intel_crtc_in_state(state, crtc, new_crtc_state, i) {
> >             bool modeset = intel_crtc_needs_modeset(new_crtc_state);
> > +           bool dc3co_to_dc6 =
> intel_display_power_get_dc3co_to_dc6(display);
> >
> >             /* CMTG needs to be restored on DC6 exit and on modset*/
> > -           if (modeset && new_crtc_state->hw.active && !crtc-
> >cmtg.enabled) {
> > +           if ((modeset || dc3co_to_dc6) && new_crtc_state->hw.active
> && !crtc->cmtg.enabled) {
> > +                   if (dc3co_to_dc6) {
> > +                           intel_cmtg_set_clk_select(new_crtc_state);
> > +                           intel_cmtg_set_timings(new_crtc_state,
> false);
> 
> In the restore path, will the `lrr` argument always be false?
> In patch 4, the same function is called with `lrr = true`.

During lrr mode it will be true, otherwise always false.

> 
> > +                           intel_cmtg_set_vrr_timings(new_crtc_state);
> > +                           intel_cmtg_set_vrr_ctl(new_crtc_state);
> > +                           intel_cmtg_set_m_n(new_crtc_state);
> > +
>       intel_display_power_reset_dc3co_to_dc6(display);
> > +                   }
> > +
> >                     intel_cmtg_enable_sync(new_crtc_state);
> 
> As this path also executes after DC6 exit, please also follow the BSpec CMTG
> enable sequence for the PSR2 deep sleep case.

In PSR2 deep sleep case target_dc_state will be set to DC6 which should 
restrict CMTG access.

> 
> CMTG will not start running until PSR2 deep sleep exit completes, so this
> sequence can fail here for the non-modeset case.

Once PSR2 deep exit is completed then only we should set target_dc_state to 
Dc3co.

> 
> >                     intel_cmtg_set_hwgb(new_crtc_state);
> >                     intel_cmtg_enable_ddi(new_crtc_state);
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c
> > b/drivers/gpu/drm/i915/display/intel_display_power.c
> > index 80ecf373fb19..a0ea46895e2e 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_power.c
> > +++ b/drivers/gpu/drm/i915/display/intel_display_power.c
> > @@ -285,6 +285,27 @@ sanitize_target_dc_state(struct intel_display
> *display,
> >     return target_dc_state;
> >   }
> >
> > +bool intel_display_power_get_dc3co_to_dc6(struct intel_display
> > +*display) {
> > +   struct i915_power_domains *power_domains = &display-
> >power.domains;
> > +   bool ret;
> > +
> > +   mutex_lock(&power_domains->lock);
> > +   ret = power_domains->dc3co_to_dc6;
> > +   mutex_unlock(&power_domains->lock);
> > +
> > +   return ret;
> > +}
> > +
> > +void intel_display_power_reset_dc3co_to_dc6(struct intel_display
> > +*display) {
> > +   struct i915_power_domains *power_domains = &display-
> >power.domains;
> > +
> > +   mutex_lock(&power_domains->lock);
> > +   power_domains->dc3co_to_dc6 = false;
> > +   mutex_unlock(&power_domains->lock);
> > +}
> > +
> >   /**
> >    * intel_display_power_set_target_dc_state - Set target dc state.
> >    * @display: display device
> > @@ -320,6 +341,10 @@ void
> intel_display_power_set_target_dc_state(struct intel_display *display,
> >     if (!dc_off_enabled)
> >             intel_power_well_enable(display, power_well);
> >
> > +   if (power_domains->target_dc_state == DC_STATE_EN_DC3CO &&
> > +       state == DC_STATE_EN_UPTO_DC6)
> > +           power_domains->dc3co_to_dc6 = true;
> > +
> 
> This only updates the software target DC state and does not guarantee an
> actual DC6 entry or exit.
> If the intent is to detect a real DC6 exit transition, then
> gen9_disable_dc_states() looks like the more appropriate place for this.
> I can also see existing PHY restore related comments there.

From driver we are just allowing Dc-state, actual entry/exit is controlled by 
DMC.
I need both current requested state and previous dc-state so added here.

Regards,
Animesh

> 
> >     power_domains->target_dc_state = state;
> >
> >     if (!dc_off_enabled)
> > diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h
> > b/drivers/gpu/drm/i915/display/intel_display_power.h
> > index d616d5d09cbe..ce1225bbc789 100644
> > --- a/drivers/gpu/drm/i915/display/intel_display_power.h
> > +++ b/drivers/gpu/drm/i915/display/intel_display_power.h
> > @@ -138,6 +138,7 @@ struct i915_power_domains {
> >      */
> >     bool initializing;
> >     bool display_core_suspended;
> > +   bool dc3co_to_dc6;
> >     int power_well_count;
> >
> >     u32 dc_state;
> > @@ -183,6 +184,8 @@ void intel_display_power_suspend_late(struct
> intel_display *display, bool s2idle
> >   void intel_display_power_resume_early(struct intel_display *display);
> >   void intel_display_power_suspend(struct intel_display *display);
> >   void intel_display_power_resume(struct intel_display *display);
> > +bool intel_display_power_get_dc3co_to_dc6(struct intel_display
> > +*display); void intel_display_power_reset_dc3co_to_dc6(struct
> > +intel_display *display);
> >   void intel_display_power_set_target_dc_state(struct intel_display
> *display,
> >                                          u32 state);
> >   u32 intel_display_power_get_current_dc_state(struct intel_display
> > *display);

Reply via email to