aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMika Kuoppala <mika.kuoppala@linux.intel.com>2012-12-19 04:13:06 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-12-19 05:17:01 -0500
commitf7e98ad4d4a8afa043126a6f24d0a154a684e081 (patch)
tree9cdb7b52da1a1c7e802ba31b02b94045f1fb10a6
parentb70ec5bf439b35a18e702f88078d393261c3e3f2 (diff)
drm/i915: Initialize hardware semaphore state on ring init
Hardware status page needs to have proper seqno set as our initial seqno can be arbitrary. If initial seqno is close to wrap boundary on init and i915_seqno_passed() (31bit space) refers to hw status page which contains zero, errorneous result will be returned. v2: clear mboxes and set hws page directly instead of going through rings. Suggested by Chris Wilson. v3: hws needs to be updated for all gens. Noticed by Chris Wilson. References: https://bugs.freedesktop.org/show_bug.cgi?id=58230 Signed-off-by: Mika Kuoppala <mika.kuoppala@intel.com> Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c8
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.c24
-rw-r--r--drivers/gpu/drm/i915/intel_ringbuffer.h2
3 files changed, 13 insertions, 21 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6685861cd176..51282b2c4943 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1954,9 +1954,7 @@ i915_gem_handle_seqno_wrap(struct drm_device *dev)
1954 1954
1955 /* Finally reset hw state */ 1955 /* Finally reset hw state */
1956 for_each_ring(ring, dev_priv, i) { 1956 for_each_ring(ring, dev_priv, i) {
1957 ret = intel_ring_handle_seqno_wrap(ring); 1957 intel_ring_init_seqno(ring, 0);
1958 if (ret)
1959 return ret;
1960 1958
1961 for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++) 1959 for (j = 0; j < ARRAY_SIZE(ring->sync_seqno); j++)
1962 ring->sync_seqno[j] = 0; 1960 ring->sync_seqno[j] = 0;
@@ -3935,6 +3933,8 @@ i915_gem_init_hw(struct drm_device *dev)
3935 3933
3936 i915_gem_init_swizzling(dev); 3934 i915_gem_init_swizzling(dev);
3937 3935
3936 dev_priv->next_seqno = dev_priv->last_seqno = (u32)~0 - 0x1000;
3937
3938 ret = intel_init_render_ring_buffer(dev); 3938 ret = intel_init_render_ring_buffer(dev);
3939 if (ret) 3939 if (ret)
3940 return ret; 3940 return ret;
@@ -3951,8 +3951,6 @@ i915_gem_init_hw(struct drm_device *dev)
3951 goto cleanup_bsd_ring; 3951 goto cleanup_bsd_ring;
3952 } 3952 }
3953 3953
3954 dev_priv->next_seqno = (u32)-1 - 0x1000;
3955
3956 /* 3954 /*
3957 * XXX: There was some w/a described somewhere suggesting loading 3955 * XXX: There was some w/a described somewhere suggesting loading
3958 * contexts before PPGTT. 3956 * contexts before PPGTT.
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c
index f536a9951ab3..2bd074ad6f54 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.c
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.c
@@ -1184,6 +1184,8 @@ static int intel_init_ring_buffer(struct drm_device *dev,
1184 if (IS_I830(ring->dev) || IS_845G(ring->dev)) 1184 if (IS_I830(ring->dev) || IS_845G(ring->dev))
1185 ring->effective_size -= 128; 1185 ring->effective_size -= 128;
1186 1186
1187 intel_ring_init_seqno(ring, dev_priv->last_seqno);
1188
1187 return 0; 1189 return 0;
1188 1190
1189err_unmap: 1191err_unmap:
@@ -1431,26 +1433,18 @@ int intel_ring_begin(struct intel_ring_buffer *ring,
1431 return __intel_ring_begin(ring, num_dwords * sizeof(uint32_t)); 1433 return __intel_ring_begin(ring, num_dwords * sizeof(uint32_t));
1432} 1434}
1433 1435
1434int intel_ring_handle_seqno_wrap(struct intel_ring_buffer *ring) 1436void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno)
1435{ 1437{
1436 int ret; 1438 struct drm_i915_private *dev_priv = ring->dev->dev_private;
1437 1439
1438 BUG_ON(ring->outstanding_lazy_request); 1440 BUG_ON(ring->outstanding_lazy_request);
1439 1441
1440 if (INTEL_INFO(ring->dev)->gen < 6) 1442 if (INTEL_INFO(ring->dev)->gen >= 6) {
1441 return 0; 1443 I915_WRITE(RING_SYNC_0(ring->mmio_base), 0);
1442 1444 I915_WRITE(RING_SYNC_1(ring->mmio_base), 0);
1443 ret = __intel_ring_begin(ring, 6 * sizeof(uint32_t)); 1445 }
1444 if (ret)
1445 return ret;
1446
1447 /* Leaving a stale, pre-wrap seqno behind in the mboxes will result in
1448 * post-wrap semaphore waits completing immediately. Clear them. */
1449 update_mboxes(ring, ring->signal_mbox[0]);
1450 update_mboxes(ring, ring->signal_mbox[1]);
1451 intel_ring_advance(ring);
1452 1446
1453 return 0; 1447 ring->set_seqno(ring, seqno);
1454} 1448}
1455 1449
1456void intel_ring_advance(struct intel_ring_buffer *ring) 1450void intel_ring_advance(struct intel_ring_buffer *ring)
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h
index 4a7cd67742da..e7b9a6aac955 100644
--- a/drivers/gpu/drm/i915/intel_ringbuffer.h
+++ b/drivers/gpu/drm/i915/intel_ringbuffer.h
@@ -205,7 +205,7 @@ static inline void intel_ring_emit(struct intel_ring_buffer *ring,
205} 205}
206void intel_ring_advance(struct intel_ring_buffer *ring); 206void intel_ring_advance(struct intel_ring_buffer *ring);
207int __must_check intel_ring_idle(struct intel_ring_buffer *ring); 207int __must_check intel_ring_idle(struct intel_ring_buffer *ring);
208int __must_check intel_ring_handle_seqno_wrap(struct intel_ring_buffer *ring); 208void intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno);
209int intel_ring_flush_all_caches(struct intel_ring_buffer *ring); 209int intel_ring_flush_all_caches(struct intel_ring_buffer *ring);
210int intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring); 210int intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring);
211 211