diff options
| author | Boris Brezillon <boris.brezillon@free-electrons.com> | 2017-06-02 04:32:08 -0400 |
|---|---|---|
| committer | Eric Anholt <eric@anholt.net> | 2017-06-15 19:29:08 -0400 |
| commit | 34c8ea400ff6383b028f63df2453914163afc07c (patch) | |
| tree | b12d8b969a76548e9b57bdcb615bfe6f02d41b46 | |
| parent | 83753117f1de4f6ef7588fac9545065eed1e85e2 (diff) | |
drm/vc4: Mimic drm_atomic_helper_commit() behavior
The VC4 KMS driver is implementing its own ->atomic_commit() but there
are a few generic helpers we can use instead of open-coding the logic.
Signed-off-by: Boris Brezillon <boris.brezillon@free-electrons.com>
Reviewed-by: Eric Anholt <eric@anholt.net>
Link: http://patchwork.freedesktop.org/patch/msgid/1496392332-8722-4-git-send-email-boris.brezillon@free-electrons.com
| -rw-r--r-- | drivers/gpu/drm/vc4/vc4_kms.c | 38 |
1 files changed, 12 insertions, 26 deletions
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c index 202f7ebf5a7b..bc6ecdc6f104 100644 --- a/drivers/gpu/drm/vc4/vc4_kms.c +++ b/drivers/gpu/drm/vc4/vc4_kms.c | |||
| @@ -42,6 +42,10 @@ vc4_atomic_complete_commit(struct vc4_commit *c) | |||
| 42 | struct drm_device *dev = state->dev; | 42 | struct drm_device *dev = state->dev; |
| 43 | struct vc4_dev *vc4 = to_vc4_dev(dev); | 43 | struct vc4_dev *vc4 = to_vc4_dev(dev); |
| 44 | 44 | ||
| 45 | drm_atomic_helper_wait_for_fences(dev, state, false); | ||
| 46 | |||
| 47 | drm_atomic_helper_wait_for_dependencies(state); | ||
| 48 | |||
| 45 | drm_atomic_helper_commit_modeset_disables(dev, state); | 49 | drm_atomic_helper_commit_modeset_disables(dev, state); |
| 46 | 50 | ||
| 47 | drm_atomic_helper_commit_planes(dev, state, 0); | 51 | drm_atomic_helper_commit_planes(dev, state, 0); |
| @@ -57,10 +61,14 @@ vc4_atomic_complete_commit(struct vc4_commit *c) | |||
| 57 | */ | 61 | */ |
| 58 | state->legacy_cursor_update = false; | 62 | state->legacy_cursor_update = false; |
| 59 | 63 | ||
| 64 | drm_atomic_helper_commit_hw_done(state); | ||
| 65 | |||
| 60 | drm_atomic_helper_wait_for_vblanks(dev, state); | 66 | drm_atomic_helper_wait_for_vblanks(dev, state); |
| 61 | 67 | ||
| 62 | drm_atomic_helper_cleanup_planes(dev, state); | 68 | drm_atomic_helper_cleanup_planes(dev, state); |
| 63 | 69 | ||
| 70 | drm_atomic_helper_commit_cleanup_done(state); | ||
| 71 | |||
| 64 | drm_atomic_state_put(state); | 72 | drm_atomic_state_put(state); |
| 65 | 73 | ||
| 66 | up(&vc4->async_modeset); | 74 | up(&vc4->async_modeset); |
| @@ -117,32 +125,10 @@ static int vc4_atomic_commit(struct drm_device *dev, | |||
| 117 | if (!c) | 125 | if (!c) |
| 118 | return -ENOMEM; | 126 | return -ENOMEM; |
| 119 | 127 | ||
| 120 | /* Make sure that any outstanding modesets have finished. */ | 128 | ret = drm_atomic_helper_setup_commit(state, nonblock); |
| 121 | if (nonblock) { | 129 | if (ret) |
| 122 | struct drm_crtc *crtc; | 130 | return ret; |
| 123 | struct drm_crtc_state *crtc_state; | 131 | |
| 124 | unsigned long flags; | ||
| 125 | bool busy = false; | ||
| 126 | |||
| 127 | /* | ||
| 128 | * If there's an undispatched event to send then we're | ||
| 129 | * obviously still busy. If there isn't, then we can | ||
| 130 | * unconditionally wait for the semaphore because it | ||
| 131 | * shouldn't be contended (for long). | ||
| 132 | * | ||
| 133 | * This is to prevent a race where queuing a new flip | ||
| 134 | * from userspace immediately on receipt of an event | ||
| 135 | * beats our clean-up and returns EBUSY. | ||
| 136 | */ | ||
| 137 | spin_lock_irqsave(&dev->event_lock, flags); | ||
| 138 | for_each_crtc_in_state(state, crtc, crtc_state, i) | ||
| 139 | busy |= vc4_event_pending(crtc); | ||
| 140 | spin_unlock_irqrestore(&dev->event_lock, flags); | ||
| 141 | if (busy) { | ||
| 142 | kfree(c); | ||
| 143 | return -EBUSY; | ||
| 144 | } | ||
| 145 | } | ||
| 146 | ret = down_interruptible(&vc4->async_modeset); | 132 | ret = down_interruptible(&vc4->async_modeset); |
| 147 | if (ret) { | 133 | if (ret) { |
| 148 | kfree(c); | 134 | kfree(c); |
