diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-03-18 05:26:04 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-04-01 16:58:06 -0400 |
commit | 921d42ead788c1dab520634c693ff8887765182c (patch) | |
tree | bac9151894e844b45432b0da65b1ada334997792 /drivers/gpu/drm/i915/i915_irq.c | |
parent | a028c4b02a77f6ed63a0b0c4d4340f4a9074df85 (diff) |
drm/i915: make semaphore signaller detection more robust
Extract all this logic into a new helper function
semaphore_wait_to_signaller_ring because:
- The current code has way too much magic.
- The current code doesn't look at bi16, which encodes VECS signallers
on HSW. Those are just added after the fact, so can't be encoded in
a neat formula.
- The current logic can't blow up since it limits its value range
sufficiently, but that's a bit too tricky to rely on in my opinion.
Especially when we start to add bdw support.
- I'm not a big fan of the explicit ring->semaphore_register list, but
I think it's more robust to use the same mapping both when
constructing the semaphore commands and when decoding them.
- Finally add a FIXME comment about lack of broadwell support here,
like in the earlier ipehr semaphore cmd detection function.
Cc: Mika Kuoppala <mika.kuoppala@intel.com>
Cc: Ben Widawsky <ben@bwidawsk.net>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Mika Kuoppala <mika.kuoppala@intel.com>
[danvet: Actually drop the untrue claim in the commit message Chris
pointed out.]
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 4be756f422ec..c8d2445b259c 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -2519,6 +2519,39 @@ ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr) | |||
2519 | } | 2519 | } |
2520 | 2520 | ||
2521 | static struct intel_ring_buffer * | 2521 | static struct intel_ring_buffer * |
2522 | semaphore_wait_to_signaller_ring(struct intel_ring_buffer *ring, u32 ipehr) | ||
2523 | { | ||
2524 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | ||
2525 | struct intel_ring_buffer *signaller; | ||
2526 | int i; | ||
2527 | |||
2528 | if (INTEL_INFO(dev_priv->dev)->gen >= 8) { | ||
2529 | /* | ||
2530 | * FIXME: gen8 semaphore support - currently we don't emit | ||
2531 | * semaphores on bdw anyway, but this needs to be addressed when | ||
2532 | * we merge that code. | ||
2533 | */ | ||
2534 | return NULL; | ||
2535 | } else { | ||
2536 | u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK; | ||
2537 | |||
2538 | for_each_ring(signaller, dev_priv, i) { | ||
2539 | if(ring == signaller) | ||
2540 | continue; | ||
2541 | |||
2542 | if (sync_bits == | ||
2543 | signaller->semaphore_register[ring->id]) | ||
2544 | return signaller; | ||
2545 | } | ||
2546 | } | ||
2547 | |||
2548 | DRM_ERROR("No signaller ring found for ring %i, ipehr 0x%08x\n", | ||
2549 | ring->id, ipehr); | ||
2550 | |||
2551 | return NULL; | ||
2552 | } | ||
2553 | |||
2554 | static struct intel_ring_buffer * | ||
2522 | semaphore_waits_for(struct intel_ring_buffer *ring, u32 *seqno) | 2555 | semaphore_waits_for(struct intel_ring_buffer *ring, u32 *seqno) |
2523 | { | 2556 | { |
2524 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | 2557 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
@@ -2558,7 +2591,7 @@ semaphore_waits_for(struct intel_ring_buffer *ring, u32 *seqno) | |||
2558 | return NULL; | 2591 | return NULL; |
2559 | 2592 | ||
2560 | *seqno = ioread32(ring->virtual_start + head + 4) + 1; | 2593 | *seqno = ioread32(ring->virtual_start + head + 4) + 1; |
2561 | return &dev_priv->ring[(ring->id + (((ipehr >> 17) & 1) + 1)) % 3]; | 2594 | return semaphore_wait_to_signaller_ring(ring, ipehr); |
2562 | } | 2595 | } |
2563 | 2596 | ||
2564 | static int semaphore_passed(struct intel_ring_buffer *ring) | 2597 | static int semaphore_passed(struct intel_ring_buffer *ring) |