All of lore.kernel.org
 help / color / mirror / Atom feed
From: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [PATCH] drm/i915/display/psr: Configure and Program IO buffer Wake and Fast Wake
Date: Thu,  1 Apr 2021 20:05:11 +0300	[thread overview]
Message-ID: <20210401170511.40870-1-gwan-gyeong.mun@intel.com> (raw)

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.souza@intel.com>
Cc: Lee Shawn C <shawn.c.lee@intel.com>
Signed-off-by: Gwan-gyeong Mun <gwan-gyeong.mun@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	other threads:[~2021-04-01 17:10 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-04-01 17:05 Gwan-gyeong Mun [this message]
2021-04-01 20:45 ` [Intel-gfx] ✗ Fi.CI.CHECKPATCH: warning for drm/i915/display/psr: Configure and Program IO buffer Wake and Fast Wake Patchwork
2021-04-01 20:50 ` [Intel-gfx] ✗ Fi.CI.DOCS: " Patchwork
2021-04-01 21:13 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2021-04-02  3:10 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
2021-04-13 20:06 ` [Intel-gfx] [PATCH] " Souza, Jose

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210401170511.40870-1-gwan-gyeong.mun@intel.com \
    --to=gwan-gyeong.mun@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.