Commit 4f9d39a7 authored by Daniel Vetter's avatar Daniel Vetter

drm/rockchip: Fix crtc_state->event signalling

It's not permissible to look at plane->state from interrupt context,
since doing that would need the irq handler to acquire the
plane->mutex lock.

The other problem is that if we pipeline updates using the new
nonblocking atomic helpers new state gets commit before the irq
handler fires, resulting in a lost event.

Fix both issues by caching the necessary values in vop_win, protected
by dev->event_lock.

Cc: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Cc: Mark yao <mark.yao@rock-chips.com>
Tested-by: default avatarTomeu Vizoso <tomeu.vizoso@collabora.com>
Reviewed-by: default avatarTomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1465388359-8070-19-git-send-email-daniel.vetter@ffwll.ch
parent 05c960e7
...@@ -98,7 +98,9 @@ struct vop_win { ...@@ -98,7 +98,9 @@ struct vop_win {
const struct vop_win_data *data; const struct vop_win_data *data;
struct vop *vop; struct vop *vop;
struct vop_plane_state state; /* protected by dev->event_lock */
bool enable;
dma_addr_t yrgb_mst;
}; };
struct vop { struct vop {
...@@ -112,6 +114,8 @@ struct vop { ...@@ -112,6 +114,8 @@ struct vop {
bool vsync_work_pending; bool vsync_work_pending;
struct completion dsp_hold_completion; struct completion dsp_hold_completion;
struct completion wait_update_complete; struct completion wait_update_complete;
/* protected by dev->event_lock */
struct drm_pending_vblank_event *event; struct drm_pending_vblank_event *event;
const struct vop_data *data; const struct vop_data *data;
...@@ -652,6 +656,11 @@ static void vop_plane_atomic_disable(struct drm_plane *plane, ...@@ -652,6 +656,11 @@ static void vop_plane_atomic_disable(struct drm_plane *plane,
if (!old_state->crtc) if (!old_state->crtc)
return; return;
spin_lock_irq(&plane->dev->event_lock);
vop_win->enable = false;
vop_win->yrgb_mst = 0;
spin_unlock_irq(&plane->dev->event_lock);
spin_lock(&vop->reg_lock); spin_lock(&vop->reg_lock);
VOP_WIN_SET(vop, win, enable, 0); VOP_WIN_SET(vop, win, enable, 0);
...@@ -686,7 +695,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, ...@@ -686,7 +695,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
/* /*
* can't update plane when vop is disabled. * can't update plane when vop is disabled.
*/ */
if (!crtc) if (WARN_ON(!crtc))
return; return;
if (WARN_ON(!vop->is_enabled)) if (WARN_ON(!vop->is_enabled))
...@@ -715,6 +724,11 @@ static void vop_plane_atomic_update(struct drm_plane *plane, ...@@ -715,6 +724,11 @@ static void vop_plane_atomic_update(struct drm_plane *plane,
offset += (src->y1 >> 16) * fb->pitches[0]; offset += (src->y1 >> 16) * fb->pitches[0];
vop_plane_state->yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0]; vop_plane_state->yrgb_mst = rk_obj->dma_addr + offset + fb->offsets[0];
spin_lock_irq(&plane->dev->event_lock);
vop_win->enable = true;
vop_win->yrgb_mst = vop_plane_state->yrgb_mst;
spin_unlock_irq(&plane->dev->event_lock);
spin_lock(&vop->reg_lock); spin_lock(&vop->reg_lock);
VOP_WIN_SET(vop, win, format, vop_plane_state->format); VOP_WIN_SET(vop, win, format, vop_plane_state->format);
...@@ -1074,16 +1088,14 @@ static const struct drm_crtc_funcs vop_crtc_funcs = { ...@@ -1074,16 +1088,14 @@ static const struct drm_crtc_funcs vop_crtc_funcs = {
static bool vop_win_pending_is_complete(struct vop_win *vop_win) static bool vop_win_pending_is_complete(struct vop_win *vop_win)
{ {
struct drm_plane *plane = &vop_win->base;
struct vop_plane_state *state = to_vop_plane_state(plane->state);
dma_addr_t yrgb_mst; dma_addr_t yrgb_mst;
if (!state->enable) if (!vop_win->enable)
return VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0; return VOP_WIN_GET(vop_win->vop, vop_win->data, enable) == 0;
yrgb_mst = VOP_WIN_GET_YRGBADDR(vop_win->vop, vop_win->data); yrgb_mst = VOP_WIN_GET_YRGBADDR(vop_win->vop, vop_win->data);
return yrgb_mst == state->yrgb_mst; return yrgb_mst == vop_win->yrgb_mst;
} }
static void vop_handle_vblank(struct vop *vop) static void vop_handle_vblank(struct vop *vop)
......
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