sys/dev/drm/i915/intel_ringbuffer.c
/**
 * Emits a PIPE_CONTROL with a non-zero post-sync operation, for
 * implementing two workarounds on gen6.  From section 1.4.7.1
 * "PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1:
 *
 * [DevSNB-C+{W/A}] Before any depth stall flush (including those
 * produced by non-pipelined state commands), software needs to first
 * send a PIPE_CONTROL with no bits set except Post-Sync Operation !=
 * 0.
 *
 * [Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache Flush Enable
 * =1, a PIPE_CONTROL with any non-zero post-sync-op is required.
 *
 * And the workaround for these two requires this workaround first:
 *
 * [Dev-SNB{W/A}]: Pipe-control with CS-stall bit set must be sent
 * BEFORE the pipe-control with a post-sync op and no write-cache
 * flushes.
 *
 * And this last workaround is tricky because of the requirements on
 * that bit.  From section 1.4.7.2.3 "Stall" of the Sandy Bridge PRM
 * volume 2 part 1:
 *
 *     "1 of the following must also be set:
 *      - Render Target Cache Flush Enable ([12] of DW1)
 *      - Depth Cache Flush Enable ([0] of DW1)
 *      - Stall at Pixel Scoreboard ([1] of DW1)
 *      - Depth Stall ([13] of DW1)
 *      - Post-Sync Operation ([13] of DW1)
 *      - Notify Enable ([8] of DW1)"
 *
 * The cache flushes require the workaround flush that triggered this
 * one, so we can't use it.  Depth stall would trigger the same.
 * Post-sync nonzero is what triggered this second workaround, so we
 * can't use that one either.  Notify enable is IRQs, which aren't
 * really our business.  That leaves only stall at scoreboard.
 */
Emits a PIPE_CONTROL with a non-zero post-sync operation, for
implementing two workarounds on gen6.  From section 1.4.7.1
"PIPE_CONTROL" of the Sandy Bridge PRM volume 2 part 1.

[DevSNB-C+{W/A}] Before any depth stall flush (including those
produced by non-pipelined state commands), software needs to first
send a PIPE_CONTROL with no bits set except Post-Sync Operation .
0.

[Dev-SNB{W/A}]: Before a PIPE_CONTROL with Write Cache Flush Enable
=1, a PIPE_CONTROL with any non-zero post-sync-op is required.

And the workaround for these two requires this workaround first.



And this last workaround is tricky because of the requirements on
that bit.  From section 1.4.7.2.3 "Stall" of the Sandy Bridge PRM
volume 2 part 1.



The cache flushes require the workaround flush that triggered this
one, so we can't use it.  Depth stall would trigger the same.
Post-sync nonzero is what triggered this second workaround, so we
can't use that one either.  Notify enable is IRQs, which aren't
really our business.  That leaves only stall at scoreboard.
Emits a PIPE_CONTROL with a non - zero post - sync operation for implementing two workarounds on gen6 . From section 1 . 4 . 7 . 1 " PIPE_CONTROL " of the Sandy Bridge PRM volume 2 part 1 . [ DevSNB - C + { W / A } ] Before any depth stall flush ( including those produced by non - pipelined state commands ) software needs to first send a PIPE_CONTROL with no bits set except Post - Sync Operation . 0 . [ Dev - SNB { W / A } ] : Before a PIPE_CONTROL with Write Cache Flush Enable = 1 a PIPE_CONTROL with any non - zero post - sync - op is required . And the workaround for these two requires this workaround first . And this last workaround is tricky because of the requirements on that bit . From section 1 . 4 . 7 . 2 . 3 " Stall " of the Sandy Bridge PRM volume 2 part 1 . The cache flushes require the workaround flush that triggered this one so we can ' t use it . Depth stall would trigger the same . Post - sync nonzero is what triggered this second workaround so we can ' t use that one either . Notify enable is IRQs which aren ' t really our business . That leaves only stall at scoreboard .
static int
intel_emit_post_sync_nonzero_flush(struct drm_i915_gem_request *req)
{
	struct intel_engine_cs *engine = req->engine;
	u32 scratch_addr = engine->scratch.gtt_offset + 2 * CACHELINE_BYTES;
	int ret;
	ret = intel_ring_begin(req, 6);
	if (ret)
		return ret;
	intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(5));
	intel_ring_emit(engine, PIPE_CONTROL_CS_STALL |
			PIPE_CONTROL_STALL_AT_SCOREBOARD);
	intel_ring_emit(engine, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); 
	intel_ring_emit(engine, 0); 
	intel_ring_emit(engine, 0); 
	intel_ring_emit(engine, MI_NOOP);
	intel_ring_advance(engine);
	ret = intel_ring_begin(req, 6);
	if (ret)
		return ret;
	intel_ring_emit(engine, GFX_OP_PIPE_CONTROL(5));
	intel_ring_emit(engine, PIPE_CONTROL_QW_WRITE);
	intel_ring_emit(engine, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); 
	intel_ring_emit(engine, 0);
	intel_ring_emit(engine, 0);
	intel_ring_emit(engine, MI_NOOP);
	intel_ring_advance(engine);
	return 0;
}
static int intel_emit_post_sync_nonzero_flush ( struct drm_i915_gem_request * req ) { struct intel_engine_cs * engine = req -> engine ; u32 scratch_addr = engine -> scratch . gtt_offset + 2 * CACHELINE_BYTES ; int ret ; ret = intel_ring_begin ( req , 6 ) ; if ( ret ) return ret ; intel_ring_emit ( engine , GFX_OP_PIPE_CONTROL ( 5 ) ) ; intel_ring_emit ( engine , PIPE_CONTROL_CS_STALL | PIPE_CONTROL_STALL_AT_SCOREBOARD ) ; intel_ring_emit ( engine , scratch_addr | PIPE_CONTROL_GLOBAL_GTT ) ; intel_ring_emit ( engine , 0 ) ; intel_ring_emit ( engine , 0 ) ; intel_ring_emit ( engine , MI_NOOP ) ; intel_ring_advance ( engine ) ; ret = intel_ring_begin ( req , 6 ) ; if ( ret ) return ret ; intel_ring_emit ( engine , GFX_OP_PIPE_CONTROL ( 5 ) ) ; intel_ring_emit ( engine , PIPE_CONTROL_QW_WRITE ) ; intel_ring_emit ( engine , scratch_addr | PIPE_CONTROL_GLOBAL_GTT ) ; intel_ring_emit ( engine , 0 ) ; intel_ring_emit ( engine , 0 ) ; intel_ring_emit ( engine , MI_NOOP ) ; intel_ring_advance ( engine ) ; return 0 ; }
Emits a PIPE_CONTROL with a non-zero post-sync operation, for
 implementing two workarounds on gen6.
Emits a PIPE_CONTROL with a non - zero post - sync operation for implementing two workarounds on gen6 .
/* address */ /* low dword */ /* high dword */ /* address */