summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/drm_atomic_helper.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/drm_atomic_helper.c')
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c53
1 files changed, 15 insertions, 38 deletions
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 820adcda45b8..b97c054f9786 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -1388,35 +1388,31 @@ int drm_atomic_helper_async_check(struct drm_device *dev,
{
struct drm_crtc *crtc;
struct drm_crtc_state *crtc_state;
- struct drm_crtc_commit *commit;
- struct drm_plane *__plane, *plane = NULL;
- struct drm_plane_state *__plane_state, *plane_state = NULL;
+ struct drm_plane *plane;
+ struct drm_plane_state *old_plane_state, *new_plane_state;
const struct drm_plane_helper_funcs *funcs;
- int i, j, n_planes = 0;
+ int i, n_planes = 0;
for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
if (drm_atomic_crtc_needs_modeset(crtc_state))
return -EINVAL;
}
- for_each_new_plane_in_state(state, __plane, __plane_state, i) {
+ for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i)
n_planes++;
- plane = __plane;
- plane_state = __plane_state;
- }
/* FIXME: we support only single plane updates for now */
- if (!plane || n_planes != 1)
+ if (n_planes != 1)
return -EINVAL;
- if (!plane_state->crtc)
+ if (!new_plane_state->crtc)
return -EINVAL;
funcs = plane->helper_private;
if (!funcs->atomic_async_update)
return -EINVAL;
- if (plane_state->fence)
+ if (new_plane_state->fence)
return -EINVAL;
/*
@@ -1424,31 +1420,11 @@ int drm_atomic_helper_async_check(struct drm_device *dev,
* the plane. This prevents our async update's changes from getting
* overridden by a previous synchronous update's state.
*/
- for_each_new_crtc_in_state(state, crtc, crtc_state, i) {
- if (plane->crtc != crtc)
- continue;
-
- spin_lock(&crtc->commit_lock);
- commit = list_first_entry_or_null(&crtc->commit_list,
- struct drm_crtc_commit,
- commit_entry);
- if (!commit) {
- spin_unlock(&crtc->commit_lock);
- continue;
- }
- spin_unlock(&crtc->commit_lock);
-
- if (!crtc->state->state)
- continue;
+ if (old_plane_state->commit &&
+ !try_wait_for_completion(&old_plane_state->commit->hw_done))
+ return -EBUSY;
- for_each_plane_in_state(crtc->state->state, __plane,
- __plane_state, j) {
- if (__plane == plane)
- return -EINVAL;
- }
- }
-
- return funcs->atomic_async_check(plane, plane_state);
+ return funcs->atomic_async_check(plane, new_plane_state);
}
EXPORT_SYMBOL(drm_atomic_helper_async_check);
@@ -1814,9 +1790,10 @@ int drm_atomic_helper_setup_commit(struct drm_atomic_state *state,
}
for_each_oldnew_plane_in_state(state, plane, old_plane_state, new_plane_state, i) {
- /* commit tracked through new_crtc_state->commit, no need to do it explicitly */
- if (new_plane_state->crtc)
- continue;
+ /*
+ * Unlike connectors, always track planes explicitly for
+ * async pageflip support.
+ */
/* Userspace is not allowed to get ahead of the previous
* commit with nonblocking ones. */