drm/i915: check gtfifodbg after possibly failed writes
authorBen Widawsky <ben@bwidawsk.net>
Thu, 9 Feb 2012 09:15:20 +0000 (10:15 +0100)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Sat, 11 Feb 2012 23:21:41 +0000 (00:21 +0100)
If we don't have a sufficient number of free entries in the FIFO, we
proceed to do a write anyway. With this check we should have a clue if
that write actually failed or not.

After some discussion with Daniel Vetter regarding his original
complaint, we agreed upon this.

Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_drv.c
drivers/gpu/drm/i915/i915_drv.h

index d783e2b4c914ccff6d0d9cf48b11829637102030..0694e170a338932ca7f81fa3559e0bf615076949 100644 (file)
@@ -421,8 +421,10 @@ void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv)
        spin_unlock_irqrestore(&dev_priv->gt_lock, irqflags);
 }
 
-void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
+int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
 {
+       int ret = 0;
+
        if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
                int loop = 500;
                u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
@@ -430,10 +432,13 @@ void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv)
                        udelay(10);
                        fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES);
                }
-               WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES);
+               if (WARN_ON(loop < 0 && fifo <= GT_FIFO_NUM_RESERVED_ENTRIES))
+                       ++ret;
                dev_priv->gt_fifo_count = fifo;
        }
        dev_priv->gt_fifo_count--;
+
+       return ret;
 }
 
 static int i915_drm_freeze(struct drm_device *dev)
@@ -1001,11 +1006,15 @@ __i915_read(64, q)
 
 #define __i915_write(x, y) \
 void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \
+       u32 __fifo_ret = 0; \
        trace_i915_reg_rw(true, reg, val, sizeof(val)); \
        if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \
-               __gen6_gt_wait_for_fifo(dev_priv); \
+               __fifo_ret = __gen6_gt_wait_for_fifo(dev_priv); \
        } \
        write##y(val, dev_priv->regs + reg); \
+       if (unlikely(__fifo_ret)) { \
+               gen6_gt_check_fifodbg(dev_priv); \
+       } \
 }
 __i915_write(8, b)
 __i915_write(16, w)
index 922aed33035d01143940227df2a5e77fdc49a5be..000a9ad17ddd1a6587118892005c17971cd8de47 100644 (file)
@@ -1401,7 +1401,7 @@ extern void intel_display_print_error_state(struct seq_file *m,
  */
 void gen6_gt_force_wake_get(struct drm_i915_private *dev_priv);
 void gen6_gt_force_wake_put(struct drm_i915_private *dev_priv);
-void __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
+int __gen6_gt_wait_for_fifo(struct drm_i915_private *dev_priv);
 
 /* We give fast paths for the really cool registers */
 #define NEEDS_FORCE_WAKE(dev_priv, reg) \