Browse Source

disp: msm: sde: separate horz/vert max downscale checks

Separate the horizontal and vertical max downscale checks
as pre-downscale introduced different limits on different
axes. Also cleanup the variable names for max downscale
limit when pre-downscale is not enabled.

Change-Id: If01aac1844d0bd5133502a50dbc38197e11da5d5
Signed-off-by: Steve Cohen <[email protected]>
Steve Cohen 5 years ago
parent
commit
9992efa7a0
3 changed files with 79 additions and 51 deletions
  1. 2 2
      msm/sde/sde_hw_catalog.c
  2. 6 4
      msm/sde/sde_hw_catalog.h
  3. 71 45
      msm/sde/sde_plane.c

+ 2 - 2
msm/sde/sde_hw_catalog.c

@@ -1407,9 +1407,9 @@ static int _sde_sspp_setup_vigs(struct device_node *np,
 				MAX_DOWNSCALE_RATIO_INROT_PD_RT_DENOMINATOR;
 			sblk->in_rot_maxdwnscale_nrt =
 					MAX_DOWNSCALE_RATIO_INROT_NRT_DEFAULT;
-			sblk->in_rot_minpredwnscale_num =
+			sblk->in_rot_maxdwnscale_rt_nopd_num =
 				MAX_DOWNSCALE_RATIO_INROT_NOPD_RT_NUMERATOR;
-			sblk->in_rot_minpredwnscale_denom =
+			sblk->in_rot_maxdwnscale_rt_nopd_denom =
 				MAX_DOWNSCALE_RATIO_INROT_NOPD_RT_DENOMINATOR;
 		} else if (IS_SDE_INLINE_ROT_REV_100(
 				sde_cfg->true_inline_rot_rev)) {

+ 6 - 4
msm/sde/sde_hw_catalog.h

@@ -680,8 +680,10 @@ enum sde_qos_lut_usage {
  * @in_rot_maxdwnscale_rt_denom: max downscale ratio for inline rotation
  *                                 rt clients - denominator
  * @in_rot_maxdwnscale_nrt: max downscale ratio for inline rotation nrt clients
- * @in_rot_minpredwnscale_num: min downscale ratio to enable pre-downscale
- * @in_rot_minpredwnscale_denom: min downscale ratio to enable pre-downscale
+ * @in_rot_maxdwnscale_rt_nopd_num: downscale threshold for when pre-downscale
+ *                                    must be enabled on HW with this support.
+ * @in_rot_maxdwnscale_rt_nopd_denom: downscale threshold for when pre-downscale
+ *                                    must be enabled on HW with this support.
  * @in_rot_maxheight: max pre rotated height for inline rotation
  * @llcc_scid: scid for the system cache
  * @llcc_slice size: slice size of the system cache
@@ -718,8 +720,8 @@ struct sde_sspp_sub_blks {
 	u32 in_rot_maxdwnscale_rt_num;
 	u32 in_rot_maxdwnscale_rt_denom;
 	u32 in_rot_maxdwnscale_nrt;
-	u32 in_rot_minpredwnscale_num;
-	u32 in_rot_minpredwnscale_denom;
+	u32 in_rot_maxdwnscale_rt_nopd_num;
+	u32 in_rot_maxdwnscale_rt_nopd_denom;
 	u32 in_rot_maxheight;
 	int llcc_scid;
 	size_t llcc_slice_size;

+ 71 - 45
msm/sde/sde_plane.c

@@ -2275,11 +2275,17 @@ static int _sde_atomic_check_pre_downscale(struct sde_plane *psde,
 	int ret = 0;
 	u32 min_ratio_numer, min_ratio_denom;
 	struct sde_hw_inline_pre_downscale_cfg *pd_cfg = &pstate->pre_down;
-	bool pd_x = pd_cfg->pre_downscale_x_0 > 1;
-	bool pd_y = pd_cfg->pre_downscale_y_0 > 1;
+	bool pd_x;
+	bool pd_y;
 
-	min_ratio_numer = psde->pipe_sblk->in_rot_minpredwnscale_num;
-	min_ratio_denom = psde->pipe_sblk->in_rot_minpredwnscale_denom;
+	if (!_sde_plane_is_pre_downscale_enabled(pd_cfg))
+		return ret;
+
+	pd_x = pd_cfg->pre_downscale_x_0 > 1;
+	pd_y = pd_cfg->pre_downscale_y_0 > 1;
+
+	min_ratio_numer = psde->pipe_sblk->in_rot_maxdwnscale_rt_nopd_num;
+	min_ratio_denom = psde->pipe_sblk->in_rot_maxdwnscale_rt_nopd_denom;
 
 	if (pd_x && !_sde_plane_has_pre_downscale(psde)) {
 		SDE_ERROR_PLANE(psde,
@@ -2314,6 +2320,47 @@ static int _sde_atomic_check_pre_downscale(struct sde_plane *psde,
 	return ret;
 }
 
+static void _sde_plane_get_max_downscale_limits(struct sde_plane *psde,
+		struct sde_plane_state *pstate, bool rt_client,
+		u32 *max_numer_w, u32 *max_denom_w,
+		u32 *max_numer_h, u32 *max_denom_h)
+{
+	bool rotated, has_predown;
+	const struct sde_sspp_sub_blks *sblk;
+	struct sde_hw_inline_pre_downscale_cfg *pd;
+
+	rotated = pstate->rotation & DRM_MODE_ROTATE_90;
+	sblk = psde->pipe_sblk;
+	*max_numer_w = sblk->maxdwnscale;
+	*max_denom_w = 1;
+	*max_numer_h = sblk->maxdwnscale;
+	*max_denom_h = 1;
+
+	has_predown = _sde_plane_has_pre_downscale(psde);
+	if (has_predown)
+		pd = &pstate->pre_down;
+
+	/**
+	 * Inline rotation has different max vertical downscaling limits since
+	 * the source-width becomes the scaler's pre-downscaled source-height.
+	 **/
+	if (rotated) {
+		if (rt_client && has_predown) {
+			*max_numer_h = pd->pre_downscale_x_0 ?
+				sblk->in_rot_maxdwnscale_rt_num :
+				sblk->in_rot_maxdwnscale_rt_nopd_num;
+			*max_denom_h = pd->pre_downscale_x_0 ?
+				sblk->in_rot_maxdwnscale_rt_denom :
+				sblk->in_rot_maxdwnscale_rt_nopd_denom;
+		} else if (rt_client) {
+			*max_numer_h = sblk->in_rot_maxdwnscale_rt_num;
+			*max_denom_h = sblk->in_rot_maxdwnscale_rt_denom;
+		} else {
+			*max_numer_h = sblk->in_rot_maxdwnscale_nrt;
+		}
+	}
+}
+
 static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state,
 	struct sde_plane *psde, const struct sde_format *fmt,
 	struct sde_plane_state *pstate, struct sde_rect *src,
@@ -2322,11 +2369,13 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state,
 	int ret = 0;
 	uint32_t deci_w, deci_h, src_deci_w, src_deci_h;
 	uint32_t scaler_src_w, scaler_src_h;
-	uint32_t max_downscale_num, max_downscale_denom;
+	uint32_t max_downscale_num_w, max_downscale_denom_w;
+	uint32_t max_downscale_num_h, max_downscale_denom_h;
 	uint32_t max_upscale, max_linewidth;
-	bool inline_rotation, rt_client, has_predown, pre_down_en = false;
+	bool inline_rotation, rt_client;
 	struct drm_crtc *crtc;
 	struct drm_crtc_state *new_cstate;
+	const struct sde_sspp_sub_blks *sblk;
 
 	if (!state || !state->state || !state->crtc) {
 		SDE_ERROR_PLANE(psde, "invalid arguments\n");
@@ -2348,45 +2397,22 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state,
 		scaler_src_w = src_deci_w;
 		scaler_src_h = src_deci_h;
 	}
-
-	max_upscale = psde->pipe_sblk->maxupscale;
-	max_linewidth = psde->pipe_sblk->maxlinewidth;
-	has_predown = _sde_plane_has_pre_downscale(psde);
-	if (has_predown)
-		pre_down_en = _sde_plane_is_pre_downscale_enabled(
-				&pstate->pre_down);
+	sblk = psde->pipe_sblk;
+	max_upscale = sblk->maxupscale;
+	max_linewidth = sblk->maxlinewidth;
 
 	crtc = state->crtc;
 	new_cstate = drm_atomic_get_new_crtc_state(state->state, crtc);
-
 	rt_client = sde_crtc_is_rt_client(crtc, new_cstate);
 
-	max_downscale_num = psde->pipe_sblk->maxdwnscale;
-	max_downscale_denom = 1;
-	/* inline rotation RT clients have a different max downscaling limit */
-	if (inline_rotation) {
-		if (rt_client && has_predown) {
-			max_downscale_num = pre_down_en ?
-				psde->pipe_sblk->in_rot_maxdwnscale_rt_num :
-				psde->pipe_sblk->in_rot_minpredwnscale_num;
-			max_downscale_denom = pre_down_en ?
-				psde->pipe_sblk->in_rot_maxdwnscale_rt_denom :
-				psde->pipe_sblk->in_rot_minpredwnscale_denom;
-		} else if (rt_client) {
-			max_downscale_num =
-				psde->pipe_sblk->in_rot_maxdwnscale_rt_num;
-			max_downscale_denom =
-				psde->pipe_sblk->in_rot_maxdwnscale_rt_denom;
-		} else {
-			max_downscale_num =
-				psde->pipe_sblk->in_rot_maxdwnscale_nrt;
-		}
-	}
+	_sde_plane_get_max_downscale_limits(psde, pstate, rt_client,
+		&max_downscale_num_w, &max_downscale_denom_w,
+		&max_downscale_num_h, &max_downscale_denom_h);
 
 	/* decimation validation */
 	if ((deci_w || deci_h)
-			&& ((deci_w > psde->pipe_sblk->maxhdeciexp)
-				|| (deci_h > psde->pipe_sblk->maxvdeciexp))) {
+			&& ((deci_w > sblk->maxhdeciexp)
+				|| (deci_h > sblk->maxvdeciexp))) {
 		SDE_ERROR_PLANE(psde, "too much decimation requested\n");
 		ret = -EINVAL;
 
@@ -2412,21 +2438,21 @@ static int _sde_atomic_check_decimation_scaler(struct drm_plane_state *state,
 	/* check max scaler capability */
 	} else if (((scaler_src_w * max_upscale) < dst->w) ||
 		((scaler_src_h * max_upscale) < dst->h) ||
-		(mult_frac(dst->w, max_downscale_num, max_downscale_denom)
+		(mult_frac(dst->w, max_downscale_num_w, max_downscale_denom_w)
 			< scaler_src_w) ||
-		(mult_frac(dst->h, max_downscale_num, max_downscale_denom)
+		(mult_frac(dst->h, max_downscale_num_h, max_downscale_denom_h)
 			< scaler_src_h)) {
 		SDE_ERROR_PLANE(psde,
-			"too much scaling %ux%u->%ux%u rot:%d dwn:%d/%d\n",
+			"too much scaling %ux%u->%ux%u rot:%d dwn:%d/%d %d/%d\n",
 			scaler_src_w, scaler_src_h, dst->w, dst->h,
-			inline_rotation, max_downscale_num,
-			max_downscale_denom);
+			inline_rotation, max_downscale_num_w,
+			max_downscale_denom_w, max_downscale_num_h,
+			max_downscale_denom_h);
 		ret = -E2BIG;
 
 	/* check inline pre-downscale support */
-	} else if (inline_rotation && pre_down_en &&
-			_sde_atomic_check_pre_downscale(psde, pstate, dst,
-			src_deci_w, src_deci_h)) {
+	} else if (inline_rotation && _sde_atomic_check_pre_downscale(psde,
+			pstate, dst, src_deci_w, src_deci_h)) {
 		ret = -EINVAL;
 
 	/* QSEED validation */