[Intel-gfx] [patch] [drm/i915] Fix up ring initialization to cover G45 oddities

Keith Packard keithp at keithp.com
Wed Oct 15 02:20:35 CEST 2008


From a84c80858b22b538e3e049b99bd9e2768e32e2b3 Mon Sep 17 00:00:00 2001
From: Keith Packard <keithp at keithp.com>
Date: Tue, 14 Oct 2008 17:07:58 -0700
Subject: [PATCH] [drm/i915] Fix up ring initialization to cover G45 oddities

G45 appears quite sensitive to ring initialization register writes,
sometimes leaving the HEAD register with the START register contents. Check
to make sure HEAD is reset correctly when START is written, and fix it up,
screaming loudly.

Signed-off-by: Keith Packard <keithp at keithp.com>
---
 drivers/gpu/drm/i915/i915_gem.c |   34 ++++++++++++++++++++++++++++++++--
 1 files changed, 32 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 7460e62..f29d33f 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2343,6 +2343,7 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
 	struct drm_gem_object *obj;
 	struct drm_i915_gem_object *obj_priv;
 	int ret;
+	u32 head;
 
 	ret = i915_gem_init_hws(dev);
 	if (ret != 0)
@@ -2383,17 +2384,46 @@ i915_gem_init_ringbuffer(struct drm_device *dev)
 
 	/* Stop the ring if it's running. */
 	I915_WRITE(PRB0_CTL, 0);
-	I915_WRITE(PRB0_HEAD, 0);
 	I915_WRITE(PRB0_TAIL, 0);
-	I915_WRITE(PRB0_START, 0);
+	I915_WRITE(PRB0_HEAD, 0);
 
 	/* Initialize the ring. */
 	I915_WRITE(PRB0_START, obj_priv->gtt_offset);
+	head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
+
+	/* G45 ring initialization fails to reset head to zero */
+	if (head != 0) {
+		DRM_ERROR ("Ring head not reset to zero ctl %08x head %08x tail %08x start %08x\n",
+			   I915_READ(PRB0_CTL),
+			   I915_READ(PRB0_HEAD),
+			   I915_READ(PRB0_TAIL),
+			   I915_READ(PRB0_START));
+		I915_WRITE(PRB0_HEAD, 0);
+	
+		DRM_ERROR ("Ring head forced to zero ctl %08x head %08x tail %08x start %08x\n",
+			   I915_READ(PRB0_CTL),
+			   I915_READ(PRB0_HEAD),
+			   I915_READ(PRB0_TAIL),
+			   I915_READ(PRB0_START));
+	}
+	
 	I915_WRITE(PRB0_CTL,
 		   ((obj->size - 4096) & RING_NR_PAGES) |
 		   RING_NO_REPORT |
 		   RING_VALID);
 
+	head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
+
+	/* If the head is still not zero, the ring is dead */
+	if (head != 0) {
+		DRM_ERROR ("Ring initialization failed ctl %08x head %08x tail %08x start %08x\n",
+			   I915_READ(PRB0_CTL),
+			   I915_READ(PRB0_HEAD),
+			   I915_READ(PRB0_TAIL),
+			   I915_READ(PRB0_START));
+		return -EIO;
+	}
+	
 	/* Update our cache of the ring state */
 	i915_kernel_lost_context(dev);
 
-- 
1.5.6.5


-- 
keith.packard at intel.com
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: This is a digitally signed message part
URL: <http://lists.freedesktop.org/archives/intel-gfx/attachments/20081014/3d302643/attachment.sig>


More information about the Intel-gfx mailing list