--- intel_ringbuffer.c.org 2013-01-18 14:33:31.647541129 +0800 +++ intel_ringbuffer.c 2013-01-18 18:27:58.433757169 +0800 @@ -252,42 +252,54 @@ drm_i915_private_t *dev_priv = ring->dev->dev_private; struct drm_i915_gem_object *obj = ring->obj; u32 head; - - /* Stop the ring if it's running. */ - I915_WRITE_CTL(ring, 0); - I915_WRITE_HEAD(ring, 0); - ring->write_tail(ring, 0); - - head = I915_READ_HEAD(ring) & HEAD_ADDR; - - /* G45 ring initialization fails to reset head to zero */ - if (head != 0) { - DRM_DEBUG_KMS("%s head not reset to zero " - "ctl %08x head %08x tail %08x start %08x\n", - ring->name, - I915_READ_CTL(ring), - I915_READ_HEAD(ring), - I915_READ_TAIL(ring), - I915_READ_START(ring)); - + int i=0; + + for (i=0;i<120; i++) { + /* Stop the ring if it's running. */ + I915_WRITE_CTL(ring, 0); + (void)I915_READ_CTL(ring); I915_WRITE_HEAD(ring, 0); + ring->write_tail(ring, 0); + + head = I915_READ_HEAD(ring) & HEAD_ADDR; - if (I915_READ_HEAD(ring) & HEAD_ADDR) { - DRM_ERROR("failed to set %s head to zero " - "ctl %08x head %08x tail %08x start %08x\n", - ring->name, - I915_READ_CTL(ring), - I915_READ_HEAD(ring), - I915_READ_TAIL(ring), - I915_READ_START(ring)); + /* G45 ring initialization fails to reset head to zero */ + if (head != 0) { + DRM_DEBUG_KMS("%s head not reset to zero " + "ctl %08x head %08x tail %08x start %08x\n", + ring->name, + I915_READ_CTL(ring), + I915_READ_HEAD(ring), + I915_READ_TAIL(ring), + I915_READ_START(ring)); + + I915_WRITE_HEAD(ring, 0); + + if (I915_READ_HEAD(ring) & HEAD_ADDR) { + DRM_ERROR("failed to set %s head to zero " + "ctl %08x head %08x tail %08x start %08x\n", + ring->name, + I915_READ_CTL(ring), + I915_READ_HEAD(ring), + I915_READ_TAIL(ring), + I915_READ_START(ring)); + } } - } + else { + printk(KERN_ALERT"in %s %d init successfully.",__FUNCTION__,i); + break; + } + + } /* Initialize the ring. This must happen _after_ we've cleared the ring * registers with the above sequence (the readback of the HEAD registers * also enforces ordering), otherwise the hw might lose the new ring * register values. */ I915_WRITE_START(ring, obj->gtt_offset); + if (I915_READ_START(ring) != obj->gtt_offset) + DRM_ERROR("failed to set %s start to GTT offset\n", ring->name); + I915_WRITE_CTL(ring, ((ring->size - PAGE_SIZE) & RING_NR_PAGES) | RING_VALID);