When driver takes over display from firmware it does some checks and if possible it tries to avoid a modeset to improve user boot experience. But even if DRRS is supported it was being left disabled as intel_crtc_copy_fastset() was overwritten new state with the old one (hardware readout). So here checking if platform has only one set of m_n registers that can change on the fly between high and low clock, if yes we can keep DRRS enabled. Cc: Vidya Srinivas <vidya.srinivas@xxxxxxxxx> Cc: Ville Syrjälä <ville.syrjala@xxxxxxxxxxxxxxx> Signed-off-by: José Roberto de Souza <jose.souza@xxxxxxxxx> --- drivers/gpu/drm/i915/display/intel_display.c | 7 ++++-- drivers/gpu/drm/i915/display/intel_drrs.c | 24 ++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_drrs.h | 2 ++ 3 files changed, 31 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index 0decf3d242372..17d0cad9e1686 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -7086,8 +7086,11 @@ static void intel_crtc_copy_fastset(const struct intel_crtc_state *old_crtc_stat */ new_crtc_state->fdi_m_n = old_crtc_state->fdi_m_n; new_crtc_state->dp_m_n = old_crtc_state->dp_m_n; - new_crtc_state->dp_m2_n2 = old_crtc_state->dp_m2_n2; - new_crtc_state->has_drrs = old_crtc_state->has_drrs; + + if (!intel_drrs_crtc_copy_fastset(old_crtc_state, new_crtc_state)) { + new_crtc_state->dp_m2_n2 = old_crtc_state->dp_m2_n2; + new_crtc_state->has_drrs = old_crtc_state->has_drrs; + } } static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state, diff --git a/drivers/gpu/drm/i915/display/intel_drrs.c b/drivers/gpu/drm/i915/display/intel_drrs.c index 166caf293f7bc..d266fad83a086 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.c +++ b/drivers/gpu/drm/i915/display/intel_drrs.c @@ -300,3 +300,27 @@ void intel_crtc_drrs_init(struct intel_crtc *crtc) mutex_init(&crtc->drrs.mutex); crtc->drrs.cpu_transcoder = INVALID_TRANSCODER; } + +/** + * intel_drrs_crtc_copy_fastset - Handles crtc state copy during fastsets when + * new state has DRRS. + * @old_crtc_state: old crtc state + * @new_crtc_state: new crtc state + * + * Handle crtc state copy during fastsets trying to keep DRRS enabled. + * That can be done in platforms that supports change the dp_m_n register on + * the fly between high and low clocks. + * + * Returns true if crtc copy was already handled otherwise returns false. + */ +bool intel_drrs_crtc_copy_fastset(const struct intel_crtc_state *old_crtc_state, + struct intel_crtc_state *new_crtc_state) +{ + struct drm_i915_private *i915 = to_i915(old_crtc_state->uapi.crtc->dev); + + /* m2_n2 register needs to already be set */ + if (intel_cpu_transcoder_has_m2_n2(i915, new_crtc_state->cpu_transcoder)) + return false; + + return true; +} diff --git a/drivers/gpu/drm/i915/display/intel_drrs.h b/drivers/gpu/drm/i915/display/intel_drrs.h index 3ad1be1ad9c13..749ac717db063 100644 --- a/drivers/gpu/drm/i915/display/intel_drrs.h +++ b/drivers/gpu/drm/i915/display/intel_drrs.h @@ -24,5 +24,7 @@ void intel_drrs_invalidate(struct drm_i915_private *dev_priv, void intel_drrs_flush(struct drm_i915_private *dev_priv, unsigned int frontbuffer_bits); void intel_crtc_drrs_init(struct intel_crtc *crtc); +bool intel_drrs_crtc_copy_fastset(const struct intel_crtc_state *old_crtc_state, + struct intel_crtc_state *new_crtc_state); #endif /* __INTEL_DRRS_H__ */ -- 2.36.0