drm/i915: check gtfifodbg after possibly failed writes

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>
This commit is contained in:
Ben Widawsky 2012-02-09 10:15:20 +01:00 committed by Daniel Vetter
parent ee64cbdbf6
commit 67a3744f75
2 changed files with 13 additions and 4 deletions

View 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); 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) { if (dev_priv->gt_fifo_count < GT_FIFO_NUM_RESERVED_ENTRIES) {
int loop = 500; int loop = 500;
u32 fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); 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); udelay(10);
fifo = I915_READ_NOTRACE(GT_FIFO_FREE_ENTRIES); 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 = fifo;
} }
dev_priv->gt_fifo_count--; dev_priv->gt_fifo_count--;
return ret;
} }
static int i915_drm_freeze(struct drm_device *dev) static int i915_drm_freeze(struct drm_device *dev)
@ -1001,11 +1006,15 @@ __i915_read(64, q)
#define __i915_write(x, y) \ #define __i915_write(x, y) \
void i915_write##x(struct drm_i915_private *dev_priv, u32 reg, u##x val) { \ 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)); \ trace_i915_reg_rw(true, reg, val, sizeof(val)); \
if (NEEDS_FORCE_WAKE((dev_priv), (reg))) { \ 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); \ write##y(val, dev_priv->regs + reg); \
if (unlikely(__fifo_ret)) { \
gen6_gt_check_fifodbg(dev_priv); \
} \
} }
__i915_write(8, b) __i915_write(8, b)
__i915_write(16, w) __i915_write(16, w)

View 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_get(struct drm_i915_private *dev_priv);
void gen6_gt_force_wake_put(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 */ /* We give fast paths for the really cool registers */
#define NEEDS_FORCE_WAKE(dev_priv, reg) \ #define NEEDS_FORCE_WAKE(dev_priv, reg) \