aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h18
-rw-r--r--drivers/gpu/drm/i915/intel_display.c40
2 files changed, 49 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index b6a58f720f9a..b2fa2a4c4454 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -245,6 +245,7 @@
245 * address/value pairs. Don't overdue it, though, x <= 2^4 must hold! 245 * address/value pairs. Don't overdue it, though, x <= 2^4 must hold!
246 */ 246 */
247#define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1) 247#define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1)
248#define MI_STORE_REGISTER_MEM(x) MI_INSTR(0x24, 2*x-1)
248#define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */ 249#define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */
249#define MI_FLUSH_DW_STORE_INDEX (1<<21) 250#define MI_FLUSH_DW_STORE_INDEX (1<<21)
250#define MI_INVALIDATE_TLB (1<<18) 251#define MI_INVALIDATE_TLB (1<<18)
@@ -693,6 +694,23 @@
693#define FPGA_DBG_RM_NOCLAIM (1<<31) 694#define FPGA_DBG_RM_NOCLAIM (1<<31)
694 695
695#define DERRMR 0x44050 696#define DERRMR 0x44050
697#define DERRMR_PIPEA_SCANLINE (1<<0)
698#define DERRMR_PIPEA_PRI_FLIP_DONE (1<<1)
699#define DERRMR_PIPEA_SPR_FLIP_DONE (1<<2)
700#define DERRMR_PIPEA_VBLANK (1<<3)
701#define DERRMR_PIPEA_HBLANK (1<<5)
702#define DERRMR_PIPEB_SCANLINE (1<<8)
703#define DERRMR_PIPEB_PRI_FLIP_DONE (1<<9)
704#define DERRMR_PIPEB_SPR_FLIP_DONE (1<<10)
705#define DERRMR_PIPEB_VBLANK (1<<11)
706#define DERRMR_PIPEB_HBLANK (1<<13)
707/* Note that PIPEC is not a simple translation of PIPEA/PIPEB */
708#define DERRMR_PIPEC_SCANLINE (1<<14)
709#define DERRMR_PIPEC_PRI_FLIP_DONE (1<<15)
710#define DERRMR_PIPEC_SPR_FLIP_DONE (1<<20)
711#define DERRMR_PIPEC_VBLANK (1<<21)
712#define DERRMR_PIPEC_HBLANK (1<<22)
713
696 714
697/* GM45+ chicken bits -- debug workaround bits that may be required 715/* GM45+ chicken bits -- debug workaround bits that may be required
698 * for various sorts of correct behavior. The top 16 bits of each are 716 * for various sorts of correct behavior. The top 16 bits of each are
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);