diff options
author | Dave Gordon <david.s.gordon@intel.com> | 2016-02-24 14:52:38 +0000 |
---|---|---|
committer | John Harrison <John.C.Harrison@Intel.com> | 2016-06-28 17:19:29 +0100 |
commit | c91ff93be86b1f929f648ac6f09788d152377e0b (patch) | |
tree | 6a920214f2c7065f33449ffb3bed8601219183cc | |
parent | e16237614e25e6ba89d64663cfceb70dea789da8 (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.c | 37 |
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); |