summaryrefslogtreecommitdiff
path: root/shared-core
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2008-05-05 22:09:34 -0700
committerKeith Packard <keithp@keithp.com>2008-05-05 22:09:34 -0700
commited6657fa8e7977b19bb836782ac8e87f0f703cef (patch)
tree4789a9233fd81b4604bcb642cbf727f0629d42a4 /shared-core
parent2c8f970baaba9c72c882677f40ce8271bff03bac (diff)
Monitor ACTHD register while polling for idle ring.
When batch buffers are executing, the ring may be stuck for a long time. Monitor the ACTHD pointer which will show if the execution engine is actually hung.
Diffstat (limited to 'shared-core')
-rw-r--r--shared-core/i915_dma.c24
1 files changed, 21 insertions, 3 deletions
diff --git a/shared-core/i915_dma.c b/shared-core/i915_dma.c
index 4bf37325..d881a231 100644
--- a/shared-core/i915_dma.c
+++ b/shared-core/i915_dma.c
@@ -41,10 +41,14 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
drm_i915_private_t *dev_priv = dev->dev_private;
drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+ u32 acthd_reg = IS_I965G(dev) ? I965REG_ACTHD : I915REG_ACTHD;
+ u32 last_acthd = I915_READ(acthd_reg);
+ u32 acthd;
int i;
- for (i = 0; i < 10000; i++) {
+ for (i = 0; i < 100000; i++) {
ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
+ acthd = I915_READ(acthd_reg);
ring->space = ring->head - (ring->tail + 8);
if (ring->space < 0)
ring->space += ring->Size;
@@ -54,8 +58,12 @@ int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
if (ring->head != last_head)
i = 0;
+ if (acthd != last_acthd)
+ i = 0;
+
last_head = ring->head;
- DRM_UDELAY(1);
+ last_acthd = acthd;
+ DRM_UDELAY(10);
}
return -EBUSY;
@@ -714,9 +722,19 @@ void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)
int i915_quiescent(struct drm_device *dev)
{
drm_i915_private_t *dev_priv = dev->dev_private;
+ int ret;
i915_kernel_lost_context(dev);
- return i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
+ ret = i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
+ if (ret)
+ {
+ i915_kernel_lost_context (dev);
+ DRM_ERROR ("not quiescent head %08x tail %08x space %08x\n",
+ dev_priv->ring.head,
+ dev_priv->ring.tail,
+ dev_priv->ring.space);
+ }
+ return ret;
}
static int i915_flush_ioctl(struct drm_device *dev, void *data,