summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Gordon <david.s.gordon@intel.com>2016-02-24 14:52:38 +0000
committerJohn Harrison <John.C.Harrison@Intel.com>2016-06-28 17:19:29 +0100
commitc91ff93be86b1f929f648ac6f09788d152377e0b (patch)
tree6a920214f2c7065f33449ffb3bed8601219183cc
parente16237614e25e6ba89d64663cfceb70dea789da8 (diff)
drmi915: add workarounds for PIPE_CONTROL instruction
Since we now use PIPE_CONTROL to update seqno on the render ring, it may be necessary to include a few extra workarounds for this opcode. Using PIPE_CONTROL this way was recently introduced in: 7c17d37 drm/i915: Use ordered seqno write interrupt generation on gen8+ execlists which appears to have triggered some stability regression in Yocto after recent forklift. Conflicts: drivers/gpu/drm/i915/intel_lrc.c Signed-off-by: Dave Gordon <david.s.gordon@intel.com>
-rw-r--r--drivers/gpu/drm/i915/intel_lrc.c37
1 files changed, 27 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/intel_lrc.c b/drivers/gpu/drm/i915/intel_lrc.c
index ba2bd0849765..e55e8b9a21c6 100644
--- a/drivers/gpu/drm/i915/intel_lrc.c
+++ b/drivers/gpu/drm/i915/intel_lrc.c
@@ -1131,17 +1131,10 @@ gen8_emit_pipe_control_qw_store_index(struct drm_i915_gem_request *request,
uint32_t data1, uint32_t data2)
{
struct intel_ringbuffer *ringbuf = request->ringbuf;
- uint32_t cmd, opts;
+ const uint32_t cmd = GFX_OP_PIPE_CONTROL(6);
+ uint32_t opts;
int ret;
- cmd = GFX_OP_PIPE_CONTROL(6);
-
- opts = PIPE_CONTROL_GEN7_GLOBAL_GTT; /* Address via GGTT */
- opts |= PIPE_CONTROL_STORE_DATA_INDEX; /* Index into HWSP */
- opts |= PIPE_CONTROL_CS_STALL; /* Stall CS until done */
- opts |= PIPE_CONTROL_QW_WRITE; /* Write QWord */
- opts |= flags; /* Extra flag bits */
-
/* The address must be QWord aligned (index must be EVEN) */
index <<= MI_STORE_DWORD_INDEX_SHIFT;
if (WARN_ON_ONCE(index & 7))
@@ -1150,10 +1143,34 @@ gen8_emit_pipe_control_qw_store_index(struct drm_i915_gem_request *request,
if (WARN_ON_ONCE(index & (1 << 5)))
return -EINVAL;
- ret = intel_logical_ring_begin(request, 6);
+ /* We're going to emit 3 PIPE_CONTROLs of 6 DWords each */
+ ret = intel_logical_ring_begin(request, 3*6);
if (ret)
return ret;
+ /* W/A: stall before flush_enable */
+ opts = PIPE_CONTROL_CS_STALL | PIPE_CONTROL_STALL_AT_SCOREBOARD;
+ intel_logical_ring_emit(ringbuf, cmd);
+ intel_logical_ring_emit(ringbuf, opts);
+ intel_logical_ring_emit(ringbuf, 0);
+ intel_logical_ring_emit(ringbuf, 0);
+ intel_logical_ring_emit(ringbuf, 0);
+ intel_logical_ring_emit(ringbuf, 0);
+
+ /* W/A: post-op before render flush */
+ opts |= PIPE_CONTROL_POSTSYNC_FLUSH;
+ opts |= PIPE_CONTROL_GEN7_GLOBAL_GTT; /* Address via GGTT */
+ opts |= PIPE_CONTROL_STORE_DATA_INDEX; /* Index into HWSP */
+ opts |= PIPE_CONTROL_QW_WRITE; /* Write QWord */
+ intel_logical_ring_emit(ringbuf, cmd);
+ intel_logical_ring_emit(ringbuf, opts);
+ intel_logical_ring_emit(ringbuf, index);
+ intel_logical_ring_emit(ringbuf, 0); /* upper_32_bits(index) */
+ intel_logical_ring_emit(ringbuf, data1);
+ intel_logical_ring_emit(ringbuf, data2);
+
+ opts |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
+ opts |= flags; /* Extra flag bits */
intel_logical_ring_emit(ringbuf, cmd);
intel_logical_ring_emit(ringbuf, opts);
intel_logical_ring_emit(ringbuf, index);