diff options
author | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2015-08-15 19:26:18 +0300 |
---|---|---|
committer | Inki Dae <daeinki@gmail.com> | 2015-08-30 18:27:38 +0300 |
commit | c4533665d819271dad890440b887776ac3d5f265 (patch) | |
tree | a4c545175fba766dfdbabf21487f6347d869db54 /drivers/gpu/drm/exynos/exynos_drm_crtc.c | |
parent | a379df19356de97afdca37c4e8f5e8729215d6ea (diff) | |
download | linux-c4533665d819271dad890440b887776ac3d5f265.tar.xz |
drm/exynos: wait all planes updates to finish
Add infrastructure to wait for all planes updates to finish by using
an atomic_t variable to track how many pending updates we are waiting
plus a wait_queue for the wait part.
It also changes vblank behaviour and keeps it enabled for all types
of updates
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
Diffstat (limited to 'drivers/gpu/drm/exynos/exynos_drm_crtc.c')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_crtc.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c index 582e041a9356..d6c2c3f8bc6e 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c +++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c @@ -75,10 +75,7 @@ static void exynos_crtc_atomic_begin(struct drm_crtc *crtc, struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); struct drm_plane *plane; - if (crtc->state->event) { - WARN_ON(drm_crtc_vblank_get(crtc) != 0); - exynos_crtc->event = crtc->state->event; - } + exynos_crtc->event = crtc->state->event; drm_atomic_crtc_for_each_plane(plane, crtc) { struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); @@ -156,6 +153,8 @@ 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; @@ -197,6 +196,13 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, 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) { @@ -205,10 +211,12 @@ void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc, 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); - drm_crtc_vblank_put(crtc); wake_up(&exynos_crtc->pending_flip_queue); } |