summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugeni Dodonov <eugeni.dodonov@intel.com>2012-02-06 16:50:23 -0200
committerEugeni Dodonov <eugeni.dodonov@intel.com>2012-02-06 18:35:20 -0200
commit0d2c3789f2917d84ac9e4a5de37630786a1c7857 (patch)
tree99d9d92869f08c953d8afce4a5c07e53929753aa
parentfe409d77ae8a709f16774e51b35a80627588643d (diff)
drm/i915: add DERRMR mask and eventsderrmr
Those are to be used with execbuffer2 ioctl to identify which events need to be masked/unmasked with that batchbuffer. Each pipe has its own set of bits, hence the monstrous switch. It could be replaced by a macro or a hash at some point. Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c96
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h20
-rw-r--r--include/drm/i915_drm.h16
3 files changed, 132 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index c01cb201849..4b1e528271e 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1011,6 +1011,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
u32 seqno;
u32 mask;
int ret, mode, i;
+ int use_derrmr, derrmr_pipe, derrmr_bits = 0;
if (!i915_gem_check_execbuffer(args)) {
DRM_ERROR("execbuf with invalid offset/length\n");
@@ -1071,6 +1072,92 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
return -EINVAL;
}
+ /* Verify if using DERRMR and prepare the unmasking bits accordingly */
+ use_derrmr = args->flags & I915_EXEC_USE_DERRMR;
+ if (use_derrmr) {
+ if (INTEL_INFO(dev)->gen < 6) {
+ DRM_ERROR("using derrmr on a pre-SNB arch\n");
+ return -EINVAL;
+ }
+ derrmr_pipe = args->flags & I915_EXEC_DERRMR_PIPE_MASK;
+ if (derrmr_pipe & I915_EXEC_DERRMR_PIPE_A) {
+ switch (args->flags & I915_EXEC_DERRMR_MASK) {
+ case I915_EXEC_DERRMR_SCANLINE:
+ derrmr_bits |= GEN6_DERRMR_PIPE_A_SCANLINE;
+ break;
+ case I915_EXEC_DERRMR_PRIMARY_FLIP:
+ derrmr_bits |= GEN6_DERRMR_PIPE_A_PRIMARY_FLIP;
+ break;
+ case I915_EXEC_DERRMR_SPRITE_FLIP:
+ derrmr_bits |= GEN6_DERRMR_PIPE_A_SPRITE_FLIP;
+ break;
+ case I915_EXEC_DERRMR_VBLANK:
+ derrmr_bits |= GEN6_DERRMR_PIPE_A_VBLANK;
+ break;
+ case I915_EXEC_DERRMR_HBLANK:
+ derrmr_bits |= GEN6_DERRMR_PIPE_A_HBLANK;
+ break;
+ default:
+ DRM_ERROR("attempting to set invalid bits in DERRMR: %llu (pipe %d)\n",
+ (args->flags & I915_EXEC_DERRMR_MASK),
+ derrmr_pipe);
+ return -EINVAL;
+ }
+ } else if (derrmr_pipe & I915_EXEC_DERRMR_PIPE_B) {
+ switch (args->flags & I915_EXEC_DERRMR_MASK) {
+ case I915_EXEC_DERRMR_SCANLINE:
+ derrmr_bits |= GEN6_DERRMR_PIPE_B_SCANLINE;
+ break;
+ case I915_EXEC_DERRMR_PRIMARY_FLIP:
+ derrmr_bits |= GEN6_DERRMR_PIPE_B_PRIMARY_FLIP;
+ break;
+ case I915_EXEC_DERRMR_SPRITE_FLIP:
+ derrmr_bits |= GEN6_DERRMR_PIPE_B_SPRITE_FLIP;
+ break;
+ case I915_EXEC_DERRMR_VBLANK:
+ derrmr_bits |= GEN6_DERRMR_PIPE_B_VBLANK;
+ break;
+ case I915_EXEC_DERRMR_HBLANK:
+ derrmr_bits |= GEN6_DERRMR_PIPE_B_HBLANK;
+ break;
+ default:
+ DRM_ERROR("attempting to set invalid bits in DERRMR: %llu (pipe %d)\n",
+ (args->flags & I915_EXEC_DERRMR_MASK),
+ derrmr_pipe);
+ return -EINVAL;
+ }
+ } else if (derrmr_pipe & I915_EXEC_DERRMR_PIPE_C) {
+ if (INTEL_INFO(dev)->gen < 7) {
+ DRM_ERROR("attempting to set derrmr flags on pipeC on pre-gen7: %llu (pipe %d)\n",
+ (args->flags & I915_EXEC_DERRMR_MASK),
+ derrmr_pipe);
+ return -EINVAL;
+ }
+ switch (args->flags & I915_EXEC_DERRMR_MASK) {
+ case I915_EXEC_DERRMR_SCANLINE:
+ derrmr_bits |= GEN7_DERRMR_PIPE_C_SCANLINE;
+ break;
+ case I915_EXEC_DERRMR_PRIMARY_FLIP:
+ derrmr_bits |= GEN7_DERRMR_PIPE_C_PRIMARY_FLIP;
+ break;
+ case I915_EXEC_DERRMR_SPRITE_FLIP:
+ derrmr_bits |= GEN7_DERRMR_PIPE_C_SPRITE_FLIP;
+ break;
+ case I915_EXEC_DERRMR_VBLANK:
+ derrmr_bits |= GEN7_DERRMR_PIPE_C_VBLANK;
+ break;
+ case I915_EXEC_DERRMR_HBLANK:
+ derrmr_bits |= GEN7_DERRMR_PIPE_C_HBLANK;
+ break;
+ default:
+ DRM_ERROR("attempting to set invalid bits in DERRMR: %llu (pipe %d)\n",
+ (args->flags & I915_EXEC_DERRMR_MASK),
+ derrmr_pipe);
+ return -EINVAL;
+ }
+ }
+ }
+
if (args->buffer_count < 1) {
DRM_ERROR("execbuf with %d buffers\n", args->buffer_count);
return -EINVAL;
@@ -1215,6 +1302,15 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
goto err;
}
+ /* Do the DERRMR bits unmasking when needed */
+ if (use_derrmr) {
+ intel_ring_emit(ring, MI_NOOP);
+ intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1));
+ intel_ring_emit(ring, GEN6_DERRMR);
+ intel_ring_emit(ring, derrmr_bits);
+ intel_ring_advance(ring);
+ }
+
trace_i915_gem_ring_dispatch(ring, seqno);
exec_start = batch_obj->gtt_offset + args->batch_start_offset;
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index c3afb783cb9..e873a848dad 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3742,4 +3742,24 @@
*/
#define GEN7_SO_WRITE_OFFSET(n) (0x5280 + (n) * 4)
+/* Display Engine Render Response Messages */
+#define GEN6_DERRMR 0x44050
+#define GEN6_DERRMR_PIPE_A_SCANLINE (1 << 0)
+#define GEN6_DERRMR_PIPE_A_PRIMARY_FLIP (1 << 1)
+#define GEN6_DERRMR_PIPE_A_SPRITE_FLIP (1 << 2)
+#define GEN6_DERRMR_PIPE_A_VBLANK (1 << 3)
+#define GEN6_DERRMR_PIPE_A_HBLANK (1 << 5)
+#define GEN6_DERRMR_PIPE_B_SCANLINE (1 << 8)
+#define GEN6_DERRMR_PIPE_B_PRIMARY_FLIP (1 << 9)
+#define GEN6_DERRMR_PIPE_B_SPRITE_FLIP (1 << 10)
+#define GEN6_DERRMR_PIPE_B_VBLANK (1 << 11)
+#define GEN6_DERRMR_PIPE_B_HBLANK (1 << 13)
+
+/* IVB */
+#define GEN7_DERRMR_PIPE_C_SCANLINE (1 << 14)
+#define GEN7_DERRMR_PIPE_C_PRIMARY_FLIP (1 << 15)
+#define GEN7_DERRMR_PIPE_C_SPRITE_FLIP (1 << 20)
+#define GEN7_DERRMR_PIPE_C_VBLANK (1 << 21)
+#define GEN7_DERRMR_PIPE_C_HBLANK (1 << 22)
+
#endif /* _I915_REG_H_ */
diff --git a/include/drm/i915_drm.h b/include/drm/i915_drm.h
index 03348d516fa..ae0448fb71a 100644
--- a/include/drm/i915_drm.h
+++ b/include/drm/i915_drm.h
@@ -655,6 +655,22 @@ struct drm_i915_gem_execbuffer2 {
#define I915_EXEC_CONSTANTS_REL_GENERAL (0<<6) /* default */
#define I915_EXEC_CONSTANTS_ABSOLUTE (1<<6)
#define I915_EXEC_CONSTANTS_REL_SURFACE (2<<6) /* gen4/5 only */
+
+/* Used for render ring response unmasking on Gen6+ architectures
+ */
+#define I915_EXEC_USE_DERRMR (1<<8)
+
+#define I915_EXEC_DERRMR_MASK (15<<9) /* Gen6+ render ring response mask */
+#define I915_EXEC_DERRMR_SCANLINE (0<<9)
+#define I915_EXEC_DERRMR_PRIMARY_FLIP (1<<9)
+#define I915_EXEC_DERRMR_SPRITE_FLIP (2<<9)
+#define I915_EXEC_DERRMR_VBLANK (4<<9)
+#define I915_EXEC_DERRMR_HBLANK (8<<9)
+/* Pipe to be controlled by the DERRMR */
+#define I915_EXEC_DERRMR_PIPE_MASK (7<<13)
+#define I915_EXEC_DERRMR_PIPE_A (0<<13)
+#define I915_EXEC_DERRMR_PIPE_B (1<<13)
+#define I915_EXEC_DERRMR_PIPE_C (2<<13)
__u64 flags;
__u64 rsvd1;
__u64 rsvd2;