Re: [PATCH 4/7] drm/i915/display/psr: Handle plane restrictions at every page flip

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 9/29/21 9:20 PM, Ville Syrjälä wrote:
On Wed, Sep 29, 2021 at 08:50:12PM +0300, Gwan-gyeong Mun wrote:


On 9/23/21 10:46 PM, José Roberto de Souza wrote:
PSR2 selective is not supported over rotated and scaled planes.
We had the rotation check in intel_psr2_sel_fetch_config_valid()
but that code path is only execute when a modeset is needed and
change those plane parameters do not require a modeset.

Also need to check those restricions in the second
for_each_oldnew_intel_plane_in_state() loop because the state could
only have a plane that is not affected by those restricitons but
the damaged area intersect with planes that has those restrictions,
so a full plane fetch is required.

BSpec: 55229
Cc: Gwan-gyeong Mun <gwan-gyeong.mun@xxxxxxxxx>
Signed-off-by: José Roberto de Souza <jose.souza@xxxxxxxxx>
---
   drivers/gpu/drm/i915/display/intel_psr.c | 45 ++++++++++++++----------
   1 file changed, 26 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c
index 1cc4130dec7b1..356e0e96abf4e 100644
--- a/drivers/gpu/drm/i915/display/intel_psr.c
+++ b/drivers/gpu/drm/i915/display/intel_psr.c
@@ -720,11 +720,7 @@ tgl_dc3co_exitline_compute_config(struct intel_dp *intel_dp,
   static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
   					      struct intel_crtc_state *crtc_state)
   {
-	struct intel_atomic_state *state = to_intel_atomic_state(crtc_state->uapi.state);
   	struct drm_i915_private *dev_priv = dp_to_i915(intel_dp);
-	struct intel_plane_state *plane_state;
-	struct intel_plane *plane;
-	int i;
if (!dev_priv->params.enable_psr2_sel_fetch &&
   	    intel_dp->psr.debug != I915_PSR_DEBUG_ENABLE_SEL_FETCH) {
@@ -739,14 +735,6 @@ static bool intel_psr2_sel_fetch_config_valid(struct intel_dp *intel_dp,
   		return false;
   	}
- for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
-		if (plane_state->uapi.rotation != DRM_MODE_ROTATE_0) {
-			drm_dbg_kms(&dev_priv->drm,
-				    "PSR2 sel fetch not enabled, plane rotated\n");
-			return false;
-		}
-	}
-
   	/* Wa_14010254185 Wa_14010103792 */
   	if (IS_TGL_DISPLAY_STEP(dev_priv, STEP_A0, STEP_C0)) {
   		drm_dbg_kms(&dev_priv->drm,
@@ -1586,6 +1574,26 @@ static void cursor_area_workaround(const struct intel_plane_state *new_plane_sta
   	clip_area_update(pipe_clip, damaged_area);
   }
+/*
+ * TODO: Not clear how to handle planes with negative position,
+ * also planes are not updated if they have a negative X
+ * position so for now doing a full update in this cases
+ *
+ * Plane scaling and rotation is not supported by selective fetch and both
+ * properties can change without a modeset, so need to be check at every
+ * atomic commmit.
+ */
+static bool psr2_sel_fetch_plane_state_supported(const struct intel_plane_state *plane_state)
+{
+	if (plane_state->uapi.dst.y1 < 0 ||
+	    plane_state->uapi.dst.x1 < 0 ||
intel_atomic_plane_check_clipping() function makes
plane_state->uapi.dst.x1 and plane_state->uapi.dst.y1 non-negative
values, so there is no need to deal with negative positions here.

Cursor can have negative coordinates as it's hardware that will do the
clipping for us.

Yes, you are right, thanks for pointing out it. The cursor plane's CUR_POS register has X and Y Position Sign bits.

Reviewed-by: Gwan-gyeong Mun <gwan-gyeong.mun@xxxxxxxxx>

And the rest of the changes look good to me.
+	    plane_state->scaler_id >= 0 ||
+	    plane_state->uapi.rotation != DRM_MODE_ROTATE_0)
+		return false;
+
+	return true;
+}
+
   int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
   				struct intel_crtc *crtc)
   {
@@ -1618,13 +1626,7 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
   		    !old_plane_state->uapi.visible)
   			continue;
- /*
-		 * TODO: Not clear how to handle planes with negative position,
-		 * also planes are not updated if they have a negative X
-		 * position so for now doing a full update in this cases
-		 */
-		if (new_plane_state->uapi.dst.y1 < 0 ||
-		    new_plane_state->uapi.dst.x1 < 0) {
+		if (!psr2_sel_fetch_plane_state_supported(new_plane_state)) {
   			full_update = true;
   			break;
   		}
@@ -1703,6 +1705,11 @@ int intel_psr2_sel_fetch_update(struct intel_atomic_state *state,
   		if (!drm_rect_intersect(&inter, &new_plane_state->uapi.dst))
   			continue;
+ if (!psr2_sel_fetch_plane_state_supported(new_plane_state)) {
+			full_update = true;
+			break;
+		}
+
   		sel_fetch_area = &new_plane_state->psr2_sel_fetch_area;
   		sel_fetch_area->y1 = inter.y1 - new_plane_state->uapi.dst.y1;
   		sel_fetch_area->y2 = inter.y2 - new_plane_state->uapi.dst.y1;





[Index of Archives]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux