These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / gpu / drm / msm / msm_atomic.c
index 5b19212..7eb253b 100644 (file)
@@ -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;
 }