mirror of https://gitee.com/openkylin/linux.git
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: Rodrigo Vivi <rodrigo.vivi@intel.com> Reviewed-by: Ben Widawsky <ben@bwidawsk.net> [danvet: Fixup format string.] Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
5ee426ca13
commit
a6cdb93a7a
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
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)
|
||||||
/*
|
/*
|
||||||
* 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)
|
||||||
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)
|
||||||
|
|
Loading…
Reference in New Issue