drm/rockchip: vop: Deal with display area out of display mode

Some linux display framework will set display area out of display mode,
this is incorrect config and will lead vop iommu pagefault, we add this
commit to avoid vop pagefault and output error info.

Signed-off-by: Sandy Huang <hjc@rock-chips.com>
Change-Id: I50f9c93d807858b8939038aae9915b4895fe35e2
This commit is contained in:
Sandy Huang
2021-07-23 10:21:50 +08:00
committed by Tao Huang
parent 3e74187d73
commit 7751fcdc18

View File

@@ -1767,10 +1767,11 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
struct drm_display_mode *mode = NULL;
struct vop_win *win = to_vop_win(plane);
struct vop_plane_state *vop_plane_state = to_vop_plane_state(state);
struct drm_display_mode *adjusted_mode = &crtc->state->adjusted_mode;
struct rockchip_crtc_state *s;
struct vop *vop = to_vop(state->crtc);
struct drm_framebuffer *fb = state->fb;
unsigned int actual_w, actual_h;
unsigned int actual_w, actual_h, dsp_w, dsp_h;
unsigned int dsp_stx, dsp_sty;
uint32_t act_info, dsp_info, dsp_st;
struct drm_rect *src = &vop_plane_state->src;
@@ -1823,10 +1824,30 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
mode = &crtc->state->adjusted_mode;
actual_w = drm_rect_width(src) >> 16;
actual_h = drm_rect_height(src) >> 16;
dsp_w = drm_rect_width(dest);
if (dest->x1 + dsp_w > adjusted_mode->hdisplay) {
DRM_ERROR("%s win%d dest->x1[%d] + dsp_w[%d] exceed mode hdisplay[%d]\n",
crtc->name, win->win_id, dest->x1, dsp_w, adjusted_mode->hdisplay);
dsp_w = adjusted_mode->hdisplay - dest->x1;
if (dsp_w < 4)
dsp_w = 4;
actual_w = dsp_w * actual_w / drm_rect_width(dest);
}
dsp_h = drm_rect_height(dest);
if (dest->y1 + dsp_h > adjusted_mode->vdisplay) {
DRM_ERROR("%s win%d dest->y1[%d] + dsp_h[%d] exceed mode vdisplay[%d]\n",
crtc->name, win->win_id, dest->y1, dsp_h, adjusted_mode->vdisplay);
dsp_h = adjusted_mode->vdisplay - dest->y1;
if (dsp_h < 4)
dsp_h = 4;
actual_h = dsp_h * actual_h / drm_rect_height(dest);
}
act_info = (actual_h - 1) << 16 | ((actual_w - 1) & 0xffff);
dsp_info = (drm_rect_height(dest) - 1) << 16;
dsp_info |= (drm_rect_width(dest) - 1) & 0xffff;
dsp_info = (dsp_h - 1) << 16;
dsp_info |= (dsp_w - 1) & 0xffff;
dsp_stx = dest->x1 + mode->crtc_htotal - mode->crtc_hsync_start;
dsp_sty = dest->y1 + mode->crtc_vtotal - mode->crtc_vsync_start;