[Freedreno] [DPU PATCH 2/2] drm/msm: dpu: Remove dpu_rect

Sean Paul seanpaul at chromium.org
Thu Jun 21 19:02:39 UTC 2018


Well, that was a lot stickier than I thought it would be! This patch
removes dpu_rect and its helpers in favor of drm_rect and its helpers.

Signed-off-by: Sean Paul <seanpaul at chromium.org>
---

Based on my tracepoints set.

 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c      |  86 ++++----
 drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h      |   2 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h   |   7 -
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c   |  10 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h   |   4 +-
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h       |  54 -----
 drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c |  25 ---
 drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c     | 185 ++++++++++--------
 drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h     |  10 +-
 9 files changed, 160 insertions(+), 223 deletions(-)

diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
index eefc1892ad47..86ed8cb45cee 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c
@@ -24,6 +24,7 @@
 #include <drm/drm_crtc.h>
 #include <drm/drm_crtc_helper.h>
 #include <drm/drm_flip_work.h>
+#include <drm/drm_rect.h>
 
 #include "dpu_kms.h"
 #include "dpu_hw_lm.h"
@@ -607,15 +608,15 @@ static void _dpu_crtc_program_lm_output_roi(struct drm_crtc *crtc)
 
 	lm_horiz_position = 0;
 	for (lm_idx = 0; lm_idx < dpu_crtc->num_mixers; lm_idx++) {
-		const struct dpu_rect *lm_roi = &crtc_state->lm_bounds[lm_idx];
+		const struct drm_rect *lm_roi = &crtc_state->lm_bounds[lm_idx];
 		struct dpu_hw_mixer *hw_lm = dpu_crtc->mixers[lm_idx].hw_lm;
 		struct dpu_hw_mixer_cfg cfg;
 
-		if (dpu_kms_rect_is_null(lm_roi))
+		if (!lm_roi || !drm_rect_visible(lm_roi))
 			continue;
 
-		cfg.out_width = lm_roi->w;
-		cfg.out_height = lm_roi->h;
+		cfg.out_width = drm_rect_width(lm_roi);
+		cfg.out_height = drm_rect_height(lm_roi);
 		cfg.right_mixer = lm_horiz_position++;
 		cfg.flags = 0;
 		hw_lm->ops.setup_mixer_out(hw_lm, &cfg);
@@ -634,7 +635,6 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 	struct dpu_hw_ctl *ctl;
 	struct dpu_hw_mixer *lm;
 	struct dpu_hw_stage_cfg *stage_cfg;
-	struct dpu_rect plane_crtc_roi;
 
 	u32 flush_mask;
 	uint32_t stage_idx, lm_idx;
@@ -656,11 +656,6 @@ static void _dpu_crtc_blend_setup_mixer(struct drm_crtc *crtc,
 		if (!state)
 			continue;
 
-		plane_crtc_roi.x = state->crtc_x;
-		plane_crtc_roi.y = state->crtc_y;
-		plane_crtc_roi.w = state->crtc_w;
-		plane_crtc_roi.h = state->crtc_h;
-
 		pstate = to_dpu_plane_state(state);
 		fb = state->fb;
 
@@ -1119,13 +1114,13 @@ static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc,
 	crtc_split_width = dpu_crtc_get_mixer_width(dpu_crtc, cstate, adj_mode);
 
 	for (i = 0; i < dpu_crtc->num_mixers; i++) {
-		cstate->lm_bounds[i].x = crtc_split_width * i;
-		cstate->lm_bounds[i].y = 0;
-		cstate->lm_bounds[i].w = crtc_split_width;
-		cstate->lm_bounds[i].h =
-			dpu_crtc_get_mixer_height(dpu_crtc, cstate, adj_mode);
-		trace_dpu_crtc_setup_lm_bounds(DRMID(crtc), i,
-					       &cstate->lm_bounds[i]);
+		struct drm_rect *r = &cstate->lm_bounds[i];
+		r->x1 = crtc_split_width * i;
+		r->y1 = 0;
+		r->x2 = r->x1 + crtc_split_width;
+		r->y2 = dpu_crtc_get_mixer_height(dpu_crtc, cstate, adj_mode);
+
+		trace_dpu_crtc_setup_lm_bounds(DRMID(crtc), i, r);
 	}
 
 	drm_mode_debug_printmodeline(adj_mode);
@@ -1822,6 +1817,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	int multirect_count = 0;
 	const struct drm_plane_state *pipe_staged[SSPP_MAX];
 	int left_zpos_cnt = 0, right_zpos_cnt = 0;
+	struct drm_rect crtc_rect = { 0 };
 
 	if (!crtc) {
 		DPU_ERROR("invalid crtc\n");
@@ -1850,8 +1846,13 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
 	_dpu_crtc_setup_lm_bounds(crtc, state);
 
+	crtc_rect.x2 = mode->hdisplay;
+	crtc_rect.y2 = mode->vdisplay;
+
 	 /* get plane state for all drm planes associated with crtc state */
 	drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) {
+		struct drm_rect dst, clip = crtc_rect;
+
 		if (IS_ERR_OR_NULL(pstate)) {
 			rc = PTR_ERR(pstate);
 			DPU_ERROR("%s: failed to get plane%d state, %d\n",
@@ -1879,14 +1880,13 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 
 		cnt++;
 
-		if (CHECK_LAYER_BOUNDS(pstate->crtc_y, pstate->crtc_h,
-				mode->vdisplay) ||
-		    CHECK_LAYER_BOUNDS(pstate->crtc_x, pstate->crtc_w,
-				mode->hdisplay)) {
+		dst = drm_plane_state_dest(pstate);
+		if (!drm_rect_intersect(&clip, &dst) ||
+		    !drm_rect_equals(&clip, &dst)) {
 			DPU_ERROR("invalid vertical/horizontal destination\n");
-			DPU_ERROR("y:%d h:%d vdisp:%d x:%d w:%d hdisp:%d\n",
-				pstate->crtc_y, pstate->crtc_h, mode->vdisplay,
-				pstate->crtc_x, pstate->crtc_w, mode->hdisplay);
+			DPU_ERROR("display: " DRM_RECT_FMT " plane: "
+				  DRM_RECT_FMT "\n", DRM_RECT_ARG(&crtc_rect),
+				  DRM_RECT_ARG(&dst));
 			rc = -E2BIG;
 			goto end;
 		}
@@ -1969,7 +1969,7 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 	 */
 	for (i = 1; i < cnt; i++) {
 		struct plane_state *prv_pstate, *cur_pstate;
-		struct dpu_rect left_rect, right_rect;
+		struct drm_rect left_rect, right_rect;
 		int32_t left_pid, right_pid;
 		int32_t stage;
 
@@ -1981,18 +1981,12 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 		stage = cur_pstate->stage;
 
 		left_pid = prv_pstate->dpu_pstate->base.plane->base.id;
-		POPULATE_RECT(&left_rect, prv_pstate->drm_pstate->crtc_x,
-			prv_pstate->drm_pstate->crtc_y,
-			prv_pstate->drm_pstate->crtc_w,
-			prv_pstate->drm_pstate->crtc_h, false);
+		left_rect = drm_plane_state_dest(prv_pstate->drm_pstate);
 
 		right_pid = cur_pstate->dpu_pstate->base.plane->base.id;
-		POPULATE_RECT(&right_rect, cur_pstate->drm_pstate->crtc_x,
-			cur_pstate->drm_pstate->crtc_y,
-			cur_pstate->drm_pstate->crtc_w,
-			cur_pstate->drm_pstate->crtc_h, false);
+		right_rect = drm_plane_state_dest(cur_pstate->drm_pstate);
 
-		if (right_rect.x < left_rect.x) {
+		if (right_rect.x1 < left_rect.x1) {
 			swap(left_pid, right_pid);
 			swap(left_rect, right_rect);
 		}
@@ -2010,19 +2004,21 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc,
 				stage, left_pid, right_pid);
 			rc = -EINVAL;
 			goto end;
-		} else if (right_rect.x != (left_rect.x + left_rect.w)) {
-			DPU_ERROR(
-				"non-contiguous coordinates for src split. stage: %d left: %d - %d right: %d - %d\n",
-				stage, left_rect.x, left_rect.w,
-				right_rect.x, right_rect.w);
+		} else if (right_rect.x1 != drm_rect_width(&left_rect)) {
+			DPU_ERROR("non-contiguous coordinates for src split. "
+				  "stage: %d left: " DRM_RECT_FMT " right: "
+				  DRM_RECT_FMT "\n", stage,
+				  DRM_RECT_ARG(&left_rect),
+				  DRM_RECT_ARG(&right_rect));
 			rc = -EINVAL;
 			goto end;
-		} else if ((left_rect.y != right_rect.y) ||
-				(left_rect.h != right_rect.h)) {
-			DPU_ERROR(
-				"source split at stage: %d. invalid yoff/height: l_y: %d r_y: %d l_h: %d r_h: %d\n",
-				stage, left_rect.y, right_rect.y,
-				left_rect.h, right_rect.h);
+		} else if (left_rect.y1 != right_rect.y1 ||
+			   drm_rect_height(&left_rect) != drm_rect_height(&right_rect)) {
+			DPU_ERROR("source split at stage: %d. invalid "
+				  "yoff/height: left: " DRM_RECT_FMT " right: "
+				  DRM_RECT_FMT "\n", stage,
+				  DRM_RECT_ARG(&left_rect),
+				  DRM_RECT_ARG(&right_rect));
 			rc = -EINVAL;
 			goto end;
 		}
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
index 39def93df641..7147dcb2be16 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h
@@ -318,7 +318,7 @@ struct dpu_crtc_state {
 	bool bw_split_vote;
 
 	bool is_ppsplit;
-	struct dpu_rect lm_bounds[CRTC_DUAL_MIXERS];
+	struct drm_rect lm_bounds[CRTC_DUAL_MIXERS];
 
 	uint64_t input_fence_timeout_ns;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
index 836ff9e87b2e..35e6bf930924 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h
@@ -424,13 +424,6 @@ struct dpu_hw_fmt_layout {
 	uint32_t plane_pitch[DPU_MAX_PLANES];
 };
 
-struct dpu_rect {
-	u16 x;
-	u16 y;
-	u16 w;
-	u16 h;
-};
-
 struct dpu_csc_cfg {
 	/* matrix coefficients in S15.16 format */
 	uint32_t csc_mv[DPU_CSC_MATRIX_COEFF_SIZE];
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
index 2b3f5e88af98..c25b52a6b219 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c
@@ -462,10 +462,12 @@ static void dpu_hw_sspp_setup_rects(struct dpu_hw_pipe *ctx,
 
 
 	/* src and dest rect programming */
-	src_xy = (cfg->src_rect.y << 16) | (cfg->src_rect.x);
-	src_size = (cfg->src_rect.h << 16) | (cfg->src_rect.w);
-	dst_xy = (cfg->dst_rect.y << 16) | (cfg->dst_rect.x);
-	dst_size = (cfg->dst_rect.h << 16) | (cfg->dst_rect.w);
+	src_xy = (cfg->src_rect.y1 << 16) | cfg->src_rect.x1;
+	src_size = (drm_rect_height(&cfg->src_rect) << 16) |
+		   drm_rect_width(&cfg->src_rect);
+	dst_xy = (cfg->dst_rect.y1 << 16) | cfg->dst_rect.x1;
+	dst_size = (drm_rect_height(&cfg->dst_rect) << 16) |
+		drm_rect_width(&cfg->dst_rect);
 
 	if (rect_index == DPU_SSPP_RECT_SOLO) {
 		ystride0 = (cfg->layout.plane_pitch[0]) |
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
index 0bb5ecb2f1b8..4d81e5f5ce1b 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h
@@ -164,8 +164,8 @@ struct dpu_hw_pixel_ext {
  */
 struct dpu_hw_pipe_cfg {
 	struct dpu_hw_fmt_layout layout;
-	struct dpu_rect src_rect;
-	struct dpu_rect dst_rect;
+	struct drm_rect src_rect;
+	struct drm_rect dst_rect;
 	enum dpu_sspp_multirect_index index;
 	enum dpu_sspp_multirect_mode mode;
 };
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
index 046e6f770560..fb4ae84a388a 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h
@@ -65,17 +65,6 @@
 
 #define DPU_ERROR(fmt, ...) pr_err("[dpu error]" fmt, ##__VA_ARGS__)
 
-#define POPULATE_RECT(rect, a, b, c, d, Q16_flag) \
-	do {						\
-		(rect)->x = (Q16_flag) ? (a) >> 16 : (a);    \
-		(rect)->y = (Q16_flag) ? (b) >> 16 : (b);    \
-		(rect)->w = (Q16_flag) ? (c) >> 16 : (c);    \
-		(rect)->h = (Q16_flag) ? (d) >> 16 : (d);    \
-	} while (0)
-
-#define CHECK_LAYER_BOUNDS(offset, size, max_size) \
-	(((size) > (max_size)) || ((offset) > ((max_size) - (size))))
-
 /**
  * ktime_compare_safe - compare two ktime structures
  *	This macro is similar to the standard ktime_compare() function, but
@@ -430,49 +419,6 @@ void dpu_kms_info_append_format(struct dpu_kms_info *info,
  */
 void dpu_kms_info_stop(struct dpu_kms_info *info);
 
-/**
- * dpu_kms_rect_intersect - intersect two rectangles
- * @r1: first rectangle
- * @r2: scissor rectangle
- * @result: result rectangle, all 0's on no intersection found
- */
-void dpu_kms_rect_intersect(const struct dpu_rect *r1,
-		const struct dpu_rect *r2,
-		struct dpu_rect *result);
-
-/**
- * dpu_kms_rect_is_equal - compares two rects
- * @r1: rect value to compare
- * @r2: rect value to compare
- *
- * Returns 1 if the rects are same, 0 otherwise.
- */
-static inline bool dpu_kms_rect_is_equal(struct dpu_rect *r1,
-		struct dpu_rect *r2)
-{
-	if ((!r1 && r2) || (r1 && !r2))
-		return false;
-
-	if (!r1 && !r2)
-		return true;
-
-	return r1->x == r2->x && r1->y == r2->y && r1->w == r2->w &&
-			r1->h == r2->h;
-}
-
-/**
- * dpu_kms_rect_is_null - returns true if the width or height of a rect is 0
- * @rect: rectangle to check for zero size
- * @Return: True if width or height of rectangle is 0
- */
-static inline bool dpu_kms_rect_is_null(const struct dpu_rect *r)
-{
-	if (!r)
-		return true;
-
-	return (!r->w || !r->h);
-}
-
 /**
  * Vblank enable/disable functions
  */
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c
index 40e016254227..a80b3da5a9fe 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms_utils.c
@@ -151,28 +151,3 @@ void dpu_kms_info_stop(struct dpu_kms_info *info)
 			info->len = info->staged_len + len;
 	}
 }
-
-void dpu_kms_rect_intersect(const struct dpu_rect *r1,
-		const struct dpu_rect *r2,
-		struct dpu_rect *result)
-{
-	int l, t, r, b;
-
-	if (!r1 || !r2 || !result)
-		return;
-
-	l = max(r1->x, r2->x);
-	t = max(r1->y, r2->y);
-	r = min((r1->x + r1->w), (r2->x + r2->w));
-	b = min((r1->y + r1->h), (r2->y + r2->h));
-
-	if (r <= l || b <= t) {
-		memset(result, 0, sizeof(*result));
-	} else {
-		result->x = l;
-		result->y = t;
-		result->w = r - l;
-		result->h = b - t;
-	}
-}
-
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
index 2c3dc00477b3..c2088a3bfba7 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c
@@ -180,8 +180,10 @@ static inline int _dpu_plane_calc_fill_level(struct drm_plane *plane,
 			continue;
 		DPU_DEBUG("plane%d/%d src_width:%d/%d\n",
 				pdpu->base.base.id, tmp->base.base.id,
-				src_width, tmp->pipe_cfg.src_rect.w);
-		src_width = max_t(u32, src_width, tmp->pipe_cfg.src_rect.w);
+				src_width,
+				drm_rect_width(&tmp->pipe_cfg.src_rect));
+		src_width = max_t(u32, src_width,
+				  drm_rect_width(&tmp->pipe_cfg.src_rect));
 	}
 
 	if (fmt->fetch_planes == DPU_PLANE_PSEUDO_PLANAR) {
@@ -272,7 +274,7 @@ static void _dpu_plane_set_qos_lut(struct drm_plane *plane,
 				fb->format->format,
 				fb->modifier);
 		total_fl = _dpu_plane_calc_fill_level(plane, fmt,
-				pdpu->pipe_cfg.src_rect.w);
+				drm_rect_width(&pdpu->pipe_cfg.src_rect));
 
 		if (fmt && DPU_FORMAT_IS_LINEAR(fmt))
 			lut_usage = DPU_QOS_LUT_USAGE_LINEAR;
@@ -493,8 +495,8 @@ static void _dpu_plane_set_ot_limit(struct drm_plane *plane,
 	memset(&ot_params, 0, sizeof(ot_params));
 	ot_params.xin_id = pdpu->pipe_hw->cap->xin_id;
 	ot_params.num = pdpu->pipe_hw->idx - SSPP_NONE;
-	ot_params.width = pdpu->pipe_cfg.src_rect.w;
-	ot_params.height = pdpu->pipe_cfg.src_rect.h;
+	ot_params.width = drm_rect_width(&pdpu->pipe_cfg.src_rect);
+	ot_params.height = drm_rect_height(&pdpu->pipe_cfg.src_rect);
 	ot_params.is_wfd = !pdpu->is_rt_pipe;
 	ot_params.frame_rate = crtc->mode.vrefresh;
 	ot_params.vbif_idx = VBIF_RT;
@@ -757,10 +759,10 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu,
 
 	/* update scaler. calculate default config for QSEED3 */
 	_dpu_plane_setup_scaler3(pdpu, pstate,
-			pdpu->pipe_cfg.src_rect.w,
-			pdpu->pipe_cfg.src_rect.h,
-			pdpu->pipe_cfg.dst_rect.w,
-			pdpu->pipe_cfg.dst_rect.h,
+			drm_rect_width(&pdpu->pipe_cfg.src_rect),
+			drm_rect_height(&pdpu->pipe_cfg.src_rect),
+			drm_rect_width(&pdpu->pipe_cfg.dst_rect),
+			drm_rect_height(&pdpu->pipe_cfg.dst_rect),
 			&pstate->scaler3_cfg, fmt,
 			chroma_subsmpl_h, chroma_subsmpl_v);
 }
@@ -807,10 +809,12 @@ static int _dpu_plane_color_fill(struct dpu_plane *pdpu,
 				pstate->multirect_index);
 
 		/* override scaler/decimation if solid fill */
-		pdpu->pipe_cfg.src_rect.x = 0;
-		pdpu->pipe_cfg.src_rect.y = 0;
-		pdpu->pipe_cfg.src_rect.w = pdpu->pipe_cfg.dst_rect.w;
-		pdpu->pipe_cfg.src_rect.h = pdpu->pipe_cfg.dst_rect.h;
+		pdpu->pipe_cfg.src_rect.x1 = 0;
+		pdpu->pipe_cfg.src_rect.y1 = 0;
+		pdpu->pipe_cfg.src_rect.x2 =
+			drm_rect_width(&pdpu->pipe_cfg.dst_rect);
+		pdpu->pipe_cfg.src_rect.y2 =
+			drm_rect_height(&pdpu->pipe_cfg.dst_rect);
 		_dpu_plane_setup_scaler(pdpu, pstate, fmt, true);
 
 		if (pdpu->pipe_hw->ops.setup_format)
@@ -854,10 +858,9 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 {
 	struct dpu_plane_state *pstate[R_MAX];
 	const struct drm_plane_state *drm_state[R_MAX];
-	struct dpu_rect src[R_MAX], dst[R_MAX];
+	struct drm_rect src[R_MAX], dst[R_MAX];
 	struct dpu_plane *dpu_plane[R_MAX];
 	const struct dpu_format *fmt[R_MAX];
-	bool q16_data = true;
 	int i, buffer_lines;
 	unsigned int max_tile_height = 1;
 	bool parallel_fetch_qualified = true;
@@ -889,13 +892,15 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 			return -EINVAL;
 		}
 
-		POPULATE_RECT(&src[i], drm_state[i]->src_x, drm_state[i]->src_y,
-			drm_state[i]->src_w, drm_state[i]->src_h, q16_data);
-		POPULATE_RECT(&dst[i], drm_state[i]->crtc_x,
-				drm_state[i]->crtc_y, drm_state[i]->crtc_w,
-				drm_state[i]->crtc_h, !q16_data);
+		src[i].x1 = drm_state[i]->src_x >> 16;
+		src[i].y1 = drm_state[i]->src_y >> 16;
+		src[i].x2 = src[i].x1 + (drm_state[i]->src_w >> 16);
+		src[i].y2 = src[i].y1 + (drm_state[i]->src_h >> 16);
 
-		if (src[i].w != dst[i].w || src[i].h != dst[i].h) {
+		dst[i] = drm_plane_state_dest(drm_state[i]);
+
+		if (drm_rect_calc_hscale(&src[i], &dst[i], 1, 1) != 1 ||
+		    drm_rect_calc_vscale(&src[i], &dst[i], 1, 1) != 1) {
 			DPU_ERROR_PLANE(dpu_plane[i],
 				"scaling is not supported in multirect mode\n");
 			return -EINVAL;
@@ -918,7 +923,8 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 		if (has_tiled_rect)
 			width_threshold /= 2;
 
-		if (parallel_fetch_qualified && src[i].w > width_threshold)
+		if (parallel_fetch_qualified &&
+		    drm_rect_width(&src[i]) > width_threshold)
 			parallel_fetch_qualified = false;
 
 	}
@@ -936,8 +942,8 @@ int dpu_plane_validate_multirect_v2(struct dpu_multirect_plane_states *plane)
 	/* TIME_MX Mode */
 	buffer_lines = 2 * max_tile_height;
 
-	if ((dst[R1].y >= dst[R0].y + dst[R0].h + buffer_lines) ||
-		(dst[R0].y >= dst[R1].y + dst[R1].h + buffer_lines)) {
+	if (dst[R1].y1 >= dst[R0].y2 + buffer_lines ||
+	    dst[R0].y1 >= dst[R1].y2 + buffer_lines) {
 		pstate[R0]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
 		pstate[R1]->multirect_mode = DPU_SSPP_MULTIRECT_TIME_MX;
 	} else {
@@ -1059,6 +1065,25 @@ static void dpu_plane_cleanup_fb(struct drm_plane *plane,
 	msm_framebuffer_cleanup(old_state->fb, old_pstate->aspace);
 }
 
+static bool dpu_plane_validate_src(struct drm_rect *src,
+				   struct drm_rect *fb_rect,
+				   uint32_t min_src_size)
+{
+	/* Ensure fb size is supported */
+	if (drm_rect_width(fb_rect) > MAX_IMG_WIDTH ||
+	    drm_rect_height(fb_rect) > MAX_IMG_HEIGHT)
+		return false;
+
+	/* Ensure src rect is above the minimum size */
+	if (drm_rect_width(src) < min_src_size ||
+	    drm_rect_height(src) < min_src_size)
+		return false;
+
+	/* Ensure src is fully encapsulated in fb */
+	return drm_rect_intersect(fb_rect, src) &&
+		drm_rect_equals(fb_rect, src);
+}
+
 static int dpu_plane_sspp_atomic_check(struct drm_plane *plane,
 		struct drm_plane_state *state)
 {
@@ -1066,9 +1091,10 @@ static int dpu_plane_sspp_atomic_check(struct drm_plane *plane,
 	struct dpu_plane *pdpu;
 	struct dpu_plane_state *pstate;
 	const struct dpu_format *fmt;
-	struct dpu_rect src, dst;
-	uint32_t max_upscale, max_downscale, min_src_size, max_linewidth;
-	bool q16_data = true;
+	struct drm_rect src, dst, fb_rect = { 0 };
+	uint32_t max_upscale = 1, max_downscale = 1;
+	uint32_t min_src_size, max_linewidth;
+	int hscale = 1, vscale = 1;
 
 	if (!plane || !state) {
 		DPU_ERROR("invalid arg(s), plane %d state %d\n",
@@ -1086,16 +1112,31 @@ static int dpu_plane_sspp_atomic_check(struct drm_plane *plane,
 		goto exit;
 	}
 
-	/* src values are in Q16 fixed point, convert to integer */
-	POPULATE_RECT(&src, state->src_x, state->src_y, state->src_w,
-		state->src_h, q16_data);
-	POPULATE_RECT(&dst, state->crtc_x, state->crtc_y, state->crtc_w,
-		state->crtc_h, !q16_data);
+	src.x1 = state->src_x >> 16;
+	src.y1 = state->src_y >> 16;
+	src.x2 = src.x1 + (state->src_w >> 16);
+	src.y2 = src.y1 + (state->src_h >> 16);
+
+	dst = drm_plane_state_dest(state);
+
+	fb_rect.x2 = state->fb->width;
+	fb_rect.y2 = state->fb->height;
 
-	max_upscale = pdpu->pipe_sblk->maxupscale;
-	max_downscale = pdpu->pipe_sblk->maxdwnscale;
 	max_linewidth = pdpu->pipe_sblk->common->maxlinewidth;
 
+	if (pdpu->features & DPU_SSPP_SCALER) {
+		max_downscale = pdpu->pipe_sblk->maxdwnscale;
+		max_upscale = pdpu->pipe_sblk->maxupscale;
+	}
+	if (drm_rect_width(&src) < drm_rect_width(&dst))
+		hscale = drm_rect_calc_hscale(&src, &dst, 1, max_upscale);
+	else
+		hscale = drm_rect_calc_hscale(&dst, &src, 1, max_downscale);
+	if (drm_rect_height(&src) < drm_rect_height(&dst))
+		vscale = drm_rect_calc_vscale(&src, &dst, 1, max_upscale);
+	else
+		vscale = drm_rect_calc_vscale(&dst, &src, 1, max_downscale);
+
 	DPU_DEBUG_PLANE(pdpu, "check %d -> %d\n",
 		dpu_plane_enabled(plane->state), dpu_plane_enabled(state));
 
@@ -1115,51 +1156,37 @@ static int dpu_plane_sspp_atomic_check(struct drm_plane *plane,
 		ret = -EINVAL;
 
 	/* check src bounds */
-	} else if (state->fb->width > MAX_IMG_WIDTH ||
-		state->fb->height > MAX_IMG_HEIGHT ||
-		src.w < min_src_size || src.h < min_src_size ||
-		CHECK_LAYER_BOUNDS(src.x, src.w, state->fb->width) ||
-		CHECK_LAYER_BOUNDS(src.y, src.h, state->fb->height)) {
-		DPU_ERROR_PLANE(pdpu, "invalid source %u, %u, %ux%u\n",
-			src.x, src.y, src.w, src.h);
+	} else if (!dpu_plane_validate_src(&src, &fb_rect, min_src_size)) {
+		DPU_ERROR_PLANE(pdpu, "invalid source " DRM_RECT_FMT "\n",
+				DRM_RECT_ARG(&src));
 		ret = -E2BIG;
 
 	/* valid yuv image */
-	} else if (DPU_FORMAT_IS_YUV(fmt) && ((src.x & 0x1) || (src.y & 0x1) ||
-			 (src.w & 0x1) || (src.h & 0x1))) {
-		DPU_ERROR_PLANE(pdpu, "invalid yuv source %u, %u, %ux%u\n",
-				src.x, src.y, src.w, src.h);
+	} else if (DPU_FORMAT_IS_YUV(fmt) &&
+		   (src.x1 & 0x1 || src.y1 & 0x1 ||
+		    drm_rect_width(&src) & 0x1 ||
+		    drm_rect_height(&src) & 0x1)) {
+		DPU_ERROR_PLANE(pdpu, "invalid yuv source " DRM_RECT_FMT "\n",
+				DRM_RECT_ARG(&src));
 		ret = -EINVAL;
 
 	/* min dst support */
-	} else if (dst.w < 0x1 || dst.h < 0x1) {
-		DPU_ERROR_PLANE(pdpu, "invalid dest rect %u, %u, %ux%u\n",
-				dst.x, dst.y, dst.w, dst.h);
-		ret = -EINVAL;
-
-	/* decimation validation */
-	} else if (!(pdpu->features & DPU_SSPP_SCALER) &&
-		((src.w != dst.w) || (src.h != dst.h))) {
-		DPU_ERROR_PLANE(pdpu,
-			"pipe doesn't support scaling %ux%u->%ux%u\n",
-			src.w, src.h, dst.w, dst.h);
+	} else if (drm_rect_width(&dst) < 0x1 || drm_rect_height(&dst) < 0x1) {
+		DPU_ERROR_PLANE(pdpu, "invalid dest rect " DRM_RECT_FMT "\n",
+				DRM_RECT_ARG(&dst));
 		ret = -EINVAL;
 
 	/* check decimated source width */
-	} else if (src.w > max_linewidth) {
-		DPU_ERROR_PLANE(pdpu,
-				"invalid src w:%u, line w:%u\n",
-				src.w, max_linewidth);
+	} else if (drm_rect_width(&src) > max_linewidth) {
+		DPU_ERROR_PLANE(pdpu, "invalid src " DRM_RECT_FMT " line:%u\n",
+				DRM_RECT_ARG(&src), max_linewidth);
 		ret = -E2BIG;
 
-	/* check max scaler capability */
-	} else if (((src.w * max_upscale) < dst.w) ||
-		((src.h * max_upscale) < dst.h) ||
-		((dst.w * max_downscale) < src.w) ||
-		((dst.h * max_downscale) < src.h)) {
-		DPU_ERROR_PLANE(pdpu,
-			"too much scaling requested %ux%u->%ux%u\n",
-			src.w, src.h, dst.w, dst.h);
+	/* check scaler capability */
+	} else if (hscale < 0 || vscale < 0) {
+		DPU_ERROR_PLANE(pdpu, "invalid scaling requested src="
+				DRM_RECT_FMT " dst=" DRM_RECT_FMT "\n",
+				DRM_RECT_ARG(&src), DRM_RECT_ARG(&dst));
 		ret = -E2BIG;
 	}
 
@@ -1253,8 +1280,7 @@ static int dpu_plane_sspp_atomic_update(struct drm_plane *plane,
 	const struct dpu_format *fmt;
 	struct drm_crtc *crtc;
 	struct drm_framebuffer *fb;
-	struct dpu_rect src, dst;
-	bool q16_data = true;
+	struct drm_rect src, dst;
 
 	if (!plane) {
 		DPU_ERROR("invalid plane\n");
@@ -1293,20 +1319,19 @@ static int dpu_plane_sspp_atomic_update(struct drm_plane *plane,
 	pdpu->is_rt_pipe = (dpu_crtc_get_client_type(crtc) != NRT_CLIENT);
 	_dpu_plane_set_qos_ctrl(plane, false, DPU_PLANE_QOS_PANIC_CTRL);
 
-	/* update roi config */
-	POPULATE_RECT(&src, state->src_x, state->src_y,
-		state->src_w, state->src_h, q16_data);
-	POPULATE_RECT(&dst, state->crtc_x, state->crtc_y,
-		state->crtc_w, state->crtc_h, !q16_data);
+	src.x1 = state->src_x >> 16;
+	src.y1 = state->src_y >> 16;
+	src.x2 = src.x1 + (state->src_w >> 16);
+	src.y2 = src.y1 + (state->src_h >> 16);
 
-	DPU_DEBUG_PLANE(pdpu,
-		"FB[%u] %u,%u,%ux%u->crtc%u %d,%d,%ux%u, %4.4s ubwc %d\n",
-			fb->base.id, src.x, src.y, src.w, src.h,
-			crtc->base.id, dst.x, dst.y, dst.w, dst.h,
+	dst = drm_plane_state_dest(state);
+
+	DPU_DEBUG_PLANE(pdpu, "FB[%u] " DRM_RECT_FMT "->crtc%u " DRM_RECT_FMT
+			", %4.4s ubwc %d\n", fb->base.id, DRM_RECT_ARG(&src),
+			crtc->base.id, DRM_RECT_ARG(&dst),
 			(char *)&fmt->base.pixel_format,
 			DPU_FORMAT_IS_UBWC(fmt));
 
-
 	pdpu->pipe_cfg.src_rect = src;
 	pdpu->pipe_cfg.dst_rect = dst;
 
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
index 41fd6a227d8b..1924c6662362 100644
--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
+++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h
@@ -17,6 +17,7 @@
 #include <linux/types.h>
 #include <linux/tracepoint.h>
 
+#include <drm/drm_rect.h>
 #include "dpu_crtc.h"
 #include "dpu_encoder_phys.h"
 #include "dpu_hw_mdss.h"
@@ -719,21 +720,20 @@ TRACE_EVENT(dpu_crtc_setup_mixer,
 );
 
 TRACE_EVENT(dpu_crtc_setup_lm_bounds,
-	TP_PROTO(uint32_t drm_id, int mixer, struct dpu_rect *bounds),
+	TP_PROTO(uint32_t drm_id, int mixer, struct drm_rect *bounds),
 	TP_ARGS(drm_id, mixer, bounds),
 	TP_STRUCT__entry(
 		__field(	uint32_t,		drm_id	)
 		__field(	int,			mixer	)
-		__field(	struct dpu_rect *,	bounds	)
+		__field(	struct drm_rect *,	bounds	)
 	),
 	TP_fast_assign(
 		__entry->drm_id = drm_id;
 		__entry->mixer = mixer;
 		__entry->bounds = bounds;
 	),
-	TP_printk("id:%u mixer:%d bounds:{%ux%u/%ux%u}", __entry->drm_id,
-		  __entry->mixer, __entry->bounds->x, __entry->bounds->y,
-		  __entry->bounds->w, __entry->bounds->h)
+	TP_printk("id:%u mixer:%d bounds:" DRM_RECT_FMT, __entry->drm_id,
+		  __entry->mixer, DRM_RECT_ARG(__entry->bounds))
 );
 
 TRACE_EVENT(dpu_crtc_vblank_enable,
-- 
Sean Paul, Software Engineer, Google / Chromium OS



More information about the Freedreno mailing list