summaryrefslogtreecommitdiffstats
path: root/kernel/drivers/gpu/drm/msm/msm_atomic.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/drivers/gpu/drm/msm/msm_atomic.c')
-rw-r--r--kernel/drivers/gpu/drm/msm/msm_atomic.c56
1 files changed, 42 insertions, 14 deletions
diff --git a/kernel/drivers/gpu/drm/msm/msm_atomic.c b/kernel/drivers/gpu/drm/msm/msm_atomic.c
index 5b192128c..7eb253bc2 100644
--- a/kernel/drivers/gpu/drm/msm/msm_atomic.c
+++ b/kernel/drivers/gpu/drm/msm/msm_atomic.c
@@ -84,6 +84,33 @@ static void commit_destroy(struct msm_commit *c)
kfree(c);
}
+static void msm_atomic_wait_for_commit_done(struct drm_device *dev,
+ struct drm_atomic_state *old_state)
+{
+ struct drm_crtc *crtc;
+ struct msm_drm_private *priv = old_state->dev->dev_private;
+ struct msm_kms *kms = priv->kms;
+ int ncrtcs = old_state->dev->mode_config.num_crtc;
+ int i;
+
+ for (i = 0; i < ncrtcs; i++) {
+ crtc = old_state->crtcs[i];
+
+ if (!crtc)
+ continue;
+
+ if (!crtc->state->enable)
+ continue;
+
+ /* Legacy cursor ioctls are completely unsynced, and userspace
+ * relies on that (by doing tons of cursor updates). */
+ if (old_state->legacy_cursor_update)
+ continue;
+
+ kms->funcs->wait_for_crtc_commit_done(kms, crtc);
+ }
+}
+
/* The (potentially) asynchronous part of the commit. At this point
* nothing can fail short of armageddon.
*/
@@ -98,7 +125,7 @@ static void complete_commit(struct msm_commit *c)
drm_atomic_helper_commit_modeset_disables(dev, state);
- drm_atomic_helper_commit_planes(dev, state);
+ drm_atomic_helper_commit_planes(dev, state, false);
drm_atomic_helper_commit_modeset_enables(dev, state);
@@ -115,7 +142,7 @@ static void complete_commit(struct msm_commit *c)
* not be critical path)
*/
- drm_atomic_helper_wait_for_vblanks(dev, state);
+ msm_atomic_wait_for_commit_done(dev, state);
drm_atomic_helper_cleanup_planes(dev, state);
@@ -139,7 +166,6 @@ static void add_fb(struct msm_commit *c, struct drm_framebuffer *fb)
c->fence = max(c->fence, msm_gem_fence(to_msm_bo(obj), MSM_PREP_READ));
}
-
int msm_atomic_check(struct drm_device *dev,
struct drm_atomic_state *state)
{
@@ -178,7 +204,7 @@ int msm_atomic_commit(struct drm_device *dev,
{
int nplanes = dev->mode_config.num_total_plane;
int ncrtcs = dev->mode_config.num_crtc;
- struct timespec timeout;
+ ktime_t timeout;
struct msm_commit *c;
int i, ret;
@@ -187,8 +213,10 @@ int msm_atomic_commit(struct drm_device *dev,
return ret;
c = commit_init(state);
- if (!c)
- return -ENOMEM;
+ if (!c) {
+ ret = -ENOMEM;
+ goto error;
+ }
/*
* Figure out what crtcs we have:
@@ -221,7 +249,7 @@ int msm_atomic_commit(struct drm_device *dev,
ret = start_atomic(dev->dev_private, c->crtc_mask);
if (ret) {
kfree(c);
- return ret;
+ goto error;
}
/*
@@ -253,16 +281,16 @@ int msm_atomic_commit(struct drm_device *dev,
return 0;
}
- jiffies_to_timespec(jiffies + msecs_to_jiffies(1000), &timeout);
+ timeout = ktime_add_ms(ktime_get(), 1000);
- ret = msm_wait_fence_interruptable(dev, c->fence, &timeout);
- if (ret) {
- WARN_ON(ret); // TODO unswap state back? or??
- commit_destroy(c);
- return ret;
- }
+ /* uninterruptible wait */
+ msm_wait_fence(dev, c->fence, &timeout, false);
complete_commit(c);
return 0;
+
+error:
+ drm_atomic_helper_cleanup_planes(dev, state);
+ return ret;
}