Remove an intel-specific hack and replace it with a fence driver callback.
authorThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Wed, 14 Feb 2007 12:31:35 +0000 (13:31 +0100)
committerThomas Hellstrom <thomas-at-tungstengraphics-dot-com>
Wed, 14 Feb 2007 12:31:35 +0000 (13:31 +0100)
linux-core/drmP.h
linux-core/drm_fence.c
linux-core/i915_drv.c
linux-core/i915_fence.c
shared-core/i915_drv.h

index e070c07..e0afc50 100644 (file)
@@ -793,10 +793,11 @@ typedef struct drm_fence_driver{
        uint32_t flush_diff;
         uint32_t sequence_mask;
         int lazy_capable;
-       int (*emit) (struct drm_device *dev, uint32_t flags,
+       int (*has_irq) (struct drm_device *dev, uint32_t class, uint32_t flags);
+       int (*emit) (struct drm_device *dev, uint32_t class, uint32_t flags,
                     uint32_t *breadcrumb,
                     uint32_t *native_type);
-       void (*poke_flush) (struct drm_device *dev);
+       void (*poke_flush) (struct drm_device *dev, uint32_t class);
 } drm_fence_driver_t;
 
 #define _DRM_FENCE_TYPE_EXE 0x00
@@ -1464,7 +1465,8 @@ extern int drm_user_object_unref(drm_file_t *priv, uint32_t user_token, drm_obje
  * fence objects (drm_fence.c)
  */
 
-extern void drm_fence_handler(drm_device_t *dev, uint32_t breadcrumb, uint32_t type);
+extern void drm_fence_handler(drm_device_t *dev, uint32_t class,
+                             uint32_t sequence, uint32_t type);
 extern void drm_fence_manager_init(drm_device_t *dev);
 extern void drm_fence_manager_takedown(drm_device_t *dev);
 extern void drm_fence_flush_old(drm_device_t *dev, uint32_t sequence);
index b4125c6..dc42894 100644 (file)
@@ -34,7 +34,8 @@
  * Typically called by the IRQ handler.
  */
 
-void drm_fence_handler(drm_device_t * dev, uint32_t sequence, uint32_t type)
+void drm_fence_handler(drm_device_t * dev, uint32_t class,
+                      uint32_t sequence, uint32_t type)
 {
        int wake = 0;
        uint32_t diff;
@@ -156,7 +157,7 @@ static int fence_signaled(drm_device_t * dev, volatile
        drm_fence_driver_t *driver = dev->driver->fence_driver;
 
        if (poke_flush)
-               driver->poke_flush(dev);
+               driver->poke_flush(dev, fence->class);
        read_lock_irqsave(&fm->lock, flags);
        signaled =
            (fence->type & mask & fence->signaled) == (fence->type & mask);
@@ -177,7 +178,6 @@ static void drm_fence_flush_exe(drm_fence_manager_t * fm,
                 * Last_exe_flush is invalid. Find oldest sequence.
                 */
 
-/*             list = fm->fence_types[_DRM_FENCE_TYPE_EXE];*/
                list = &fm->ring;
                if (list->next == &fm->ring) {
                        return;
@@ -234,7 +234,7 @@ int drm_fence_object_flush(drm_device_t * dev,
                }
        }
        write_unlock_irqrestore(&fm->lock, flags);
-       driver->poke_flush(dev);
+       driver->poke_flush(dev, fence->class);
        return 0;
 }
 
@@ -273,11 +273,37 @@ void drm_fence_flush_old(drm_device_t * dev, uint32_t sequence)
 
 EXPORT_SYMBOL(drm_fence_flush_old);
 
+static int drm_fence_lazy_wait(drm_device_t *dev,
+                              volatile drm_fence_object_t *fence,
+                              int ignore_signals, uint32_t mask)
+{
+       drm_fence_manager_t *fm = &dev->fm;
+       unsigned long _end = jiffies + 3*DRM_HZ;
+       int ret = 0;
+
+       do {
+               DRM_WAIT_ON(ret, fm->fence_queue, 3 * DRM_HZ,
+                           fence_signaled(dev, fence, mask, 1));
+               if (time_after_eq(jiffies, _end))
+                       break;
+       } while (ret == -EINTR && ignore_signals);
+       if (time_after_eq(jiffies, _end) && (ret != 0))
+               ret = -EBUSY;
+       if (ret) {
+               if (ret == -EBUSY) {
+                       DRM_ERROR("Fence timeout. "
+                                 "GPU lockup or fence driver was "
+                                 "taken down.\n");
+               }
+               return ((ret == -EINTR) ? -EAGAIN : ret);
+       }
+       return 0;
+}
+
 int drm_fence_object_wait(drm_device_t * dev,
                          volatile drm_fence_object_t * fence,
                          int lazy, int ignore_signals, uint32_t mask)
 {
-       drm_fence_manager_t *fm = &dev->fm;
        drm_fence_driver_t *driver = dev->driver->fence_driver;
        int ret = 0;
        unsigned long _end;
@@ -298,46 +324,32 @@ int drm_fence_object_wait(drm_device_t * dev,
 
        if (lazy && driver->lazy_capable) {
 
-               do {
-                       DRM_WAIT_ON(ret, fm->fence_queue, 3 * DRM_HZ,
-                                   fence_signaled(dev, fence, mask, 1));
-                       if (time_after_eq(jiffies, _end))
-                               break;
-               } while (ret == -EINTR && ignore_signals);
-               if (time_after_eq(jiffies, _end) && (ret != 0))
-                       ret = -EBUSY;
-               if (ret) {
-                       if (ret == -EBUSY) {
-                               DRM_ERROR("Fence timeout. "
-                                         "GPU lockup or fence driver was "
-                                         "taken down.\n");
-                       }
-                       return ((ret == -EINTR) ? -EAGAIN : ret);
-               }
-       } else if ((fence->class == 0) && (mask & DRM_FENCE_TYPE_EXE) &&
-                  driver->lazy_capable) {
+               ret = drm_fence_lazy_wait(dev, fence, ignore_signals, mask);
+               if (ret)
+                       return ret;
 
-               /*
-                * We use IRQ wait for EXE fence if available to gain 
-                * CPU in some cases.
-                */
+       } else {
 
-               do {
-                       DRM_WAIT_ON(ret, fm->fence_queue, 3 * DRM_HZ,
-                                   fence_signaled(dev, fence,
-                                                  DRM_FENCE_TYPE_EXE, 1));
-                       if (time_after_eq(jiffies, _end))
-                               break;
-               } while (ret == -EINTR && ignore_signals);
-               if (time_after_eq(jiffies, _end) && (ret != 0))
-                       ret = -EBUSY;
-               if (ret)
-                       return ((ret == -EINTR) ? -EAGAIN : ret);
-       }
+               if (driver->has_irq(dev, fence->class,
+                                   DRM_FENCE_TYPE_EXE)) {
+                       ret = drm_fence_lazy_wait(dev, fence, ignore_signals,
+                                                 DRM_FENCE_TYPE_EXE);
+                       if (ret)
+                               return ret;
+               }
 
+               if (driver->has_irq(dev, fence->class,
+                                   mask & ~DRM_FENCE_TYPE_EXE)) {
+                       ret = drm_fence_lazy_wait(dev, fence, ignore_signals,
+                                                 mask);
+                       if (ret)
+                               return ret;
+               }
+       }
        if (fence_signaled(dev, fence, mask, 0))
                return 0;
 
+       DRM_ERROR("Busy wait\n");
        /*
         * Avoid kernel-space busy-waits.
         */
@@ -367,7 +379,7 @@ int drm_fence_object_emit(drm_device_t * dev, drm_fence_object_t * fence,
        int ret;
 
        drm_fence_unring(dev, &fence->ring);
-       ret = driver->emit(dev, fence_flags, &sequence, &native_type);
+       ret = driver->emit(dev, fence->class, fence_flags, &sequence, &native_type);
        if (ret)
                return ret;
 
index 848ffa7..b7bf883 100644 (file)
@@ -47,6 +47,7 @@ static drm_fence_driver_t i915_fence_driver = {
        .lazy_capable = 1,
        .emit = i915_fence_emit_sequence,
        .poke_flush = i915_poke_flush,
+       .has_irq = i915_fence_has_irq,
 };
 #endif
 #ifdef I915_HAVE_BUFFER
index 2182604..fa2a3d1 100644 (file)
@@ -61,7 +61,7 @@ static void i915_perform_flush(drm_device_t * dev)
 
                diff = sequence - fm->last_exe_flush;
                if (diff < driver->wrap_diff && diff != 0) {
-                       drm_fence_handler(dev, sequence, DRM_FENCE_TYPE_EXE);
+                       drm_fence_handler(dev, 0, sequence, DRM_FENCE_TYPE_EXE);
                }
 
                diff = sequence - fm->exe_flush_sequence;
@@ -84,7 +84,7 @@ static void i915_perform_flush(drm_device_t * dev)
                        flush_flags = dev_priv->flush_flags;
                        flush_sequence = dev_priv->flush_sequence;
                        dev_priv->flush_pending = 0;
-                       drm_fence_handler(dev, flush_sequence, flush_flags);
+                       drm_fence_handler(dev, 0, flush_sequence, flush_flags);
                }
        }
 
@@ -104,13 +104,13 @@ static void i915_perform_flush(drm_device_t * dev)
                        flush_flags = dev_priv->flush_flags;
                        flush_sequence = dev_priv->flush_sequence;
                        dev_priv->flush_pending = 0;
-                       drm_fence_handler(dev, flush_sequence, flush_flags);
+                       drm_fence_handler(dev, 0, flush_sequence, flush_flags);
                }
        }
 
 }
 
-void i915_poke_flush(drm_device_t * dev)
+void i915_poke_flush(drm_device_t * dev, uint32_t class)
 {
        drm_fence_manager_t *fm = &dev->fm;
        unsigned long flags;
@@ -120,7 +120,7 @@ void i915_poke_flush(drm_device_t * dev)
        write_unlock_irqrestore(&fm->lock, flags);
 }
 
-int i915_fence_emit_sequence(drm_device_t * dev, uint32_t flags,
+int i915_fence_emit_sequence(drm_device_t * dev, uint32_t class, uint32_t flags,
                             uint32_t * sequence, uint32_t * native_type)
 {
        drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
@@ -144,3 +144,15 @@ void i915_fence_handler(drm_device_t * dev)
        i915_perform_flush(dev);
        write_unlock(&fm->lock);
 }
+
+int i915_fence_has_irq(drm_device_t *dev, uint32_t class, uint32_t flags)
+{
+       /*
+        * We have an irq that tells us when we have a new breadcrumb.
+        */
+
+       if (class == 0 && flags == DRM_FENCE_TYPE_EXE)
+               return 1;
+
+       return 0;
+}
index ffc9d43..675fd16 100644 (file)
@@ -178,10 +178,12 @@ extern void i915_mem_release(drm_device_t * dev,
 
 
 extern void i915_fence_handler(drm_device_t *dev);
-extern int i915_fence_emit_sequence(drm_device_t *dev, uint32_t flags,
+extern int i915_fence_emit_sequence(drm_device_t *dev, uint32_t class,
+                                   uint32_t flags,
                                    uint32_t *sequence, 
                                    uint32_t *native_type);
-extern void i915_poke_flush(drm_device_t *dev);
+extern void i915_poke_flush(drm_device_t *dev, uint32_t class);
+extern int i915_fence_has_irq(drm_device_t *dev, uint32_t class, uint32_t flags);
 #endif
 
 #ifdef I915_HAVE_BUFFER