[PATCH 34/36] drm/i915: Clean up intel_atomic_setup_scalers()

Ville Syrjala ville.syrjala at linux.intel.com
Wed Dec 18 16:10:51 UTC 2019


From: Ville Syrjälä <ville.syrjala at linux.intel.com>

intel_atomic_setup_scalers() is very hard to read.
Restructure it by making a clean separation between
the pfit and planes.

Signed-off-by: Ville Syrjälä <ville.syrjala at linux.intel.com>
---
 drivers/gpu/drm/i915/display/intel_atomic.c  | 135 ++++++++-----------
 drivers/gpu/drm/i915/display/intel_atomic.h  |   5 +-
 drivers/gpu/drm/i915/display/intel_display.c |   3 +-
 3 files changed, 62 insertions(+), 81 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic.c b/drivers/gpu/drm/i915/display/intel_atomic.c
index 5ade7c1a6114..085351d59655 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic.c
@@ -423,11 +423,37 @@ static void intel_plane_setup_scaler(struct intel_crtc_state *crtc_state,
 		      plane->base.base.id, plane->base.name);
 }
 
+static int skl_add_scaled_planes(struct intel_atomic_state *state,
+				 struct intel_crtc *crtc)
+{
+	struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
+	struct intel_crtc_state *crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+	const struct intel_crtc_scaler_state *scaler_state =
+		&crtc_state->scaler_state;
+	struct intel_plane *plane;
+
+	for_each_intel_plane_on_crtc(&dev_priv->drm, crtc, plane) {
+		int scaler_user = intel_plane_scaler_user(plane);
+		struct intel_plane_state *plane_state;
+
+		if ((scaler_state->scaler_users & BIT(scaler_user)) == 0)
+			continue;
+
+		plane_state = intel_atomic_get_plane_state(state, plane);
+		if (IS_ERR(plane_state))
+			return PTR_ERR(plane_state);
+
+		crtc_state->update_planes |= BIT(plane->id);
+	}
+
+	return 0;
+}
+
 /**
  * intel_atomic_setup_scalers() - setup scalers for crtc per staged requests
- * @dev_priv: i915 device
- * @intel_crtc: intel crtc
- * @crtc_state: incoming crtc_state to validate and setup scalers
+ * @state: the atomic state
+ * @crtc: the crtc
  *
  * This function sets up scalers based on staged scaling requests for
  * a @crtc and its planes. It is called from crtc level check path. If request
@@ -440,89 +466,46 @@ static void intel_plane_setup_scaler(struct intel_crtc_state *crtc_state,
  *         0 - scalers were setup succesfully
  *         error code - otherwise
  */
-int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
-			       struct intel_crtc *intel_crtc,
-			       struct intel_crtc_state *crtc_state)
+int intel_atomic_setup_scalers(struct intel_atomic_state *state,
+			       struct intel_crtc *crtc)
 {
-	struct drm_plane *plane = NULL;
-	struct intel_plane *intel_plane;
-	struct intel_plane_state *plane_state = NULL;
+	struct intel_crtc_state *new_crtc_state =
+		intel_atomic_get_new_crtc_state(state, crtc);
+	const struct intel_crtc_state *old_crtc_state =
+		intel_atomic_get_old_crtc_state(state, crtc);
 	struct intel_crtc_scaler_state *scaler_state =
-		&crtc_state->scaler_state;
-	struct drm_atomic_state *drm_state = crtc_state->uapi.state;
-	struct intel_atomic_state *intel_state = to_intel_atomic_state(drm_state);
-	int num_scalers_need;
+		&new_crtc_state->scaler_state;
+	struct intel_plane_state *new_plane_state;
+	struct intel_plane *plane;
+	int num_scaler_users = hweight32(scaler_state->scaler_users);
 	int i;
 
-	num_scalers_need = hweight32(scaler_state->scaler_users);
+	if (num_scaler_users > crtc->num_scalers) {
+		DRM_DEBUG_KMS("[CRTC:%d:%s] Too many scaling requests %d > %d\n",
+			      crtc->base.base.id, crtc->base.name,
+			      num_scaler_users, crtc->num_scalers);
+		return -EINVAL;
+	}
 
-	/*
-	 * High level flow:
-	 * - staged scaler requests are already in scaler_state->scaler_users
-	 * - check whether staged scaling requests can be supported
-	 * - add planes using scalers that aren't in current transaction
-	 * - assign scalers to requested users
-	 * - as part of plane commit, scalers will be committed
-	 *   (i.e., either attached or detached) to respective planes in hw
-	 * - as part of crtc_commit, scaler will be either attached or detached
-	 *   to crtc in hw
-	 */
+	if (skl_can_use_hq_scaler(old_crtc_state) !=
+	    skl_can_use_hq_scaler(new_crtc_state)) {
+		int ret;
 
-	/* fail if required scalers > available scalers */
-	if (num_scalers_need > intel_crtc->num_scalers){
-		DRM_DEBUG_KMS("Too many scaling requests %d > %d\n",
-			num_scalers_need, intel_crtc->num_scalers);
-		return -EINVAL;
+		ret = skl_add_scaled_planes(state, crtc);
+		if (ret)
+			return ret;
+
+		if (scaler_state->scaler_users & BIT(intel_crtc_scaler_user()))
+			new_crtc_state->update_pipe = true;
 	}
 
-	/* walkthrough scaler_users bits and start assigning scalers */
-	for (i = 0; i < sizeof(scaler_state->scaler_users) * 8; i++) {
-		/* skip if scaler not required */
-		if (!(scaler_state->scaler_users & (1 << i)))
+	intel_crtc_setup_scaler(new_crtc_state);
+
+	for_each_new_intel_plane_in_state(state, plane, new_plane_state, i) {
+		if (plane->pipe != crtc->pipe)
 			continue;
 
-		if (i == SKL_CRTC_INDEX) {
-			intel_crtc_setup_scaler(crtc_state);
-		} else {
-			/* plane scaler case: assign as a plane scaler */
-			/* find the plane that set the bit as scaler_user */
-			plane = drm_state->planes[i].ptr;
-
-			/*
-			 * to enable/disable hq mode, add planes that are using scaler
-			 * into this transaction
-			 */
-			if (!plane) {
-				struct drm_plane_state *state;
-
-				/*
-				 * GLK+ scalers don't have a HQ mode so it
-				 * isn't necessary to change between HQ and dyn mode
-				 * on those platforms.
-				 */
-				if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
-					continue;
-
-				plane = drm_plane_from_index(&dev_priv->drm, i);
-				state = drm_atomic_get_plane_state(drm_state, plane);
-				if (IS_ERR(state)) {
-					DRM_DEBUG_KMS("Failed to add [PLANE:%d] to drm_state\n",
-						plane->base.id);
-					return PTR_ERR(state);
-				}
-			}
-
-			intel_plane = to_intel_plane(plane);
-
-			/* plane on different crtc cannot be a scaler user of this crtc */
-			if (WARN_ON(intel_plane->pipe != intel_crtc->pipe))
-				continue;
-
-			plane_state = intel_atomic_get_new_plane_state(intel_state,
-								       intel_plane);
-
-			intel_plane_setup_scaler(crtc_state, plane_state);
-		}
+		intel_plane_setup_scaler(new_crtc_state, new_plane_state);
 	}
 
 	return 0;
diff --git a/drivers/gpu/drm/i915/display/intel_atomic.h b/drivers/gpu/drm/i915/display/intel_atomic.h
index 4cb565fd9c9b..bb8b1d7de72f 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic.h
+++ b/drivers/gpu/drm/i915/display/intel_atomic.h
@@ -46,9 +46,8 @@ struct intel_crtc_state *
 intel_atomic_get_crtc_state(struct drm_atomic_state *state,
 			    struct intel_crtc *crtc);
 
-int intel_atomic_setup_scalers(struct drm_i915_private *dev_priv,
-			       struct intel_crtc *intel_crtc,
-			       struct intel_crtc_state *crtc_state);
+int intel_atomic_setup_scalers(struct intel_atomic_state *state,
+			       struct intel_crtc *crtc);
 bool skl_can_use_hq_scaler(const struct intel_crtc_state *crtc_state);
 int intel_plane_scaler_user(struct intel_plane *plane);
 int intel_crtc_scaler_user(void);
diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c
index b38c2d8ffde2..99e90e8ef67e 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -12335,8 +12335,7 @@ static int intel_crtc_atomic_check(struct intel_atomic_state *state,
 		if (mode_changed || crtc_state->update_pipe)
 			ret = skl_update_scaler_crtc(crtc_state);
 		if (!ret)
-			ret = intel_atomic_setup_scalers(dev_priv, crtc,
-							 crtc_state);
+			ret = intel_atomic_setup_scalers(state, crtc);
 	}
 
 	if (HAS_IPS(dev_priv))
-- 
2.23.0



More information about the Intel-gfx-trybot mailing list