mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
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:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user