]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
drm/i915/psr: Modify intel_dp_get_su_granularity to support panel replay
authorJouni Högander <jouni.hogander@intel.com>
Fri, 10 May 2024 09:38:18 +0000 (12:38 +0300)
committerJouni Högander <jouni.hogander@intel.com>
Wed, 15 May 2024 07:56:27 +0000 (10:56 +0300)
Currently intel_dp_get_su_granularity doesn't support panel replay.
This fix modifies it to support panel replay as well.

v4:
  - use drm_dp_dpcd_readb instead of drm_dp_dpcd_read
  - ensure return value is 0 if drm_dp_dpcd_readb fails
v3: use correct offset for DP_PANEL_PANEL_REPLAY_CAPABILITY
v2: rely on PSR definitions on common bits

Signed-off-by: Jouni Högander <jouni.hogander@intel.com>
Reviewed-by: Animesh Manna <animesh.manna@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240510093823.3146455-8-jouni.hogander@intel.com
drivers/gpu/drm/i915/display/intel_psr.c

index 0a5ce29f09d118fdc46712318dfa4699f6aec135..6d1f442f3d14e19614e223ab62e4c86a0d665676 100644 (file)
@@ -468,6 +468,40 @@ static u8 intel_dp_get_sink_sync_latency(struct intel_dp *intel_dp)
        return val;
 }
 
+static u8 intel_dp_get_su_capability(struct intel_dp *intel_dp)
+{
+       u8 su_capability = 0;
+
+       if (intel_dp->psr.sink_panel_replay_su_support)
+               drm_dp_dpcd_readb(&intel_dp->aux,
+                                 DP_PANEL_PANEL_REPLAY_CAPABILITY,
+                                 &su_capability);
+       else
+               su_capability = intel_dp->psr_dpcd[1];
+
+       return su_capability;
+}
+
+static unsigned int
+intel_dp_get_su_x_granularity_offset(struct intel_dp *intel_dp)
+{
+       return intel_dp->psr.sink_panel_replay_su_support ?
+               DP_PANEL_PANEL_REPLAY_X_GRANULARITY :
+               DP_PSR2_SU_X_GRANULARITY;
+}
+
+static unsigned int
+intel_dp_get_su_y_granularity_offset(struct intel_dp *intel_dp)
+{
+       return intel_dp->psr.sink_panel_replay_su_support ?
+               DP_PANEL_PANEL_REPLAY_Y_GRANULARITY :
+               DP_PSR2_SU_Y_GRANULARITY;
+}
+
+/*
+ * Note: Bits related to granularity are same in panel replay and psr
+ * registers. Rely on PSR definitions on these "common" bits.
+ */
 static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
 {
        struct drm_i915_private *i915 = dp_to_i915(intel_dp);
@@ -475,18 +509,29 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
        u16 w;
        u8 y;
 
-       /* If sink don't have specific granularity requirements set legacy ones */
-       if (!(intel_dp->psr_dpcd[1] & DP_PSR2_SU_GRANULARITY_REQUIRED)) {
+       /*
+        * TODO: Do we need to take into account panel supporting both PSR and
+        * Panel replay?
+        */
+
+       /*
+        * If sink don't have specific granularity requirements set legacy
+        * ones.
+        */
+       if (!(intel_dp_get_su_capability(intel_dp) &
+             DP_PSR2_SU_GRANULARITY_REQUIRED)) {
                /* As PSR2 HW sends full lines, we do not care about x granularity */
                w = 4;
                y = 4;
                goto exit;
        }
 
-       r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_X_GRANULARITY, &w, 2);
+       r = drm_dp_dpcd_read(&intel_dp->aux,
+                            intel_dp_get_su_x_granularity_offset(intel_dp),
+                            &w, 2);
        if (r != 2)
                drm_dbg_kms(&i915->drm,
-                           "Unable to read DP_PSR2_SU_X_GRANULARITY\n");
+                           "Unable to read selective update x granularity\n");
        /*
         * Spec says that if the value read is 0 the default granularity should
         * be used instead.
@@ -494,10 +539,12 @@ static void intel_dp_get_su_granularity(struct intel_dp *intel_dp)
        if (r != 2 || w == 0)
                w = 4;
 
-       r = drm_dp_dpcd_read(&intel_dp->aux, DP_PSR2_SU_Y_GRANULARITY, &y, 1);
+       r = drm_dp_dpcd_read(&intel_dp->aux,
+                            intel_dp_get_su_y_granularity_offset(intel_dp),
+                            &y, 1);
        if (r != 1) {
                drm_dbg_kms(&i915->drm,
-                           "Unable to read DP_PSR2_SU_Y_GRANULARITY\n");
+                           "Unable to read selective update y granularity\n");
                y = 4;
        }
        if (y == 0)
@@ -590,7 +637,8 @@ void intel_psr_init_dpcd(struct intel_dp *intel_dp)
        if (intel_dp->psr_dpcd[0])
                _psr_init_dpcd(intel_dp);
 
-       if (intel_dp->psr.sink_psr2_support)
+       if (intel_dp->psr.sink_psr2_support ||
+           intel_dp->psr.sink_panel_replay_su_support)
                intel_dp_get_su_granularity(intel_dp);
 }