diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2018-03-16 01:55:53 -0700 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2018-03-16 01:55:52 -0700 |
| commit | a915fa29fa749067395dd798d1d6542b709e0c6f (patch) | |
| tree | 8c6423b400ecc0d4568616da7053214049302c21 /drivers/gpu/drm | |
| parent | 8353ae1eafcc5b93e3ad49da1adc00bb139e311e (diff) | |
| parent | 240bc58d6aa8f63f6acb06f224abadab2157b2d4 (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.c | 62 |
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; } |
