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.srini...@intel.com>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Signed-off-by: José Roberto de Souza <jose.so...@intel.com>
---
 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 04bc296761be0..c6509c29e942b 100644
--- a/drivers/gpu/drm/i915/display/intel_drrs.c
+++ b/drivers/gpu/drm/i915/display/intel_drrs.c
@@ -305,3 +305,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

Reply via email to