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); + 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); 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; + 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); -- 2.29.0
