summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2008-09-02 20:02:35 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2008-09-02 20:02:35 +0000
commite638c5d4ba7095c89965d1906c0314fc1ee09c1a (patch)
treee70a913e470bab0fde768934e3a780ffc14e4c41 /sys/dev
parent359b97098eaf6797095d750331f36fef7b85ca1b (diff)
Track progress inside of batchbuffers so we know the hardware isn't
wedged. This avoids early temination of long-running commands. From Keith Packard, via drm git. Tested by several on various chipsets.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/pci/drm/i915_dma.c14
-rw-r--r--sys/dev/pci/drm/i915_drv.h2
2 files changed, 13 insertions, 3 deletions
diff --git a/sys/dev/pci/drm/i915_dma.c b/sys/dev/pci/drm/i915_dma.c
index d35007a6fc0..2b8f077338d 100644
--- a/sys/dev/pci/drm/i915_dma.c
+++ b/sys/dev/pci/drm/i915_dma.c
@@ -40,11 +40,15 @@ 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(PRB0_HEAD) & HEAD_ADDR;
+ u_int32_t acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
+ u_int32_t last_acthd = I915_READ(acthd_reg);
+ u_int32_t acthd;
+ u_int32_t last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
int i;
- for (i = 0; i < 10000; i++) {
+ for (i = 0; i < 100000; i++) {
ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
+ acthd = I915_READ(acthd_reg);
ring->space = ring->head - (ring->tail + 8);
if (ring->space < 0)
ring->space += ring->Size;
@@ -53,9 +57,13 @@ 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;
+ msleep(dev_priv, &dev->dev_lock, PZERO | PCATCH, "i915wt",
+ hz / 100);
}
return -EBUSY;
diff --git a/sys/dev/pci/drm/i915_drv.h b/sys/dev/pci/drm/i915_drv.h
index cf9d112bcc5..2f2da9365d7 100644
--- a/sys/dev/pci/drm/i915_drv.h
+++ b/sys/dev/pci/drm/i915_drv.h
@@ -562,6 +562,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define PRB1_HEAD 0x02044 /* 915+ only */
#define PRB1_START 0x02048 /* 915+ only */
#define PRB1_CTL 0x0204c /* 915+ only */
+#define ACTHD_I965 0x02074
#define HWS_PGA 0x02080
#define IPEIR 0x02088
#define NOPID 0x02094
@@ -592,6 +593,7 @@ extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
#define EMR 0x020b4
#define ESR 0x020b8
#define INSTPM 0x020c0
+#define ACTHD 0x020c8
#define FW_BLC 0x020d8
#define FW_BLC_SELF 0x020e0 /* 915+ only */
#define MI_ARB_STATE 0x020e4 /* 915+ only */