Commit 08a89018 authored by Liu Ying's avatar Liu Ying Committed by Philipp Zabel

drm/imx: ipuv3 plane: Check different types of plane separately

The IPUv3 primary plane doesn't support partial off screen.
So, this patch separates plane check logics for primary plane and overlay
plane and adds more limitations on the primary plane.
Signed-off-by: default avatarLiu Ying <gnuiyl@gmail.com>
Acked-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: default avatarPhilipp Zabel <p.zabel@pengutronix.de>
parent 9253d059
...@@ -199,37 +199,46 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc, ...@@ -199,37 +199,46 @@ int ipu_plane_mode_set(struct ipu_plane *ipu_plane, struct drm_crtc *crtc,
if (src_w != crtc_w || src_h != crtc_h) if (src_w != crtc_w || src_h != crtc_h)
return -EINVAL; return -EINVAL;
/* clip to crtc bounds */ if (ipu_plane->base.type == DRM_PLANE_TYPE_PRIMARY) {
if (crtc_x < 0) { /* full plane doesn't support partial off screen */
if (-crtc_x > crtc_w) if (crtc_x || crtc_y || crtc_w != mode->hdisplay ||
crtc_h != mode->vdisplay)
return -EINVAL; return -EINVAL;
src_x += -crtc_x;
src_w -= -crtc_x; /* full plane minimum width is 13 pixels */
crtc_w -= -crtc_x; if (crtc_w < 13)
crtc_x = 0;
}
if (crtc_y < 0) {
if (-crtc_y > crtc_h)
return -EINVAL;
src_y += -crtc_y;
src_h -= -crtc_y;
crtc_h -= -crtc_y;
crtc_y = 0;
}
if (crtc_x + crtc_w > mode->hdisplay) {
if (crtc_x > mode->hdisplay)
return -EINVAL;
crtc_w = mode->hdisplay - crtc_x;
src_w = crtc_w;
}
if (crtc_y + crtc_h > mode->vdisplay) {
if (crtc_y > mode->vdisplay)
return -EINVAL; return -EINVAL;
crtc_h = mode->vdisplay - crtc_y; } else if (ipu_plane->base.type == DRM_PLANE_TYPE_OVERLAY) {
src_h = crtc_h; /* clip to crtc bounds */
} if (crtc_x < 0) {
/* full plane minimum width is 13 pixels */ if (-crtc_x > crtc_w)
if (crtc_w < 13 && (ipu_plane->dp_flow != IPU_DP_FLOW_SYNC_FG)) return -EINVAL;
src_x += -crtc_x;
src_w -= -crtc_x;
crtc_w -= -crtc_x;
crtc_x = 0;
}
if (crtc_y < 0) {
if (-crtc_y > crtc_h)
return -EINVAL;
src_y += -crtc_y;
src_h -= -crtc_y;
crtc_h -= -crtc_y;
crtc_y = 0;
}
if (crtc_x + crtc_w > mode->hdisplay) {
if (crtc_x > mode->hdisplay)
return -EINVAL;
crtc_w = mode->hdisplay - crtc_x;
src_w = crtc_w;
}
if (crtc_y + crtc_h > mode->vdisplay) {
if (crtc_y > mode->vdisplay)
return -EINVAL;
crtc_h = mode->vdisplay - crtc_y;
src_h = crtc_h;
}
} else
return -EINVAL; return -EINVAL;
if (crtc_h < 2) if (crtc_h < 2)
return -EINVAL; return -EINVAL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment