aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRodrigo Vivi <rodrigo.vivi@intel.com>2014-06-30 12:53:39 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-07-07 17:16:34 -0400
commita6cdb93a7a135b853353fffecbdc2e60ba56a016 (patch)
treec523639a6041e944e3d44d95bbe7ab5cb53df3ca
parent5ee426ca135c91e071d23853e876b957526841c5 (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.c42
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
2927ipehr_is_semaphore_wait(struct drm_device *dev, u32 ipehr) 2927ipehr_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
2943static struct intel_engine_cs * 2938static struct intel_engine_cs *
2944semaphore_wait_to_signaller_ring(struct intel_engine_cs *ring, u32 ipehr) 2939semaphore_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
3018static int semaphore_passed(struct intel_engine_cs *ring) 3022static int semaphore_passed(struct intel_engine_cs *ring)