Ipehr just carries Dword 0 and on Gen 8, offsets are located
on Dword 2 and 3 of MI_SEMAPHORE_WAIT.

This implementation was based on Ben's work and on Ville's suggestion for Ben

v2: fix typo. Removing spurious 0% from debug msg "0x%0%0". (Daniel)

Cc: Daniel Vetter <daniel.vet...@ffwll.ch>
Cc: Ville Syrjälä <ville.syrj...@linux.intel.com>
Cc: Ben Widawsky <b...@bwidawsk.net>
Signed-off-by: Rodrigo Vivi <rodrigo.v...@intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 42 ++++++++++++++++++++++-------------------
 1 file changed, 23 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index 0217a41..05264ad 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2784,12 +2784,7 @@ static bool
 ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr)
 {
        if (INTEL_INFO(dev)->gen >= 8) {
-               /*
-                * FIXME: gen8 semaphore support - currently we don't emit
-                * semaphores on bdw anyway, but this needs to be addressed when
-                * we merge that code.
-                */
-               return false;
+               return (ipehr >> 23) == 0x1c;
        } else {
                ipehr &= ~MI_SEMAPHORE_SYNC_MASK;
                return ipehr == (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE |
@@ -2798,19 +2793,20 @@ ipehr_is_semaphore_wait(struct drm_device *dev, u32 
ipehr)
 }
 
 static struct intel_engine_cs *
-semaphore_wait_to_signaller_ring(struct intel_engine_cs *ring, u32 ipehr)
+semaphore_wait_to_signaller_ring(struct intel_engine_cs *ring, u32 ipehr, u64 
offset)
 {
        struct drm_i915_private *dev_priv = ring->dev->dev_private;
        struct intel_engine_cs *signaller;
        int i;
 
        if (INTEL_INFO(dev_priv->dev)->gen >= 8) {
-               /*
-                * FIXME: gen8 semaphore support - currently we don't emit
-                * semaphores on bdw anyway, but this needs to be addressed when
-                * we merge that code.
-                */
-               return NULL;
+               for_each_ring(signaller, dev_priv, i) {
+                       if (ring == signaller)
+                               continue;
+
+                       if (offset == 
signaller->semaphore.signal_ggtt[ring->id])
+                               return signaller;
+               }
        } else {
                u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK;
 
@@ -2823,8 +2819,8 @@ semaphore_wait_to_signaller_ring(struct intel_engine_cs 
*ring, u32 ipehr)
                }
        }
 
-       DRM_ERROR("No signaller ring found for ring %i, ipehr 0x%08x\n",
-                 ring->id, ipehr);
+       DRM_ERROR("No signaller ring found for ring %i, ipehr 0x%08x, offset 
0x%016llx\n",
+                 ring->id, ipehr, offset);
 
        return NULL;
 }
@@ -2834,7 +2830,8 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 
*seqno)
 {
        struct drm_i915_private *dev_priv = ring->dev->dev_private;
        u32 cmd, ipehr, head;
-       int i;
+       u64 offset = 0;
+       int i, backwards;
 
        ipehr = I915_READ(RING_IPEHR(ring->mmio_base));
        if (!ipehr_is_semaphore_wait(ring->dev, ipehr))
@@ -2843,13 +2840,15 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 
*seqno)
        /*
         * HEAD is likely pointing to the dword after the actual command,
         * so scan backwards until we find the MBOX. But limit it to just 3
-        * dwords. Note that we don't care about ACTHD here since that might
+        * or 4 dwords depending on the semaphore wait command size.
+        * Note that we don't care about ACTHD here since that might
         * point at at batch, and semaphores are always emitted into the
         * ringbuffer itself.
         */
        head = I915_READ_HEAD(ring) & HEAD_ADDR;
+       backwards = (INTEL_INFO(ring->dev)->gen >= 8) ? 5 : 4;
 
-       for (i = 4; i; --i) {
+       for (i = backwards; i; --i) {
                /*
                 * Be paranoid and presume the hw has gone off into the wild -
                 * our ring is smaller than what the hardware (and hence
@@ -2869,7 +2868,12 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 
*seqno)
                return NULL;
 
        *seqno = ioread32(ring->buffer->virtual_start + head + 4) + 1;
-       return semaphore_wait_to_signaller_ring(ring, ipehr);
+       if (INTEL_INFO(ring->dev)->gen >= 8) {
+               offset = ioread32(ring->buffer->virtual_start + head + 12);
+               offset <<= 32;
+               offset = ioread32(ring->buffer->virtual_start + head + 8);
+       }
+       return semaphore_wait_to_signaller_ring(ring, ipehr, offset);
 }
 
 static int semaphore_passed(struct intel_engine_cs *ring)
-- 
1.9.3

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to