<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Mon, Aug 26, 2013 at 1:42 PM, Stéphane Marchesin <span dir="ltr"><<a href="mailto:stephane.marchesin@gmail.com" target="_blank">stephane.marchesin@gmail.com</a>></span> wrote:<br>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote"><div class="im">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" target="_blank">chris@chris-wilson.co.uk</a>><br>
Lightly-tested-by: Stephane Marchesin <<a href="mailto:marchesin@icps.u-strasbg.fr" target="_blank">marchesin@icps.u-strasbg.fr</a>><br></blockquote><div><br></div></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></div></div></blockquote><div><br></div><div>Oh actually this one is a bit different... Give me 3 hours :)</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">

<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="HOEnZb"><font color="#888888">
<div><br></div><div>Stéphane</div></font></span><div><div class="h5"><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" target="_blank">marchesin@icps.u-strasbg.fr</a>><br>
Cc: Ben Widawsky <<a href="mailto:ben@bwidawsk.net" target="_blank">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><font color="#888888">--<br>
1.8.4.rc3<br>
</font></span></blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div>