@@ -4817,6 +4817,9 @@ i915_gem_init_hw(struct drm_device *dev)
}
}
+ for_each_ring(ring, dev_priv, i)
+ intel_ring_reset(ring);
+
i915_gem_init_swizzling(dev);
/*
@@ -4827,19 +4830,19 @@ i915_gem_init_hw(struct drm_device *dev)
*/
init_unused_rings(dev);
- for_each_ring(ring, dev_priv, i) {
- ret = ring->init_hw(ring);
- if (ret)
- goto out;
+ ret = i915_ppgtt_init_hw(dev);
+ if (ret && ret != -EIO) {
+ DRM_ERROR("PPGTT enable failed %d\n", ret);
+ i915_gem_cleanup_ringbuffer(dev);
}
for (i = 0; i < NUM_L3_SLICES(dev); i++)
i915_gem_l3_remap(&dev_priv->ring[RCS], i);
- ret = i915_ppgtt_init_hw(dev);
- if (ret && ret != -EIO) {
- DRM_ERROR("PPGTT enable failed %d\n", ret);
- i915_gem_cleanup_ringbuffer(dev);
+ for_each_ring(ring, dev_priv, i) {
+ ret = ring->init_hw(ring);
+ if (ret)
+ goto out;
}
ret = i915_gem_context_enable(dev_priv);
@@ -560,6 +560,22 @@ static bool stop_ring(struct intel_engine_cs *ring)
return (I915_READ_HEAD(ring) & HEAD_ADDR) == 0;
}
+void intel_ring_reset(struct intel_engine_cs *ring)
+{
+ struct intel_ringbuffer *ringbuf = ring->buffer;
+
+ WARN_ON(!stop_ring(ring));
+
+ if (WARN_ON(ringbuf == NULL))
+ return;
+
+ ringbuf->head = 0;
+ ringbuf->tail = 0;
+
+ ringbuf->last_retired_head = -1;
+}
+
+
static int init_ring_common(struct intel_engine_cs *ring)
{
struct drm_device *dev = ring->dev;
@@ -614,6 +630,9 @@ static int init_ring_common(struct intel_engine_cs *ring)
I915_WRITE_HEAD(ring, 0);
(void)I915_READ_HEAD(ring);
+ I915_WRITE_HEAD(ring, ringbuf->head);
+ I915_WRITE_TAIL(ring, ringbuf->head);
+
I915_WRITE_CTL(ring,
((ringbuf->size - PAGE_SIZE) & RING_NR_PAGES)
| RING_VALID);
@@ -621,7 +640,7 @@ static int init_ring_common(struct intel_engine_cs *ring)
/* If the head is still not zero, the ring is dead */
if (wait_for((I915_READ_CTL(ring) & RING_VALID) != 0 &&
I915_READ_START(ring) == i915_gem_obj_ggtt_offset(obj) &&
- (I915_READ_HEAD(ring) & HEAD_ADDR) == 0, 50)) {
+ (I915_READ_HEAD(ring) & HEAD_ADDR) == ringbuf->head, 50)) {
DRM_ERROR("%s initialization failed "
"ctl %08x (valid? %d) head %08x tail %08x start %08x [expected %08lx]\n",
ring->name,
@@ -632,13 +651,12 @@ static int init_ring_common(struct intel_engine_cs *ring)
goto out;
}
+ I915_WRITE_TAIL(ring, ringbuf->tail);
+
ringbuf->last_retired_head = -1;
- ringbuf->head = I915_READ_HEAD(ring);
- ringbuf->tail = I915_READ_TAIL(ring) & TAIL_ADDR;
intel_ring_update_space(ringbuf);
memset(&ring->hangcheck, 0, sizeof(ring->hangcheck));
-
out:
intel_uncore_forcewake_put(dev_priv, FORCEWAKE_ALL);
@@ -408,6 +408,7 @@ int __intel_ring_space(int head, int tail, int size);
void intel_ring_update_space(struct intel_ringbuffer *ringbuf);
int intel_ring_space(struct intel_ringbuffer *ringbuf);
bool intel_ring_stopped(struct intel_engine_cs *ring);
+void intel_ring_reset(struct intel_engine_cs *ring);
void __intel_ring_advance(struct intel_engine_cs *ring);
int __must_check intel_ring_idle(struct intel_engine_cs *ring);