summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2018-03-16 01:55:53 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2018-03-16 01:55:52 -0700
commita915fa29fa749067395dd798d1d6542b709e0c6f (patch)
tree8c6423b400ecc0d4568616da7053214049302c21 /drivers/gpu/drm
parent8353ae1eafcc5b93e3ad49da1adc00bb139e311e (diff)
parent240bc58d6aa8f63f6acb06f224abadab2157b2d4 (diff)
Merge "drm/msm/sde: add validation checks for source split"
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/msm/sde/sde_crtc.c62
1 files changed, 43 insertions, 19 deletions
diff --git a/drivers/gpu/drm/msm/sde/sde_crtc.c b/drivers/gpu/drm/msm/sde/sde_crtc.c
index 96ef909e14f4..ea3f138ee461 100644
--- a/drivers/gpu/drm/msm/sde/sde_crtc.c
+++ b/drivers/gpu/drm/msm/sde/sde_crtc.c
@@ -1441,43 +1441,67 @@ static int sde_crtc_atomic_check(struct drm_crtc *crtc,
goto end;
}
- /*
- * enforce pipe priority restrictions
+ /* validate source split:
* use pstates sorted by stage to check planes on same stage
* we assume that all pipes are in source split so its valid to compare
* without taking into account left/right mixer placement
*/
for (i = 1; i < cnt; i++) {
struct plane_state *prv_pstate, *cur_pstate;
- int32_t prv_x, cur_x, prv_id, cur_id;
+ struct sde_rect left_rect, right_rect;
+ int32_t left_pid, right_pid;
+ int32_t stage;
prv_pstate = &pstates[i - 1];
cur_pstate = &pstates[i];
if (prv_pstate->stage != cur_pstate->stage)
continue;
- prv_x = prv_pstate->drm_pstate->crtc_x;
- cur_x = cur_pstate->drm_pstate->crtc_x;
- prv_id = prv_pstate->sde_pstate->base.plane->base.id;
- cur_id = cur_pstate->sde_pstate->base.plane->base.id;
+ stage = cur_pstate->stage;
- /*
- * Planes are enumerated in pipe-priority order such that planes
- * with lower drm_id must be left-most in a shared blend-stage
- * when using source split.
+ left_pid = prv_pstate->sde_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);
+
+ right_pid = cur_pstate->sde_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);
+
+ if (right_rect.x < left_rect.x) {
+ swap(left_pid, right_pid);
+ swap(left_rect, right_rect);
+ }
+
+ /**
+ * - planes are enumerated in pipe-priority order such that
+ * planes with lower drm_id must be left-most in a shared
+ * blend-stage when using source split.
+ * - planes in source split must be contiguous in width
+ * - planes in source split must have same dest yoff and height
*/
- if (cur_x > prv_x && cur_id < prv_id) {
+ if (right_pid < left_pid) {
+ SDE_ERROR(
+ "invalid src split cfg. priority mismatch. stage: %d left: %d right: %d\n",
+ stage, left_pid, right_pid);
+ rc = -EINVAL;
+ goto end;
+ } else if (right_rect.x != (left_rect.x + left_rect.w)) {
SDE_ERROR(
- "shared z_pos %d lower id plane%d @ x%d should be left of plane%d @ x %d\n",
- cur_pstate->stage, cur_id, cur_x,
- prv_id, prv_x);
+ "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);
rc = -EINVAL;
goto end;
- } else if (cur_x < prv_x && cur_id > prv_id) {
+ } else if ((left_rect.y != right_rect.y) ||
+ (left_rect.h != right_rect.h)) {
SDE_ERROR(
- "shared z_pos %d lower id plane%d @ x%d should be left of plane%d @ x %d\n",
- cur_pstate->stage, prv_id, prv_x,
- cur_id, cur_x);
+ "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);
rc = -EINVAL;
goto end;
}