@@ -111,6 +111,7 @@ struct vop {
struct device *dev;
struct drm_device *drm_dev;
bool is_enabled;
+ bool vblank_active;
/* mutex vsync_ work */
struct mutex vsync_mutex;
@@ -961,6 +962,7 @@ static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
unsigned long flags;
spin_lock_irqsave(&drm->event_lock, flags);
+
e = vop->event;
if (e && e->base.file_priv == file_priv) {
vop->event = NULL;
@@ -1108,9 +1110,10 @@ static void vop_crtc_atomic_begin(struct drm_crtc *crtc,
{
struct vop *vop = to_vop(crtc);
- if (crtc->state->event) {
- WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+ WARN_ON(drm_crtc_vblank_get(crtc) != 0);
+ vop->vblank_active = true;
+ if (crtc->state->event) {
vop->event = crtc->state->event;
crtc->state->event = NULL;
}
@@ -1200,11 +1203,16 @@ static void vop_handle_vblank(struct vop *vop)
spin_lock_irqsave(&drm->event_lock, flags);
drm_crtc_send_vblank_event(crtc, vop->event);
- drm_crtc_vblank_put(crtc);
vop->event = NULL;
spin_unlock_irqrestore(&drm->event_lock, flags);
}
+
+ if (vop->vblank_active) {
+ vop->vblank_active = false;
+ drm_crtc_vblank_put(crtc);
+ }
+
if (!completion_done(&vop->wait_update_complete))
complete(&vop->wait_update_complete);
}
@@ -1485,6 +1493,7 @@ static int vop_initial(struct vop *vop)
clk_disable(vop->aclk);
vop->is_enabled = false;
+ vop->vblank_active = false;
return 0;
vblank should be enabled regardless of whether an event is expected back. This is especially important for a cursor plane. Signed-off-by: Sean Paul <seanpaul@chromium.org> --- drivers/gpu/drm/rockchip/rockchip_drm_vop.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)