From c91ff93be86b1f929f648ac6f09788d152377e0b Mon Sep 17 00:00:00 2001 From: Dave Gordon Date: Wed, 24 Feb 2016 14:52:38 +0000 Subject: 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 --- drivers/gpu/drm/i915/intel_lrc.c | 37 +++++++++++++++++++++++++++---------- 1 file 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); -- cgit v1.2.3