As per b.spec 49274, the IO buffer Wake lines and Fast Wake lines can be
calculated based on the following formula.

 IO buffer wake lines = ROUNDUP(PSR2 IO wake time / total line time in 
microseconds)
 Fast wake lines = ROUNDUP(PSR2 aux transaction time / total line time in 
microseconds)
 For both fields limit the minimum to 7 lines and maximum to 12 lines
 PSR2 IO wake time = 50us, PSR2 aux transaction time = 32us.

It calculates IO buffer Wake and Fast Wake based on b.spec 49274 and
programs it.

v2: Address Jose's review comment.
 - Do not overwrite the values.
 - Move calulating and validating of io_buffer_wake/fast_wake to
    intel_psr2_config_valid() from intel_psr_compute_config()
 - Add macros for hardcoded values.
 - Simplify and reuse the validating the io_buffer_wake/fast_wake.

v3: Rebased

Cc: José Roberto de Souza <jose.so...@intel.com>
Cc: Lee Shawn C <shawn.c....@intel.com>
Signed-off-by: Gwan-gyeong Mun <gwan-gyeong....@intel.com>
---
 .../drm/i915/display/intel_display_types.h    |  2 +
 drivers/gpu/drm/i915/display/intel_psr.c      | 65 +++++++++++++++----
 drivers/gpu/drm/i915/i915_reg.h               |  8 +++
 3 files changed, 63 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h 
b/drivers/gpu/drm/i915/display/intel_display_types.h
index e2e707c4dff5..79df8da9b89e 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1496,6 +1496,8 @@ struct intel_psr {
        u16 su_x_granularity;
        bool dc3co_enabled;
        u32 dc3co_exit_delay;
+       u32 io_buffer_wake;
+       u32 fast_wake;
        struct delayed_work dc3co_work;
        struct drm_dp_vsc_sdp vsc;
 };
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c 
b/drivers/gpu/drm/i915/display/intel_psr.c
index 54ad5c378355..a1fff724fb67 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -531,19 +531,15 @@ static void hsw_activate_psr2(struct intel_dp *intel_dp)
        val |= intel_psr2_get_tp_time(intel_dp);
 
        if (DISPLAY_VER(dev_priv) >= 12) {
-               /*
-                * TODO: 7 lines of IO_BUFFER_WAKE and FAST_WAKE are default
-                * values from BSpec. In order to setting an optimal power
-                * consumption, lower than 4k resoluition mode needs to decrese
-                * IO_BUFFER_WAKE and FAST_WAKE. And higher than 4K resolution
-                * mode needs to increase IO_BUFFER_WAKE and FAST_WAKE.
-                */
-               val |= TGL_EDP_PSR2_BLOCK_COUNT_NUM_2;
-               val |= TGL_EDP_PSR2_IO_BUFFER_WAKE(7);
-               val |= TGL_EDP_PSR2_FAST_WAKE(7);
+               if (intel_dp->psr.io_buffer_wake < 9 || intel_dp->psr.fast_wake 
< 9)
+                       val |= TGL_EDP_PSR2_BLOCK_COUNT_NUM_2;
+               else
+                       val |= TGL_EDP_PSR2_BLOCK_COUNT_NUM_3;
+               val |= 
TGL_EDP_PSR2_IO_BUFFER_WAKE(intel_dp->psr.io_buffer_wake);
+               val |= TGL_EDP_PSR2_FAST_WAKE(intel_dp->psr.fast_wake);
        } else if (DISPLAY_VER(dev_priv) >= 9) {
-               val |= EDP_PSR2_IO_BUFFER_WAKE(7);
-               val |= EDP_PSR2_FAST_WAKE(7);
+               val |= EDP_PSR2_IO_BUFFER_WAKE(intel_dp->psr.io_buffer_wake);
+               val |= EDP_PSR2_FAST_WAKE(intel_dp->psr.fast_wake);
        }
 
        if (intel_dp->psr.psr2_sel_fetch_enabled) {
@@ -724,7 +720,9 @@ static bool intel_psr2_config_valid(struct intel_dp 
*intel_dp,
        struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
        int crtc_hdisplay = crtc_state->hw.adjusted_mode.crtc_hdisplay;
        int crtc_vdisplay = crtc_state->hw.adjusted_mode.crtc_vdisplay;
+       u32 io_buffer_wake, io_buffer_wake_max, io_buffer_wake_min;
        int psr_max_h = 0, psr_max_v = 0, max_bpp = 0;
+       u32 fast_wake, fast_wake_max, fast_wake_min;
 
        if (!intel_dp->psr.sink_psr2_support)
                return false;
@@ -768,14 +766,26 @@ static bool intel_psr2_config_valid(struct intel_dp 
*intel_dp,
                psr_max_h = 5120;
                psr_max_v = 3200;
                max_bpp = 30;
+               io_buffer_wake_max = TGL_EDP_PSR2_IO_BUFFER_WAKE_MAX_LINES;
+               io_buffer_wake_min = TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES;
+               fast_wake_max = TGL_EDP_PSR2_FAST_WAKE_MAX_LINES;
+               fast_wake_min = TGL_EDP_PSR2_FAST_WAKE_MIN_LINES;
        } else if (DISPLAY_VER(dev_priv) >= 10) {
                psr_max_h = 4096;
                psr_max_v = 2304;
                max_bpp = 24;
+               io_buffer_wake_max = EDP_PSR2_IO_BUFFER_WAKE_MAX_LINES;
+               io_buffer_wake_min = EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES;
+               fast_wake_max = EDP_PSR2_FAST_WAKE_MAX_LINES;
+               fast_wake_min = EDP_PSR2_FAST_WAKE_MIN_LINES;
        } else if (IS_DISPLAY_VER(dev_priv, 9)) {
                psr_max_h = 3640;
                psr_max_v = 2304;
                max_bpp = 24;
+               io_buffer_wake_max = EDP_PSR2_IO_BUFFER_WAKE_MAX_LINES;
+               io_buffer_wake_min = EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES;
+               fast_wake_max = EDP_PSR2_FAST_WAKE_MAX_LINES;
+               fast_wake_min = EDP_PSR2_FAST_WAKE_MIN_LINES;
        }
 
        if (crtc_state->pipe_bpp > max_bpp) {
@@ -785,6 +795,37 @@ static bool intel_psr2_config_valid(struct intel_dp 
*intel_dp,
                return false;
        }
 
+       /*
+        * B.Spec 49274
+        * IO buffer wake lines = ROUNDUP(PSR2 IO wake time / total line time 
in microseconds)
+        * Fast wake lines = ROUNDUP(PSR2 aux transaction time / total line 
time in microseconds)
+        * For both fields limit the minimum to 7 lines and maximum to 12 lines
+        * PSR2 IO wake time = 50us, PSR2 aux transaction time = 32us.
+        */
+       io_buffer_wake = 
intel_usecs_to_scanlines(&crtc_state->uapi.adjusted_mode,
+                                                 EDP_PSR2_IO_WAKE_TIME);
+       fast_wake = intel_usecs_to_scanlines(&crtc_state->uapi.adjusted_mode,
+                                            EDP_PSR2_AUX_TRANSACTION_TIME);
+
+       if (io_buffer_wake < io_buffer_wake_min || io_buffer_wake > 
io_buffer_wake_max) {
+               drm_dbg_kms(&dev_priv->drm,
+                           "PSR condition failed: Invalid PSR2 IO Buffer Wake 
lines (%d)\n",
+                           io_buffer_wake);
+               return false;
+       }
+
+       if (fast_wake < fast_wake_min || fast_wake > fast_wake_max) {
+               drm_dbg_kms(&dev_priv->drm,
+                           "PSR condition failed: Invalid PSR2 FAST Wake lines 
(%d)\n",
+                           fast_wake);
+               return false;
+       }
+
+       intel_dp->psr.io_buffer_wake =
+               io_buffer_wake < EDP_PSR2_IO_BUFFER_WAKE_DEFAULT ? 
EDP_PSR2_IO_BUFFER_WAKE_DEFAULT : io_buffer_wake;
+       intel_dp->psr.fast_wake =
+               fast_wake < EDP_PSR2_FAST_WAKE_DEFAULT ? 
EDP_PSR2_FAST_WAKE_DEFAULT : fast_wake;
+
        /*
         * HW sends SU blocks of size four scan lines, which means the starting
         * X coordinate and Y granularity requirements will always be met. We
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index cbf7a60afe54..0fc121720364 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -4568,14 +4568,22 @@ enum {
 #define   EDP_MAX_SU_DISABLE_TIME(t)           ((t) << 20)
 #define   EDP_MAX_SU_DISABLE_TIME_MASK         (0x1f << 20)
 #define   EDP_PSR2_IO_BUFFER_WAKE_MAX_LINES    8
+#define   EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES    5
+#define   EDP_PSR2_IO_BUFFER_WAKE_DEFAULT      7
 #define   EDP_PSR2_IO_BUFFER_WAKE(lines)       
((EDP_PSR2_IO_BUFFER_WAKE_MAX_LINES - (lines)) << 13)
 #define   EDP_PSR2_IO_BUFFER_WAKE_MASK         (3 << 13)
+#define   EDP_PSR2_IO_WAKE_TIME                        50
+#define   TGL_EDP_PSR2_IO_BUFFER_WAKE_MAX_LINES        12
 #define   TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES        5
 #define   TGL_EDP_PSR2_IO_BUFFER_WAKE(lines)   (((lines) - 
TGL_EDP_PSR2_IO_BUFFER_WAKE_MIN_LINES) << 13)
 #define   TGL_EDP_PSR2_IO_BUFFER_WAKE_MASK     (7 << 13)
 #define   EDP_PSR2_FAST_WAKE_MAX_LINES         8
+#define   EDP_PSR2_FAST_WAKE_MIN_LINES         5
+#define   EDP_PSR2_FAST_WAKE_DEFAULT           7
 #define   EDP_PSR2_FAST_WAKE(lines)            ((EDP_PSR2_FAST_WAKE_MAX_LINES 
- (lines)) << 11)
 #define   EDP_PSR2_FAST_WAKE_MASK              (3 << 11)
+#define   EDP_PSR2_AUX_TRANSACTION_TIME                32
+#define   TGL_EDP_PSR2_FAST_WAKE_MAX_LINES     12
 #define   TGL_EDP_PSR2_FAST_WAKE_MIN_LINES     5
 #define   TGL_EDP_PSR2_FAST_WAKE(lines)                (((lines) - 
TGL_EDP_PSR2_FAST_WAKE_MIN_LINES) << 10)
 #define   TGL_EDP_PSR2_FAST_WAKE_MASK          (7 << 10)
-- 
2.30.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to