Blob Blame History Raw
From 6fbde5173ed9ff15062329f6c2c55c19bf74b0bc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= <ville.syrjala@linux.intel.com>
Date: Tue, 15 Mar 2022 15:59:57 +0200
Subject: drm/i915/fbc: Skip nuke when flip is pending
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: de5bd083d247cfcc0c21524366b473967fef7031
Patch-mainline: v5.19-rc1
References: jsc#PED-1166 jsc#PED-1168 jsc#PED-1170 jsc#PED-1218 jsc#PED-1220 jsc#PED-1222 jsc#PED-1223 jsc#PED-1225

Don't issue a nuke from frontbuffer flush while a flip is pending.
This avoids the DSPADDR/DSPSURF rmw abuse from the pre-snb nuke
from racing with the DSPADDR/DSPSURF write being performed by
the flip/plane update. The flip itself will already cause the nuke
so a double nuke is redundant.

Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20220315140001.1172-4-ville.syrjala@linux.intel.com
Reviewed-by: Mika Kahola <mika.kahola@intel.com>
Acked-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 drivers/gpu/drm/i915/display/intel_fbc.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fbc.c b/drivers/gpu/drm/i915/display/intel_fbc.c
index 539549224eb3..a31d1d778ce8 100644
--- a/drivers/gpu/drm/i915/display/intel_fbc.c
+++ b/drivers/gpu/drm/i915/display/intel_fbc.c
@@ -667,6 +667,10 @@ static bool intel_fbc_is_compressing(struct intel_fbc *fbc)
 
 static void intel_fbc_nuke(struct intel_fbc *fbc)
 {
+	struct drm_i915_private *i915 = fbc->i915;
+
+	drm_WARN_ON(&i915->drm, fbc->flip_pending);
+
 	trace_intel_fbc_nuke(fbc->state.plane);
 
 	fbc->funcs->nuke(fbc);
@@ -969,6 +973,7 @@ static void intel_fbc_update_state(struct intel_atomic_state *state,
 	struct intel_fbc_state *fbc_state = &fbc->state;
 
 	WARN_ON(plane_state->no_fbc_reason);
+	WARN_ON(fbc_state->plane && fbc_state->plane != plane);
 
 	fbc_state->plane = plane;
 
@@ -1273,6 +1278,7 @@ static void __intel_fbc_disable(struct intel_fbc *fbc)
 	__intel_fbc_cleanup_cfb(fbc);
 
 	fbc->state.plane = NULL;
+	fbc->flip_pending = false;
 	fbc->busy_bits = 0;
 }
 
@@ -1367,12 +1373,12 @@ static void __intel_fbc_flush(struct intel_fbc *fbc,
 	if (origin == ORIGIN_FLIP || origin == ORIGIN_CURSOR_UPDATE)
 		goto out;
 
-	if (fbc->busy_bits)
+	if (fbc->busy_bits || fbc->flip_pending)
 		goto out;
 
 	if (fbc->active)
 		intel_fbc_nuke(fbc);
-	else if (!fbc->flip_pending)
+	else
 		__intel_fbc_post_update(fbc);
 
 out:
-- 
2.38.1