diff options
author | Gustavo Padovan <gustavo.padovan@collabora.co.uk> | 2015-08-15 13:26:18 -0300 |
---|---|---|
committer | Inki Dae <daeinki@gmail.com> | 2015-08-31 00:27:38 +0900 |
commit | c4533665d819271dad890440b887776ac3d5f265 (patch) | |
tree | a4c545175fba766dfdbabf21487f6347d869db54 /drivers/gpu/drm/exynos/exynos_drm_drv.c | |
parent | a379df19356de97afdca37c4e8f5e8729215d6ea (diff) | |
download | lwn-c4533665d819271dad890440b887776ac3d5f265.tar.gz lwn-c4533665d819271dad890440b887776ac3d5f265.zip |
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_drv.c')
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_drv.c | 44 |
1 files changed, 43 insertions, 1 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c index 898591792b12..1350c8e2d587 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_drv.c +++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c @@ -45,11 +45,37 @@ struct exynos_atomic_commit { u32 crtcs; }; +static void exynos_atomic_wait_for_commit(struct drm_atomic_state *state) +{ + struct drm_crtc_state *crtc_state; + struct drm_crtc *crtc; + int i, ret; + + for_each_crtc_in_state(state, crtc, crtc_state, i) { + struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); + + if (!crtc->state->enable) + continue; + + ret = drm_crtc_vblank_get(crtc); + if (ret) + continue; + + exynos_drm_crtc_wait_pending_update(exynos_crtc); + drm_crtc_vblank_put(crtc); + } +} + static void exynos_atomic_commit_complete(struct exynos_atomic_commit *commit) { struct drm_device *dev = commit->dev; struct exynos_drm_private *priv = dev->dev_private; struct drm_atomic_state *state = commit->state; + struct drm_plane *plane; + struct drm_crtc *crtc; + struct drm_plane_state *plane_state; + struct drm_crtc_state *crtc_state; + int i; drm_atomic_helper_commit_modeset_disables(dev, state); @@ -63,9 +89,25 @@ static void exynos_atomic_commit_complete(struct exynos_atomic_commit *commit) * have the relevant clocks enabled to perform the update. */ + for_each_crtc_in_state(state, crtc, crtc_state, i) { + struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); + + atomic_set(&exynos_crtc->pending_update, 0); + } + + for_each_plane_in_state(state, plane, plane_state, i) { + struct exynos_drm_crtc *exynos_crtc = + to_exynos_crtc(plane->crtc); + + if (!plane->crtc) + continue; + + atomic_inc(&exynos_crtc->pending_update); + } + drm_atomic_helper_commit_planes(dev, state); - drm_atomic_helper_wait_for_vblanks(dev, state); + exynos_atomic_wait_for_commit(state); drm_atomic_helper_cleanup_planes(dev, state); |