<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Aug 26, 2013 at 12:58 PM, Chris Wilson <span dir="ltr"><<a href="mailto:chris@chris-wilson.co.uk" target="_blank">chris@chris-wilson.co.uk</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">RCS flips do work on Iybridge+ so long as we can unmask the messages<br>
through DERRMR. However, there are quite a few workarounds mentioned<br>
regarding unmasking more than one event or triggering more than one<br>
message through DERRMR. Those workarounds in principle prevent us from<br>
performing pipelined flips (and asynchronous flips across multiple<br>
planes) and equally apply to the "known good" BCS ring. Given that it<br>
already appears to work, and also appears to work with unmasking all 3<br>
planes at once (and queuing flips across multiple planes), be brave.<br>
<br>
Bugzlla: <a href="https://bugs.freedesktop.org/show_bug.cgi?id=67600" target="_blank">https://bugs.freedesktop.org/show_bug.cgi?id=67600</a><br>
Signed-off-by: Chris Wilson <<a href="mailto:chris@chris-wilson.co.uk">chris@chris-wilson.co.uk</a>><br>
Lightly-tested-by: Stephane Marchesin <<a href="mailto:marchesin@icps.u-strasbg.fr">marchesin@icps.u-strasbg.fr</a>><br></blockquote><div><br></div><div>You can go ahead and say Tested-by, I ran my usual tests for 3 hours and it didn't crash/show an issue. It would crash in ~10-30 minutes with the other patches.</div>
<div><br></div><div>Stéphane</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Cc: Stephane Marchesin <<a href="mailto:marchesin@icps.u-strasbg.fr">marchesin@icps.u-strasbg.fr</a>><br>
Cc: Ben Widawsky <<a href="mailto:ben@bwidawsk.net">ben@bwidawsk.net</a>><br>
---<br>
drivers/gpu/drm/i915/i915_reg.h | 18 ++++++++++++++++<br>
drivers/gpu/drm/i915/intel_display.c | 40 ++++++++++++++++++++++++++++--------<br>
2 files changed, 49 insertions(+), 9 deletions(-)<br>
<br>
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h<br>
index c6f5009..df168f4 100644<br>
--- a/drivers/gpu/drm/i915/i915_reg.h<br>
+++ b/drivers/gpu/drm/i915/i915_reg.h<br>
@@ -230,6 +230,7 @@<br>
* address/value pairs. Don't overdue it, though, x <= 2^4 must hold!<br>
*/<br>
#define MI_LOAD_REGISTER_IMM(x) MI_INSTR(0x22, 2*x-1)<br>
+#define MI_STORE_REGISTER_MEM(x) MI_INSTR(0x24, 2*x-1)<br>
#define MI_FLUSH_DW MI_INSTR(0x26, 1) /* for GEN6 */<br>
#define MI_FLUSH_DW_STORE_INDEX (1<<21)<br>
#define MI_INVALIDATE_TLB (1<<18)<br>
@@ -678,6 +679,23 @@<br>
#define FPGA_DBG_RM_NOCLAIM (1<<31)<br>
<br>
#define DERRMR 0x44050<br>
+#define DERRMR_PIPEA_SCANLINE (1<<0)<br>
+#define DERRMR_PIPEA_PRI_FLIP_DONE (1<<1)<br>
+#define DERRMR_PIPEA_SPR_FLIP_DONE (1<<2)<br>
+#define DERRMR_PIPEA_VBLANK (1<<3)<br>
+#define DERRMR_PIPEA_HBLANK (1<<5)<br>
+#define DERRMR_PIPEB_SCANLINE (1<<8)<br>
+#define DERRMR_PIPEB_PRI_FLIP_DONE (1<<9)<br>
+#define DERRMR_PIPEB_SPR_FLIP_DONE (1<<10)<br>
+#define DERRMR_PIPEB_VBLANK (1<<11)<br>
+#define DERRMR_PIPEB_HBLANK (1<<13)<br>
+/* Note that PIPEC is not a simple translation of PIPEA/PIPEB */<br>
+#define DERRMR_PIPEC_SCANLINE (1<<14)<br>
+#define DERRMR_PIPEC_PRI_FLIP_DONE (1<<15)<br>
+#define DERRMR_PIPEC_SPR_FLIP_DONE (1<<20)<br>
+#define DERRMR_PIPEC_VBLANK (1<<21)<br>
+#define DERRMR_PIPEC_HBLANK (1<<22)<br>
+<br>
<br>
/* GM45+ chicken bits -- debug workaround bits that may be required<br>
* for various sorts of correct behavior. The top 16 bits of each are<br>
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c<br>
index 9748dce..ffbcbd1 100644<br>
--- a/drivers/gpu/drm/i915/intel_display.c<br>
+++ b/drivers/gpu/drm/i915/intel_display.c<br>
@@ -7826,12 +7826,6 @@ err:<br>
return ret;<br>
}<br>
<br>
-/*<br>
- * On gen7 we currently use the blit ring because (in early silicon at least)<br>
- * the render ring doesn't give us interrpts for page flip completion, which<br>
- * means clients will hang after the first flip is queued. Fortunately the<br>
- * blit ring generates interrupts properly, so use it instead.<br>
- */<br>
static int intel_gen7_queue_flip(struct drm_device *dev,<br>
struct drm_crtc *crtc,<br>
struct drm_framebuffer *fb,<br>
@@ -7839,9 +7833,13 @@ static int intel_gen7_queue_flip(struct drm_device *dev,<br>
{<br>
struct drm_i915_private *dev_priv = dev->dev_private;<br>
struct intel_crtc *intel_crtc = to_intel_crtc(crtc);<br>
- struct intel_ring_buffer *ring = &dev_priv->ring[BCS];<br>
+ struct intel_ring_buffer *ring;<br>
uint32_t plane_bit = 0;<br>
- int ret;<br>
+ int len, ret;<br>
+<br>
+ ring = obj->ring;<br>
+ if (ring == NULL || ring->id != RCS)<br>
+ ring = &dev_priv->ring[BCS];<br>
<br>
ret = intel_pin_and_fence_fb_obj(dev, obj, ring);<br>
if (ret)<br>
@@ -7863,10 +7861,34 @@ static int intel_gen7_queue_flip(struct drm_device *dev,<br>
goto err_unpin;<br>
}<br>
<br>
- ret = intel_ring_begin(ring, 4);<br>
+ len = 4;<br>
+ if (ring->id == RCS)<br>
+ len += 6;<br>
+<br>
+ ret = intel_ring_begin(ring, len);<br>
if (ret)<br>
goto err_unpin;<br>
<br>
+ /* Unmask the flip-done completion message. Note that the bspec says that<br>
+ * we should do this for both the BCS and RCS, and that we must not unmask<br>
+ * more than one flip event at any time (or ensure that one flip message<br>
+ * can be sent by waiting for flip-done prior to queueing new flips).<br>
+ * Experimentation says that BCS works despite DERRMR masking all<br>
+ * flip-done completion events and that unmasking all planes at once<br>
+ * for the RCS also doesn't appear to drop events. Setting the DERRMR<br>
+ * to zero does lead to lockups within MI_DISPLAY_FLIP.<br>
+ */<br>
+ if (ring->id == RCS) {<br>
+ intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));<br>
+ intel_ring_emit(ring, DERRMR);<br>
+ intel_ring_emit(ring, ~(DERRMR_PIPEA_PRI_FLIP_DONE |<br>
+ DERRMR_PIPEB_PRI_FLIP_DONE |<br>
+ DERRMR_PIPEC_PRI_FLIP_DONE));<br>
+ intel_ring_emit(ring, MI_STORE_REGISTER_MEM(1));<br>
+ intel_ring_emit(ring, DERRMR);<br>
+ intel_ring_emit(ring, ring->scratch.gtt_offset + 256);<br>
+ }<br>
+<br>
intel_ring_emit(ring, MI_DISPLAY_FLIP_I915 | plane_bit);<br>
intel_ring_emit(ring, (fb->pitches[0] | obj->tiling_mode));<br>
intel_ring_emit(ring, i915_gem_obj_ggtt_offset(obj) + intel_crtc->dspaddr_offset);<br>
<span class="HOEnZb"><font color="#888888">--<br>
1.8.4.rc3<br>
</font></span></blockquote></div><br></div></div>