From: "José Roberto de Souza" <jose.souza@intel.com>
To: intel-gfx@lists.freedesktop.org
Subject: [Intel-gfx] [PATCH 2/2] drm/i915/display/psr: Use continuos full frame to handle frontbuffer invalidations
Date: Thu, 24 Mar 2022 11:13:47 -0700 [thread overview]
Message-ID: <20220324181347.129378-2-jose.souza@intel.com> (raw)
In-Reply-To: <20220324181347.129378-1-jose.souza@intel.com>
Instead of exit PSR when a frontbuffer invalidation happens, we can
enable the PSR2 selective fetch continuous full frame, that will keep
the panel updated like PSR was disabled but without keeping PSR active.
So as soon as the frontbuffer flush happens we can disable the
continuous full frame and start to do selective fetches much quicker
than the path that would enable PSR, that will wait a few frames
to actually activate PSR.
Also this approach has proven to fix some glitches found in Alderlake-P
when there are a lot of invalidations happening together with page
flips.
Some may ask why it is writing to CURSURFLIVE(), it is because
that is the way that hardware team provided us to poke display to
handle PSR updates, and it is being used since display 9.
Cc: Khaled Almahallawy <khaled.almahallawy@intel.com>
Cc: Shawn C Lee <shawn.c.lee@intel.com>
Cc: Jouni Högander <jouni.hogander@intel.com>
Cc: Mika Kahola <mika.kahola@intel.com>
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
---
drivers/gpu/drm/i915/display/intel_psr.c | 109 ++++++++++++++++++++---
1 file changed, 95 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index d87b357806c91..f7b7b374374b1 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1450,6 +1450,22 @@ static inline u32 man_trk_ctl_partial_frame_bit_get(struct drm_i915_private *dev
PSR2_MAN_TRK_CTL_SF_PARTIAL_FRAME_UPDATE;
}
+static inline u32 man_trk_ctl_continuos_full_frame(struct drm_i915_private *dev_priv)
+{
+ return IS_ALDERLAKE_P(dev_priv) ?
+ ADLP_PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME :
+ PSR2_MAN_TRK_CTL_SF_CONTINUOS_FULL_FRAME;
+}
+
+static inline u32 man_trk_ctl_su_region_start_end_mask(struct drm_i915_private *dev_priv)
+{
+ if (IS_ALDERLAKE_P(dev_priv))
+ return ADLP_PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK |
+ ADLP_PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK;
+ return PSR2_MAN_TRK_CTL_SU_REGION_START_ADDR_MASK |
+ PSR2_MAN_TRK_CTL_SU_REGION_END_ADDR_MASK;
+}
+
static void psr_force_hw_tracking_exit(struct intel_dp *intel_dp)
{
struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
@@ -1546,8 +1562,9 @@ void intel_psr2_program_trans_man_trk_ctl(const struct intel_crtc_state *crtc_st
if (!crtc_state->enable_psr2_sel_fetch)
return;
- intel_de_write(dev_priv, PSR2_MAN_TRK_CTL(crtc_state->cpu_transcoder),
- crtc_state->psr2_man_track_ctl);
+ intel_de_rmw(dev_priv, PSR2_MAN_TRK_CTL(crtc_state->cpu_transcoder),
+ man_trk_ctl_su_region_start_end_mask(dev_priv),
+ crtc_state->psr2_man_track_ctl);
}
static void psr2_man_trk_ctl_calc(struct intel_crtc_state *crtc_state,
@@ -2127,6 +2144,26 @@ static void intel_psr_work(struct work_struct *work)
mutex_unlock(&intel_dp->psr.lock);
}
+static void _psr_invalidate_handle(struct intel_dp *intel_dp,
+ unsigned int prev_busy_frontbuffer_bits)
+{
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
+ if (intel_dp->psr.psr2_sel_fetch_enabled) {
+ u32 val = man_trk_ctl_continuos_full_frame(dev_priv) |
+ man_trk_ctl_partial_frame_bit_get(dev_priv);
+
+ /* continuos full frame is already enabled */
+ if (prev_busy_frontbuffer_bits)
+ return;
+
+ intel_de_rmw(dev_priv, PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder), 0, val);
+ intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
+ } else {
+ intel_psr_exit(intel_dp);
+ }
+}
+
/**
* intel_psr_invalidate - Invalidade PSR
* @dev_priv: i915 device
@@ -2151,6 +2188,7 @@ void intel_psr_invalidate(struct drm_i915_private *dev_priv,
for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {
unsigned int pipe_frontbuffer_bits = frontbuffer_bits;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ unsigned int prev_busy_frontbuffer_bits;
mutex_lock(&intel_dp->psr.lock);
if (!intel_dp->psr.enabled) {
@@ -2158,12 +2196,13 @@ void intel_psr_invalidate(struct drm_i915_private *dev_priv,
continue;
}
+ prev_busy_frontbuffer_bits = intel_dp->psr.busy_frontbuffer_bits;
pipe_frontbuffer_bits &=
INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe);
intel_dp->psr.busy_frontbuffer_bits |= pipe_frontbuffer_bits;
if (pipe_frontbuffer_bits)
- intel_psr_exit(intel_dp);
+ _psr_invalidate_handle(intel_dp, prev_busy_frontbuffer_bits);
mutex_unlock(&intel_dp->psr.lock);
}
@@ -2195,6 +2234,49 @@ tgl_dc3co_flush_locked(struct intel_dp *intel_dp, unsigned int frontbuffer_bits,
intel_dp->psr.dc3co_exit_delay);
}
+static void _psr_flush_handle(struct intel_dp *intel_dp,
+ unsigned int prev_busy_frontbuffer_bits)
+{
+ struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
+
+ if (intel_dp->psr.psr2_sel_fetch_enabled) {
+ /* is continuos full frame enabled? */
+ if (prev_busy_frontbuffer_bits) {
+ /* it is, can we turn it off? */
+ if (intel_dp->psr.busy_frontbuffer_bits == 0) {
+ u32 clear = man_trk_ctl_continuos_full_frame(dev_priv);
+ u32 set = man_trk_ctl_single_full_frame_bit_get(dev_priv) |
+ man_trk_ctl_partial_frame_bit_get(dev_priv);
+
+ /*
+ * turn continuos full frame off and do a single
+ * full frame
+ */
+ intel_de_rmw(dev_priv,
+ PSR2_MAN_TRK_CTL(intel_dp->psr.transcoder),
+ clear, set);
+ intel_de_write(dev_priv, CURSURFLIVE(intel_dp->psr.pipe), 0);
+ }
+ } else {
+ /*
+ * continuos full frame is disabled, only a single full
+ * frame is required
+ */
+ psr_force_hw_tracking_exit(intel_dp);
+ }
+ } else {
+ /*
+ * if prev_busy_frontbuffer_bits is set, it means that PSR is
+ * inactive
+ */
+ if (prev_busy_frontbuffer_bits == 0)
+ psr_force_hw_tracking_exit(intel_dp);
+
+ if (!intel_dp->psr.active && !intel_dp->psr.busy_frontbuffer_bits)
+ schedule_work(&intel_dp->psr.work);
+ }
+}
+
/**
* intel_psr_flush - Flush PSR
* @dev_priv: i915 device
@@ -2216,6 +2298,7 @@ void intel_psr_flush(struct drm_i915_private *dev_priv,
for_each_intel_encoder_with_psr(&dev_priv->drm, encoder) {
unsigned int pipe_frontbuffer_bits = frontbuffer_bits;
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+ unsigned int prev_busy_frontbuffer_bits;
mutex_lock(&intel_dp->psr.lock);
if (!intel_dp->psr.enabled) {
@@ -2223,6 +2306,7 @@ void intel_psr_flush(struct drm_i915_private *dev_priv,
continue;
}
+ prev_busy_frontbuffer_bits = intel_dp->psr.busy_frontbuffer_bits;
pipe_frontbuffer_bits &=
INTEL_FRONTBUFFER_ALL_MASK(intel_dp->psr.pipe);
intel_dp->psr.busy_frontbuffer_bits &= ~pipe_frontbuffer_bits;
@@ -2232,25 +2316,22 @@ void intel_psr_flush(struct drm_i915_private *dev_priv,
* we have to ensure that the PSR is not activated until
* intel_psr_resume() is called.
*/
- if (intel_dp->psr.paused) {
- mutex_unlock(&intel_dp->psr.lock);
- continue;
- }
+ if (intel_dp->psr.paused)
+ goto exit;
if (origin == ORIGIN_FLIP ||
(origin == ORIGIN_CURSOR_UPDATE &&
!intel_dp->psr.psr2_sel_fetch_enabled)) {
tgl_dc3co_flush_locked(intel_dp, frontbuffer_bits, origin);
- mutex_unlock(&intel_dp->psr.lock);
- continue;
+ goto exit;
}
- /* By definition flush = invalidate + flush */
- if (pipe_frontbuffer_bits)
- psr_force_hw_tracking_exit(intel_dp);
+ if (pipe_frontbuffer_bits == 0)
+ goto exit;
- if (!intel_dp->psr.active && !intel_dp->psr.busy_frontbuffer_bits)
- schedule_work(&intel_dp->psr.work);
+ /* By definition flush = invalidate + flush */
+ _psr_flush_handle(intel_dp, prev_busy_frontbuffer_bits);
+exit:
mutex_unlock(&intel_dp->psr.lock);
}
}
--
2.35.1
next prev parent reply other threads:[~2022-03-24 18:12 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-24 18:13 [Intel-gfx] [PATCH 1/2] drm/i915/display/psr: Set partial frame enable when forcing full frame fetch José Roberto de Souza
2022-03-24 18:13 ` José Roberto de Souza [this message]
2022-03-25 14:21 ` [Intel-gfx] [PATCH 2/2] drm/i915/display/psr: Use continuos full frame to handle frontbuffer invalidations Hogander, Jouni
2022-03-25 14:46 ` Souza, Jose
2022-03-30 6:23 ` Hogander, Jouni
2022-03-24 18:59 ` [Intel-gfx] ✗ Fi.CI.DOCS: warning for series starting with [1/2] drm/i915/display/psr: Set partial frame enable when forcing full frame fetch Patchwork
2022-03-24 19:26 ` [Intel-gfx] ✓ Fi.CI.BAT: success " Patchwork
2022-03-24 21:48 ` [Intel-gfx] ✗ Fi.CI.IGT: failure " Patchwork
2022-03-25 9:04 ` [Intel-gfx] [PATCH 1/2] " Hogander, Jouni
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=20220324181347.129378-2-jose.souza@intel.com \
--to=jose.souza@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox