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 | 15 ++++++++++++--- .../gpu/drm/i915/display/intel_display_power.c | 17 +++++++++++++++++ .../gpu/drm/i915/display/intel_display_power.h | 2 ++ 3 files changed, 31 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 36ff17b88be7..4662bccf30f4 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7556,12 +7556,21 @@ 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_and_reset_dc3co_to_dc6(display); /* - * TODO: CMTG needs to be restored on DC6 exit and DC3co entry condition - * need to be checked before calling CMTG functions. + * TODO: DC3co entry condition need to be checked before calling CMTG functions. */ - 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_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 751e6b7d4a29..637d547831c0 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -285,6 +285,19 @@ sanitize_target_dc_state(struct intel_display *display, return target_dc_state; } +bool intel_display_power_get_and_reset_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; + power_domains->dc3co_to_dc6 = false; + mutex_unlock(&power_domains->lock); + + return ret; +} + /** * intel_display_power_set_target_dc_state - Set target dc state. * @display: display device @@ -320,6 +333,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..b43d4146a78a 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,7 @@ 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_and_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
