From 0d2c3789f2917d84ac9e4a5de37630786a1c7857 Mon Sep 17 00:00:00 2001 From: Eugeni Dodonov Date: Mon, 6 Feb 2012 16:50:23 -0200 Subject: drm/i915: add DERRMR mask and events 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 --- drivers/gpu/drm/i915/i915_gem_execbuffer.c | 96 ++++++++++++++++++++++++++++++ drivers/gpu/drm/i915/i915_reg.h | 20 +++++++ include/drm/i915_drm.h | 16 +++++ 3 files changed, 132 insertions(+) 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; -- cgit v1.2.3