On Wed, Jan 29, 2014 at 11:55:27AM -0800, Ben Widawsky wrote: > 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 <ben@xxxxxxxxxxxx> > --- > 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 8b745dc..6e8edaf 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -243,6 +243,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 b750835..3cfcc78 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, > @@ -1939,39 +1964,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 > - > - > - Maybe stick this stuff into the header to begin with to avoid churn. > int intel_init_render_ring_buffer(struct drm_device *dev) > { > drm_i915_private_t *dev_priv = dev->dev_private; > @@ -2007,7 +1999,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; > @@ -2192,7 +2184,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; > @@ -2257,7 +2249,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; > @@ -2306,7 +2298,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.3 > > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@xxxxxxxxxxxxxxxxxxxxx > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- Ville Syrjälä Intel OTC _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx