From: Ville Syrjälä <ville.syrj...@linux.intel.com>

Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
---
 drivers/gpu/drm/i915/intel_atomic.c |   36 +++++++++++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/drivers/gpu/drm/i915/intel_atomic.c 
b/drivers/gpu/drm/i915/intel_atomic.c
index e52d92a..36446d1 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -2471,9 +2471,23 @@ void intel_atomic_handle_vblank(struct drm_device *dev, 
int pipe)
 void intel_atomic_clear_flips(struct drm_crtc *crtc)
 {
        struct drm_device *dev = crtc->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_plane *intel_plane;
+       struct intel_flip *intel_flip, *next;
        int pipe = intel_crtc->pipe;
+       unsigned long flags;
+       LIST_HEAD(flips);
+
+       /*
+        * If there are flips still waiting for the GPU, remove them
+        * from the list, so that they won't be able to move over to
+        * drm_flip_helpers' possession after we've called
+        * drm_flip_helper_clear().
+        */
+       spin_lock_irqsave(&dev_priv->flip.lock, flags);
+       list_cut_position(&flips, &dev_priv->flip.list, 
dev_priv->flip.list.prev);
+       spin_unlock_irqrestore(&dev_priv->flip.lock, flags);
 
        drm_flip_helper_clear(&intel_crtc->flip_helper);
 
@@ -2481,4 +2495,26 @@ void intel_atomic_clear_flips(struct drm_crtc *crtc)
                if (intel_plane->pipe == pipe)
                        drm_flip_helper_clear(&intel_plane->flip_helper);
        }
+
+       /*
+        * Drop all non-ready flips. Doing this after calling
+        * drm_flip_helper_clear() maintaines the correct order
+        * of completion events.
+        */
+       list_for_each_entry_safe(intel_flip, next, &flips, base.list) {
+               struct intel_ring_buffer *ring = intel_flip->ring;
+
+               if (ring) {
+                       intel_flip->ring = NULL;
+                       ring->irq_put(ring);
+               }
+
+               intel_flip_complete(&intel_flip->base);
+               /*
+                * FIXME drm_flip_helper calls the following functions
+                * from a workqueue. Perhaps we should do the same here?
+                */
+               intel_flip_finish(&intel_flip->base);
+               intel_flip_cleanup(&intel_flip->base);
+       }
 }
-- 
1.7.8.6

_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to