This just waits until the hw passed the current ring position with
cmd execution. This slightly changes the existing i915_wait_request
function to make uninterruptible waiting possible - no point in
returning to userspace while mucking around with the overlay, that
piece of hw is just too fragile.

Also replace a magic 0 with the symbolic constant (and kill the then
superflous comment) while I was looking at the code.

Signed-off-by: Daniel Vetter <daniel.vet...@ffwll.ch>
---
 drivers/gpu/drm/i915/i915_drv.h |    1 +
 drivers/gpu/drm/i915/i915_gem.c |   51 +++++++++++++++++++++++++++++++-------
 include/drm/drm_os_linux.h      |    2 +-
 3 files changed, 43 insertions(+), 11 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0344afd..0327ecf 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -720,6 +720,7 @@ void i915_gem_cleanup_ringbuffer(struct drm_device *dev);
 int i915_gem_do_init(struct drm_device *dev, unsigned long start,
                     unsigned long end);
 int i915_gem_idle(struct drm_device *dev);
+int i915_lp_ring_sync(struct drm_device *dev);
 int i915_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
 int i915_gem_object_set_to_gtt_domain(struct drm_gem_object *obj,
                                      int write);
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index e0da986..a3d8fa8 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1738,12 +1738,8 @@ i915_gem_retire_work_handler(struct work_struct *work)
        mutex_unlock(&dev->struct_mutex);
 }
 
-/**
- * Waits for a sequence number to be signaled, and cleans up the
- * request and object lists appropriately for that event.
- */
 static int
-i915_wait_request(struct drm_device *dev, uint32_t seqno)
+i915_do_wait_request(struct drm_device *dev, uint32_t seqno, int interruptible)
 {
        drm_i915_private_t *dev_priv = dev->dev_private;
        u32 ier;
@@ -1765,10 +1761,17 @@ i915_wait_request(struct drm_device *dev, uint32_t 
seqno)
 
                dev_priv->mm.waiting_gem_seqno = seqno;
                i915_user_irq_get(dev);
-               ret = wait_event_interruptible(dev_priv->irq_queue,
-                                              
i915_seqno_passed(i915_get_gem_seqno(dev),
-                                                                seqno) ||
-                                              dev_priv->mm.wedged);
+               if (interruptible)
+                       ret = wait_event_interruptible(dev_priv->irq_queue,
+                                      
i915_seqno_passed(i915_get_gem_seqno(dev),
+                                                        seqno) ||
+                                      dev_priv->mm.wedged);
+               else
+                       wait_event(dev_priv->irq_queue,
+                                      
i915_seqno_passed(i915_get_gem_seqno(dev),
+                                                        seqno) ||
+                                      dev_priv->mm.wedged);
+
                i915_user_irq_put(dev);
                dev_priv->mm.waiting_gem_seqno = 0;
        }
@@ -1790,6 +1793,34 @@ i915_wait_request(struct drm_device *dev, uint32_t seqno)
        return ret;
 }
 
+/**
+ * Waits for a sequence number to be signaled, and cleans up the
+ * request and object lists appropriately for that event.
+ */
+static int
+i915_wait_request(struct drm_device *dev, uint32_t seqno)
+{
+       return i915_do_wait_request(dev, seqno, 1);
+}
+
+/**
+ * Waits for the ring to finish up to the latest request. Usefull for waiting
+ * for flip events, e.g for the overlay support. */
+int i915_lp_ring_sync(struct drm_device *dev)
+{
+       uint32_t seqno;
+       int ret;
+
+       seqno = i915_add_request(dev, NULL, 0);
+
+       if (seqno == 0)
+               return -ENOMEM;
+
+       ret = i915_do_wait_request(dev, seqno, 0);
+       BUG_ON(ret == -ERESTARTSYS);
+       return ret;
+}
+
 static void
 i915_gem_flush(struct drm_device *dev,
               uint32_t invalidate_domains,
@@ -1856,7 +1887,7 @@ i915_gem_flush(struct drm_device *dev,
 #endif
                BEGIN_LP_RING(2);
                OUT_RING(cmd);
-               OUT_RING(0); /* noop */
+               OUT_RING(MI_NOOP);
                ADVANCE_LP_RING();
        }
 }
diff --git a/include/drm/drm_os_linux.h b/include/drm/drm_os_linux.h
index 26641e9..3933691 100644
--- a/include/drm/drm_os_linux.h
+++ b/include/drm/drm_os_linux.h
@@ -123,5 +123,5 @@ do {                                                        
        \
        remove_wait_queue(&(queue), &entry);                    \
 } while (0)
 
-#define DRM_WAKEUP( queue ) wake_up_interruptible( queue )
+#define DRM_WAKEUP( queue ) wake_up( queue )
 #define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue )
-- 
1.6.3.3


------------------------------------------------------------------------------
Come build with us! The BlackBerry&reg; Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9&#45;12, 2009. Register now&#33;
http://p.sf.net/sfu/devconf
--
_______________________________________________
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel

Reply via email to