From c52ed70cfd489da18d096a8a8d42acd4fb38897f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Syrj=C3=A4l=C3=A4?= Date: Fri, 31 Jan 2014 13:44:41 +0200 Subject: [PATCH] drm/i915: Prevent MI_DISPLAY_FLIP straddling two cachelines on IVB MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit According to BSpec the entire MI_DISPLAY_FLIP packet must be contained in a single cacheline. Make sure that happens. Signed-off-by: Ville Syrjälä --- drivers/gpu/drm/i915/intel_display.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 4d4a0d9..5cf943a 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c @@ -8565,7 +8565,7 @@ static int intel_gen7_queue_flip(struct drm_device *dev, struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_ring_buffer *ring; uint32_t plane_bit = 0; - int len, ret; + int len = 0, ret; ring = obj->ring; if (IS_VALLEYVIEW(dev) || ring == NULL || ring->id != RCS) @@ -8591,10 +8591,19 @@ static int intel_gen7_queue_flip(struct drm_device *dev, goto err_unpin; } - len = 4; if (ring->id == RCS) len += 6; + /* + * BSpec MI_DISPLAY_FLIP for IVB: + * "The full packet must be contained within the same cache line." + */ + if (ring->tail + len*4 + 4*4 <= ring->effective_size && + (((ring->tail + len*4) & 63) > 64 - 4*4)) + len += (64 - ((ring->tail + len*4) & 63)) / 4; + + len += 4; + ret = intel_ring_begin(ring, len); if (ret) goto err_unpin; @@ -8618,8 +8627,12 @@ static int intel_gen7_queue_flip(struct drm_device *dev, MI_SRM_LRM_GLOBAL_GTT); intel_ring_emit(ring, DERRMR); intel_ring_emit(ring, ring->scratch.gtt_offset + 256); + len -= 6; } + while (len-- > 4) + intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit); intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); -- 1.8.3.2