drm/i915: Force sync command ordering (Gen6+)
authorBen Widawsky <ben@bwidawsk.net>
Tue, 13 Dec 2011 03:21:58 +0000 (19:21 -0800)
committerKeith Packard <keithp@keithp.com>
Tue, 3 Jan 2012 17:09:44 +0000 (09:09 -0800)
The docs say this is required for Gen7, and since the bit was added for
Gen6, we are also setting it there pit pf paranoia. Particularly as
Chris points out, if PIPE_CONTROL counts as a 3d state packet.

This was found through doc inspection by Ken and applies to Gen6+;

Reported-by: Kenneth Graunke <kenneth@whitecape.org>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Reviewed-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Keith Packard <keithp@keithp.com>
drivers/gpu/drm/i915/i915_gem_execbuffer.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_ringbuffer.c

index 68e5b41dc7f214cabc91382e7ff4b3c037268c4d..11545ff90db646b16a42f6cdc382733229f5d2e2 100644 (file)
@@ -984,6 +984,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
        struct intel_ring_buffer *ring;
        u32 exec_start, exec_len;
        u32 seqno;
+       u32 mask;
        int ret, mode, i;
 
        if (!i915_gem_check_execbuffer(args)) {
@@ -1021,6 +1022,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
        }
 
        mode = args->flags & I915_EXEC_CONSTANTS_MASK;
+       mask = I915_EXEC_CONSTANTS_MASK;
        switch (mode) {
        case I915_EXEC_CONSTANTS_REL_GENERAL:
        case I915_EXEC_CONSTANTS_ABSOLUTE:
@@ -1033,6 +1035,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                        if (INTEL_INFO(dev)->gen > 5 &&
                            mode == I915_EXEC_CONSTANTS_REL_SURFACE)
                                return -EINVAL;
+
+                       /* The HW changed the meaning on this bit on gen6 */
+                       if (INTEL_INFO(dev)->gen >= 6)
+                               mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE;
                }
                break;
        default:
@@ -1172,8 +1178,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
                intel_ring_emit(ring, MI_NOOP);
                intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
                intel_ring_emit(ring, INSTPM);
-               intel_ring_emit(ring,
-                               I915_EXEC_CONSTANTS_MASK << 16 | mode);
+               intel_ring_emit(ring, mask << 16 | mode);
                intel_ring_advance(ring);
 
                dev_priv->relative_constants_mode = mode;
index 194d9874002b305e31ae63e06d74275af053fd32..3ae2c7c00ef28767d6267f5c548498dd2623a021 100644 (file)
 #define   INSTPM_AGPBUSY_DIS (1<<11) /* gen3: when disabled, pending interrupts
                                        will not assert AGPBUSY# and will only
                                        be delivered when out of C3. */
+#define   INSTPM_FORCE_ORDERING                                (1<<7) /* GEN6+ */
 #define ACTHD          0x020c8
 #define FW_BLC         0x020d8
 #define FW_BLC2                0x020dc
index ca70e2f1044517425ce3ad0ea3ab85db7c0df5ee..f5dae5deca71ac4ba6e1b1191fbdad3ea5b92dc4 100644 (file)
@@ -414,6 +414,11 @@ static int init_render_ring(struct intel_ring_buffer *ring)
                        return ret;
        }
 
+       if (INTEL_INFO(dev)->gen >= 6) {
+               I915_WRITE(INSTPM,
+                          INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING);
+       }
+
        return ret;
 }