Commit a6cdb93a authored by Rodrigo Vivi's avatar Rodrigo Vivi Committed by Daniel Vetter

drm/i915: Implement MI decode for gen8

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

Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Ben Widawsky <ben@bwidawsk.net>
Signed-off-by: default avatarRodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: default avatarBen Widawsky <ben@bwidawsk.net>
[danvet: Fixup format string.]
Signed-off-by: default avatarDaniel Vetter <daniel.vetter@ffwll.ch>
parent 5ee426ca
...@@ -2927,12 +2927,7 @@ static bool ...@@ -2927,12 +2927,7 @@ static bool
ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr) ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr)
{ {
if (INTEL_INFO(dev)->gen >= 8) { if (INTEL_INFO(dev)->gen >= 8) {
/* return (ipehr >> 23) == 0x1c;
* 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;
} else { } else {
ipehr &= ~MI_SEMAPHORE_SYNC_MASK; ipehr &= ~MI_SEMAPHORE_SYNC_MASK;
return ipehr == (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | return ipehr == (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE |
...@@ -2941,19 +2936,20 @@ ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr) ...@@ -2941,19 +2936,20 @@ ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr)
} }
static struct intel_engine_cs * 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 drm_i915_private *dev_priv = ring->dev->dev_private;
struct intel_engine_cs *signaller; struct intel_engine_cs *signaller;
int i; int i;
if (INTEL_INFO(dev_priv->dev)->gen >= 8) { if (INTEL_INFO(dev_priv->dev)->gen >= 8) {
/* for_each_ring(signaller, dev_priv, i) {
* FIXME: gen8 semaphore support - currently we don't emit if (ring == signaller)
* semaphores on bdw anyway, but this needs to be addressed when continue;
* we merge that code.
*/ if (offset == signaller->semaphore.signal_ggtt[ring->id])
return NULL; return signaller;
}
} else { } else {
u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK; u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK;
...@@ -2966,8 +2962,8 @@ semaphore_wait_to_signaller_ring(struct intel_engine_cs *ring, u32 ipehr) ...@@ -2966,8 +2962,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", DRM_ERROR("No signaller ring found for ring %i, ipehr 0x%08x, offset 0x%016llx\n",
ring->id, ipehr); ring->id, ipehr, offset);
return NULL; return NULL;
} }
...@@ -2977,7 +2973,8 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno) ...@@ -2977,7 +2973,8 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno)
{ {
struct drm_i915_private *dev_priv = ring->dev->dev_private; struct drm_i915_private *dev_priv = ring->dev->dev_private;
u32 cmd, ipehr, head; u32 cmd, ipehr, head;
int i; u64 offset = 0;
int i, backwards;
ipehr = I915_READ(RING_IPEHR(ring->mmio_base)); ipehr = I915_READ(RING_IPEHR(ring->mmio_base));
if (!ipehr_is_semaphore_wait(ring->dev, ipehr)) if (!ipehr_is_semaphore_wait(ring->dev, ipehr))
...@@ -2986,13 +2983,15 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno) ...@@ -2986,13 +2983,15 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno)
/* /*
* HEAD is likely pointing to the dword after the actual command, * 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 * 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 * point at at batch, and semaphores are always emitted into the
* ringbuffer itself. * ringbuffer itself.
*/ */
head = I915_READ_HEAD(ring) & HEAD_ADDR; 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 - * Be paranoid and presume the hw has gone off into the wild -
* our ring is smaller than what the hardware (and hence * our ring is smaller than what the hardware (and hence
...@@ -3012,7 +3011,12 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno) ...@@ -3012,7 +3011,12 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno)
return NULL; return NULL;
*seqno = ioread32(ring->buffer->virtual_start + head + 4) + 1; *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) static int semaphore_passed(struct intel_engine_cs *ring)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment