diff options
author | Rodrigo Vivi <rodrigo.vivi@intel.com> | 2014-06-30 12:53:39 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-07-07 17:16:34 -0400 |
commit | a6cdb93a7a135b853353fffecbdc2e60ba56a016 (patch) | |
tree | c523639a6041e944e3d44d95bbe7ab5cb53df3ca | |
parent | 5ee426ca135c91e071d23853e876b957526841c5 (diff) |
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>
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 42 |
1 files changed, 23 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index c50e3b41d6fe..d672053fdb10 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -2927,12 +2927,7 @@ static bool | |||
2927 | ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr) | 2927 | ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr) |
2928 | { | 2928 | { |
2929 | if (INTEL_INFO(dev)->gen >= 8) { | 2929 | if (INTEL_INFO(dev)->gen >= 8) { |
2930 | /* | 2930 | return (ipehr >> 23) == 0x1c; |
2931 | * FIXME: gen8 semaphore support - currently we don't emit | ||
2932 | * semaphores on bdw anyway, but this needs to be addressed when | ||
2933 | * we merge that code. | ||
2934 | */ | ||
2935 | return false; | ||
2936 | } else { | 2931 | } else { |
2937 | ipehr &= ~MI_SEMAPHORE_SYNC_MASK; | 2932 | ipehr &= ~MI_SEMAPHORE_SYNC_MASK; |
2938 | return ipehr == (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | | 2933 | return ipehr == (MI_SEMAPHORE_MBOX | MI_SEMAPHORE_COMPARE | |
@@ -2941,19 +2936,20 @@ ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr) | |||
2941 | } | 2936 | } |
2942 | 2937 | ||
2943 | static struct intel_engine_cs * | 2938 | static struct intel_engine_cs * |
2944 | semaphore_wait_to_signaller_ring(struct intel_engine_cs *ring, u32 ipehr) | 2939 | semaphore_wait_to_signaller_ring(struct intel_engine_cs *ring, u32 ipehr, u64 offset) |
2945 | { | 2940 | { |
2946 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | 2941 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
2947 | struct intel_engine_cs *signaller; | 2942 | struct intel_engine_cs *signaller; |
2948 | int i; | 2943 | int i; |
2949 | 2944 | ||
2950 | if (INTEL_INFO(dev_priv->dev)->gen >= 8) { | 2945 | if (INTEL_INFO(dev_priv->dev)->gen >= 8) { |
2951 | /* | 2946 | for_each_ring(signaller, dev_priv, i) { |
2952 | * FIXME: gen8 semaphore support - currently we don't emit | 2947 | if (ring == signaller) |
2953 | * semaphores on bdw anyway, but this needs to be addressed when | 2948 | continue; |
2954 | * we merge that code. | 2949 | |
2955 | */ | 2950 | if (offset == signaller->semaphore.signal_ggtt[ring->id]) |
2956 | return NULL; | 2951 | return signaller; |
2952 | } | ||
2957 | } else { | 2953 | } else { |
2958 | u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK; | 2954 | u32 sync_bits = ipehr & MI_SEMAPHORE_SYNC_MASK; |
2959 | 2955 | ||
@@ -2966,8 +2962,8 @@ semaphore_wait_to_signaller_ring(struct intel_engine_cs *ring, u32 ipehr) | |||
2966 | } | 2962 | } |
2967 | } | 2963 | } |
2968 | 2964 | ||
2969 | DRM_ERROR("No signaller ring found for ring %i, ipehr 0x%08x\n", | 2965 | DRM_ERROR("No signaller ring found for ring %i, ipehr 0x%08x, offset 0x%016llx\n", |
2970 | ring->id, ipehr); | 2966 | ring->id, ipehr, offset); |
2971 | 2967 | ||
2972 | return NULL; | 2968 | return NULL; |
2973 | } | 2969 | } |
@@ -2977,7 +2973,8 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno) | |||
2977 | { | 2973 | { |
2978 | struct drm_i915_private *dev_priv = ring->dev->dev_private; | 2974 | struct drm_i915_private *dev_priv = ring->dev->dev_private; |
2979 | u32 cmd, ipehr, head; | 2975 | u32 cmd, ipehr, head; |
2980 | int i; | 2976 | u64 offset = 0; |
2977 | int i, backwards; | ||
2981 | 2978 | ||
2982 | ipehr = I915_READ(RING_IPEHR(ring->mmio_base)); | 2979 | ipehr = I915_READ(RING_IPEHR(ring->mmio_base)); |
2983 | if (!ipehr_is_semaphore_wait(ring->dev, ipehr)) | 2980 | if (!ipehr_is_semaphore_wait(ring->dev, ipehr)) |
@@ -2986,13 +2983,15 @@ semaphore_waits_for(struct intel_engine_cs *ring, u32 *seqno) | |||
2986 | /* | 2983 | /* |
2987 | * HEAD is likely pointing to the dword after the actual command, | 2984 | * HEAD is likely pointing to the dword after the actual command, |
2988 | * so scan backwards until we find the MBOX. But limit it to just 3 | 2985 | * so scan backwards until we find the MBOX. But limit it to just 3 |
2989 | * dwords. Note that we don't care about ACTHD here since that might | 2986 | * or 4 dwords depending on the semaphore wait command size. |
2987 | * Note that we don't care about ACTHD here since that might | ||
2990 | * point at at batch, and semaphores are always emitted into the | 2988 | * point at at batch, and semaphores are always emitted into the |
2991 | * ringbuffer itself. | 2989 | * ringbuffer itself. |
2992 | */ | 2990 | */ |
2993 | head = I915_READ_HEAD(ring) & HEAD_ADDR; | 2991 | head = I915_READ_HEAD(ring) & HEAD_ADDR; |
2992 | backwards = (INTEL_INFO(ring->dev)->gen >= 8) ? 5 : 4; | ||
2994 | 2993 | ||
2995 | for (i = 4; i; --i) { | 2994 | for (i = backwards; i; --i) { |
2996 | /* | 2995 | /* |
2997 | * Be paranoid and presume the hw has gone off into the wild - | 2996 | * Be paranoid and presume the hw has gone off into the wild - |
2998 | * our ring is smaller than what the hardware (and hence | 2997 | * 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 | return NULL; | 3011 | return NULL; |
3013 | 3012 | ||
3014 | *seqno = ioread32(ring->buffer->virtual_start + head + 4) + 1; | 3013 | *seqno = ioread32(ring->buffer->virtual_start + head + 4) + 1; |
3015 | return semaphore_wait_to_signaller_ring(ring, ipehr); | 3014 | if (INTEL_INFO(ring->dev)->gen >= 8) { |
3015 | offset = ioread32(ring->buffer->virtual_start + head + 12); | ||
3016 | offset <<= 32; | ||
3017 | offset = ioread32(ring->buffer->virtual_start + head + 8); | ||
3018 | } | ||
3019 | return semaphore_wait_to_signaller_ring(ring, ipehr, offset); | ||
3016 | } | 3020 | } |
3017 | 3021 | ||
3018 | static int semaphore_passed(struct intel_engine_cs *ring) | 3022 | static int semaphore_passed(struct intel_engine_cs *ring) |