Semaphore waits use a new instruction, MI_SEMAPHORE_WAIT. The seqno to wait on is all well defined by the table in the previous patch. There is nothing else different from previous GEN's semaphore synchronization code.
v2: Update macros to not require the other ring's ring->id (Chris) Signed-off-by: Ben Widawsky <b...@bwidawsk.net> --- drivers/gpu/drm/i915/i915_reg.h | 3 ++ drivers/gpu/drm/i915/intel_ringbuffer.c | 66 +++++++++++++++------------------ drivers/gpu/drm/i915/intel_ringbuffer.h | 30 +++++++++++++++ 3 files changed, 62 insertions(+), 37 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 5c3bf66..a47463f 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h @@ -242,6 +242,9 @@ #define MI_RESTORE_INHIBIT (1<<0) #define MI_SEMAPHORE_SIGNAL MI_INSTR(0x1b, 0) /* GEN8+ */ #define MI_SEMAPHORE_TARGET(engine) ((engine)<<15) +#define MI_SEMAPHORE_WAIT MI_INSTR(0x1c, 2) /* GEN8+ */ +#define MI_SEMAPHORE_POLL (1<<15) +#define MI_SEMAPHORE_SAD_GTE_SDD (1<<12) #define MI_STORE_DWORD_IMM MI_INSTR(0x20, 1) #define MI_MEM_VIRTUAL (1 << 22) /* 965+ only */ #define MI_STORE_DWORD_INDEX MI_INSTR(0x21, 1) diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index f40d4da..cf20140 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c @@ -797,6 +797,31 @@ static inline bool i915_gem_has_seqno_wrapped(struct drm_device *dev, * @signaller - ring which has, or will signal * @seqno - seqno which the waiter will block on */ + +static int +gen8_ring_sync(struct intel_ring_buffer *waiter, + struct intel_ring_buffer *signaller, + u32 seqno) +{ + struct drm_i915_private *dev_priv = waiter->dev->dev_private; + int ret; + + ret = intel_ring_begin(waiter, 4); + if (ret) + return ret; + + intel_ring_emit(waiter, MI_SEMAPHORE_WAIT | + MI_SEMAPHORE_GLOBAL_GTT | + MI_SEMAPHORE_SAD_GTE_SDD); + intel_ring_emit(waiter, seqno); + intel_ring_emit(waiter, + lower_32_bits(GEN8_WAIT_OFFSET(waiter, signaller->id))); + intel_ring_emit(waiter, + upper_32_bits(GEN8_WAIT_OFFSET(waiter, signaller->id))); + intel_ring_advance(waiter); + return 0; +} + static int gen6_ring_sync(struct intel_ring_buffer *waiter, struct intel_ring_buffer *signaller, @@ -1935,39 +1960,6 @@ static int gen6_ring_flush(struct intel_ring_buffer *ring, return 0; } -/* seqno size is actually only a uint32, but since we plan to use MI_FLUSH_DW to - * do the writes, and that must have qw aligned offsets, simply pretend it's 8b. - */ -#define SEQNO_SIZE sizeof(uint64_t) -#define GEN8_SIGNAL_OFFSET(to) \ - (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \ - (ring->id * I915_NUM_RINGS * SEQNO_SIZE) + \ - (SEQNO_SIZE * (to))) - -#define GEN8_WAIT_OFFSET(from) \ - (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \ - ((from) * I915_NUM_RINGS * SEQNO_SIZE) + \ - (SEQNO_SIZE * ring->id)) - -#define GEN8_RING_SEMAPHORE_INIT do { \ - if (!dev_priv->semaphore_obj) { \ - break; \ - } \ - ring->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET(RCS); \ - ring->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET(VCS); \ - ring->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET(BCS); \ - ring->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET(VECS); \ - ring->semaphore.mbox[RCS] = GEN8_WAIT_OFFSET(RCS); \ - ring->semaphore.mbox[VCS] = GEN8_WAIT_OFFSET(VCS); \ - ring->semaphore.mbox[BCS] = GEN8_WAIT_OFFSET(BCS); \ - ring->semaphore.mbox[VECS] = GEN8_WAIT_OFFSET(VECS); \ - ring->semaphore.signal_ggtt[ring->id] = MI_SEMAPHORE_SYNC_INVALID; \ - ring->semaphore.mbox[ring->id] = GEN6_NOSYNC; \ - } while(0) -#undef seqno_size - - - int intel_init_render_ring_buffer(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; @@ -2003,7 +1995,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) ring->irq_enable_mask = GT_RENDER_USER_INTERRUPT; ring->get_seqno = gen6_ring_get_seqno; ring->set_seqno = ring_set_seqno; - ring->semaphore.sync_to = gen6_ring_sync; + ring->semaphore.sync_to = gen8_ring_sync; if (i915_semaphore_is_enabled(dev)) { BUG_ON(!dev_priv->semaphore_obj); ring->semaphore.signal = gen8_rcs_signal; @@ -2188,7 +2180,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *dev) ring->irq_put = gen8_ring_put_irq; ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; - ring->semaphore.sync_to = gen6_ring_sync; + ring->semaphore.sync_to = gen8_ring_sync; if (i915_semaphore_is_enabled(dev)) { ring->semaphore.signal = gen8_xcs_signal; GEN8_RING_SEMAPHORE_INIT; @@ -2253,7 +2245,7 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) ring->irq_get = gen8_ring_get_irq; ring->irq_put = gen8_ring_put_irq; ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; - ring->semaphore.sync_to = gen6_ring_sync; + ring->semaphore.sync_to = gen8_ring_sync; if (i915_semaphore_is_enabled(dev)) { ring->semaphore.signal = gen8_xcs_signal; GEN8_RING_SEMAPHORE_INIT; @@ -2302,7 +2294,7 @@ int intel_init_vebox_ring_buffer(struct drm_device *dev) ring->irq_get = gen8_ring_get_irq; ring->irq_put = gen8_ring_put_irq; ring->dispatch_execbuffer = gen8_ring_dispatch_execbuffer; - ring->semaphore.sync_to = gen6_ring_sync; + ring->semaphore.sync_to = gen8_ring_sync; if (i915_semaphore_is_enabled(dev)) { ring->semaphore.signal = gen8_xcs_signal; GEN8_RING_SEMAPHORE_INIT; diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index f1e7a66..ed55370 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h @@ -33,6 +33,36 @@ struct intel_hw_status_page { #define I915_READ_IMR(ring) I915_READ(RING_IMR((ring)->mmio_base)) #define I915_WRITE_IMR(ring, val) I915_WRITE(RING_IMR((ring)->mmio_base), val) +/* seqno size is actually only a uint32, but since we plan to use MI_FLUSH_DW to + * do the writes, and that must have qw aligned offsets, simply pretend it's 8b. + */ +#define i915_semaphore_seqno_size sizeof(uint64_t) +#define GEN8_SIGNAL_OFFSET(to) \ + (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \ + (ring->id * I915_NUM_RINGS * i915_semaphore_seqno_size) + \ + (i915_semaphore_seqno_size * (to))) + +#define GEN8_WAIT_OFFSET(__ring, from) \ + (i915_gem_obj_ggtt_offset(dev_priv->semaphore_obj) + \ + ((from) * I915_NUM_RINGS * i915_semaphore_seqno_size) + \ + (i915_semaphore_seqno_size * (__ring)->id)) + +#define GEN8_RING_SEMAPHORE_INIT do { \ + if (!dev_priv->semaphore_obj) { \ + break; \ + } \ + ring->semaphore.signal_ggtt[RCS] = GEN8_SIGNAL_OFFSET(RCS); \ + ring->semaphore.signal_ggtt[VCS] = GEN8_SIGNAL_OFFSET(VCS); \ + ring->semaphore.signal_ggtt[BCS] = GEN8_SIGNAL_OFFSET(BCS); \ + ring->semaphore.signal_ggtt[VECS] = GEN8_SIGNAL_OFFSET(VECS); \ + ring->semaphore.mbox[RCS] = GEN8_WAIT_OFFSET(ring, RCS); \ + ring->semaphore.mbox[VCS] = GEN8_WAIT_OFFSET(ring, VCS); \ + ring->semaphore.mbox[BCS] = GEN8_WAIT_OFFSET(ring, BCS); \ + ring->semaphore.mbox[VECS] = GEN8_WAIT_OFFSET(ring, VECS); \ + ring->semaphore.signal_ggtt[ring->id] = MI_SEMAPHORE_SYNC_INVALID; \ + ring->semaphore.mbox[ring->id] = GEN6_NOSYNC; \ + } while(0) + enum intel_ring_hangcheck_action { HANGCHECK_IDLE = 0, HANGCHECK_WAIT, -- 1.8.5.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/intel-gfx