From mboxrd@z Thu Jan 1 00:00:00 1970 From: Ville =?iso-8859-1?Q?Syrj=E4l=E4?= Subject: Re: [PATCH 07/13] drm/i915/bdw: implement semaphore wait Date: Thu, 30 Jan 2014 14:48:09 +0200 Message-ID: <20140130124809.GL9454@intel.com> References: <1391025333-31587-1-git-send-email-benjamin.widawsky@intel.com> <1391025333-31587-8-git-send-email-benjamin.widawsky@intel.com> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Return-path: Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by gabe.freedesktop.org (Postfix) with ESMTP id 7AECBFFA29 for ; Thu, 30 Jan 2014 04:48:13 -0800 (PST) Content-Disposition: inline In-Reply-To: <1391025333-31587-8-git-send-email-benjamin.widawsky@intel.com> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: intel-gfx-bounces@lists.freedesktop.org Errors-To: intel-gfx-bounces@lists.freedesktop.org To: Ben Widawsky Cc: Intel GFX , Ben Widawsky List-Id: intel-gfx@lists.freedesktop.org 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 > --- > 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/i9= 15/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 =3D waiter->dev->dev_private; > + int ret; > + > + ret =3D 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_buffe= r *ring, > return 0; > } > = > -/* seqno size is actually only a uint32, but since we plan to use MI_FLU= SH_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] =3D GEN8_SIGNAL_OFFSET(RCS); \ > - ring->semaphore.signal_ggtt[VCS] =3D GEN8_SIGNAL_OFFSET(VCS); \ > - ring->semaphore.signal_ggtt[BCS] =3D GEN8_SIGNAL_OFFSET(BCS); \ > - ring->semaphore.signal_ggtt[VECS] =3D GEN8_SIGNAL_OFFSET(VECS); \ > - ring->semaphore.mbox[RCS] =3D GEN8_WAIT_OFFSET(RCS); \ > - ring->semaphore.mbox[VCS] =3D GEN8_WAIT_OFFSET(VCS); \ > - ring->semaphore.mbox[BCS] =3D GEN8_WAIT_OFFSET(BCS); \ > - ring->semaphore.mbox[VECS] =3D GEN8_WAIT_OFFSET(VECS); \ > - ring->semaphore.signal_ggtt[ring->id] =3D MI_SEMAPHORE_SYNC_INVALID; \ > - ring->semaphore.mbox[ring->id] =3D 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 =3D dev->dev_private; > @@ -2007,7 +1999,7 @@ int intel_init_render_ring_buffer(struct drm_device= *dev) > ring->irq_enable_mask =3D GT_RENDER_USER_INTERRUPT; > ring->get_seqno =3D gen6_ring_get_seqno; > ring->set_seqno =3D ring_set_seqno; > - ring->semaphore.sync_to =3D gen6_ring_sync; > + ring->semaphore.sync_to =3D gen8_ring_sync; > if (i915_semaphore_is_enabled(dev)) { > BUG_ON(!dev_priv->semaphore_obj); > ring->semaphore.signal =3D gen8_rcs_signal; > @@ -2192,7 +2184,7 @@ int intel_init_bsd_ring_buffer(struct drm_device *d= ev) > ring->irq_put =3D gen8_ring_put_irq; > ring->dispatch_execbuffer =3D > gen8_ring_dispatch_execbuffer; > - ring->semaphore.sync_to =3D gen6_ring_sync; > + ring->semaphore.sync_to =3D gen8_ring_sync; > if (i915_semaphore_is_enabled(dev)) { > ring->semaphore.signal =3D gen8_xcs_signal; > GEN8_RING_SEMAPHORE_INIT; > @@ -2257,7 +2249,7 @@ int intel_init_blt_ring_buffer(struct drm_device *d= ev) > ring->irq_get =3D gen8_ring_get_irq; > ring->irq_put =3D gen8_ring_put_irq; > ring->dispatch_execbuffer =3D gen8_ring_dispatch_execbuffer; > - ring->semaphore.sync_to =3D gen6_ring_sync; > + ring->semaphore.sync_to =3D gen8_ring_sync; > if (i915_semaphore_is_enabled(dev)) { > ring->semaphore.signal =3D gen8_xcs_signal; > GEN8_RING_SEMAPHORE_INIT; > @@ -2306,7 +2298,7 @@ int intel_init_vebox_ring_buffer(struct drm_device = *dev) > ring->irq_get =3D gen8_ring_get_irq; > ring->irq_put =3D gen8_ring_put_irq; > ring->dispatch_execbuffer =3D gen8_ring_dispatch_execbuffer; > - ring->semaphore.sync_to =3D gen6_ring_sync; > + ring->semaphore.sync_to =3D gen8_ring_sync; > if (i915_semaphore_is_enabled(dev)) { > ring->semaphore.signal =3D gen8_xcs_signal; > GEN8_RING_SEMAPHORE_INIT; > diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i9= 15/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_FLU= SH_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] =3D GEN8_SIGNAL_OFFSET(RCS); \ > + ring->semaphore.signal_ggtt[VCS] =3D GEN8_SIGNAL_OFFSET(VCS); \ > + ring->semaphore.signal_ggtt[BCS] =3D GEN8_SIGNAL_OFFSET(BCS); \ > + ring->semaphore.signal_ggtt[VECS] =3D GEN8_SIGNAL_OFFSET(VECS); \ > + ring->semaphore.mbox[RCS] =3D GEN8_WAIT_OFFSET(ring, RCS); \ > + ring->semaphore.mbox[VCS] =3D GEN8_WAIT_OFFSET(ring, VCS); \ > + ring->semaphore.mbox[BCS] =3D GEN8_WAIT_OFFSET(ring, BCS); \ > + ring->semaphore.mbox[VECS] =3D GEN8_WAIT_OFFSET(ring, VECS); \ > + ring->semaphore.signal_ggtt[ring->id] =3D MI_SEMAPHORE_SYNC_INVALID; \ > + ring->semaphore.mbox[ring->id] =3D GEN6_NOSYNC; \ > + } while(0) > + > enum intel_ring_hangcheck_action { > HANGCHECK_IDLE =3D 0, > HANGCHECK_WAIT, > -- = > 1.8.5.3 > = > _______________________________________________ > Intel-gfx mailing list > Intel-gfx@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/intel-gfx -- = Ville Syrj=E4l=E4 Intel OTC