diff options
author | Ben Widawsky <ben@bwidawsk.net> | 2011-12-12 22:21:58 -0500 |
---|---|---|
committer | Keith Packard <keithp@keithp.com> | 2012-01-03 12:09:44 -0500 |
commit | 84f9f938be4156e4baea466688bd6abae1c9e6ba (patch) | |
tree | 7d722807e6f9c86db1eb74ae6b2931a3e54140e0 /drivers/gpu | |
parent | e2971bdab2b761683353da383c0fd5ac704d1cca (diff) |
drm/i915: Force sync command ordering (Gen6+)
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>
Diffstat (limited to 'drivers/gpu')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 9 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.c | 5 |
3 files changed, 13 insertions, 2 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 68e5b41dc7f2..11545ff90db6 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -984,6 +984,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
984 | struct intel_ring_buffer *ring; | 984 | struct intel_ring_buffer *ring; |
985 | u32 exec_start, exec_len; | 985 | u32 exec_start, exec_len; |
986 | u32 seqno; | 986 | u32 seqno; |
987 | u32 mask; | ||
987 | int ret, mode, i; | 988 | int ret, mode, i; |
988 | 989 | ||
989 | if (!i915_gem_check_execbuffer(args)) { | 990 | if (!i915_gem_check_execbuffer(args)) { |
@@ -1021,6 +1022,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1021 | } | 1022 | } |
1022 | 1023 | ||
1023 | mode = args->flags & I915_EXEC_CONSTANTS_MASK; | 1024 | mode = args->flags & I915_EXEC_CONSTANTS_MASK; |
1025 | mask = I915_EXEC_CONSTANTS_MASK; | ||
1024 | switch (mode) { | 1026 | switch (mode) { |
1025 | case I915_EXEC_CONSTANTS_REL_GENERAL: | 1027 | case I915_EXEC_CONSTANTS_REL_GENERAL: |
1026 | case I915_EXEC_CONSTANTS_ABSOLUTE: | 1028 | case I915_EXEC_CONSTANTS_ABSOLUTE: |
@@ -1033,6 +1035,10 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1033 | if (INTEL_INFO(dev)->gen > 5 && | 1035 | if (INTEL_INFO(dev)->gen > 5 && |
1034 | mode == I915_EXEC_CONSTANTS_REL_SURFACE) | 1036 | mode == I915_EXEC_CONSTANTS_REL_SURFACE) |
1035 | return -EINVAL; | 1037 | return -EINVAL; |
1038 | |||
1039 | /* The HW changed the meaning on this bit on gen6 */ | ||
1040 | if (INTEL_INFO(dev)->gen >= 6) | ||
1041 | mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE; | ||
1036 | } | 1042 | } |
1037 | break; | 1043 | break; |
1038 | default: | 1044 | default: |
@@ -1172,8 +1178,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, | |||
1172 | intel_ring_emit(ring, MI_NOOP); | 1178 | intel_ring_emit(ring, MI_NOOP); |
1173 | intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); | 1179 | intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); |
1174 | intel_ring_emit(ring, INSTPM); | 1180 | intel_ring_emit(ring, INSTPM); |
1175 | intel_ring_emit(ring, | 1181 | intel_ring_emit(ring, mask << 16 | mode); |
1176 | I915_EXEC_CONSTANTS_MASK << 16 | mode); | ||
1177 | intel_ring_advance(ring); | 1182 | intel_ring_advance(ring); |
1178 | 1183 | ||
1179 | dev_priv->relative_constants_mode = mode; | 1184 | dev_priv->relative_constants_mode = mode; |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index 194d9874002b..3ae2c7c00ef2 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -442,6 +442,7 @@ | |||
442 | #define INSTPM_AGPBUSY_DIS (1<<11) /* gen3: when disabled, pending interrupts | 442 | #define INSTPM_AGPBUSY_DIS (1<<11) /* gen3: when disabled, pending interrupts |
443 | will not assert AGPBUSY# and will only | 443 | will not assert AGPBUSY# and will only |
444 | be delivered when out of C3. */ | 444 | be delivered when out of C3. */ |
445 | #define INSTPM_FORCE_ORDERING (1<<7) /* GEN6+ */ | ||
445 | #define ACTHD 0x020c8 | 446 | #define ACTHD 0x020c8 |
446 | #define FW_BLC 0x020d8 | 447 | #define FW_BLC 0x020d8 |
447 | #define FW_BLC2 0x020dc | 448 | #define FW_BLC2 0x020dc |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index ca70e2f10445..f5dae5deca71 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -414,6 +414,11 @@ static int init_render_ring(struct intel_ring_buffer *ring) | |||
414 | return ret; | 414 | return ret; |
415 | } | 415 | } |
416 | 416 | ||
417 | if (INTEL_INFO(dev)->gen >= 6) { | ||
418 | I915_WRITE(INSTPM, | ||
419 | INSTPM_FORCE_ORDERING << 16 | INSTPM_FORCE_ORDERING); | ||
420 | } | ||
421 | |||
417 | return ret; | 422 | return ret; |
418 | } | 423 | } |
419 | 424 | ||