@@ -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;
}
@@ -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;
@@ -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];
@@ -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]) |
@@ -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;
};
@@ -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
*/
@@ -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;
- }
-}
-
@@ -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;
@@ -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,
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@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(-)