aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorChris Wilson <chris@chris-wilson.co.uk>2013-08-26 15:58:12 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2013-09-03 13:17:55 -0400
commitffe74d75502e3a9b0791240b5562bcbecc6ab8dc (patch)
treece91b82d07449c92532c1077775dcd7dcaf51808 /drivers/gpu/drm/i915/intel_display.c
parent0d1aacac36530fce058d7a0db3da7befd5765417 (diff)
drm/i915: Use RCS flips on Ivybridge+
RCS flips do work on Iybridge+ so long as we can unmask the messages through DERRMR. However, there are quite a few workarounds mentioned regarding unmasking more than one event or triggering more than one message through DERRMR. Those workarounds in principle prevent us from performing pipelined flips (and asynchronous flips across multiple planes) and equally apply to the "known good" BCS ring. Given that it already appears to work, and also appears to work with unmasking all 3 planes at once (and queuing flips across multiple planes), be brave. Bugzlla: https://bugs.freedesktop.org/show_bug.cgi?id=67600 Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk> Lightly-tested-by: Stephane Marchesin <marchesin@icps.u-strasbg.fr> Cc: Stephane Marchesin <marchesin@icps.u-strasbg.fr> Cc: Ben Widawsky <ben@bwidawsk.net> Tested-by: Stéphane Marchesin <marcheu@chromium.org> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 38452d82ac7d..a98392f9894e 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -7828,12 +7828,6 @@ err:
7828 return ret; 7828 return ret;
7829} 7829}
7830 7830
7831/*
7832 * On gen7 we currently use the blit ring because (in early silicon at least)
7833 * the render ring doesn't give us interrpts for page flip completion, which
7834 * means clients will hang after the first flip is queued. Fortunately the
7835 * blit ring generates interrupts properly, so use it instead.
7836 */
7837static int intel_gen7_queue_flip(struct drm_device *dev, 7831static int intel_gen7_queue_flip(struct drm_device *dev,
7838 struct drm_crtc *crtc, 7832 struct drm_crtc *crtc,
7839 struct drm_framebuffer *fb, 7833 struct drm_framebuffer *fb,
@@ -7842,9 +7836,13 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
7842{ 7836{
7843 struct drm_i915_private *dev_priv = dev->dev_private; 7837 struct drm_i915_private *dev_priv = dev->dev_private;
7844 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 7838 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
7845 struct intel_ring_buffer *ring = &dev_priv->ring[BCS]; 7839 struct intel_ring_buffer *ring;
7846 uint32_t plane_bit = 0; 7840 uint32_t plane_bit = 0;
7847 int ret; 7841 int len, ret;
7842
7843 ring = obj->ring;
7844 if (ring == NULL || ring->id != RCS)
7845 ring = &dev_priv->ring[BCS];
7848 7846
7849 ret = intel_pin_and_fence_fb_obj(dev, obj, ring); 7847 ret = intel_pin_and_fence_fb_obj(dev, obj, ring);
7850 if (ret) 7848 if (ret)
@@ -7866,10 +7864,34 @@ static int intel_gen7_queue_flip(struct drm_device *dev,
7866 goto err_unpin; 7864 goto err_unpin;
7867 } 7865 }
7868 7866
7869 ret = intel_ring_begin(ring, 4); 7867 len = 4;
7868 if (ring->id == RCS)
7869 len += 6;
7870
7871 ret = intel_ring_begin(ring, len);
7870 if (ret) 7872 if (ret)
7871 goto err_unpin; 7873 goto err_unpin;
7872 7874
7875 /* Unmask the flip-done completion message. Note that the bspec says that
7876 * we should do this for both the BCS and RCS, and that we must not unmask
7877 * more than one flip event at any time (or ensure that one flip message
7878 * can be sent by waiting for flip-done prior to queueing new flips).
7879 * Experimentation says that BCS works despite DERRMR masking all
7880 * flip-done completion events and that unmasking all planes at once
7881 * for the RCS also doesn't appear to drop events. Setting the DERRMR
7882 * to zero does lead to lockups within MI_DISPLAY_FLIP.
7883 */
7884 if (ring->id == RCS) {
7885 intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
7886 intel_ring_emit(ring, DERRMR);
7887 intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE |
7888 DERRMR_PIPEB_PRI_FLIP_DONE |
7889 DERRMR_PIPEC_PRI_FLIP_DONE));
7890 intel_ring_emit(ring, MI_STORE_REGISTER_MEM(1));
7891 intel_ring_emit(ring, DERRMR);
7892 intel_ring_emit(ring, ring->scratch.gtt_offset + 256);
7893 }
7894
7873 intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit); 7895 intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);
7874 intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode)); 7896 intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode));
7875 intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset); 7897 intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);