Blob Blame History Raw
From 4d3a545e694c2451b84cc298c82fab34df0dc2c3 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Jos=C3=A9=20Roberto=20de=20Souza?= <jose.souza@intel.com>
Date: Mon, 8 Nov 2021 13:38:07 -0800
Subject: drm/i915/psr: Fix PSR2 handling of multiplanar format
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Git-commit: c582ffadbe6cf64be4544d9d168bcc520bd0c984
Patch-mainline: v5.17-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

When a plane with a multiplanar format is added to the state by
drm_atomic_add_affected_planes(), only the UV plane is
added, so a intel_atomic_get_new_plane_state() call to get the Y
plane state can return a null pointer.
To fix this, intel_atomic_get_plane_state() should be called and
the return needs to be checked for errors, as it could return a EAGAIN
as other atomic state could be holding the lock for the Y plane.

Other issue with the patch being fixed is that the Y plane is not
being committed to hardware because the corresponded plane bit is not
set in update_planes when UV and Y planes are added to the state by
drm_atomic_add_affected_planes().

Cc: Jouni Högander <jouni.hogander@intel.com>
Cc: Mika Kahola <mika.kahola@intel.com>
Fixes: 3809991ff5f4 ("drm/i915/display: Add initial selective fetch support for biplanar formats")
Signed-off-by: José Roberto de Souza <jose.souza@intel.com>
Reviewed-by: Jouni Högander <jouni.hogander@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20211108213807.39865-1-jose.souza@intel.com
Acked-by: Patrik Jakobsson <pjakobsson@suse.de>
---
 drivers/gpu/drm/i915/display/intel_psr.c | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 9d589d471e33..a1a663f362e7 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -1732,13 +1732,17 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
 		 * same area for Y plane as well.
 		 */
 		if (linked) {
-			struct intel_plane_state *linked_new_plane_state =
-			  intel_atomic_get_new_plane_state(state, linked);
-			struct drm_rect *linked_sel_fetch_area =
-			  &linked_new_plane_state->psr2_sel_fetch_area;
+			struct intel_plane_state *linked_new_plane_state;
+			struct drm_rect *linked_sel_fetch_area;
 
+			linked_new_plane_state = intel_atomic_get_plane_state(state, linked);
+			if (IS_ERR(linked_new_plane_state))
+				return PTR_ERR(linked_new_plane_state);
+
+			linked_sel_fetch_area = &linked_new_plane_state->psr2_sel_fetch_area;
 			linked_sel_fetch_area->y1 = sel_fetch_area->y1;
 			linked_sel_fetch_area->y2 = sel_fetch_area->y2;
+			crtc_state->update_planes |= BIT(linked->id);
 		}
 	}
 
-- 
2.38.1