From 7dbffc08e4f3f295d787b6391fe122c9250b7700 Mon Sep 17 00:00:00 2001 From: Mika Kuoppala Date: Mon, 17 Dec 2012 12:13:26 +0200 Subject: [PATCH 1/4] 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. References: https://bugs.freedesktop.org/show_bug.cgi?id=58230 Signed-off-by: Mika Kuoppala --- drivers/gpu/drm/i915/i915_gem.c | 6 +++--- drivers/gpu/drm/i915/intel_ringbuffer.c | 18 ++++++++++++++++-- drivers/gpu/drm/i915/intel_ringbuffer.h | 3 ++- 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index d15c862..8dc5cc1 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c @@ -1954,7 +1954,7 @@ i915_gem_handle_seqno_wrap(struct drm_device *dev) /* Finally reset hw state */ for_each_ring(ring, dev_priv, i) { - ret = intel_ring_handle_seqno_wrap(ring); + ret = intel_ring_init_seqno(ring, 0); if (ret) return ret; @@ -3933,6 +3933,8 @@ i915_gem_init_hw(struct drm_device *dev) i915_gem_init_swizzling(dev); + dev_priv->next_seqno = dev_priv->last_seqno = (u32)~0 - 0x1000; + ret = intel_init_render_ring_buffer(dev); if (ret) return ret; @@ -3949,8 +3951,6 @@ i915_gem_init_hw(struct drm_device *dev) goto cleanup_bsd_ring; } - dev_priv->next_seqno = (u32)-1 - 0x1000; - /* * XXX: There was some w/a described somewhere suggesting loading * contexts before PPGTT. diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index 69bbe7b..7e38511f 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -1171,6 +1171,10 @@ static int intel_init_ring_buffer(struct drm_device *dev, if (IS_I830(ring->dev) || IS_845G(ring->dev)) ring->effective_size -= 128; + ret = intel_ring_init_seqno(ring, dev_priv->last_seqno); + if (ret) + goto err_unmap; + return 0; err_unmap: @@ -1418,7 +1422,7 @@ int intel_ring_begin(struct intel_ring_buffer *ring, return __intel_ring_begin(ring, num_dwords * sizeof(uint32_t)); } -int intel_ring_handle_seqno_wrap(struct intel_ring_buffer *ring) +int intel_ring_init_seqno(struct intel_ring_buffer *ring, u32 seqno) { int ret; @@ -1427,7 +1431,7 @@ int intel_ring_handle_seqno_wrap(struct intel_ring_buffer *ring) if (INTEL_INFO(ring->dev)->gen < 6) return 0; - ret = __intel_ring_begin(ring, 6 * sizeof(uint32_t)); + ret = __intel_ring_begin(ring, 10 * sizeof(uint32_t)); if (ret) return ret; @@ -1435,8 +1439,18 @@ int intel_ring_handle_seqno_wrap(struct intel_ring_buffer *ring) * post-wrap semaphore waits completing immediately. Clear them. */ update_mboxes(ring, ring->signal_mbox[0]); update_mboxes(ring, ring->signal_mbox[1]); + intel_ring_emit(ring, MI_STORE_DWORD_INDEX); + intel_ring_emit(ring, I915_GEM_HWS_INDEX << MI_STORE_DWORD_INDEX_SHIFT); + intel_ring_emit(ring, seqno); + intel_ring_emit(ring, MI_USER_INTERRUPT); intel_ring_advance(ring); + /* Wait until mboxes have actually cleared before pushing + * anything to the rings */ + ret = ring_wait_for_space(ring, ring->size - 8); + if (ret) + return ret; + return 0; } diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index b4a533e..cb5a663 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -196,7 +196,8 @@ static inline void intel_ring_emit(struct intel_ring_buffer *ring, } void intel_ring_advance(struct intel_ring_buffer *ring); int __must_check intel_ring_idle(struct intel_ring_buffer *ring); -int __must_check intel_ring_handle_seqno_wrap(struct intel_ring_buffer *ring); +int __must_check intel_ring_init_seqno(struct intel_ring_buffer *ring, + u32 seqno); int intel_ring_flush_all_caches(struct intel_ring_buffer *ring); int intel_ring_invalidate_all_caches(struct intel_ring_buffer *ring); -- 1.7.9.5