Sandybridge(Gen6) has new format for PIPE_CONTROL command,
the flush and post-op control are in dword 1 now. This
changes command length field for difference between Ironlake
and Sandybridge.

I tried to test this with noop request and issue PIPE_CONTROL
command for each sequence and track notify interrupts, which
seems work fine. Hopefully we don't need workaround like on
Ironlake for Sandybridge.

Signed-off-by: Zhenyu Wang <[email protected]>
---
 drivers/gpu/drm/i915/i915_gem.c |   77 +++++++++++++++++++++++----------------
 drivers/gpu/drm/i915/i915_reg.h |   11 +++++-
 2 files changed, 55 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 112699f..aad41b7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -1595,7 +1595,7 @@ i915_gem_process_flushing_list(struct drm_device *dev,
 
 #define PIPE_CONTROL_FLUSH(addr)                                       \
        OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |          \
-                PIPE_CONTROL_DEPTH_STALL);                             \
+                PIPE_CONTROL_DEPTH_STALL | 2);                         \
        OUT_RING(addr | PIPE_CONTROL_GLOBAL_GTT);                       \
        OUT_RING(0);                                                    \
        OUT_RING(0);                                                    \
@@ -1635,37 +1635,50 @@ i915_add_request(struct drm_device *dev, struct 
drm_file *file_priv,
                dev_priv->mm.next_gem_seqno++;
 
        if (HAS_PIPE_CONTROL(dev)) {
-               u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
+               if (IS_GEN6(dev)) {
+                       BEGIN_LP_RING(6);
+                       OUT_RING(GFX_OP_PIPE_CONTROL | 3);
+                       OUT_RING(PIPE_CONTROL_QW_WRITE |
+                                PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_IS_FLUSH |
+                                PIPE_CONTROL_NOTIFY);
+                       OUT_RING(dev_priv->seqno_gfx_addr | 
PIPE_CONTROL_GLOBAL_GTT);
+                       OUT_RING(seqno);
+                       OUT_RING(0);
+                       OUT_RING(0);
+                       ADVANCE_LP_RING();
+               } else {
+                       u32 scratch_addr = dev_priv->seqno_gfx_addr + 128;
 
-               /*
-                * Workaround qword write incoherence by flushing the
-                * PIPE_NOTIFY buffers out to memory before requesting
-                * an interrupt.
-                */
-               BEGIN_LP_RING(32);
-               OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
-                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH);
-               OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
-               OUT_RING(seqno);
-               OUT_RING(0);
-               PIPE_CONTROL_FLUSH(scratch_addr);
-               scratch_addr += 128; /* write to separate cachelines */
-               PIPE_CONTROL_FLUSH(scratch_addr);
-               scratch_addr += 128;
-               PIPE_CONTROL_FLUSH(scratch_addr);
-               scratch_addr += 128;
-               PIPE_CONTROL_FLUSH(scratch_addr);
-               scratch_addr += 128;
-               PIPE_CONTROL_FLUSH(scratch_addr);
-               scratch_addr += 128;
-               PIPE_CONTROL_FLUSH(scratch_addr);
-               OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
-                        PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
-                        PIPE_CONTROL_NOTIFY);
-               OUT_RING(dev_priv->seqno_gfx_addr | PIPE_CONTROL_GLOBAL_GTT);
-               OUT_RING(seqno);
-               OUT_RING(0);
-               ADVANCE_LP_RING();
+                       /*
+                        * Workaround qword write incoherence by flushing the
+                        * PIPE_NOTIFY buffers out to memory before requesting
+                        * an interrupt.
+                        */
+                       BEGIN_LP_RING(32);
+                       OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+                                PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH 
| 2);
+                       OUT_RING(dev_priv->seqno_gfx_addr | 
PIPE_CONTROL_GLOBAL_GTT);
+                       OUT_RING(seqno);
+                       OUT_RING(0);
+                       PIPE_CONTROL_FLUSH(scratch_addr);
+                       scratch_addr += 128; /* write to separate cachelines */
+                       PIPE_CONTROL_FLUSH(scratch_addr);
+                       scratch_addr += 128;
+                       PIPE_CONTROL_FLUSH(scratch_addr);
+                       scratch_addr += 128;
+                       PIPE_CONTROL_FLUSH(scratch_addr);
+                       scratch_addr += 128;
+                       PIPE_CONTROL_FLUSH(scratch_addr);
+                       scratch_addr += 128;
+                       PIPE_CONTROL_FLUSH(scratch_addr);
+                       OUT_RING(GFX_OP_PIPE_CONTROL | PIPE_CONTROL_QW_WRITE |
+                                PIPE_CONTROL_WC_FLUSH | PIPE_CONTROL_TC_FLUSH |
+                                PIPE_CONTROL_NOTIFY);
+                       OUT_RING(dev_priv->seqno_gfx_addr | 
PIPE_CONTROL_GLOBAL_GTT);
+                       OUT_RING(seqno);
+                       OUT_RING(0);
+                       ADVANCE_LP_RING();
+               }
        } else {
                BEGIN_LP_RING(4);
                OUT_RING(MI_STORE_DWORD_INDEX);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index f3e39cc..2740f09 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -230,7 +230,12 @@
 #define   ASYNC_FLIP                (1<<22)
 #define   DISPLAY_PLANE_A           (0<<20)
 #define   DISPLAY_PLANE_B           (1<<20)
-#define GFX_OP_PIPE_CONTROL    ((0x3<<29)|(0x3<<27)|(0x2<<24)|2)
+#define GFX_OP_PIPE_CONTROL    ((0x3<<29)|(0x3<<27)|(0x2<<24))
+#define   PIPE_CONTROL_CS_STALL        (1<<20)
+#define   PIPE_CONTROL_GLOBAL_SNAPSHOT_COUNT_RESET     (1<<19)
+#define   PIPE_CONTROL_TLB_INVALIDATE  (1<<18)
+#define   PIPE_CONTROL_SYNC_GFDT       (1<<17)
+#define   PIPE_CONTROL_MEDIA_STATE_CLEAR       (1<<16)
 #define   PIPE_CONTROL_QW_WRITE        (1<<14)
 #define   PIPE_CONTROL_DEPTH_STALL (1<<13)
 #define   PIPE_CONTROL_WC_FLUSH        (1<<12)
@@ -238,6 +243,10 @@
 #define   PIPE_CONTROL_TC_FLUSH (1<<10) /* GM45+ only */
 #define   PIPE_CONTROL_ISP_DIS (1<<9)
 #define   PIPE_CONTROL_NOTIFY  (1<<8)
+#define   PIPE_CONTROL_VF_CACHE_INVALIDATE     (1<<4)
+#define   PIPE_CONTROL_CONST_CACHE_INVALIDATE  (1<<3)
+#define   PIPE_CONTROL_STATE_CACHE_INVALIDATE  (1<<2)
+#define   PIPE_CONTROL_DEPTH_CACHE_FLUSH       (1<<0)
 #define   PIPE_CONTROL_GLOBAL_GTT (1<<2) /* in addr dword */
 #define   PIPE_CONTROL_STALL_EN        (1<<1) /* in addr word, Ironlake+ only 
*/
 
-- 
1.7.1

_______________________________________________
Intel-gfx mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to