[Intel-gfx] [PATCH 02/36] drm/i915/gt: Split low level gen2-7 CS emitters
Mika Kuoppala
mika.kuoppala at linux.intel.com
Tue Jun 2 09:04:12 UTC 2020
Chris Wilson <chris at chris-wilson.co.uk> writes:
> Pull the routines for writing CS packets out of intel_ring_submission
> into their own files. These are low level operations for building CS
> instructions, rather than the logic for filling the global ring buffer
> with requests, and we will wnat to reuse them outside of this context.
*want.
Acked-by: Mika Kuoppala <mika.kuoppala at linux.intel.com>
>
> Signed-off-by: Chris Wilson <chris at chris-wilson.co.uk>
> ---
> drivers/gpu/drm/i915/Makefile | 2 +
> drivers/gpu/drm/i915/gt/gen2_engine_cs.c | 340 +++++++
> drivers/gpu/drm/i915/gt/gen2_engine_cs.h | 38 +
> drivers/gpu/drm/i915/gt/gen6_engine_cs.c | 455 ++++++++++
> drivers/gpu/drm/i915/gt/gen6_engine_cs.h | 39 +
> drivers/gpu/drm/i915/gt/intel_engine.h | 1 -
> .../gpu/drm/i915/gt/intel_ring_submission.c | 832 +-----------------
> 7 files changed, 901 insertions(+), 806 deletions(-)
> create mode 100644 drivers/gpu/drm/i915/gt/gen2_engine_cs.c
> create mode 100644 drivers/gpu/drm/i915/gt/gen2_engine_cs.h
> create mode 100644 drivers/gpu/drm/i915/gt/gen6_engine_cs.c
> create mode 100644 drivers/gpu/drm/i915/gt/gen6_engine_cs.h
>
> diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile
> index b0da6ea6e3f1..41a27fd5dbc7 100644
> --- a/drivers/gpu/drm/i915/Makefile
> +++ b/drivers/gpu/drm/i915/Makefile
> @@ -78,6 +78,8 @@ gt-y += \
> gt/debugfs_engines.o \
> gt/debugfs_gt.o \
> gt/debugfs_gt_pm.o \
> + gt/gen2_engine_cs.o \
> + gt/gen6_engine_cs.o \
> gt/gen6_ppgtt.o \
> gt/gen7_renderclear.o \
> gt/gen8_ppgtt.o \
> diff --git a/drivers/gpu/drm/i915/gt/gen2_engine_cs.c b/drivers/gpu/drm/i915/gt/gen2_engine_cs.c
> new file mode 100644
> index 000000000000..8d2e85081247
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/gen2_engine_cs.c
> @@ -0,0 +1,340 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2020 Intel Corporation
> + */
> +
> +#include "gen2_engine_cs.h"
> +#include "i915_drv.h"
> +#include "intel_engine.h"
> +#include "intel_gpu_commands.h"
> +#include "intel_gt.h"
> +#include "intel_gt_irq.h"
> +#include "intel_ring.h"
> +
> +int gen2_emit_flush(struct i915_request *rq, u32 mode)
> +{
> + unsigned int num_store_dw;
> + u32 cmd, *cs;
> +
> + cmd = MI_FLUSH;
> + num_store_dw = 0;
> + if (mode & EMIT_INVALIDATE)
> + cmd |= MI_READ_FLUSH;
> + if (mode & EMIT_FLUSH)
> + num_store_dw = 4;
> +
> + cs = intel_ring_begin(rq, 2 + 3 * num_store_dw);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + *cs++ = cmd;
> + while (num_store_dw--) {
> + *cs++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
> + *cs++ = intel_gt_scratch_offset(rq->engine->gt,
> + INTEL_GT_SCRATCH_FIELD_DEFAULT);
> + *cs++ = 0;
> + }
> + *cs++ = MI_FLUSH | MI_NO_WRITE_FLUSH;
> +
> + intel_ring_advance(rq, cs);
> +
> + return 0;
> +}
> +
> +int gen4_emit_flush_rcs(struct i915_request *rq, u32 mode)
> +{
> + u32 cmd, *cs;
> + int i;
> +
> + /*
> + * read/write caches:
> + *
> + * I915_GEM_DOMAIN_RENDER is always invalidated, but is
> + * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is
> + * also flushed at 2d versus 3d pipeline switches.
> + *
> + * read-only caches:
> + *
> + * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
> + * MI_READ_FLUSH is set, and is always flushed on 965.
> + *
> + * I915_GEM_DOMAIN_COMMAND may not exist?
> + *
> + * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
> + * invalidated when MI_EXE_FLUSH is set.
> + *
> + * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
> + * invalidated with every MI_FLUSH.
> + *
> + * TLBs:
> + *
> + * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
> + * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
> + * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
> + * are flushed at any MI_FLUSH.
> + */
> +
> + cmd = MI_FLUSH;
> + if (mode & EMIT_INVALIDATE) {
> + cmd |= MI_EXE_FLUSH;
> + if (IS_G4X(rq->i915) || IS_GEN(rq->i915, 5))
> + cmd |= MI_INVALIDATE_ISP;
> + }
> +
> + i = 2;
> + if (mode & EMIT_INVALIDATE)
> + i += 20;
> +
> + cs = intel_ring_begin(rq, i);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + *cs++ = cmd;
> +
> + /*
> + * A random delay to let the CS invalidate take effect? Without this
> + * delay, the GPU relocation path fails as the CS does not see
> + * the updated contents. Just as important, if we apply the flushes
> + * to the EMIT_FLUSH branch (i.e. immediately after the relocation
> + * write and before the invalidate on the next batch), the relocations
> + * still fail. This implies that is a delay following invalidation
> + * that is required to reset the caches as opposed to a delay to
> + * ensure the memory is written.
> + */
> + if (mode & EMIT_INVALIDATE) {
> + *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
> + *cs++ = intel_gt_scratch_offset(rq->engine->gt,
> + INTEL_GT_SCRATCH_FIELD_DEFAULT) |
> + PIPE_CONTROL_GLOBAL_GTT;
> + *cs++ = 0;
> + *cs++ = 0;
> +
> + for (i = 0; i < 12; i++)
> + *cs++ = MI_FLUSH;
> +
> + *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
> + *cs++ = intel_gt_scratch_offset(rq->engine->gt,
> + INTEL_GT_SCRATCH_FIELD_DEFAULT) |
> + PIPE_CONTROL_GLOBAL_GTT;
> + *cs++ = 0;
> + *cs++ = 0;
> + }
> +
> + *cs++ = cmd;
> +
> + intel_ring_advance(rq, cs);
> +
> + return 0;
> +}
> +
> +int gen4_emit_flush_vcs(struct i915_request *rq, u32 mode)
> +{
> + u32 *cs;
> +
> + cs = intel_ring_begin(rq, 2);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + *cs++ = MI_FLUSH;
> + *cs++ = MI_NOOP;
> + intel_ring_advance(rq, cs);
> +
> + return 0;
> +}
> +
> +u32 *gen3_emit_breadcrumb(struct i915_request *rq, u32 *cs)
> +{
> + GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);
> + GEM_BUG_ON(offset_in_page(i915_request_active_timeline(rq)->hwsp_offset) != I915_GEM_HWS_SEQNO_ADDR);
> +
> + *cs++ = MI_FLUSH;
> +
> + *cs++ = MI_STORE_DWORD_INDEX;
> + *cs++ = I915_GEM_HWS_SEQNO_ADDR;
> + *cs++ = rq->fence.seqno;
> +
> + *cs++ = MI_USER_INTERRUPT;
> + *cs++ = MI_NOOP;
> +
> + rq->tail = intel_ring_offset(rq, cs);
> + assert_ring_tail_valid(rq->ring, rq->tail);
> +
> + return cs;
> +}
> +
> +#define GEN5_WA_STORES 8 /* must be at least 1! */
> +u32 *gen5_emit_breadcrumb(struct i915_request *rq, u32 *cs)
> +{
> + int i;
> +
> + GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);
> + GEM_BUG_ON(offset_in_page(i915_request_active_timeline(rq)->hwsp_offset) != I915_GEM_HWS_SEQNO_ADDR);
> +
> + *cs++ = MI_FLUSH;
> +
> + BUILD_BUG_ON(GEN5_WA_STORES < 1);
> + for (i = 0; i < GEN5_WA_STORES; i++) {
> + *cs++ = MI_STORE_DWORD_INDEX;
> + *cs++ = I915_GEM_HWS_SEQNO_ADDR;
> + *cs++ = rq->fence.seqno;
> + }
> +
> + *cs++ = MI_USER_INTERRUPT;
> +
> + rq->tail = intel_ring_offset(rq, cs);
> + assert_ring_tail_valid(rq->ring, rq->tail);
> +
> + return cs;
> +}
> +#undef GEN5_WA_STORES
> +
> +/* Just userspace ABI convention to limit the wa batch bo to a resonable size */
> +#define I830_BATCH_LIMIT SZ_256K
> +#define I830_TLB_ENTRIES (2)
> +#define I830_WA_SIZE max(I830_TLB_ENTRIES * SZ_4K, I830_BATCH_LIMIT)
> +int i830_emit_bb_start(struct i915_request *rq,
> + u64 offset, u32 len,
> + unsigned int dispatch_flags)
> +{
> + u32 *cs, cs_offset =
> + intel_gt_scratch_offset(rq->engine->gt,
> + INTEL_GT_SCRATCH_FIELD_DEFAULT);
> +
> + GEM_BUG_ON(rq->engine->gt->scratch->size < I830_WA_SIZE);
> +
> + cs = intel_ring_begin(rq, 6);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + /* Evict the invalid PTE TLBs */
> + *cs++ = COLOR_BLT_CMD | BLT_WRITE_RGBA;
> + *cs++ = BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | 4096;
> + *cs++ = I830_TLB_ENTRIES << 16 | 4; /* load each page */
> + *cs++ = cs_offset;
> + *cs++ = 0xdeadbeef;
> + *cs++ = MI_NOOP;
> + intel_ring_advance(rq, cs);
> +
> + if ((dispatch_flags & I915_DISPATCH_PINNED) == 0) {
> + if (len > I830_BATCH_LIMIT)
> + return -ENOSPC;
> +
> + cs = intel_ring_begin(rq, 6 + 2);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + /*
> + * Blit the batch (which has now all relocs applied) to the
> + * stable batch scratch bo area (so that the CS never
> + * stumbles over its tlb invalidation bug) ...
> + */
> + *cs++ = SRC_COPY_BLT_CMD | BLT_WRITE_RGBA | (6 - 2);
> + *cs++ = BLT_DEPTH_32 | BLT_ROP_SRC_COPY | 4096;
> + *cs++ = DIV_ROUND_UP(len, 4096) << 16 | 4096;
> + *cs++ = cs_offset;
> + *cs++ = 4096;
> + *cs++ = offset;
> +
> + *cs++ = MI_FLUSH;
> + *cs++ = MI_NOOP;
> + intel_ring_advance(rq, cs);
> +
> + /* ... and execute it. */
> + offset = cs_offset;
> + }
> +
> + if (!(dispatch_flags & I915_DISPATCH_SECURE))
> + offset |= MI_BATCH_NON_SECURE;
> +
> + cs = intel_ring_begin(rq, 2);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + *cs++ = MI_BATCH_BUFFER_START | MI_BATCH_GTT;
> + *cs++ = offset;
> + intel_ring_advance(rq, cs);
> +
> + return 0;
> +}
> +
> +int gen3_emit_bb_start(struct i915_request *rq,
> + u64 offset, u32 len,
> + unsigned int dispatch_flags)
> +{
> + u32 *cs;
> +
> + if (!(dispatch_flags & I915_DISPATCH_SECURE))
> + offset |= MI_BATCH_NON_SECURE;
> +
> + cs = intel_ring_begin(rq, 2);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + *cs++ = MI_BATCH_BUFFER_START | MI_BATCH_GTT;
> + *cs++ = offset;
> + intel_ring_advance(rq, cs);
> +
> + return 0;
> +}
> +
> +int gen4_emit_bb_start(struct i915_request *rq,
> + u64 offset, u32 length,
> + unsigned int dispatch_flags)
> +{
> + u32 security;
> + u32 *cs;
> +
> + security = MI_BATCH_NON_SECURE_I965;
> + if (dispatch_flags & I915_DISPATCH_SECURE)
> + security = 0;
> +
> + cs = intel_ring_begin(rq, 2);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + *cs++ = MI_BATCH_BUFFER_START | MI_BATCH_GTT | security;
> + *cs++ = offset;
> + intel_ring_advance(rq, cs);
> +
> + return 0;
> +}
> +
> +void gen2_irq_enable(struct intel_engine_cs *engine)
> +{
> + struct drm_i915_private *i915 = engine->i915;
> +
> + i915->irq_mask &= ~engine->irq_enable_mask;
> + intel_uncore_write16(&i915->uncore, GEN2_IMR, i915->irq_mask);
> + ENGINE_POSTING_READ16(engine, RING_IMR);
> +}
> +
> +void gen2_irq_disable(struct intel_engine_cs *engine)
> +{
> + struct drm_i915_private *i915 = engine->i915;
> +
> + i915->irq_mask |= engine->irq_enable_mask;
> + intel_uncore_write16(&i915->uncore, GEN2_IMR, i915->irq_mask);
> +}
> +
> +void gen3_irq_enable(struct intel_engine_cs *engine)
> +{
> + engine->i915->irq_mask &= ~engine->irq_enable_mask;
> + intel_uncore_write(engine->uncore, GEN2_IMR, engine->i915->irq_mask);
> + intel_uncore_posting_read_fw(engine->uncore, GEN2_IMR);
> +}
> +
> +void gen3_irq_disable(struct intel_engine_cs *engine)
> +{
> + engine->i915->irq_mask |= engine->irq_enable_mask;
> + intel_uncore_write(engine->uncore, GEN2_IMR, engine->i915->irq_mask);
> +}
> +
> +void gen5_irq_enable(struct intel_engine_cs *engine)
> +{
> + gen5_gt_enable_irq(engine->gt, engine->irq_enable_mask);
> +}
> +
> +void gen5_irq_disable(struct intel_engine_cs *engine)
> +{
> + gen5_gt_disable_irq(engine->gt, engine->irq_enable_mask);
> +}
> diff --git a/drivers/gpu/drm/i915/gt/gen2_engine_cs.h b/drivers/gpu/drm/i915/gt/gen2_engine_cs.h
> new file mode 100644
> index 000000000000..a5cd64a65c9e
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/gen2_engine_cs.h
> @@ -0,0 +1,38 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2020 Intel Corporation
> + */
> +
> +#ifndef __GEN2_ENGINE_CS_H__
> +#define __GEN2_ENGINE_CS_H__
> +
> +#include <linux/types.h>
> +
> +struct i915_request;
> +struct intel_engine_cs;
> +
> +int gen2_emit_flush(struct i915_request *rq, u32 mode);
> +int gen4_emit_flush_rcs(struct i915_request *rq, u32 mode);
> +int gen4_emit_flush_vcs(struct i915_request *rq, u32 mode);
> +
> +u32 *gen3_emit_breadcrumb(struct i915_request *rq, u32 *cs);
> +u32 *gen5_emit_breadcrumb(struct i915_request *rq, u32 *cs);
> +
> +int i830_emit_bb_start(struct i915_request *rq,
> + u64 offset, u32 len,
> + unsigned int dispatch_flags);
> +int gen3_emit_bb_start(struct i915_request *rq,
> + u64 offset, u32 len,
> + unsigned int dispatch_flags);
> +int gen4_emit_bb_start(struct i915_request *rq,
> + u64 offset, u32 length,
> + unsigned int dispatch_flags);
> +
> +void gen2_irq_enable(struct intel_engine_cs *engine);
> +void gen2_irq_disable(struct intel_engine_cs *engine);
> +void gen3_irq_enable(struct intel_engine_cs *engine);
> +void gen3_irq_disable(struct intel_engine_cs *engine);
> +void gen5_irq_enable(struct intel_engine_cs *engine);
> +void gen5_irq_disable(struct intel_engine_cs *engine);
> +
> +#endif /* __GEN2_ENGINE_CS_H__ */
> diff --git a/drivers/gpu/drm/i915/gt/gen6_engine_cs.c b/drivers/gpu/drm/i915/gt/gen6_engine_cs.c
> new file mode 100644
> index 000000000000..ce38d1bcaba3
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/gen6_engine_cs.c
> @@ -0,0 +1,455 @@
> +// SPDX-License-Identifier: MIT
> +/*
> + * Copyright © 2020 Intel Corporation
> + */
> +
> +#include "gen6_engine_cs.h"
> +#include "intel_engine.h"
> +#include "intel_gpu_commands.h"
> +#include "intel_gt.h"
> +#include "intel_gt_irq.h"
> +#include "intel_gt_pm_irq.h"
> +#include "intel_ring.h"
> +
> +#define HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH * sizeof(u32))
> +
> +/*
> + * 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.
> + */
> +static int
> +gen6_emit_post_sync_nonzero_flush(struct i915_request *rq)
> +{
> + u32 scratch_addr =
> + intel_gt_scratch_offset(rq->engine->gt,
> + INTEL_GT_SCRATCH_FIELD_RENDER_FLUSH);
> + u32 *cs;
> +
> + cs = intel_ring_begin(rq, 6);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + *cs++ = GFX_OP_PIPE_CONTROL(5);
> + *cs++ = PIPE_CONTROL_CS_STALL | PIPE_CONTROL_STALL_AT_SCOREBOARD;
> + *cs++ = scratch_addr | PIPE_CONTROL_GLOBAL_GTT;
> + *cs++ = 0; /* low dword */
> + *cs++ = 0; /* high dword */
> + *cs++ = MI_NOOP;
> + intel_ring_advance(rq, cs);
> +
> + cs = intel_ring_begin(rq, 6);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + *cs++ = GFX_OP_PIPE_CONTROL(5);
> + *cs++ = PIPE_CONTROL_QW_WRITE;
> + *cs++ = scratch_addr | PIPE_CONTROL_GLOBAL_GTT;
> + *cs++ = 0;
> + *cs++ = 0;
> + *cs++ = MI_NOOP;
> + intel_ring_advance(rq, cs);
> +
> + return 0;
> +}
> +
> +int gen6_emit_flush_rcs(struct i915_request *rq, u32 mode)
> +{
> + u32 scratch_addr =
> + intel_gt_scratch_offset(rq->engine->gt,
> + INTEL_GT_SCRATCH_FIELD_RENDER_FLUSH);
> + u32 *cs, flags = 0;
> + int ret;
> +
> + /* Force SNB workarounds for PIPE_CONTROL flushes */
> + ret = gen6_emit_post_sync_nonzero_flush(rq);
> + if (ret)
> + return ret;
> +
> + /*
> + * Just flush everything. Experiments have shown that reducing the
> + * number of bits based on the write domains has little performance
> + * impact. And when rearranging requests, the order of flushes is
> + * unknown.
> + */
> + if (mode & EMIT_FLUSH) {
> + flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
> + flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
> + /*
> + * Ensure that any following seqno writes only happen
> + * when the render cache is indeed flushed.
> + */
> + flags |= PIPE_CONTROL_CS_STALL;
> + }
> + if (mode & EMIT_INVALIDATE) {
> + flags |= PIPE_CONTROL_TLB_INVALIDATE;
> + flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
> + flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
> + flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
> + flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
> + flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
> + /*
> + * TLB invalidate requires a post-sync write.
> + */
> + flags |= PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_CS_STALL;
> + }
> +
> + cs = intel_ring_begin(rq, 4);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + *cs++ = GFX_OP_PIPE_CONTROL(4);
> + *cs++ = flags;
> + *cs++ = scratch_addr | PIPE_CONTROL_GLOBAL_GTT;
> + *cs++ = 0;
> + intel_ring_advance(rq, cs);
> +
> + return 0;
> +}
> +
> +u32 *gen6_emit_breadcrumb_rcs(struct i915_request *rq, u32 *cs)
> +{
> + /* First we do the gen6_emit_post_sync_nonzero_flush w/a */
> + *cs++ = GFX_OP_PIPE_CONTROL(4);
> + *cs++ = PIPE_CONTROL_CS_STALL | PIPE_CONTROL_STALL_AT_SCOREBOARD;
> + *cs++ = 0;
> + *cs++ = 0;
> +
> + *cs++ = GFX_OP_PIPE_CONTROL(4);
> + *cs++ = PIPE_CONTROL_QW_WRITE;
> + *cs++ = intel_gt_scratch_offset(rq->engine->gt,
> + INTEL_GT_SCRATCH_FIELD_DEFAULT) |
> + PIPE_CONTROL_GLOBAL_GTT;
> + *cs++ = 0;
> +
> + /* Finally we can flush and with it emit the breadcrumb */
> + *cs++ = GFX_OP_PIPE_CONTROL(4);
> + *cs++ = (PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH |
> + PIPE_CONTROL_DEPTH_CACHE_FLUSH |
> + PIPE_CONTROL_DC_FLUSH_ENABLE |
> + PIPE_CONTROL_QW_WRITE |
> + PIPE_CONTROL_CS_STALL);
> + *cs++ = i915_request_active_timeline(rq)->hwsp_offset |
> + PIPE_CONTROL_GLOBAL_GTT;
> + *cs++ = rq->fence.seqno;
> +
> + *cs++ = MI_USER_INTERRUPT;
> + *cs++ = MI_NOOP;
> +
> + rq->tail = intel_ring_offset(rq, cs);
> + assert_ring_tail_valid(rq->ring, rq->tail);
> +
> + return cs;
> +}
> +
> +static int mi_flush_dw(struct i915_request *rq, u32 flags)
> +{
> + u32 cmd, *cs;
> +
> + cs = intel_ring_begin(rq, 4);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + cmd = MI_FLUSH_DW;
> +
> + /*
> + * We always require a command barrier so that subsequent
> + * commands, such as breadcrumb interrupts, are strictly ordered
> + * wrt the contents of the write cache being flushed to memory
> + * (and thus being coherent from the CPU).
> + */
> + cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
> +
> + /*
> + * Bspec vol 1c.3 - blitter engine command streamer:
> + * "If ENABLED, all TLBs will be invalidated once the flush
> + * operation is complete. This bit is only valid when the
> + * Post-Sync Operation field is a value of 1h or 3h."
> + */
> + cmd |= flags;
> +
> + *cs++ = cmd;
> + *cs++ = HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT;
> + *cs++ = 0;
> + *cs++ = MI_NOOP;
> +
> + intel_ring_advance(rq, cs);
> +
> + return 0;
> +}
> +
> +static int gen6_flush_dw(struct i915_request *rq, u32 mode, u32 invflags)
> +{
> + return mi_flush_dw(rq, mode & EMIT_INVALIDATE ? invflags : 0);
> +}
> +
> +int gen6_emit_flush_xcs(struct i915_request *rq, u32 mode)
> +{
> + return gen6_flush_dw(rq, mode, MI_INVALIDATE_TLB);
> +}
> +
> +int gen6_emit_flush_vcs(struct i915_request *rq, u32 mode)
> +{
> + return gen6_flush_dw(rq, mode, MI_INVALIDATE_TLB | MI_INVALIDATE_BSD);
> +}
> +
> +int gen6_emit_bb_start(struct i915_request *rq,
> + u64 offset, u32 len,
> + unsigned int dispatch_flags)
> +{
> + u32 security;
> + u32 *cs;
> +
> + security = MI_BATCH_NON_SECURE_I965;
> + if (dispatch_flags & I915_DISPATCH_SECURE)
> + security = 0;
> +
> + cs = intel_ring_begin(rq, 2);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + cs = __gen6_emit_bb_start(cs, offset, security);
> + intel_ring_advance(rq, cs);
> +
> + return 0;
> +}
> +
> +int
> +hsw_emit_bb_start(struct i915_request *rq,
> + u64 offset, u32 len,
> + unsigned int dispatch_flags)
> +{
> + u32 security;
> + u32 *cs;
> +
> + security = MI_BATCH_PPGTT_HSW | MI_BATCH_NON_SECURE_HSW;
> + if (dispatch_flags & I915_DISPATCH_SECURE)
> + security = 0;
> +
> + cs = intel_ring_begin(rq, 2);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + cs = __gen6_emit_bb_start(cs, offset, security);
> + intel_ring_advance(rq, cs);
> +
> + return 0;
> +}
> +
> +static int gen7_stall_cs(struct i915_request *rq)
> +{
> + u32 *cs;
> +
> + cs = intel_ring_begin(rq, 4);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + *cs++ = GFX_OP_PIPE_CONTROL(4);
> + *cs++ = PIPE_CONTROL_CS_STALL | PIPE_CONTROL_STALL_AT_SCOREBOARD;
> + *cs++ = 0;
> + *cs++ = 0;
> + intel_ring_advance(rq, cs);
> +
> + return 0;
> +}
> +
> +int gen7_emit_flush_rcs(struct i915_request *rq, u32 mode)
> +{
> + u32 scratch_addr =
> + intel_gt_scratch_offset(rq->engine->gt,
> + INTEL_GT_SCRATCH_FIELD_RENDER_FLUSH);
> + u32 *cs, flags = 0;
> +
> + /*
> + * Ensure that any following seqno writes only happen when the render
> + * cache is indeed flushed.
> + *
> + * Workaround: 4th PIPE_CONTROL command (except the ones with only
> + * read-cache invalidate bits set) must have the CS_STALL bit set. We
> + * don't try to be clever and just set it unconditionally.
> + */
> + flags |= PIPE_CONTROL_CS_STALL;
> +
> + /*
> + * CS_STALL suggests at least a post-sync write.
> + */
> + flags |= PIPE_CONTROL_QW_WRITE;
> + flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
> +
> + /*
> + * Just flush everything. Experiments have shown that reducing the
> + * number of bits based on the write domains has little performance
> + * impact.
> + */
> + if (mode & EMIT_FLUSH) {
> + flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
> + flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
> + flags |= PIPE_CONTROL_DC_FLUSH_ENABLE;
> + flags |= PIPE_CONTROL_FLUSH_ENABLE;
> + }
> + if (mode & EMIT_INVALIDATE) {
> + flags |= PIPE_CONTROL_TLB_INVALIDATE;
> + flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
> + flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
> + flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
> + flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
> + flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
> + flags |= PIPE_CONTROL_MEDIA_STATE_CLEAR;
> +
> + /*
> + * Workaround: we must issue a pipe_control with CS-stall bit
> + * set before a pipe_control command that has the state cache
> + * invalidate bit set.
> + */
> + gen7_stall_cs(rq);
> + }
> +
> + cs = intel_ring_begin(rq, 4);
> + if (IS_ERR(cs))
> + return PTR_ERR(cs);
> +
> + *cs++ = GFX_OP_PIPE_CONTROL(4);
> + *cs++ = flags;
> + *cs++ = scratch_addr;
> + *cs++ = 0;
> + intel_ring_advance(rq, cs);
> +
> + return 0;
> +}
> +
> +u32 *gen7_emit_breadcrumb_rcs(struct i915_request *rq, u32 *cs)
> +{
> + *cs++ = GFX_OP_PIPE_CONTROL(4);
> + *cs++ = (PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH |
> + PIPE_CONTROL_DEPTH_CACHE_FLUSH |
> + PIPE_CONTROL_DC_FLUSH_ENABLE |
> + PIPE_CONTROL_FLUSH_ENABLE |
> + PIPE_CONTROL_QW_WRITE |
> + PIPE_CONTROL_GLOBAL_GTT_IVB |
> + PIPE_CONTROL_CS_STALL);
> + *cs++ = i915_request_active_timeline(rq)->hwsp_offset;
> + *cs++ = rq->fence.seqno;
> +
> + *cs++ = MI_USER_INTERRUPT;
> + *cs++ = MI_NOOP;
> +
> + rq->tail = intel_ring_offset(rq, cs);
> + assert_ring_tail_valid(rq->ring, rq->tail);
> +
> + return cs;
> +}
> +
> +u32 *gen6_emit_breadcrumb_xcs(struct i915_request *rq, u32 *cs)
> +{
> + GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);
> + GEM_BUG_ON(offset_in_page(i915_request_active_timeline(rq)->hwsp_offset) != I915_GEM_HWS_SEQNO_ADDR);
> +
> + *cs++ = MI_FLUSH_DW | MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX;
> + *cs++ = I915_GEM_HWS_SEQNO_ADDR | MI_FLUSH_DW_USE_GTT;
> + *cs++ = rq->fence.seqno;
> +
> + *cs++ = MI_USER_INTERRUPT;
> +
> + rq->tail = intel_ring_offset(rq, cs);
> + assert_ring_tail_valid(rq->ring, rq->tail);
> +
> + return cs;
> +}
> +
> +#define GEN7_XCS_WA 32
> +u32 *gen7_emit_breadcrumb_xcs(struct i915_request *rq, u32 *cs)
> +{
> + int i;
> +
> + GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);
> + GEM_BUG_ON(offset_in_page(i915_request_active_timeline(rq)->hwsp_offset) != I915_GEM_HWS_SEQNO_ADDR);
> +
> + *cs++ = MI_FLUSH_DW | MI_INVALIDATE_TLB |
> + MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX;
> + *cs++ = I915_GEM_HWS_SEQNO_ADDR | MI_FLUSH_DW_USE_GTT;
> + *cs++ = rq->fence.seqno;
> +
> + for (i = 0; i < GEN7_XCS_WA; i++) {
> + *cs++ = MI_STORE_DWORD_INDEX;
> + *cs++ = I915_GEM_HWS_SEQNO_ADDR;
> + *cs++ = rq->fence.seqno;
> + }
> +
> + *cs++ = MI_FLUSH_DW;
> + *cs++ = 0;
> + *cs++ = 0;
> +
> + *cs++ = MI_USER_INTERRUPT;
> + *cs++ = MI_NOOP;
> +
> + rq->tail = intel_ring_offset(rq, cs);
> + assert_ring_tail_valid(rq->ring, rq->tail);
> +
> + return cs;
> +}
> +#undef GEN7_XCS_WA
> +
> +void gen6_irq_enable(struct intel_engine_cs *engine)
> +{
> + ENGINE_WRITE(engine, RING_IMR,
> + ~(engine->irq_enable_mask | engine->irq_keep_mask));
> +
> + /* Flush/delay to ensure the RING_IMR is active before the GT IMR */
> + ENGINE_POSTING_READ(engine, RING_IMR);
> +
> + gen5_gt_enable_irq(engine->gt, engine->irq_enable_mask);
> +}
> +
> +void gen6_irq_disable(struct intel_engine_cs *engine)
> +{
> + ENGINE_WRITE(engine, RING_IMR, ~engine->irq_keep_mask);
> + gen5_gt_disable_irq(engine->gt, engine->irq_enable_mask);
> +}
> +
> +void hsw_irq_enable_vecs(struct intel_engine_cs *engine)
> +{
> + ENGINE_WRITE(engine, RING_IMR, ~engine->irq_enable_mask);
> +
> + /* Flush/delay to ensure the RING_IMR is active before the GT IMR */
> + ENGINE_POSTING_READ(engine, RING_IMR);
> +
> + gen6_gt_pm_unmask_irq(engine->gt, engine->irq_enable_mask);
> +}
> +
> +void hsw_irq_disable_vecs(struct intel_engine_cs *engine)
> +{
> + ENGINE_WRITE(engine, RING_IMR, ~0);
> + gen6_gt_pm_mask_irq(engine->gt, engine->irq_enable_mask);
> +}
> diff --git a/drivers/gpu/drm/i915/gt/gen6_engine_cs.h b/drivers/gpu/drm/i915/gt/gen6_engine_cs.h
> new file mode 100644
> index 000000000000..76c6bc9f3bde
> --- /dev/null
> +++ b/drivers/gpu/drm/i915/gt/gen6_engine_cs.h
> @@ -0,0 +1,39 @@
> +/* SPDX-License-Identifier: MIT */
> +/*
> + * Copyright © 2020 Intel Corporation
> + */
> +
> +#ifndef __GEN6_ENGINE_CS_H__
> +#define __GEN6_ENGINE_CS_H__
> +
> +#include <linux/types.h>
> +
> +#include "intel_gpu_commands.h"
> +
> +struct i915_request;
> +struct intel_engine_cs;
> +
> +int gen6_emit_flush_rcs(struct i915_request *rq, u32 mode);
> +int gen6_emit_flush_vcs(struct i915_request *rq, u32 mode);
> +int gen6_emit_flush_xcs(struct i915_request *rq, u32 mode);
> +u32 *gen6_emit_breadcrumb_rcs(struct i915_request *rq, u32 *cs);
> +u32 *gen6_emit_breadcrumb_xcs(struct i915_request *rq, u32 *cs);
> +
> +int gen7_emit_flush_rcs(struct i915_request *rq, u32 mode);
> +u32 *gen7_emit_breadcrumb_rcs(struct i915_request *rq, u32 *cs);
> +u32 *gen7_emit_breadcrumb_xcs(struct i915_request *rq, u32 *cs);
> +
> +int gen6_emit_bb_start(struct i915_request *rq,
> + u64 offset, u32 len,
> + unsigned int dispatch_flags);
> +int hsw_emit_bb_start(struct i915_request *rq,
> + u64 offset, u32 len,
> + unsigned int dispatch_flags);
> +
> +void gen6_irq_enable(struct intel_engine_cs *engine);
> +void gen6_irq_disable(struct intel_engine_cs *engine);
> +
> +void hsw_irq_enable_vecs(struct intel_engine_cs *engine);
> +void hsw_irq_disable_vecs(struct intel_engine_cs *engine);
> +
> +#endif /* __GEN6_ENGINE_CS_H__ */
> diff --git a/drivers/gpu/drm/i915/gt/intel_engine.h b/drivers/gpu/drm/i915/gt/intel_engine.h
> index 9bf6d4989968..791897f8d847 100644
> --- a/drivers/gpu/drm/i915/gt/intel_engine.h
> +++ b/drivers/gpu/drm/i915/gt/intel_engine.h
> @@ -187,7 +187,6 @@ intel_write_status_page(struct intel_engine_cs *engine, int reg, u32 value)
> #define I915_GEM_HWS_SEQNO 0x40
> #define I915_GEM_HWS_SEQNO_ADDR (I915_GEM_HWS_SEQNO * sizeof(u32))
> #define I915_GEM_HWS_SCRATCH 0x80
> -#define I915_GEM_HWS_SCRATCH_ADDR (I915_GEM_HWS_SCRATCH * sizeof(u32))
>
> #define I915_HWS_CSB_BUF0_INDEX 0x10
> #define I915_HWS_CSB_WRITE_INDEX 0x1f
> diff --git a/drivers/gpu/drm/i915/gt/intel_ring_submission.c b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
> index ca7286e58409..96881cd8b17b 100644
> --- a/drivers/gpu/drm/i915/gt/intel_ring_submission.c
> +++ b/drivers/gpu/drm/i915/gt/intel_ring_submission.c
> @@ -27,21 +27,15 @@
> *
> */
>
> -#include <linux/log2.h>
> -
> -#include "gem/i915_gem_context.h"
> -
> +#include "gen2_engine_cs.h"
> +#include "gen6_engine_cs.h"
> #include "gen6_ppgtt.h"
> #include "gen7_renderclear.h"
> #include "i915_drv.h"
> -#include "i915_trace.h"
> #include "intel_context.h"
> #include "intel_gt.h"
> -#include "intel_gt_irq.h"
> -#include "intel_gt_pm_irq.h"
> #include "intel_reset.h"
> #include "intel_ring.h"
> -#include "intel_workarounds.h"
> #include "shmem_utils.h"
>
> /* Rough estimate of the typical request size, performing a flush,
> @@ -49,436 +43,6 @@
> */
> #define LEGACY_REQUEST_SIZE 200
>
> -static int
> -gen2_render_ring_flush(struct i915_request *rq, u32 mode)
> -{
> - unsigned int num_store_dw;
> - u32 cmd, *cs;
> -
> - cmd = MI_FLUSH;
> - num_store_dw = 0;
> - if (mode & EMIT_INVALIDATE)
> - cmd |= MI_READ_FLUSH;
> - if (mode & EMIT_FLUSH)
> - num_store_dw = 4;
> -
> - cs = intel_ring_begin(rq, 2 + 3 * num_store_dw);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - *cs++ = cmd;
> - while (num_store_dw--) {
> - *cs++ = MI_STORE_DWORD_IMM | MI_MEM_VIRTUAL;
> - *cs++ = intel_gt_scratch_offset(rq->engine->gt,
> - INTEL_GT_SCRATCH_FIELD_DEFAULT);
> - *cs++ = 0;
> - }
> - *cs++ = MI_FLUSH | MI_NO_WRITE_FLUSH;
> -
> - intel_ring_advance(rq, cs);
> -
> - return 0;
> -}
> -
> -static int
> -gen4_render_ring_flush(struct i915_request *rq, u32 mode)
> -{
> - u32 cmd, *cs;
> - int i;
> -
> - /*
> - * read/write caches:
> - *
> - * I915_GEM_DOMAIN_RENDER is always invalidated, but is
> - * only flushed if MI_NO_WRITE_FLUSH is unset. On 965, it is
> - * also flushed at 2d versus 3d pipeline switches.
> - *
> - * read-only caches:
> - *
> - * I915_GEM_DOMAIN_SAMPLER is flushed on pre-965 if
> - * MI_READ_FLUSH is set, and is always flushed on 965.
> - *
> - * I915_GEM_DOMAIN_COMMAND may not exist?
> - *
> - * I915_GEM_DOMAIN_INSTRUCTION, which exists on 965, is
> - * invalidated when MI_EXE_FLUSH is set.
> - *
> - * I915_GEM_DOMAIN_VERTEX, which exists on 965, is
> - * invalidated with every MI_FLUSH.
> - *
> - * TLBs:
> - *
> - * On 965, TLBs associated with I915_GEM_DOMAIN_COMMAND
> - * and I915_GEM_DOMAIN_CPU in are invalidated at PTE write and
> - * I915_GEM_DOMAIN_RENDER and I915_GEM_DOMAIN_SAMPLER
> - * are flushed at any MI_FLUSH.
> - */
> -
> - cmd = MI_FLUSH;
> - if (mode & EMIT_INVALIDATE) {
> - cmd |= MI_EXE_FLUSH;
> - if (IS_G4X(rq->i915) || IS_GEN(rq->i915, 5))
> - cmd |= MI_INVALIDATE_ISP;
> - }
> -
> - i = 2;
> - if (mode & EMIT_INVALIDATE)
> - i += 20;
> -
> - cs = intel_ring_begin(rq, i);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - *cs++ = cmd;
> -
> - /*
> - * A random delay to let the CS invalidate take effect? Without this
> - * delay, the GPU relocation path fails as the CS does not see
> - * the updated contents. Just as important, if we apply the flushes
> - * to the EMIT_FLUSH branch (i.e. immediately after the relocation
> - * write and before the invalidate on the next batch), the relocations
> - * still fail. This implies that is a delay following invalidation
> - * that is required to reset the caches as opposed to a delay to
> - * ensure the memory is written.
> - */
> - if (mode & EMIT_INVALIDATE) {
> - *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
> - *cs++ = intel_gt_scratch_offset(rq->engine->gt,
> - INTEL_GT_SCRATCH_FIELD_DEFAULT) |
> - PIPE_CONTROL_GLOBAL_GTT;
> - *cs++ = 0;
> - *cs++ = 0;
> -
> - for (i = 0; i < 12; i++)
> - *cs++ = MI_FLUSH;
> -
> - *cs++ = GFX_OP_PIPE_CONTROL(4) | PIPE_CONTROL_QW_WRITE;
> - *cs++ = intel_gt_scratch_offset(rq->engine->gt,
> - INTEL_GT_SCRATCH_FIELD_DEFAULT) |
> - PIPE_CONTROL_GLOBAL_GTT;
> - *cs++ = 0;
> - *cs++ = 0;
> - }
> -
> - *cs++ = cmd;
> -
> - intel_ring_advance(rq, cs);
> -
> - return 0;
> -}
> -
> -/*
> - * 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.
> - */
> -static int
> -gen6_emit_post_sync_nonzero_flush(struct i915_request *rq)
> -{
> - u32 scratch_addr =
> - intel_gt_scratch_offset(rq->engine->gt,
> - INTEL_GT_SCRATCH_FIELD_RENDER_FLUSH);
> - u32 *cs;
> -
> - cs = intel_ring_begin(rq, 6);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - *cs++ = GFX_OP_PIPE_CONTROL(5);
> - *cs++ = PIPE_CONTROL_CS_STALL | PIPE_CONTROL_STALL_AT_SCOREBOARD;
> - *cs++ = scratch_addr | PIPE_CONTROL_GLOBAL_GTT;
> - *cs++ = 0; /* low dword */
> - *cs++ = 0; /* high dword */
> - *cs++ = MI_NOOP;
> - intel_ring_advance(rq, cs);
> -
> - cs = intel_ring_begin(rq, 6);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - *cs++ = GFX_OP_PIPE_CONTROL(5);
> - *cs++ = PIPE_CONTROL_QW_WRITE;
> - *cs++ = scratch_addr | PIPE_CONTROL_GLOBAL_GTT;
> - *cs++ = 0;
> - *cs++ = 0;
> - *cs++ = MI_NOOP;
> - intel_ring_advance(rq, cs);
> -
> - return 0;
> -}
> -
> -static int
> -gen6_render_ring_flush(struct i915_request *rq, u32 mode)
> -{
> - u32 scratch_addr =
> - intel_gt_scratch_offset(rq->engine->gt,
> - INTEL_GT_SCRATCH_FIELD_RENDER_FLUSH);
> - u32 *cs, flags = 0;
> - int ret;
> -
> - /* Force SNB workarounds for PIPE_CONTROL flushes */
> - ret = gen6_emit_post_sync_nonzero_flush(rq);
> - if (ret)
> - return ret;
> -
> - /* Just flush everything. Experiments have shown that reducing the
> - * number of bits based on the write domains has little performance
> - * impact.
> - */
> - if (mode & EMIT_FLUSH) {
> - flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
> - flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
> - /*
> - * Ensure that any following seqno writes only happen
> - * when the render cache is indeed flushed.
> - */
> - flags |= PIPE_CONTROL_CS_STALL;
> - }
> - if (mode & EMIT_INVALIDATE) {
> - flags |= PIPE_CONTROL_TLB_INVALIDATE;
> - flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
> - flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
> - flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
> - flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
> - flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
> - /*
> - * TLB invalidate requires a post-sync write.
> - */
> - flags |= PIPE_CONTROL_QW_WRITE | PIPE_CONTROL_CS_STALL;
> - }
> -
> - cs = intel_ring_begin(rq, 4);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - *cs++ = GFX_OP_PIPE_CONTROL(4);
> - *cs++ = flags;
> - *cs++ = scratch_addr | PIPE_CONTROL_GLOBAL_GTT;
> - *cs++ = 0;
> - intel_ring_advance(rq, cs);
> -
> - return 0;
> -}
> -
> -static u32 *gen6_rcs_emit_breadcrumb(struct i915_request *rq, u32 *cs)
> -{
> - /* First we do the gen6_emit_post_sync_nonzero_flush w/a */
> - *cs++ = GFX_OP_PIPE_CONTROL(4);
> - *cs++ = PIPE_CONTROL_CS_STALL | PIPE_CONTROL_STALL_AT_SCOREBOARD;
> - *cs++ = 0;
> - *cs++ = 0;
> -
> - *cs++ = GFX_OP_PIPE_CONTROL(4);
> - *cs++ = PIPE_CONTROL_QW_WRITE;
> - *cs++ = intel_gt_scratch_offset(rq->engine->gt,
> - INTEL_GT_SCRATCH_FIELD_DEFAULT) |
> - PIPE_CONTROL_GLOBAL_GTT;
> - *cs++ = 0;
> -
> - /* Finally we can flush and with it emit the breadcrumb */
> - *cs++ = GFX_OP_PIPE_CONTROL(4);
> - *cs++ = (PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH |
> - PIPE_CONTROL_DEPTH_CACHE_FLUSH |
> - PIPE_CONTROL_DC_FLUSH_ENABLE |
> - PIPE_CONTROL_QW_WRITE |
> - PIPE_CONTROL_CS_STALL);
> - *cs++ = i915_request_active_timeline(rq)->hwsp_offset |
> - PIPE_CONTROL_GLOBAL_GTT;
> - *cs++ = rq->fence.seqno;
> -
> - *cs++ = MI_USER_INTERRUPT;
> - *cs++ = MI_NOOP;
> -
> - rq->tail = intel_ring_offset(rq, cs);
> - assert_ring_tail_valid(rq->ring, rq->tail);
> -
> - return cs;
> -}
> -
> -static int
> -gen7_render_ring_cs_stall_wa(struct i915_request *rq)
> -{
> - u32 *cs;
> -
> - cs = intel_ring_begin(rq, 4);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - *cs++ = GFX_OP_PIPE_CONTROL(4);
> - *cs++ = PIPE_CONTROL_CS_STALL | PIPE_CONTROL_STALL_AT_SCOREBOARD;
> - *cs++ = 0;
> - *cs++ = 0;
> - intel_ring_advance(rq, cs);
> -
> - return 0;
> -}
> -
> -static int
> -gen7_render_ring_flush(struct i915_request *rq, u32 mode)
> -{
> - u32 scratch_addr =
> - intel_gt_scratch_offset(rq->engine->gt,
> - INTEL_GT_SCRATCH_FIELD_RENDER_FLUSH);
> - u32 *cs, flags = 0;
> -
> - /*
> - * Ensure that any following seqno writes only happen when the render
> - * cache is indeed flushed.
> - *
> - * Workaround: 4th PIPE_CONTROL command (except the ones with only
> - * read-cache invalidate bits set) must have the CS_STALL bit set. We
> - * don't try to be clever and just set it unconditionally.
> - */
> - flags |= PIPE_CONTROL_CS_STALL;
> -
> - /*
> - * CS_STALL suggests at least a post-sync write.
> - */
> - flags |= PIPE_CONTROL_QW_WRITE;
> - flags |= PIPE_CONTROL_GLOBAL_GTT_IVB;
> -
> - /* Just flush everything. Experiments have shown that reducing the
> - * number of bits based on the write domains has little performance
> - * impact.
> - */
> - if (mode & EMIT_FLUSH) {
> - flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH;
> - flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH;
> - flags |= PIPE_CONTROL_DC_FLUSH_ENABLE;
> - flags |= PIPE_CONTROL_FLUSH_ENABLE;
> - }
> - if (mode & EMIT_INVALIDATE) {
> - flags |= PIPE_CONTROL_TLB_INVALIDATE;
> - flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE;
> - flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE;
> - flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE;
> - flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE;
> - flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE;
> - flags |= PIPE_CONTROL_MEDIA_STATE_CLEAR;
> -
> - /* Workaround: we must issue a pipe_control with CS-stall bit
> - * set before a pipe_control command that has the state cache
> - * invalidate bit set. */
> - gen7_render_ring_cs_stall_wa(rq);
> - }
> -
> - cs = intel_ring_begin(rq, 4);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - *cs++ = GFX_OP_PIPE_CONTROL(4);
> - *cs++ = flags;
> - *cs++ = scratch_addr;
> - *cs++ = 0;
> - intel_ring_advance(rq, cs);
> -
> - return 0;
> -}
> -
> -static u32 *gen7_rcs_emit_breadcrumb(struct i915_request *rq, u32 *cs)
> -{
> - *cs++ = GFX_OP_PIPE_CONTROL(4);
> - *cs++ = (PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH |
> - PIPE_CONTROL_DEPTH_CACHE_FLUSH |
> - PIPE_CONTROL_DC_FLUSH_ENABLE |
> - PIPE_CONTROL_FLUSH_ENABLE |
> - PIPE_CONTROL_QW_WRITE |
> - PIPE_CONTROL_GLOBAL_GTT_IVB |
> - PIPE_CONTROL_CS_STALL);
> - *cs++ = i915_request_active_timeline(rq)->hwsp_offset;
> - *cs++ = rq->fence.seqno;
> -
> - *cs++ = MI_USER_INTERRUPT;
> - *cs++ = MI_NOOP;
> -
> - rq->tail = intel_ring_offset(rq, cs);
> - assert_ring_tail_valid(rq->ring, rq->tail);
> -
> - return cs;
> -}
> -
> -static u32 *gen6_xcs_emit_breadcrumb(struct i915_request *rq, u32 *cs)
> -{
> - GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);
> - GEM_BUG_ON(offset_in_page(i915_request_active_timeline(rq)->hwsp_offset) != I915_GEM_HWS_SEQNO_ADDR);
> -
> - *cs++ = MI_FLUSH_DW | MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX;
> - *cs++ = I915_GEM_HWS_SEQNO_ADDR | MI_FLUSH_DW_USE_GTT;
> - *cs++ = rq->fence.seqno;
> -
> - *cs++ = MI_USER_INTERRUPT;
> -
> - rq->tail = intel_ring_offset(rq, cs);
> - assert_ring_tail_valid(rq->ring, rq->tail);
> -
> - return cs;
> -}
> -
> -#define GEN7_XCS_WA 32
> -static u32 *gen7_xcs_emit_breadcrumb(struct i915_request *rq, u32 *cs)
> -{
> - int i;
> -
> - GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);
> - GEM_BUG_ON(offset_in_page(i915_request_active_timeline(rq)->hwsp_offset) != I915_GEM_HWS_SEQNO_ADDR);
> -
> - *cs++ = MI_FLUSH_DW | MI_INVALIDATE_TLB |
> - MI_FLUSH_DW_OP_STOREDW | MI_FLUSH_DW_STORE_INDEX;
> - *cs++ = I915_GEM_HWS_SEQNO_ADDR | MI_FLUSH_DW_USE_GTT;
> - *cs++ = rq->fence.seqno;
> -
> - for (i = 0; i < GEN7_XCS_WA; i++) {
> - *cs++ = MI_STORE_DWORD_INDEX;
> - *cs++ = I915_GEM_HWS_SEQNO_ADDR;
> - *cs++ = rq->fence.seqno;
> - }
> -
> - *cs++ = MI_FLUSH_DW;
> - *cs++ = 0;
> - *cs++ = 0;
> -
> - *cs++ = MI_USER_INTERRUPT;
> - *cs++ = MI_NOOP;
> -
> - rq->tail = intel_ring_offset(rq, cs);
> - assert_ring_tail_valid(rq->ring, rq->tail);
> -
> - return cs;
> -}
> -#undef GEN7_XCS_WA
> -
> static void set_hwstam(struct intel_engine_cs *engine, u32 mask)
> {
> /*
> @@ -918,255 +482,6 @@ static void i9xx_submit_request(struct i915_request *request)
> intel_ring_set_tail(request->ring, request->tail));
> }
>
> -static u32 *i9xx_emit_breadcrumb(struct i915_request *rq, u32 *cs)
> -{
> - GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);
> - GEM_BUG_ON(offset_in_page(i915_request_active_timeline(rq)->hwsp_offset) != I915_GEM_HWS_SEQNO_ADDR);
> -
> - *cs++ = MI_FLUSH;
> -
> - *cs++ = MI_STORE_DWORD_INDEX;
> - *cs++ = I915_GEM_HWS_SEQNO_ADDR;
> - *cs++ = rq->fence.seqno;
> -
> - *cs++ = MI_USER_INTERRUPT;
> - *cs++ = MI_NOOP;
> -
> - rq->tail = intel_ring_offset(rq, cs);
> - assert_ring_tail_valid(rq->ring, rq->tail);
> -
> - return cs;
> -}
> -
> -#define GEN5_WA_STORES 8 /* must be at least 1! */
> -static u32 *gen5_emit_breadcrumb(struct i915_request *rq, u32 *cs)
> -{
> - int i;
> -
> - GEM_BUG_ON(i915_request_active_timeline(rq)->hwsp_ggtt != rq->engine->status_page.vma);
> - GEM_BUG_ON(offset_in_page(i915_request_active_timeline(rq)->hwsp_offset) != I915_GEM_HWS_SEQNO_ADDR);
> -
> - *cs++ = MI_FLUSH;
> -
> - BUILD_BUG_ON(GEN5_WA_STORES < 1);
> - for (i = 0; i < GEN5_WA_STORES; i++) {
> - *cs++ = MI_STORE_DWORD_INDEX;
> - *cs++ = I915_GEM_HWS_SEQNO_ADDR;
> - *cs++ = rq->fence.seqno;
> - }
> -
> - *cs++ = MI_USER_INTERRUPT;
> -
> - rq->tail = intel_ring_offset(rq, cs);
> - assert_ring_tail_valid(rq->ring, rq->tail);
> -
> - return cs;
> -}
> -#undef GEN5_WA_STORES
> -
> -static void
> -gen5_irq_enable(struct intel_engine_cs *engine)
> -{
> - gen5_gt_enable_irq(engine->gt, engine->irq_enable_mask);
> -}
> -
> -static void
> -gen5_irq_disable(struct intel_engine_cs *engine)
> -{
> - gen5_gt_disable_irq(engine->gt, engine->irq_enable_mask);
> -}
> -
> -static void
> -i9xx_irq_enable(struct intel_engine_cs *engine)
> -{
> - engine->i915->irq_mask &= ~engine->irq_enable_mask;
> - intel_uncore_write(engine->uncore, GEN2_IMR, engine->i915->irq_mask);
> - intel_uncore_posting_read_fw(engine->uncore, GEN2_IMR);
> -}
> -
> -static void
> -i9xx_irq_disable(struct intel_engine_cs *engine)
> -{
> - engine->i915->irq_mask |= engine->irq_enable_mask;
> - intel_uncore_write(engine->uncore, GEN2_IMR, engine->i915->irq_mask);
> -}
> -
> -static void
> -i8xx_irq_enable(struct intel_engine_cs *engine)
> -{
> - struct drm_i915_private *i915 = engine->i915;
> -
> - i915->irq_mask &= ~engine->irq_enable_mask;
> - intel_uncore_write16(&i915->uncore, GEN2_IMR, i915->irq_mask);
> - ENGINE_POSTING_READ16(engine, RING_IMR);
> -}
> -
> -static void
> -i8xx_irq_disable(struct intel_engine_cs *engine)
> -{
> - struct drm_i915_private *i915 = engine->i915;
> -
> - i915->irq_mask |= engine->irq_enable_mask;
> - intel_uncore_write16(&i915->uncore, GEN2_IMR, i915->irq_mask);
> -}
> -
> -static int
> -bsd_ring_flush(struct i915_request *rq, u32 mode)
> -{
> - u32 *cs;
> -
> - cs = intel_ring_begin(rq, 2);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - *cs++ = MI_FLUSH;
> - *cs++ = MI_NOOP;
> - intel_ring_advance(rq, cs);
> - return 0;
> -}
> -
> -static void
> -gen6_irq_enable(struct intel_engine_cs *engine)
> -{
> - ENGINE_WRITE(engine, RING_IMR,
> - ~(engine->irq_enable_mask | engine->irq_keep_mask));
> -
> - /* Flush/delay to ensure the RING_IMR is active before the GT IMR */
> - ENGINE_POSTING_READ(engine, RING_IMR);
> -
> - gen5_gt_enable_irq(engine->gt, engine->irq_enable_mask);
> -}
> -
> -static void
> -gen6_irq_disable(struct intel_engine_cs *engine)
> -{
> - ENGINE_WRITE(engine, RING_IMR, ~engine->irq_keep_mask);
> - gen5_gt_disable_irq(engine->gt, engine->irq_enable_mask);
> -}
> -
> -static void
> -hsw_vebox_irq_enable(struct intel_engine_cs *engine)
> -{
> - ENGINE_WRITE(engine, RING_IMR, ~engine->irq_enable_mask);
> -
> - /* Flush/delay to ensure the RING_IMR is active before the GT IMR */
> - ENGINE_POSTING_READ(engine, RING_IMR);
> -
> - gen6_gt_pm_unmask_irq(engine->gt, engine->irq_enable_mask);
> -}
> -
> -static void
> -hsw_vebox_irq_disable(struct intel_engine_cs *engine)
> -{
> - ENGINE_WRITE(engine, RING_IMR, ~0);
> - gen6_gt_pm_mask_irq(engine->gt, engine->irq_enable_mask);
> -}
> -
> -static int
> -i965_emit_bb_start(struct i915_request *rq,
> - u64 offset, u32 length,
> - unsigned int dispatch_flags)
> -{
> - u32 *cs;
> -
> - cs = intel_ring_begin(rq, 2);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - *cs++ = MI_BATCH_BUFFER_START | MI_BATCH_GTT | (dispatch_flags &
> - I915_DISPATCH_SECURE ? 0 : MI_BATCH_NON_SECURE_I965);
> - *cs++ = offset;
> - intel_ring_advance(rq, cs);
> -
> - return 0;
> -}
> -
> -/* Just userspace ABI convention to limit the wa batch bo to a resonable size */
> -#define I830_BATCH_LIMIT SZ_256K
> -#define I830_TLB_ENTRIES (2)
> -#define I830_WA_SIZE max(I830_TLB_ENTRIES*4096, I830_BATCH_LIMIT)
> -static int
> -i830_emit_bb_start(struct i915_request *rq,
> - u64 offset, u32 len,
> - unsigned int dispatch_flags)
> -{
> - u32 *cs, cs_offset =
> - intel_gt_scratch_offset(rq->engine->gt,
> - INTEL_GT_SCRATCH_FIELD_DEFAULT);
> -
> - GEM_BUG_ON(rq->engine->gt->scratch->size < I830_WA_SIZE);
> -
> - cs = intel_ring_begin(rq, 6);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - /* Evict the invalid PTE TLBs */
> - *cs++ = COLOR_BLT_CMD | BLT_WRITE_RGBA;
> - *cs++ = BLT_DEPTH_32 | BLT_ROP_COLOR_COPY | 4096;
> - *cs++ = I830_TLB_ENTRIES << 16 | 4; /* load each page */
> - *cs++ = cs_offset;
> - *cs++ = 0xdeadbeef;
> - *cs++ = MI_NOOP;
> - intel_ring_advance(rq, cs);
> -
> - if ((dispatch_flags & I915_DISPATCH_PINNED) == 0) {
> - if (len > I830_BATCH_LIMIT)
> - return -ENOSPC;
> -
> - cs = intel_ring_begin(rq, 6 + 2);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - /* Blit the batch (which has now all relocs applied) to the
> - * stable batch scratch bo area (so that the CS never
> - * stumbles over its tlb invalidation bug) ...
> - */
> - *cs++ = SRC_COPY_BLT_CMD | BLT_WRITE_RGBA | (6 - 2);
> - *cs++ = BLT_DEPTH_32 | BLT_ROP_SRC_COPY | 4096;
> - *cs++ = DIV_ROUND_UP(len, 4096) << 16 | 4096;
> - *cs++ = cs_offset;
> - *cs++ = 4096;
> - *cs++ = offset;
> -
> - *cs++ = MI_FLUSH;
> - *cs++ = MI_NOOP;
> - intel_ring_advance(rq, cs);
> -
> - /* ... and execute it. */
> - offset = cs_offset;
> - }
> -
> - cs = intel_ring_begin(rq, 2);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - *cs++ = MI_BATCH_BUFFER_START | MI_BATCH_GTT;
> - *cs++ = offset | (dispatch_flags & I915_DISPATCH_SECURE ? 0 :
> - MI_BATCH_NON_SECURE);
> - intel_ring_advance(rq, cs);
> -
> - return 0;
> -}
> -
> -static int
> -i915_emit_bb_start(struct i915_request *rq,
> - u64 offset, u32 len,
> - unsigned int dispatch_flags)
> -{
> - u32 *cs;
> -
> - cs = intel_ring_begin(rq, 2);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - *cs++ = MI_BATCH_BUFFER_START | MI_BATCH_GTT;
> - *cs++ = offset | (dispatch_flags & I915_DISPATCH_SECURE ? 0 :
> - MI_BATCH_NON_SECURE);
> - intel_ring_advance(rq, cs);
> -
> - return 0;
> -}
> -
> static void __ring_context_fini(struct intel_context *ce)
> {
> i915_vma_put(ce->state);
> @@ -1704,99 +1019,6 @@ static void gen6_bsd_submit_request(struct i915_request *request)
> intel_uncore_forcewake_put(uncore, FORCEWAKE_ALL);
> }
>
> -static int mi_flush_dw(struct i915_request *rq, u32 flags)
> -{
> - u32 cmd, *cs;
> -
> - cs = intel_ring_begin(rq, 4);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - cmd = MI_FLUSH_DW;
> -
> - /*
> - * We always require a command barrier so that subsequent
> - * commands, such as breadcrumb interrupts, are strictly ordered
> - * wrt the contents of the write cache being flushed to memory
> - * (and thus being coherent from the CPU).
> - */
> - cmd |= MI_FLUSH_DW_STORE_INDEX | MI_FLUSH_DW_OP_STOREDW;
> -
> - /*
> - * Bspec vol 1c.3 - blitter engine command streamer:
> - * "If ENABLED, all TLBs will be invalidated once the flush
> - * operation is complete. This bit is only valid when the
> - * Post-Sync Operation field is a value of 1h or 3h."
> - */
> - cmd |= flags;
> -
> - *cs++ = cmd;
> - *cs++ = I915_GEM_HWS_SCRATCH_ADDR | MI_FLUSH_DW_USE_GTT;
> - *cs++ = 0;
> - *cs++ = MI_NOOP;
> -
> - intel_ring_advance(rq, cs);
> -
> - return 0;
> -}
> -
> -static int gen6_flush_dw(struct i915_request *rq, u32 mode, u32 invflags)
> -{
> - return mi_flush_dw(rq, mode & EMIT_INVALIDATE ? invflags : 0);
> -}
> -
> -static int gen6_bsd_ring_flush(struct i915_request *rq, u32 mode)
> -{
> - return gen6_flush_dw(rq, mode, MI_INVALIDATE_TLB | MI_INVALIDATE_BSD);
> -}
> -
> -static int
> -hsw_emit_bb_start(struct i915_request *rq,
> - u64 offset, u32 len,
> - unsigned int dispatch_flags)
> -{
> - u32 *cs;
> -
> - cs = intel_ring_begin(rq, 2);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - *cs++ = MI_BATCH_BUFFER_START | (dispatch_flags & I915_DISPATCH_SECURE ?
> - 0 : MI_BATCH_PPGTT_HSW | MI_BATCH_NON_SECURE_HSW);
> - /* bit0-7 is the length on GEN6+ */
> - *cs++ = offset;
> - intel_ring_advance(rq, cs);
> -
> - return 0;
> -}
> -
> -static int
> -gen6_emit_bb_start(struct i915_request *rq,
> - u64 offset, u32 len,
> - unsigned int dispatch_flags)
> -{
> - u32 *cs;
> -
> - cs = intel_ring_begin(rq, 2);
> - if (IS_ERR(cs))
> - return PTR_ERR(cs);
> -
> - *cs++ = MI_BATCH_BUFFER_START | (dispatch_flags & I915_DISPATCH_SECURE ?
> - 0 : MI_BATCH_NON_SECURE_I965);
> - /* bit0-7 is the length on GEN6+ */
> - *cs++ = offset;
> - intel_ring_advance(rq, cs);
> -
> - return 0;
> -}
> -
> -/* Blitter support (SandyBridge+) */
> -
> -static int gen6_ring_flush(struct i915_request *rq, u32 mode)
> -{
> - return gen6_flush_dw(rq, mode, MI_INVALIDATE_TLB);
> -}
> -
> static void i9xx_set_default_submission(struct intel_engine_cs *engine)
> {
> engine->submit_request = i9xx_submit_request;
> @@ -1843,11 +1065,11 @@ static void setup_irq(struct intel_engine_cs *engine)
> engine->irq_enable = gen5_irq_enable;
> engine->irq_disable = gen5_irq_disable;
> } else if (INTEL_GEN(i915) >= 3) {
> - engine->irq_enable = i9xx_irq_enable;
> - engine->irq_disable = i9xx_irq_disable;
> + engine->irq_enable = gen3_irq_enable;
> + engine->irq_disable = gen3_irq_disable;
> } else {
> - engine->irq_enable = i8xx_irq_enable;
> - engine->irq_disable = i8xx_irq_disable;
> + engine->irq_enable = gen2_irq_enable;
> + engine->irq_disable = gen2_irq_disable;
> }
> }
>
> @@ -1874,7 +1096,7 @@ static void setup_common(struct intel_engine_cs *engine)
> * equivalent to our next initial bread so we can elide
> * engine->emit_init_breadcrumb().
> */
> - engine->emit_fini_breadcrumb = i9xx_emit_breadcrumb;
> + engine->emit_fini_breadcrumb = gen3_emit_breadcrumb;
> if (IS_GEN(i915, 5))
> engine->emit_fini_breadcrumb = gen5_emit_breadcrumb;
>
> @@ -1883,11 +1105,11 @@ static void setup_common(struct intel_engine_cs *engine)
> if (INTEL_GEN(i915) >= 6)
> engine->emit_bb_start = gen6_emit_bb_start;
> else if (INTEL_GEN(i915) >= 4)
> - engine->emit_bb_start = i965_emit_bb_start;
> + engine->emit_bb_start = gen4_emit_bb_start;
> else if (IS_I830(i915) || IS_I845G(i915))
> engine->emit_bb_start = i830_emit_bb_start;
> else
> - engine->emit_bb_start = i915_emit_bb_start;
> + engine->emit_bb_start = gen3_emit_bb_start;
> }
>
> static void setup_rcs(struct intel_engine_cs *engine)
> @@ -1900,18 +1122,18 @@ static void setup_rcs(struct intel_engine_cs *engine)
> engine->irq_enable_mask = GT_RENDER_USER_INTERRUPT;
>
> if (INTEL_GEN(i915) >= 7) {
> - engine->emit_flush = gen7_render_ring_flush;
> - engine->emit_fini_breadcrumb = gen7_rcs_emit_breadcrumb;
> + engine->emit_flush = gen7_emit_flush_rcs;
> + engine->emit_fini_breadcrumb = gen7_emit_breadcrumb_rcs;
> } else if (IS_GEN(i915, 6)) {
> - engine->emit_flush = gen6_render_ring_flush;
> - engine->emit_fini_breadcrumb = gen6_rcs_emit_breadcrumb;
> + engine->emit_flush = gen6_emit_flush_rcs;
> + engine->emit_fini_breadcrumb = gen6_emit_breadcrumb_rcs;
> } else if (IS_GEN(i915, 5)) {
> - engine->emit_flush = gen4_render_ring_flush;
> + engine->emit_flush = gen4_emit_flush_rcs;
> } else {
> if (INTEL_GEN(i915) < 4)
> - engine->emit_flush = gen2_render_ring_flush;
> + engine->emit_flush = gen2_emit_flush;
> else
> - engine->emit_flush = gen4_render_ring_flush;
> + engine->emit_flush = gen4_emit_flush_rcs;
> engine->irq_enable_mask = I915_USER_INTERRUPT;
> }
>
> @@ -1929,15 +1151,15 @@ static void setup_vcs(struct intel_engine_cs *engine)
> /* gen6 bsd needs a special wa for tail updates */
> if (IS_GEN(i915, 6))
> engine->set_default_submission = gen6_bsd_set_default_submission;
> - engine->emit_flush = gen6_bsd_ring_flush;
> + engine->emit_flush = gen6_emit_flush_vcs;
> engine->irq_enable_mask = GT_BSD_USER_INTERRUPT;
>
> if (IS_GEN(i915, 6))
> - engine->emit_fini_breadcrumb = gen6_xcs_emit_breadcrumb;
> + engine->emit_fini_breadcrumb = gen6_emit_breadcrumb_xcs;
> else
> - engine->emit_fini_breadcrumb = gen7_xcs_emit_breadcrumb;
> + engine->emit_fini_breadcrumb = gen7_emit_breadcrumb_xcs;
> } else {
> - engine->emit_flush = bsd_ring_flush;
> + engine->emit_flush = gen4_emit_flush_vcs;
> if (IS_GEN(i915, 5))
> engine->irq_enable_mask = ILK_BSD_USER_INTERRUPT;
> else
> @@ -1949,13 +1171,13 @@ static void setup_bcs(struct intel_engine_cs *engine)
> {
> struct drm_i915_private *i915 = engine->i915;
>
> - engine->emit_flush = gen6_ring_flush;
> + engine->emit_flush = gen6_emit_flush_xcs;
> engine->irq_enable_mask = GT_BLT_USER_INTERRUPT;
>
> if (IS_GEN(i915, 6))
> - engine->emit_fini_breadcrumb = gen6_xcs_emit_breadcrumb;
> + engine->emit_fini_breadcrumb = gen6_emit_breadcrumb_xcs;
> else
> - engine->emit_fini_breadcrumb = gen7_xcs_emit_breadcrumb;
> + engine->emit_fini_breadcrumb = gen7_emit_breadcrumb_xcs;
> }
>
> static void setup_vecs(struct intel_engine_cs *engine)
> @@ -1964,12 +1186,12 @@ static void setup_vecs(struct intel_engine_cs *engine)
>
> GEM_BUG_ON(INTEL_GEN(i915) < 7);
>
> - engine->emit_flush = gen6_ring_flush;
> + engine->emit_flush = gen6_emit_flush_xcs;
> engine->irq_enable_mask = PM_VEBOX_USER_INTERRUPT;
> - engine->irq_enable = hsw_vebox_irq_enable;
> - engine->irq_disable = hsw_vebox_irq_disable;
> + engine->irq_enable = hsw_irq_enable_vecs;
> + engine->irq_disable = hsw_irq_disable_vecs;
>
> - engine->emit_fini_breadcrumb = gen7_xcs_emit_breadcrumb;
> + engine->emit_fini_breadcrumb = gen7_emit_breadcrumb_xcs;
> }
>
> static int gen7_ctx_switch_bb_setup(struct intel_engine_cs * const engine,
> --
> 2.20.1
>
> _______________________________________________
> Intel-gfx mailing list
> Intel-gfx at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/intel-gfx
More information about the Intel-gfx
mailing list