diff options
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_crtc.c')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_crtc.c | 58 |
1 files changed, 21 insertions, 37 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 785ffa6cc309..2530bf57716a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -69,8 +69,6 @@ static void exynos_crtc_atomic_begin(struct drm_crtc *crtc, { struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); - exynos_crtc->event = crtc->state->event; - if (exynos_crtc->ops->atomic_begin) exynos_crtc->ops->atomic_begin(exynos_crtc); } @@ -79,9 +77,24 @@ static void exynos_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state) { struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); + struct drm_pending_vblank_event *event; + unsigned long flags; if (exynos_crtc->ops->atomic_flush) exynos_crtc->ops->atomic_flush(exynos_crtc); + + event = crtc->state->event; + if (event) { + crtc->state->event = NULL; + + spin_lock_irqsave(&crtc->dev->event_lock, flags); + if (drm_crtc_vblank_get(crtc) == 0) + drm_crtc_arm_vblank_event(crtc, event); + else + drm_crtc_send_vblank_event(crtc, event); + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); + } + } static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { @@ -134,8 +147,6 @@ struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev, exynos_crtc->ops = ops; exynos_crtc->ctx = ctx; - init_waitqueue_head(&exynos_crtc->wait_update); - crtc = &exynos_crtc->base; private->crtc[pipe] = crtc; @@ -175,32 +186,6 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe) exynos_crtc->ops->disable_vblank(exynos_crtc); } -void exynos_drm_crtc_wait_pending_update(struct exynos_drm_crtc *exynos_crtc) -{ - wait_event_timeout(exynos_crtc->wait_update, - (atomic_read(&exynos_crtc->pending_update) == 0), - msecs_to_jiffies(50)); -} - -void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc, - struct exynos_drm_plane *exynos_plane) -{ - struct drm_crtc *crtc = &exynos_crtc->base; - unsigned long flags; - - exynos_plane->pending_fb = NULL; - - if (atomic_dec_and_test(&exynos_crtc->pending_update)) - wake_up(&exynos_crtc->wait_update); - - spin_lock_irqsave(&crtc->dev->event_lock, flags); - if (exynos_crtc->event) - drm_crtc_send_vblank_event(crtc, exynos_crtc->event); - - exynos_crtc->event = NULL; - spin_unlock_irqrestore(&crtc->dev->event_lock, flags); -} - int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, enum exynos_drm_output_type out_type) { @@ -228,20 +213,19 @@ void exynos_drm_crtc_te_handler(struct drm_crtc *crtc) void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file) { - struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); struct drm_pending_vblank_event *e; unsigned long flags; spin_lock_irqsave(&crtc->dev->event_lock, flags); - e = exynos_crtc->event; - if (e && e->base.file_priv == file) { - exynos_crtc->event = NULL; - atomic_dec(&exynos_crtc->pending_update); - } + e = crtc->state->event; + if (e && e->base.file_priv == file) + crtc->state->event = NULL; + else + e = NULL; spin_unlock_irqrestore(&crtc->dev->event_lock, flags); - if (e && e->base.file_priv == file) + if (e) drm_event_cancel_free(crtc->dev, &e->base); } |