Jelajahi Sumber

disp: msm: sde: consider num DS for mixer width

Helper function is returning the width of single mixer. During
atomic crtc check, the number of destination scaler is not
considered before width check and can fail possible higher
resolutions. The mixerwidth should be taken as a multiple of
num_ds_enabled.

Change-Id: Id9e5e0ccf0cebb54d2a242e039d8dc3676b3729f
Signed-off-by: Nilaan Gunabalachandran <[email protected]>
Nilaan Gunabalachandran 6 tahun lalu
induk
melakukan
233ded8506
1 mengubah file dengan 17 tambahan dan 24 penghapusan
  1. 17 24
      msm/sde/sde_crtc.c

+ 17 - 24
msm/sde/sde_crtc.c

@@ -4368,13 +4368,19 @@ static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc,
 	struct sde_crtc_state *cstate;
 	const struct drm_plane_state *pstate;
 	const struct drm_plane_state *pipe_staged[SSPP_MAX];
-	int rc = 0, multirect_count = 0, i;
+	int rc = 0, multirect_count = 0, i, mixer_width, mixer_height;
 
 	sde_crtc = to_sde_crtc(crtc);
 	cstate = to_sde_crtc_state(state);
 
 	memset(pipe_staged, 0, sizeof(pipe_staged));
 
+	mixer_width = sde_crtc_get_mixer_width(sde_crtc, cstate, mode);
+	mixer_height = sde_crtc_get_mixer_height(sde_crtc, cstate, mode);
+
+	if (cstate->num_ds_enabled)
+		mixer_width = mixer_width * cstate->num_ds_enabled;
+
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) {
 		if (IS_ERR_OR_NULL(pstate)) {
 			rc = PTR_ERR(pstate);
@@ -4427,6 +4433,15 @@ static int _sde_crtc_check_get_pstates(struct drm_crtc *crtc,
 				pstate->crtc_x, pstate->crtc_w, mode->hdisplay);
 			return -E2BIG;
 		}
+
+		if (cstate->num_ds_enabled &&
+				((pstate->crtc_h > mixer_height) ||
+				(pstate->crtc_w > mixer_width))) {
+			SDE_ERROR("plane w/h:%x*%x > mixer w/h:%x*%x\n",
+					pstate->crtc_w, pstate->crtc_h,
+					mixer_width, mixer_height);
+			return -E2BIG;
+		}
 	}
 
 	for (i = 1; i < SSPP_MAX; i++) {
@@ -4565,10 +4580,8 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
 	struct sde_crtc *sde_crtc;
 	struct plane_state *pstates = NULL;
 	struct sde_crtc_state *cstate;
-	const struct drm_plane_state *pstate;
-	struct drm_plane *plane;
 	struct drm_display_mode *mode;
-	int mixer_height, mixer_width, rc = 0;
+	int rc = 0;
 	struct sde_multirect_plane_states *multirect_plane = NULL;
 	struct drm_connector *conn;
 	struct drm_connector_list_iter conn_iter;
@@ -4625,26 +4638,6 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
 		}
 	drm_connector_list_iter_end(&conn_iter);
 
-	mixer_width = sde_crtc_get_mixer_width(sde_crtc, cstate, mode);
-	mixer_height = sde_crtc_get_mixer_height(sde_crtc, cstate, mode);
-
-	if (cstate->num_ds_enabled) {
-		if (!state->state)
-			goto end;
-
-		drm_atomic_crtc_state_for_each_plane_state(plane,
-							pstate, state) {
-			if ((pstate->crtc_h > mixer_height) ||
-					(pstate->crtc_w > mixer_width)) {
-				SDE_ERROR("plane w/h:%x*%x > mixer w/h:%x*%x\n",
-					pstate->crtc_w, pstate->crtc_h,
-					mixer_width, mixer_height);
-				return -E2BIG;
-				goto end;
-			}
-		}
-	}
-
 	_sde_crtc_setup_is_ppsplit(state);
 	_sde_crtc_setup_lm_bounds(crtc, state);