162306a36Sopenharmony_ci// SPDX-License-Identifier: MIT 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright © 2014 Intel Corporation 462306a36Sopenharmony_ci */ 562306a36Sopenharmony_ci 662306a36Sopenharmony_ci#include "gem/i915_gem_lmem.h" 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#include "gen8_engine_cs.h" 962306a36Sopenharmony_ci#include "i915_drv.h" 1062306a36Sopenharmony_ci#include "i915_perf.h" 1162306a36Sopenharmony_ci#include "i915_reg.h" 1262306a36Sopenharmony_ci#include "intel_context.h" 1362306a36Sopenharmony_ci#include "intel_engine.h" 1462306a36Sopenharmony_ci#include "intel_engine_regs.h" 1562306a36Sopenharmony_ci#include "intel_gpu_commands.h" 1662306a36Sopenharmony_ci#include "intel_gt.h" 1762306a36Sopenharmony_ci#include "intel_gt_regs.h" 1862306a36Sopenharmony_ci#include "intel_lrc.h" 1962306a36Sopenharmony_ci#include "intel_lrc_reg.h" 2062306a36Sopenharmony_ci#include "intel_ring.h" 2162306a36Sopenharmony_ci#include "shmem_utils.h" 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci/* 2462306a36Sopenharmony_ci * The per-platform tables are u8-encoded in @data. Decode @data and set the 2562306a36Sopenharmony_ci * addresses' offset and commands in @regs. The following encoding is used 2662306a36Sopenharmony_ci * for each byte. There are 2 steps: decoding commands and decoding addresses. 2762306a36Sopenharmony_ci * 2862306a36Sopenharmony_ci * Commands: 2962306a36Sopenharmony_ci * [7]: create NOPs - number of NOPs are set in lower bits 3062306a36Sopenharmony_ci * [6]: When creating MI_LOAD_REGISTER_IMM command, allow to set 3162306a36Sopenharmony_ci * MI_LRI_FORCE_POSTED 3262306a36Sopenharmony_ci * [5:0]: Number of NOPs or registers to set values to in case of 3362306a36Sopenharmony_ci * MI_LOAD_REGISTER_IMM 3462306a36Sopenharmony_ci * 3562306a36Sopenharmony_ci * Addresses: these are decoded after a MI_LOAD_REGISTER_IMM command by "count" 3662306a36Sopenharmony_ci * number of registers. They are set by using the REG/REG16 macros: the former 3762306a36Sopenharmony_ci * is used for offsets smaller than 0x200 while the latter is for values bigger 3862306a36Sopenharmony_ci * than that. Those macros already set all the bits documented below correctly: 3962306a36Sopenharmony_ci * 4062306a36Sopenharmony_ci * [7]: When a register offset needs more than 6 bits, use additional bytes, to 4162306a36Sopenharmony_ci * follow, for the lower bits 4262306a36Sopenharmony_ci * [6:0]: Register offset, without considering the engine base. 4362306a36Sopenharmony_ci * 4462306a36Sopenharmony_ci * This function only tweaks the commands and register offsets. Values are not 4562306a36Sopenharmony_ci * filled out. 4662306a36Sopenharmony_ci */ 4762306a36Sopenharmony_cistatic void set_offsets(u32 *regs, 4862306a36Sopenharmony_ci const u8 *data, 4962306a36Sopenharmony_ci const struct intel_engine_cs *engine, 5062306a36Sopenharmony_ci bool close) 5162306a36Sopenharmony_ci#define NOP(x) (BIT(7) | (x)) 5262306a36Sopenharmony_ci#define LRI(count, flags) ((flags) << 6 | (count) | BUILD_BUG_ON_ZERO(count >= BIT(6))) 5362306a36Sopenharmony_ci#define POSTED BIT(0) 5462306a36Sopenharmony_ci#define REG(x) (((x) >> 2) | BUILD_BUG_ON_ZERO(x >= 0x200)) 5562306a36Sopenharmony_ci#define REG16(x) \ 5662306a36Sopenharmony_ci (((x) >> 9) | BIT(7) | BUILD_BUG_ON_ZERO(x >= 0x10000)), \ 5762306a36Sopenharmony_ci (((x) >> 2) & 0x7f) 5862306a36Sopenharmony_ci#define END 0 5962306a36Sopenharmony_ci{ 6062306a36Sopenharmony_ci const u32 base = engine->mmio_base; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci while (*data) { 6362306a36Sopenharmony_ci u8 count, flags; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci if (*data & BIT(7)) { /* skip */ 6662306a36Sopenharmony_ci count = *data++ & ~BIT(7); 6762306a36Sopenharmony_ci regs += count; 6862306a36Sopenharmony_ci continue; 6962306a36Sopenharmony_ci } 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci count = *data & 0x3f; 7262306a36Sopenharmony_ci flags = *data >> 6; 7362306a36Sopenharmony_ci data++; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci *regs = MI_LOAD_REGISTER_IMM(count); 7662306a36Sopenharmony_ci if (flags & POSTED) 7762306a36Sopenharmony_ci *regs |= MI_LRI_FORCE_POSTED; 7862306a36Sopenharmony_ci if (GRAPHICS_VER(engine->i915) >= 11) 7962306a36Sopenharmony_ci *regs |= MI_LRI_LRM_CS_MMIO; 8062306a36Sopenharmony_ci regs++; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci GEM_BUG_ON(!count); 8362306a36Sopenharmony_ci do { 8462306a36Sopenharmony_ci u32 offset = 0; 8562306a36Sopenharmony_ci u8 v; 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci do { 8862306a36Sopenharmony_ci v = *data++; 8962306a36Sopenharmony_ci offset <<= 7; 9062306a36Sopenharmony_ci offset |= v & ~BIT(7); 9162306a36Sopenharmony_ci } while (v & BIT(7)); 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci regs[0] = base + (offset << 2); 9462306a36Sopenharmony_ci regs += 2; 9562306a36Sopenharmony_ci } while (--count); 9662306a36Sopenharmony_ci } 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci if (close) { 9962306a36Sopenharmony_ci /* Close the batch; used mainly by live_lrc_layout() */ 10062306a36Sopenharmony_ci *regs = MI_BATCH_BUFFER_END; 10162306a36Sopenharmony_ci if (GRAPHICS_VER(engine->i915) >= 11) 10262306a36Sopenharmony_ci *regs |= BIT(0); 10362306a36Sopenharmony_ci } 10462306a36Sopenharmony_ci} 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_cistatic const u8 gen8_xcs_offsets[] = { 10762306a36Sopenharmony_ci NOP(1), 10862306a36Sopenharmony_ci LRI(11, 0), 10962306a36Sopenharmony_ci REG16(0x244), 11062306a36Sopenharmony_ci REG(0x034), 11162306a36Sopenharmony_ci REG(0x030), 11262306a36Sopenharmony_ci REG(0x038), 11362306a36Sopenharmony_ci REG(0x03c), 11462306a36Sopenharmony_ci REG(0x168), 11562306a36Sopenharmony_ci REG(0x140), 11662306a36Sopenharmony_ci REG(0x110), 11762306a36Sopenharmony_ci REG(0x11c), 11862306a36Sopenharmony_ci REG(0x114), 11962306a36Sopenharmony_ci REG(0x118), 12062306a36Sopenharmony_ci 12162306a36Sopenharmony_ci NOP(9), 12262306a36Sopenharmony_ci LRI(9, 0), 12362306a36Sopenharmony_ci REG16(0x3a8), 12462306a36Sopenharmony_ci REG16(0x28c), 12562306a36Sopenharmony_ci REG16(0x288), 12662306a36Sopenharmony_ci REG16(0x284), 12762306a36Sopenharmony_ci REG16(0x280), 12862306a36Sopenharmony_ci REG16(0x27c), 12962306a36Sopenharmony_ci REG16(0x278), 13062306a36Sopenharmony_ci REG16(0x274), 13162306a36Sopenharmony_ci REG16(0x270), 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci NOP(13), 13462306a36Sopenharmony_ci LRI(2, 0), 13562306a36Sopenharmony_ci REG16(0x200), 13662306a36Sopenharmony_ci REG(0x028), 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci END 13962306a36Sopenharmony_ci}; 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_cistatic const u8 gen9_xcs_offsets[] = { 14262306a36Sopenharmony_ci NOP(1), 14362306a36Sopenharmony_ci LRI(14, POSTED), 14462306a36Sopenharmony_ci REG16(0x244), 14562306a36Sopenharmony_ci REG(0x034), 14662306a36Sopenharmony_ci REG(0x030), 14762306a36Sopenharmony_ci REG(0x038), 14862306a36Sopenharmony_ci REG(0x03c), 14962306a36Sopenharmony_ci REG(0x168), 15062306a36Sopenharmony_ci REG(0x140), 15162306a36Sopenharmony_ci REG(0x110), 15262306a36Sopenharmony_ci REG(0x11c), 15362306a36Sopenharmony_ci REG(0x114), 15462306a36Sopenharmony_ci REG(0x118), 15562306a36Sopenharmony_ci REG(0x1c0), 15662306a36Sopenharmony_ci REG(0x1c4), 15762306a36Sopenharmony_ci REG(0x1c8), 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci NOP(3), 16062306a36Sopenharmony_ci LRI(9, POSTED), 16162306a36Sopenharmony_ci REG16(0x3a8), 16262306a36Sopenharmony_ci REG16(0x28c), 16362306a36Sopenharmony_ci REG16(0x288), 16462306a36Sopenharmony_ci REG16(0x284), 16562306a36Sopenharmony_ci REG16(0x280), 16662306a36Sopenharmony_ci REG16(0x27c), 16762306a36Sopenharmony_ci REG16(0x278), 16862306a36Sopenharmony_ci REG16(0x274), 16962306a36Sopenharmony_ci REG16(0x270), 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci NOP(13), 17262306a36Sopenharmony_ci LRI(1, POSTED), 17362306a36Sopenharmony_ci REG16(0x200), 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci NOP(13), 17662306a36Sopenharmony_ci LRI(44, POSTED), 17762306a36Sopenharmony_ci REG(0x028), 17862306a36Sopenharmony_ci REG(0x09c), 17962306a36Sopenharmony_ci REG(0x0c0), 18062306a36Sopenharmony_ci REG(0x178), 18162306a36Sopenharmony_ci REG(0x17c), 18262306a36Sopenharmony_ci REG16(0x358), 18362306a36Sopenharmony_ci REG(0x170), 18462306a36Sopenharmony_ci REG(0x150), 18562306a36Sopenharmony_ci REG(0x154), 18662306a36Sopenharmony_ci REG(0x158), 18762306a36Sopenharmony_ci REG16(0x41c), 18862306a36Sopenharmony_ci REG16(0x600), 18962306a36Sopenharmony_ci REG16(0x604), 19062306a36Sopenharmony_ci REG16(0x608), 19162306a36Sopenharmony_ci REG16(0x60c), 19262306a36Sopenharmony_ci REG16(0x610), 19362306a36Sopenharmony_ci REG16(0x614), 19462306a36Sopenharmony_ci REG16(0x618), 19562306a36Sopenharmony_ci REG16(0x61c), 19662306a36Sopenharmony_ci REG16(0x620), 19762306a36Sopenharmony_ci REG16(0x624), 19862306a36Sopenharmony_ci REG16(0x628), 19962306a36Sopenharmony_ci REG16(0x62c), 20062306a36Sopenharmony_ci REG16(0x630), 20162306a36Sopenharmony_ci REG16(0x634), 20262306a36Sopenharmony_ci REG16(0x638), 20362306a36Sopenharmony_ci REG16(0x63c), 20462306a36Sopenharmony_ci REG16(0x640), 20562306a36Sopenharmony_ci REG16(0x644), 20662306a36Sopenharmony_ci REG16(0x648), 20762306a36Sopenharmony_ci REG16(0x64c), 20862306a36Sopenharmony_ci REG16(0x650), 20962306a36Sopenharmony_ci REG16(0x654), 21062306a36Sopenharmony_ci REG16(0x658), 21162306a36Sopenharmony_ci REG16(0x65c), 21262306a36Sopenharmony_ci REG16(0x660), 21362306a36Sopenharmony_ci REG16(0x664), 21462306a36Sopenharmony_ci REG16(0x668), 21562306a36Sopenharmony_ci REG16(0x66c), 21662306a36Sopenharmony_ci REG16(0x670), 21762306a36Sopenharmony_ci REG16(0x674), 21862306a36Sopenharmony_ci REG16(0x678), 21962306a36Sopenharmony_ci REG16(0x67c), 22062306a36Sopenharmony_ci REG(0x068), 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_ci END 22362306a36Sopenharmony_ci}; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_cistatic const u8 gen12_xcs_offsets[] = { 22662306a36Sopenharmony_ci NOP(1), 22762306a36Sopenharmony_ci LRI(13, POSTED), 22862306a36Sopenharmony_ci REG16(0x244), 22962306a36Sopenharmony_ci REG(0x034), 23062306a36Sopenharmony_ci REG(0x030), 23162306a36Sopenharmony_ci REG(0x038), 23262306a36Sopenharmony_ci REG(0x03c), 23362306a36Sopenharmony_ci REG(0x168), 23462306a36Sopenharmony_ci REG(0x140), 23562306a36Sopenharmony_ci REG(0x110), 23662306a36Sopenharmony_ci REG(0x1c0), 23762306a36Sopenharmony_ci REG(0x1c4), 23862306a36Sopenharmony_ci REG(0x1c8), 23962306a36Sopenharmony_ci REG(0x180), 24062306a36Sopenharmony_ci REG16(0x2b4), 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci NOP(5), 24362306a36Sopenharmony_ci LRI(9, POSTED), 24462306a36Sopenharmony_ci REG16(0x3a8), 24562306a36Sopenharmony_ci REG16(0x28c), 24662306a36Sopenharmony_ci REG16(0x288), 24762306a36Sopenharmony_ci REG16(0x284), 24862306a36Sopenharmony_ci REG16(0x280), 24962306a36Sopenharmony_ci REG16(0x27c), 25062306a36Sopenharmony_ci REG16(0x278), 25162306a36Sopenharmony_ci REG16(0x274), 25262306a36Sopenharmony_ci REG16(0x270), 25362306a36Sopenharmony_ci 25462306a36Sopenharmony_ci END 25562306a36Sopenharmony_ci}; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_cistatic const u8 dg2_xcs_offsets[] = { 25862306a36Sopenharmony_ci NOP(1), 25962306a36Sopenharmony_ci LRI(15, POSTED), 26062306a36Sopenharmony_ci REG16(0x244), 26162306a36Sopenharmony_ci REG(0x034), 26262306a36Sopenharmony_ci REG(0x030), 26362306a36Sopenharmony_ci REG(0x038), 26462306a36Sopenharmony_ci REG(0x03c), 26562306a36Sopenharmony_ci REG(0x168), 26662306a36Sopenharmony_ci REG(0x140), 26762306a36Sopenharmony_ci REG(0x110), 26862306a36Sopenharmony_ci REG(0x1c0), 26962306a36Sopenharmony_ci REG(0x1c4), 27062306a36Sopenharmony_ci REG(0x1c8), 27162306a36Sopenharmony_ci REG(0x180), 27262306a36Sopenharmony_ci REG16(0x2b4), 27362306a36Sopenharmony_ci REG(0x120), 27462306a36Sopenharmony_ci REG(0x124), 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci NOP(1), 27762306a36Sopenharmony_ci LRI(9, POSTED), 27862306a36Sopenharmony_ci REG16(0x3a8), 27962306a36Sopenharmony_ci REG16(0x28c), 28062306a36Sopenharmony_ci REG16(0x288), 28162306a36Sopenharmony_ci REG16(0x284), 28262306a36Sopenharmony_ci REG16(0x280), 28362306a36Sopenharmony_ci REG16(0x27c), 28462306a36Sopenharmony_ci REG16(0x278), 28562306a36Sopenharmony_ci REG16(0x274), 28662306a36Sopenharmony_ci REG16(0x270), 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci END 28962306a36Sopenharmony_ci}; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_cistatic const u8 gen8_rcs_offsets[] = { 29262306a36Sopenharmony_ci NOP(1), 29362306a36Sopenharmony_ci LRI(14, POSTED), 29462306a36Sopenharmony_ci REG16(0x244), 29562306a36Sopenharmony_ci REG(0x034), 29662306a36Sopenharmony_ci REG(0x030), 29762306a36Sopenharmony_ci REG(0x038), 29862306a36Sopenharmony_ci REG(0x03c), 29962306a36Sopenharmony_ci REG(0x168), 30062306a36Sopenharmony_ci REG(0x140), 30162306a36Sopenharmony_ci REG(0x110), 30262306a36Sopenharmony_ci REG(0x11c), 30362306a36Sopenharmony_ci REG(0x114), 30462306a36Sopenharmony_ci REG(0x118), 30562306a36Sopenharmony_ci REG(0x1c0), 30662306a36Sopenharmony_ci REG(0x1c4), 30762306a36Sopenharmony_ci REG(0x1c8), 30862306a36Sopenharmony_ci 30962306a36Sopenharmony_ci NOP(3), 31062306a36Sopenharmony_ci LRI(9, POSTED), 31162306a36Sopenharmony_ci REG16(0x3a8), 31262306a36Sopenharmony_ci REG16(0x28c), 31362306a36Sopenharmony_ci REG16(0x288), 31462306a36Sopenharmony_ci REG16(0x284), 31562306a36Sopenharmony_ci REG16(0x280), 31662306a36Sopenharmony_ci REG16(0x27c), 31762306a36Sopenharmony_ci REG16(0x278), 31862306a36Sopenharmony_ci REG16(0x274), 31962306a36Sopenharmony_ci REG16(0x270), 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci NOP(13), 32262306a36Sopenharmony_ci LRI(1, 0), 32362306a36Sopenharmony_ci REG(0x0c8), 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci END 32662306a36Sopenharmony_ci}; 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_cistatic const u8 gen9_rcs_offsets[] = { 32962306a36Sopenharmony_ci NOP(1), 33062306a36Sopenharmony_ci LRI(14, POSTED), 33162306a36Sopenharmony_ci REG16(0x244), 33262306a36Sopenharmony_ci REG(0x34), 33362306a36Sopenharmony_ci REG(0x30), 33462306a36Sopenharmony_ci REG(0x38), 33562306a36Sopenharmony_ci REG(0x3c), 33662306a36Sopenharmony_ci REG(0x168), 33762306a36Sopenharmony_ci REG(0x140), 33862306a36Sopenharmony_ci REG(0x110), 33962306a36Sopenharmony_ci REG(0x11c), 34062306a36Sopenharmony_ci REG(0x114), 34162306a36Sopenharmony_ci REG(0x118), 34262306a36Sopenharmony_ci REG(0x1c0), 34362306a36Sopenharmony_ci REG(0x1c4), 34462306a36Sopenharmony_ci REG(0x1c8), 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci NOP(3), 34762306a36Sopenharmony_ci LRI(9, POSTED), 34862306a36Sopenharmony_ci REG16(0x3a8), 34962306a36Sopenharmony_ci REG16(0x28c), 35062306a36Sopenharmony_ci REG16(0x288), 35162306a36Sopenharmony_ci REG16(0x284), 35262306a36Sopenharmony_ci REG16(0x280), 35362306a36Sopenharmony_ci REG16(0x27c), 35462306a36Sopenharmony_ci REG16(0x278), 35562306a36Sopenharmony_ci REG16(0x274), 35662306a36Sopenharmony_ci REG16(0x270), 35762306a36Sopenharmony_ci 35862306a36Sopenharmony_ci NOP(13), 35962306a36Sopenharmony_ci LRI(1, 0), 36062306a36Sopenharmony_ci REG(0xc8), 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci NOP(13), 36362306a36Sopenharmony_ci LRI(44, POSTED), 36462306a36Sopenharmony_ci REG(0x28), 36562306a36Sopenharmony_ci REG(0x9c), 36662306a36Sopenharmony_ci REG(0xc0), 36762306a36Sopenharmony_ci REG(0x178), 36862306a36Sopenharmony_ci REG(0x17c), 36962306a36Sopenharmony_ci REG16(0x358), 37062306a36Sopenharmony_ci REG(0x170), 37162306a36Sopenharmony_ci REG(0x150), 37262306a36Sopenharmony_ci REG(0x154), 37362306a36Sopenharmony_ci REG(0x158), 37462306a36Sopenharmony_ci REG16(0x41c), 37562306a36Sopenharmony_ci REG16(0x600), 37662306a36Sopenharmony_ci REG16(0x604), 37762306a36Sopenharmony_ci REG16(0x608), 37862306a36Sopenharmony_ci REG16(0x60c), 37962306a36Sopenharmony_ci REG16(0x610), 38062306a36Sopenharmony_ci REG16(0x614), 38162306a36Sopenharmony_ci REG16(0x618), 38262306a36Sopenharmony_ci REG16(0x61c), 38362306a36Sopenharmony_ci REG16(0x620), 38462306a36Sopenharmony_ci REG16(0x624), 38562306a36Sopenharmony_ci REG16(0x628), 38662306a36Sopenharmony_ci REG16(0x62c), 38762306a36Sopenharmony_ci REG16(0x630), 38862306a36Sopenharmony_ci REG16(0x634), 38962306a36Sopenharmony_ci REG16(0x638), 39062306a36Sopenharmony_ci REG16(0x63c), 39162306a36Sopenharmony_ci REG16(0x640), 39262306a36Sopenharmony_ci REG16(0x644), 39362306a36Sopenharmony_ci REG16(0x648), 39462306a36Sopenharmony_ci REG16(0x64c), 39562306a36Sopenharmony_ci REG16(0x650), 39662306a36Sopenharmony_ci REG16(0x654), 39762306a36Sopenharmony_ci REG16(0x658), 39862306a36Sopenharmony_ci REG16(0x65c), 39962306a36Sopenharmony_ci REG16(0x660), 40062306a36Sopenharmony_ci REG16(0x664), 40162306a36Sopenharmony_ci REG16(0x668), 40262306a36Sopenharmony_ci REG16(0x66c), 40362306a36Sopenharmony_ci REG16(0x670), 40462306a36Sopenharmony_ci REG16(0x674), 40562306a36Sopenharmony_ci REG16(0x678), 40662306a36Sopenharmony_ci REG16(0x67c), 40762306a36Sopenharmony_ci REG(0x68), 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci END 41062306a36Sopenharmony_ci}; 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_cistatic const u8 gen11_rcs_offsets[] = { 41362306a36Sopenharmony_ci NOP(1), 41462306a36Sopenharmony_ci LRI(15, POSTED), 41562306a36Sopenharmony_ci REG16(0x244), 41662306a36Sopenharmony_ci REG(0x034), 41762306a36Sopenharmony_ci REG(0x030), 41862306a36Sopenharmony_ci REG(0x038), 41962306a36Sopenharmony_ci REG(0x03c), 42062306a36Sopenharmony_ci REG(0x168), 42162306a36Sopenharmony_ci REG(0x140), 42262306a36Sopenharmony_ci REG(0x110), 42362306a36Sopenharmony_ci REG(0x11c), 42462306a36Sopenharmony_ci REG(0x114), 42562306a36Sopenharmony_ci REG(0x118), 42662306a36Sopenharmony_ci REG(0x1c0), 42762306a36Sopenharmony_ci REG(0x1c4), 42862306a36Sopenharmony_ci REG(0x1c8), 42962306a36Sopenharmony_ci REG(0x180), 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci NOP(1), 43262306a36Sopenharmony_ci LRI(9, POSTED), 43362306a36Sopenharmony_ci REG16(0x3a8), 43462306a36Sopenharmony_ci REG16(0x28c), 43562306a36Sopenharmony_ci REG16(0x288), 43662306a36Sopenharmony_ci REG16(0x284), 43762306a36Sopenharmony_ci REG16(0x280), 43862306a36Sopenharmony_ci REG16(0x27c), 43962306a36Sopenharmony_ci REG16(0x278), 44062306a36Sopenharmony_ci REG16(0x274), 44162306a36Sopenharmony_ci REG16(0x270), 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci LRI(1, POSTED), 44462306a36Sopenharmony_ci REG(0x1b0), 44562306a36Sopenharmony_ci 44662306a36Sopenharmony_ci NOP(10), 44762306a36Sopenharmony_ci LRI(1, 0), 44862306a36Sopenharmony_ci REG(0x0c8), 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci END 45162306a36Sopenharmony_ci}; 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_cistatic const u8 gen12_rcs_offsets[] = { 45462306a36Sopenharmony_ci NOP(1), 45562306a36Sopenharmony_ci LRI(13, POSTED), 45662306a36Sopenharmony_ci REG16(0x244), 45762306a36Sopenharmony_ci REG(0x034), 45862306a36Sopenharmony_ci REG(0x030), 45962306a36Sopenharmony_ci REG(0x038), 46062306a36Sopenharmony_ci REG(0x03c), 46162306a36Sopenharmony_ci REG(0x168), 46262306a36Sopenharmony_ci REG(0x140), 46362306a36Sopenharmony_ci REG(0x110), 46462306a36Sopenharmony_ci REG(0x1c0), 46562306a36Sopenharmony_ci REG(0x1c4), 46662306a36Sopenharmony_ci REG(0x1c8), 46762306a36Sopenharmony_ci REG(0x180), 46862306a36Sopenharmony_ci REG16(0x2b4), 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci NOP(5), 47162306a36Sopenharmony_ci LRI(9, POSTED), 47262306a36Sopenharmony_ci REG16(0x3a8), 47362306a36Sopenharmony_ci REG16(0x28c), 47462306a36Sopenharmony_ci REG16(0x288), 47562306a36Sopenharmony_ci REG16(0x284), 47662306a36Sopenharmony_ci REG16(0x280), 47762306a36Sopenharmony_ci REG16(0x27c), 47862306a36Sopenharmony_ci REG16(0x278), 47962306a36Sopenharmony_ci REG16(0x274), 48062306a36Sopenharmony_ci REG16(0x270), 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ci LRI(3, POSTED), 48362306a36Sopenharmony_ci REG(0x1b0), 48462306a36Sopenharmony_ci REG16(0x5a8), 48562306a36Sopenharmony_ci REG16(0x5ac), 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci NOP(6), 48862306a36Sopenharmony_ci LRI(1, 0), 48962306a36Sopenharmony_ci REG(0x0c8), 49062306a36Sopenharmony_ci NOP(3 + 9 + 1), 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci LRI(51, POSTED), 49362306a36Sopenharmony_ci REG16(0x588), 49462306a36Sopenharmony_ci REG16(0x588), 49562306a36Sopenharmony_ci REG16(0x588), 49662306a36Sopenharmony_ci REG16(0x588), 49762306a36Sopenharmony_ci REG16(0x588), 49862306a36Sopenharmony_ci REG16(0x588), 49962306a36Sopenharmony_ci REG(0x028), 50062306a36Sopenharmony_ci REG(0x09c), 50162306a36Sopenharmony_ci REG(0x0c0), 50262306a36Sopenharmony_ci REG(0x178), 50362306a36Sopenharmony_ci REG(0x17c), 50462306a36Sopenharmony_ci REG16(0x358), 50562306a36Sopenharmony_ci REG(0x170), 50662306a36Sopenharmony_ci REG(0x150), 50762306a36Sopenharmony_ci REG(0x154), 50862306a36Sopenharmony_ci REG(0x158), 50962306a36Sopenharmony_ci REG16(0x41c), 51062306a36Sopenharmony_ci REG16(0x600), 51162306a36Sopenharmony_ci REG16(0x604), 51262306a36Sopenharmony_ci REG16(0x608), 51362306a36Sopenharmony_ci REG16(0x60c), 51462306a36Sopenharmony_ci REG16(0x610), 51562306a36Sopenharmony_ci REG16(0x614), 51662306a36Sopenharmony_ci REG16(0x618), 51762306a36Sopenharmony_ci REG16(0x61c), 51862306a36Sopenharmony_ci REG16(0x620), 51962306a36Sopenharmony_ci REG16(0x624), 52062306a36Sopenharmony_ci REG16(0x628), 52162306a36Sopenharmony_ci REG16(0x62c), 52262306a36Sopenharmony_ci REG16(0x630), 52362306a36Sopenharmony_ci REG16(0x634), 52462306a36Sopenharmony_ci REG16(0x638), 52562306a36Sopenharmony_ci REG16(0x63c), 52662306a36Sopenharmony_ci REG16(0x640), 52762306a36Sopenharmony_ci REG16(0x644), 52862306a36Sopenharmony_ci REG16(0x648), 52962306a36Sopenharmony_ci REG16(0x64c), 53062306a36Sopenharmony_ci REG16(0x650), 53162306a36Sopenharmony_ci REG16(0x654), 53262306a36Sopenharmony_ci REG16(0x658), 53362306a36Sopenharmony_ci REG16(0x65c), 53462306a36Sopenharmony_ci REG16(0x660), 53562306a36Sopenharmony_ci REG16(0x664), 53662306a36Sopenharmony_ci REG16(0x668), 53762306a36Sopenharmony_ci REG16(0x66c), 53862306a36Sopenharmony_ci REG16(0x670), 53962306a36Sopenharmony_ci REG16(0x674), 54062306a36Sopenharmony_ci REG16(0x678), 54162306a36Sopenharmony_ci REG16(0x67c), 54262306a36Sopenharmony_ci REG(0x068), 54362306a36Sopenharmony_ci REG(0x084), 54462306a36Sopenharmony_ci NOP(1), 54562306a36Sopenharmony_ci 54662306a36Sopenharmony_ci END 54762306a36Sopenharmony_ci}; 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_cistatic const u8 xehp_rcs_offsets[] = { 55062306a36Sopenharmony_ci NOP(1), 55162306a36Sopenharmony_ci LRI(13, POSTED), 55262306a36Sopenharmony_ci REG16(0x244), 55362306a36Sopenharmony_ci REG(0x034), 55462306a36Sopenharmony_ci REG(0x030), 55562306a36Sopenharmony_ci REG(0x038), 55662306a36Sopenharmony_ci REG(0x03c), 55762306a36Sopenharmony_ci REG(0x168), 55862306a36Sopenharmony_ci REG(0x140), 55962306a36Sopenharmony_ci REG(0x110), 56062306a36Sopenharmony_ci REG(0x1c0), 56162306a36Sopenharmony_ci REG(0x1c4), 56262306a36Sopenharmony_ci REG(0x1c8), 56362306a36Sopenharmony_ci REG(0x180), 56462306a36Sopenharmony_ci REG16(0x2b4), 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci NOP(5), 56762306a36Sopenharmony_ci LRI(9, POSTED), 56862306a36Sopenharmony_ci REG16(0x3a8), 56962306a36Sopenharmony_ci REG16(0x28c), 57062306a36Sopenharmony_ci REG16(0x288), 57162306a36Sopenharmony_ci REG16(0x284), 57262306a36Sopenharmony_ci REG16(0x280), 57362306a36Sopenharmony_ci REG16(0x27c), 57462306a36Sopenharmony_ci REG16(0x278), 57562306a36Sopenharmony_ci REG16(0x274), 57662306a36Sopenharmony_ci REG16(0x270), 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ci LRI(3, POSTED), 57962306a36Sopenharmony_ci REG(0x1b0), 58062306a36Sopenharmony_ci REG16(0x5a8), 58162306a36Sopenharmony_ci REG16(0x5ac), 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci NOP(6), 58462306a36Sopenharmony_ci LRI(1, 0), 58562306a36Sopenharmony_ci REG(0x0c8), 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_ci END 58862306a36Sopenharmony_ci}; 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_cistatic const u8 dg2_rcs_offsets[] = { 59162306a36Sopenharmony_ci NOP(1), 59262306a36Sopenharmony_ci LRI(15, POSTED), 59362306a36Sopenharmony_ci REG16(0x244), 59462306a36Sopenharmony_ci REG(0x034), 59562306a36Sopenharmony_ci REG(0x030), 59662306a36Sopenharmony_ci REG(0x038), 59762306a36Sopenharmony_ci REG(0x03c), 59862306a36Sopenharmony_ci REG(0x168), 59962306a36Sopenharmony_ci REG(0x140), 60062306a36Sopenharmony_ci REG(0x110), 60162306a36Sopenharmony_ci REG(0x1c0), 60262306a36Sopenharmony_ci REG(0x1c4), 60362306a36Sopenharmony_ci REG(0x1c8), 60462306a36Sopenharmony_ci REG(0x180), 60562306a36Sopenharmony_ci REG16(0x2b4), 60662306a36Sopenharmony_ci REG(0x120), 60762306a36Sopenharmony_ci REG(0x124), 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci NOP(1), 61062306a36Sopenharmony_ci LRI(9, POSTED), 61162306a36Sopenharmony_ci REG16(0x3a8), 61262306a36Sopenharmony_ci REG16(0x28c), 61362306a36Sopenharmony_ci REG16(0x288), 61462306a36Sopenharmony_ci REG16(0x284), 61562306a36Sopenharmony_ci REG16(0x280), 61662306a36Sopenharmony_ci REG16(0x27c), 61762306a36Sopenharmony_ci REG16(0x278), 61862306a36Sopenharmony_ci REG16(0x274), 61962306a36Sopenharmony_ci REG16(0x270), 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci LRI(3, POSTED), 62262306a36Sopenharmony_ci REG(0x1b0), 62362306a36Sopenharmony_ci REG16(0x5a8), 62462306a36Sopenharmony_ci REG16(0x5ac), 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci NOP(6), 62762306a36Sopenharmony_ci LRI(1, 0), 62862306a36Sopenharmony_ci REG(0x0c8), 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ci END 63162306a36Sopenharmony_ci}; 63262306a36Sopenharmony_ci 63362306a36Sopenharmony_cistatic const u8 mtl_rcs_offsets[] = { 63462306a36Sopenharmony_ci NOP(1), 63562306a36Sopenharmony_ci LRI(15, POSTED), 63662306a36Sopenharmony_ci REG16(0x244), 63762306a36Sopenharmony_ci REG(0x034), 63862306a36Sopenharmony_ci REG(0x030), 63962306a36Sopenharmony_ci REG(0x038), 64062306a36Sopenharmony_ci REG(0x03c), 64162306a36Sopenharmony_ci REG(0x168), 64262306a36Sopenharmony_ci REG(0x140), 64362306a36Sopenharmony_ci REG(0x110), 64462306a36Sopenharmony_ci REG(0x1c0), 64562306a36Sopenharmony_ci REG(0x1c4), 64662306a36Sopenharmony_ci REG(0x1c8), 64762306a36Sopenharmony_ci REG(0x180), 64862306a36Sopenharmony_ci REG16(0x2b4), 64962306a36Sopenharmony_ci REG(0x120), 65062306a36Sopenharmony_ci REG(0x124), 65162306a36Sopenharmony_ci 65262306a36Sopenharmony_ci NOP(1), 65362306a36Sopenharmony_ci LRI(9, POSTED), 65462306a36Sopenharmony_ci REG16(0x3a8), 65562306a36Sopenharmony_ci REG16(0x28c), 65662306a36Sopenharmony_ci REG16(0x288), 65762306a36Sopenharmony_ci REG16(0x284), 65862306a36Sopenharmony_ci REG16(0x280), 65962306a36Sopenharmony_ci REG16(0x27c), 66062306a36Sopenharmony_ci REG16(0x278), 66162306a36Sopenharmony_ci REG16(0x274), 66262306a36Sopenharmony_ci REG16(0x270), 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci NOP(2), 66562306a36Sopenharmony_ci LRI(2, POSTED), 66662306a36Sopenharmony_ci REG16(0x5a8), 66762306a36Sopenharmony_ci REG16(0x5ac), 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_ci NOP(6), 67062306a36Sopenharmony_ci LRI(1, 0), 67162306a36Sopenharmony_ci REG(0x0c8), 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_ci END 67462306a36Sopenharmony_ci}; 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci#undef END 67762306a36Sopenharmony_ci#undef REG16 67862306a36Sopenharmony_ci#undef REG 67962306a36Sopenharmony_ci#undef LRI 68062306a36Sopenharmony_ci#undef NOP 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_cistatic const u8 *reg_offsets(const struct intel_engine_cs *engine) 68362306a36Sopenharmony_ci{ 68462306a36Sopenharmony_ci /* 68562306a36Sopenharmony_ci * The gen12+ lists only have the registers we program in the basic 68662306a36Sopenharmony_ci * default state. We rely on the context image using relative 68762306a36Sopenharmony_ci * addressing to automatic fixup the register state between the 68862306a36Sopenharmony_ci * physical engines for virtual engine. 68962306a36Sopenharmony_ci */ 69062306a36Sopenharmony_ci GEM_BUG_ON(GRAPHICS_VER(engine->i915) >= 12 && 69162306a36Sopenharmony_ci !intel_engine_has_relative_mmio(engine)); 69262306a36Sopenharmony_ci 69362306a36Sopenharmony_ci if (engine->flags & I915_ENGINE_HAS_RCS_REG_STATE) { 69462306a36Sopenharmony_ci if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 70)) 69562306a36Sopenharmony_ci return mtl_rcs_offsets; 69662306a36Sopenharmony_ci else if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 55)) 69762306a36Sopenharmony_ci return dg2_rcs_offsets; 69862306a36Sopenharmony_ci else if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 50)) 69962306a36Sopenharmony_ci return xehp_rcs_offsets; 70062306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 12) 70162306a36Sopenharmony_ci return gen12_rcs_offsets; 70262306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 11) 70362306a36Sopenharmony_ci return gen11_rcs_offsets; 70462306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 9) 70562306a36Sopenharmony_ci return gen9_rcs_offsets; 70662306a36Sopenharmony_ci else 70762306a36Sopenharmony_ci return gen8_rcs_offsets; 70862306a36Sopenharmony_ci } else { 70962306a36Sopenharmony_ci if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 55)) 71062306a36Sopenharmony_ci return dg2_xcs_offsets; 71162306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 12) 71262306a36Sopenharmony_ci return gen12_xcs_offsets; 71362306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 9) 71462306a36Sopenharmony_ci return gen9_xcs_offsets; 71562306a36Sopenharmony_ci else 71662306a36Sopenharmony_ci return gen8_xcs_offsets; 71762306a36Sopenharmony_ci } 71862306a36Sopenharmony_ci} 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_cistatic int lrc_ring_mi_mode(const struct intel_engine_cs *engine) 72162306a36Sopenharmony_ci{ 72262306a36Sopenharmony_ci if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 50)) 72362306a36Sopenharmony_ci return 0x70; 72462306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 12) 72562306a36Sopenharmony_ci return 0x60; 72662306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 9) 72762306a36Sopenharmony_ci return 0x54; 72862306a36Sopenharmony_ci else if (engine->class == RENDER_CLASS) 72962306a36Sopenharmony_ci return 0x58; 73062306a36Sopenharmony_ci else 73162306a36Sopenharmony_ci return -1; 73262306a36Sopenharmony_ci} 73362306a36Sopenharmony_ci 73462306a36Sopenharmony_cistatic int lrc_ring_bb_offset(const struct intel_engine_cs *engine) 73562306a36Sopenharmony_ci{ 73662306a36Sopenharmony_ci if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 50)) 73762306a36Sopenharmony_ci return 0x80; 73862306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 12) 73962306a36Sopenharmony_ci return 0x70; 74062306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 9) 74162306a36Sopenharmony_ci return 0x64; 74262306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 8 && 74362306a36Sopenharmony_ci engine->class == RENDER_CLASS) 74462306a36Sopenharmony_ci return 0xc4; 74562306a36Sopenharmony_ci else 74662306a36Sopenharmony_ci return -1; 74762306a36Sopenharmony_ci} 74862306a36Sopenharmony_ci 74962306a36Sopenharmony_cistatic int lrc_ring_gpr0(const struct intel_engine_cs *engine) 75062306a36Sopenharmony_ci{ 75162306a36Sopenharmony_ci if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 50)) 75262306a36Sopenharmony_ci return 0x84; 75362306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 12) 75462306a36Sopenharmony_ci return 0x74; 75562306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 9) 75662306a36Sopenharmony_ci return 0x68; 75762306a36Sopenharmony_ci else if (engine->class == RENDER_CLASS) 75862306a36Sopenharmony_ci return 0xd8; 75962306a36Sopenharmony_ci else 76062306a36Sopenharmony_ci return -1; 76162306a36Sopenharmony_ci} 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_cistatic int lrc_ring_wa_bb_per_ctx(const struct intel_engine_cs *engine) 76462306a36Sopenharmony_ci{ 76562306a36Sopenharmony_ci if (GRAPHICS_VER(engine->i915) >= 12) 76662306a36Sopenharmony_ci return 0x12; 76762306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 9 || engine->class == RENDER_CLASS) 76862306a36Sopenharmony_ci return 0x18; 76962306a36Sopenharmony_ci else 77062306a36Sopenharmony_ci return -1; 77162306a36Sopenharmony_ci} 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_cistatic int lrc_ring_indirect_ptr(const struct intel_engine_cs *engine) 77462306a36Sopenharmony_ci{ 77562306a36Sopenharmony_ci int x; 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci x = lrc_ring_wa_bb_per_ctx(engine); 77862306a36Sopenharmony_ci if (x < 0) 77962306a36Sopenharmony_ci return x; 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_ci return x + 2; 78262306a36Sopenharmony_ci} 78362306a36Sopenharmony_ci 78462306a36Sopenharmony_cistatic int lrc_ring_indirect_offset(const struct intel_engine_cs *engine) 78562306a36Sopenharmony_ci{ 78662306a36Sopenharmony_ci int x; 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci x = lrc_ring_indirect_ptr(engine); 78962306a36Sopenharmony_ci if (x < 0) 79062306a36Sopenharmony_ci return x; 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_ci return x + 2; 79362306a36Sopenharmony_ci} 79462306a36Sopenharmony_ci 79562306a36Sopenharmony_cistatic int lrc_ring_cmd_buf_cctl(const struct intel_engine_cs *engine) 79662306a36Sopenharmony_ci{ 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_ci if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 50)) 79962306a36Sopenharmony_ci /* 80062306a36Sopenharmony_ci * Note that the CSFE context has a dummy slot for CMD_BUF_CCTL 80162306a36Sopenharmony_ci * simply to match the RCS context image layout. 80262306a36Sopenharmony_ci */ 80362306a36Sopenharmony_ci return 0xc6; 80462306a36Sopenharmony_ci else if (engine->class != RENDER_CLASS) 80562306a36Sopenharmony_ci return -1; 80662306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 12) 80762306a36Sopenharmony_ci return 0xb6; 80862306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 11) 80962306a36Sopenharmony_ci return 0xaa; 81062306a36Sopenharmony_ci else 81162306a36Sopenharmony_ci return -1; 81262306a36Sopenharmony_ci} 81362306a36Sopenharmony_ci 81462306a36Sopenharmony_cistatic u32 81562306a36Sopenharmony_cilrc_ring_indirect_offset_default(const struct intel_engine_cs *engine) 81662306a36Sopenharmony_ci{ 81762306a36Sopenharmony_ci if (GRAPHICS_VER(engine->i915) >= 12) 81862306a36Sopenharmony_ci return GEN12_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT; 81962306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 11) 82062306a36Sopenharmony_ci return GEN11_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT; 82162306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 9) 82262306a36Sopenharmony_ci return GEN9_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT; 82362306a36Sopenharmony_ci else if (GRAPHICS_VER(engine->i915) >= 8) 82462306a36Sopenharmony_ci return GEN8_CTX_RCS_INDIRECT_CTX_OFFSET_DEFAULT; 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_ci GEM_BUG_ON(GRAPHICS_VER(engine->i915) < 8); 82762306a36Sopenharmony_ci 82862306a36Sopenharmony_ci return 0; 82962306a36Sopenharmony_ci} 83062306a36Sopenharmony_ci 83162306a36Sopenharmony_cistatic void 83262306a36Sopenharmony_cilrc_setup_indirect_ctx(u32 *regs, 83362306a36Sopenharmony_ci const struct intel_engine_cs *engine, 83462306a36Sopenharmony_ci u32 ctx_bb_ggtt_addr, 83562306a36Sopenharmony_ci u32 size) 83662306a36Sopenharmony_ci{ 83762306a36Sopenharmony_ci GEM_BUG_ON(!size); 83862306a36Sopenharmony_ci GEM_BUG_ON(!IS_ALIGNED(size, CACHELINE_BYTES)); 83962306a36Sopenharmony_ci GEM_BUG_ON(lrc_ring_indirect_ptr(engine) == -1); 84062306a36Sopenharmony_ci regs[lrc_ring_indirect_ptr(engine) + 1] = 84162306a36Sopenharmony_ci ctx_bb_ggtt_addr | (size / CACHELINE_BYTES); 84262306a36Sopenharmony_ci 84362306a36Sopenharmony_ci GEM_BUG_ON(lrc_ring_indirect_offset(engine) == -1); 84462306a36Sopenharmony_ci regs[lrc_ring_indirect_offset(engine) + 1] = 84562306a36Sopenharmony_ci lrc_ring_indirect_offset_default(engine) << 6; 84662306a36Sopenharmony_ci} 84762306a36Sopenharmony_ci 84862306a36Sopenharmony_cistatic void init_common_regs(u32 * const regs, 84962306a36Sopenharmony_ci const struct intel_context *ce, 85062306a36Sopenharmony_ci const struct intel_engine_cs *engine, 85162306a36Sopenharmony_ci bool inhibit) 85262306a36Sopenharmony_ci{ 85362306a36Sopenharmony_ci u32 ctl; 85462306a36Sopenharmony_ci int loc; 85562306a36Sopenharmony_ci 85662306a36Sopenharmony_ci ctl = _MASKED_BIT_ENABLE(CTX_CTRL_INHIBIT_SYN_CTX_SWITCH); 85762306a36Sopenharmony_ci ctl |= _MASKED_BIT_DISABLE(CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT); 85862306a36Sopenharmony_ci if (inhibit) 85962306a36Sopenharmony_ci ctl |= CTX_CTRL_ENGINE_CTX_RESTORE_INHIBIT; 86062306a36Sopenharmony_ci if (GRAPHICS_VER(engine->i915) < 11) 86162306a36Sopenharmony_ci ctl |= _MASKED_BIT_DISABLE(CTX_CTRL_ENGINE_CTX_SAVE_INHIBIT | 86262306a36Sopenharmony_ci CTX_CTRL_RS_CTX_ENABLE); 86362306a36Sopenharmony_ci regs[CTX_CONTEXT_CONTROL] = ctl; 86462306a36Sopenharmony_ci 86562306a36Sopenharmony_ci regs[CTX_TIMESTAMP] = ce->stats.runtime.last; 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_ci loc = lrc_ring_bb_offset(engine); 86862306a36Sopenharmony_ci if (loc != -1) 86962306a36Sopenharmony_ci regs[loc + 1] = 0; 87062306a36Sopenharmony_ci} 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_cistatic void init_wa_bb_regs(u32 * const regs, 87362306a36Sopenharmony_ci const struct intel_engine_cs *engine) 87462306a36Sopenharmony_ci{ 87562306a36Sopenharmony_ci const struct i915_ctx_workarounds * const wa_ctx = &engine->wa_ctx; 87662306a36Sopenharmony_ci 87762306a36Sopenharmony_ci if (wa_ctx->per_ctx.size) { 87862306a36Sopenharmony_ci const u32 ggtt_offset = i915_ggtt_offset(wa_ctx->vma); 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_ci GEM_BUG_ON(lrc_ring_wa_bb_per_ctx(engine) == -1); 88162306a36Sopenharmony_ci regs[lrc_ring_wa_bb_per_ctx(engine) + 1] = 88262306a36Sopenharmony_ci (ggtt_offset + wa_ctx->per_ctx.offset) | 0x01; 88362306a36Sopenharmony_ci } 88462306a36Sopenharmony_ci 88562306a36Sopenharmony_ci if (wa_ctx->indirect_ctx.size) { 88662306a36Sopenharmony_ci lrc_setup_indirect_ctx(regs, engine, 88762306a36Sopenharmony_ci i915_ggtt_offset(wa_ctx->vma) + 88862306a36Sopenharmony_ci wa_ctx->indirect_ctx.offset, 88962306a36Sopenharmony_ci wa_ctx->indirect_ctx.size); 89062306a36Sopenharmony_ci } 89162306a36Sopenharmony_ci} 89262306a36Sopenharmony_ci 89362306a36Sopenharmony_cistatic void init_ppgtt_regs(u32 *regs, const struct i915_ppgtt *ppgtt) 89462306a36Sopenharmony_ci{ 89562306a36Sopenharmony_ci if (i915_vm_is_4lvl(&ppgtt->vm)) { 89662306a36Sopenharmony_ci /* 64b PPGTT (48bit canonical) 89762306a36Sopenharmony_ci * PDP0_DESCRIPTOR contains the base address to PML4 and 89862306a36Sopenharmony_ci * other PDP Descriptors are ignored. 89962306a36Sopenharmony_ci */ 90062306a36Sopenharmony_ci ASSIGN_CTX_PML4(ppgtt, regs); 90162306a36Sopenharmony_ci } else { 90262306a36Sopenharmony_ci ASSIGN_CTX_PDP(ppgtt, regs, 3); 90362306a36Sopenharmony_ci ASSIGN_CTX_PDP(ppgtt, regs, 2); 90462306a36Sopenharmony_ci ASSIGN_CTX_PDP(ppgtt, regs, 1); 90562306a36Sopenharmony_ci ASSIGN_CTX_PDP(ppgtt, regs, 0); 90662306a36Sopenharmony_ci } 90762306a36Sopenharmony_ci} 90862306a36Sopenharmony_ci 90962306a36Sopenharmony_cistatic struct i915_ppgtt *vm_alias(struct i915_address_space *vm) 91062306a36Sopenharmony_ci{ 91162306a36Sopenharmony_ci if (i915_is_ggtt(vm)) 91262306a36Sopenharmony_ci return i915_vm_to_ggtt(vm)->alias; 91362306a36Sopenharmony_ci else 91462306a36Sopenharmony_ci return i915_vm_to_ppgtt(vm); 91562306a36Sopenharmony_ci} 91662306a36Sopenharmony_ci 91762306a36Sopenharmony_cistatic void __reset_stop_ring(u32 *regs, const struct intel_engine_cs *engine) 91862306a36Sopenharmony_ci{ 91962306a36Sopenharmony_ci int x; 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_ci x = lrc_ring_mi_mode(engine); 92262306a36Sopenharmony_ci if (x != -1) { 92362306a36Sopenharmony_ci regs[x + 1] &= ~STOP_RING; 92462306a36Sopenharmony_ci regs[x + 1] |= STOP_RING << 16; 92562306a36Sopenharmony_ci } 92662306a36Sopenharmony_ci} 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_cistatic void __lrc_init_regs(u32 *regs, 92962306a36Sopenharmony_ci const struct intel_context *ce, 93062306a36Sopenharmony_ci const struct intel_engine_cs *engine, 93162306a36Sopenharmony_ci bool inhibit) 93262306a36Sopenharmony_ci{ 93362306a36Sopenharmony_ci /* 93462306a36Sopenharmony_ci * A context is actually a big batch buffer with several 93562306a36Sopenharmony_ci * MI_LOAD_REGISTER_IMM commands followed by (reg, value) pairs. The 93662306a36Sopenharmony_ci * values we are setting here are only for the first context restore: 93762306a36Sopenharmony_ci * on a subsequent save, the GPU will recreate this batchbuffer with new 93862306a36Sopenharmony_ci * values (including all the missing MI_LOAD_REGISTER_IMM commands that 93962306a36Sopenharmony_ci * we are not initializing here). 94062306a36Sopenharmony_ci * 94162306a36Sopenharmony_ci * Must keep consistent with virtual_update_register_offsets(). 94262306a36Sopenharmony_ci */ 94362306a36Sopenharmony_ci 94462306a36Sopenharmony_ci if (inhibit) 94562306a36Sopenharmony_ci memset(regs, 0, PAGE_SIZE); 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_ci set_offsets(regs, reg_offsets(engine), engine, inhibit); 94862306a36Sopenharmony_ci 94962306a36Sopenharmony_ci init_common_regs(regs, ce, engine, inhibit); 95062306a36Sopenharmony_ci init_ppgtt_regs(regs, vm_alias(ce->vm)); 95162306a36Sopenharmony_ci 95262306a36Sopenharmony_ci init_wa_bb_regs(regs, engine); 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci __reset_stop_ring(regs, engine); 95562306a36Sopenharmony_ci} 95662306a36Sopenharmony_ci 95762306a36Sopenharmony_civoid lrc_init_regs(const struct intel_context *ce, 95862306a36Sopenharmony_ci const struct intel_engine_cs *engine, 95962306a36Sopenharmony_ci bool inhibit) 96062306a36Sopenharmony_ci{ 96162306a36Sopenharmony_ci __lrc_init_regs(ce->lrc_reg_state, ce, engine, inhibit); 96262306a36Sopenharmony_ci} 96362306a36Sopenharmony_ci 96462306a36Sopenharmony_civoid lrc_reset_regs(const struct intel_context *ce, 96562306a36Sopenharmony_ci const struct intel_engine_cs *engine) 96662306a36Sopenharmony_ci{ 96762306a36Sopenharmony_ci __reset_stop_ring(ce->lrc_reg_state, engine); 96862306a36Sopenharmony_ci} 96962306a36Sopenharmony_ci 97062306a36Sopenharmony_cistatic void 97162306a36Sopenharmony_ciset_redzone(void *vaddr, const struct intel_engine_cs *engine) 97262306a36Sopenharmony_ci{ 97362306a36Sopenharmony_ci if (!IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) 97462306a36Sopenharmony_ci return; 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_ci vaddr += engine->context_size; 97762306a36Sopenharmony_ci 97862306a36Sopenharmony_ci memset(vaddr, CONTEXT_REDZONE, I915_GTT_PAGE_SIZE); 97962306a36Sopenharmony_ci} 98062306a36Sopenharmony_ci 98162306a36Sopenharmony_cistatic void 98262306a36Sopenharmony_cicheck_redzone(const void *vaddr, const struct intel_engine_cs *engine) 98362306a36Sopenharmony_ci{ 98462306a36Sopenharmony_ci if (!IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) 98562306a36Sopenharmony_ci return; 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_ci vaddr += engine->context_size; 98862306a36Sopenharmony_ci 98962306a36Sopenharmony_ci if (memchr_inv(vaddr, CONTEXT_REDZONE, I915_GTT_PAGE_SIZE)) 99062306a36Sopenharmony_ci drm_err_once(&engine->i915->drm, 99162306a36Sopenharmony_ci "%s context redzone overwritten!\n", 99262306a36Sopenharmony_ci engine->name); 99362306a36Sopenharmony_ci} 99462306a36Sopenharmony_ci 99562306a36Sopenharmony_cistatic u32 context_wa_bb_offset(const struct intel_context *ce) 99662306a36Sopenharmony_ci{ 99762306a36Sopenharmony_ci return PAGE_SIZE * ce->wa_bb_page; 99862306a36Sopenharmony_ci} 99962306a36Sopenharmony_ci 100062306a36Sopenharmony_cistatic u32 *context_indirect_bb(const struct intel_context *ce) 100162306a36Sopenharmony_ci{ 100262306a36Sopenharmony_ci void *ptr; 100362306a36Sopenharmony_ci 100462306a36Sopenharmony_ci GEM_BUG_ON(!ce->wa_bb_page); 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_ci ptr = ce->lrc_reg_state; 100762306a36Sopenharmony_ci ptr -= LRC_STATE_OFFSET; /* back to start of context image */ 100862306a36Sopenharmony_ci ptr += context_wa_bb_offset(ce); 100962306a36Sopenharmony_ci 101062306a36Sopenharmony_ci return ptr; 101162306a36Sopenharmony_ci} 101262306a36Sopenharmony_ci 101362306a36Sopenharmony_civoid lrc_init_state(struct intel_context *ce, 101462306a36Sopenharmony_ci struct intel_engine_cs *engine, 101562306a36Sopenharmony_ci void *state) 101662306a36Sopenharmony_ci{ 101762306a36Sopenharmony_ci bool inhibit = true; 101862306a36Sopenharmony_ci 101962306a36Sopenharmony_ci set_redzone(state, engine); 102062306a36Sopenharmony_ci 102162306a36Sopenharmony_ci if (engine->default_state) { 102262306a36Sopenharmony_ci shmem_read(engine->default_state, 0, 102362306a36Sopenharmony_ci state, engine->context_size); 102462306a36Sopenharmony_ci __set_bit(CONTEXT_VALID_BIT, &ce->flags); 102562306a36Sopenharmony_ci inhibit = false; 102662306a36Sopenharmony_ci } 102762306a36Sopenharmony_ci 102862306a36Sopenharmony_ci /* Clear the ppHWSP (inc. per-context counters) */ 102962306a36Sopenharmony_ci memset(state, 0, PAGE_SIZE); 103062306a36Sopenharmony_ci 103162306a36Sopenharmony_ci /* Clear the indirect wa and storage */ 103262306a36Sopenharmony_ci if (ce->wa_bb_page) 103362306a36Sopenharmony_ci memset(state + context_wa_bb_offset(ce), 0, PAGE_SIZE); 103462306a36Sopenharmony_ci 103562306a36Sopenharmony_ci /* 103662306a36Sopenharmony_ci * The second page of the context object contains some registers which 103762306a36Sopenharmony_ci * must be set up prior to the first execution. 103862306a36Sopenharmony_ci */ 103962306a36Sopenharmony_ci __lrc_init_regs(state + LRC_STATE_OFFSET, ce, engine, inhibit); 104062306a36Sopenharmony_ci} 104162306a36Sopenharmony_ci 104262306a36Sopenharmony_ciu32 lrc_indirect_bb(const struct intel_context *ce) 104362306a36Sopenharmony_ci{ 104462306a36Sopenharmony_ci return i915_ggtt_offset(ce->state) + context_wa_bb_offset(ce); 104562306a36Sopenharmony_ci} 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_cistatic u32 *setup_predicate_disable_wa(const struct intel_context *ce, u32 *cs) 104862306a36Sopenharmony_ci{ 104962306a36Sopenharmony_ci /* If predication is active, this will be noop'ed */ 105062306a36Sopenharmony_ci *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT | (4 - 2); 105162306a36Sopenharmony_ci *cs++ = lrc_indirect_bb(ce) + DG2_PREDICATE_RESULT_WA; 105262306a36Sopenharmony_ci *cs++ = 0; 105362306a36Sopenharmony_ci *cs++ = 0; /* No predication */ 105462306a36Sopenharmony_ci 105562306a36Sopenharmony_ci /* predicated end, only terminates if SET_PREDICATE_RESULT:0 is clear */ 105662306a36Sopenharmony_ci *cs++ = MI_BATCH_BUFFER_END | BIT(15); 105762306a36Sopenharmony_ci *cs++ = MI_SET_PREDICATE | MI_SET_PREDICATE_DISABLE; 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_ci /* Instructions are no longer predicated (disabled), we can proceed */ 106062306a36Sopenharmony_ci *cs++ = MI_STORE_DWORD_IMM_GEN4 | MI_USE_GGTT | (4 - 2); 106162306a36Sopenharmony_ci *cs++ = lrc_indirect_bb(ce) + DG2_PREDICATE_RESULT_WA; 106262306a36Sopenharmony_ci *cs++ = 0; 106362306a36Sopenharmony_ci *cs++ = 1; /* enable predication before the next BB */ 106462306a36Sopenharmony_ci 106562306a36Sopenharmony_ci *cs++ = MI_BATCH_BUFFER_END; 106662306a36Sopenharmony_ci GEM_BUG_ON(offset_in_page(cs) > DG2_PREDICATE_RESULT_WA); 106762306a36Sopenharmony_ci 106862306a36Sopenharmony_ci return cs; 106962306a36Sopenharmony_ci} 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_cistatic struct i915_vma * 107262306a36Sopenharmony_ci__lrc_alloc_state(struct intel_context *ce, struct intel_engine_cs *engine) 107362306a36Sopenharmony_ci{ 107462306a36Sopenharmony_ci struct drm_i915_gem_object *obj; 107562306a36Sopenharmony_ci struct i915_vma *vma; 107662306a36Sopenharmony_ci u32 context_size; 107762306a36Sopenharmony_ci 107862306a36Sopenharmony_ci context_size = round_up(engine->context_size, I915_GTT_PAGE_SIZE); 107962306a36Sopenharmony_ci 108062306a36Sopenharmony_ci if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) 108162306a36Sopenharmony_ci context_size += I915_GTT_PAGE_SIZE; /* for redzone */ 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_ci if (GRAPHICS_VER(engine->i915) >= 12) { 108462306a36Sopenharmony_ci ce->wa_bb_page = context_size / PAGE_SIZE; 108562306a36Sopenharmony_ci context_size += PAGE_SIZE; 108662306a36Sopenharmony_ci } 108762306a36Sopenharmony_ci 108862306a36Sopenharmony_ci if (intel_context_is_parent(ce) && intel_engine_uses_guc(engine)) { 108962306a36Sopenharmony_ci ce->parallel.guc.parent_page = context_size / PAGE_SIZE; 109062306a36Sopenharmony_ci context_size += PARENT_SCRATCH_SIZE; 109162306a36Sopenharmony_ci } 109262306a36Sopenharmony_ci 109362306a36Sopenharmony_ci obj = i915_gem_object_create_lmem(engine->i915, context_size, 109462306a36Sopenharmony_ci I915_BO_ALLOC_PM_VOLATILE); 109562306a36Sopenharmony_ci if (IS_ERR(obj)) { 109662306a36Sopenharmony_ci obj = i915_gem_object_create_shmem(engine->i915, context_size); 109762306a36Sopenharmony_ci if (IS_ERR(obj)) 109862306a36Sopenharmony_ci return ERR_CAST(obj); 109962306a36Sopenharmony_ci 110062306a36Sopenharmony_ci /* 110162306a36Sopenharmony_ci * Wa_22016122933: For Media version 13.0, all Media GT shared 110262306a36Sopenharmony_ci * memory needs to be mapped as WC on CPU side and UC (PAT 110362306a36Sopenharmony_ci * index 2) on GPU side. 110462306a36Sopenharmony_ci */ 110562306a36Sopenharmony_ci if (intel_gt_needs_wa_22016122933(engine->gt)) 110662306a36Sopenharmony_ci i915_gem_object_set_cache_coherency(obj, I915_CACHE_NONE); 110762306a36Sopenharmony_ci } 110862306a36Sopenharmony_ci 110962306a36Sopenharmony_ci vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL); 111062306a36Sopenharmony_ci if (IS_ERR(vma)) { 111162306a36Sopenharmony_ci i915_gem_object_put(obj); 111262306a36Sopenharmony_ci return vma; 111362306a36Sopenharmony_ci } 111462306a36Sopenharmony_ci 111562306a36Sopenharmony_ci return vma; 111662306a36Sopenharmony_ci} 111762306a36Sopenharmony_ci 111862306a36Sopenharmony_cistatic struct intel_timeline * 111962306a36Sopenharmony_cipinned_timeline(struct intel_context *ce, struct intel_engine_cs *engine) 112062306a36Sopenharmony_ci{ 112162306a36Sopenharmony_ci struct intel_timeline *tl = fetch_and_zero(&ce->timeline); 112262306a36Sopenharmony_ci 112362306a36Sopenharmony_ci return intel_timeline_create_from_engine(engine, page_unmask_bits(tl)); 112462306a36Sopenharmony_ci} 112562306a36Sopenharmony_ci 112662306a36Sopenharmony_ciint lrc_alloc(struct intel_context *ce, struct intel_engine_cs *engine) 112762306a36Sopenharmony_ci{ 112862306a36Sopenharmony_ci struct intel_ring *ring; 112962306a36Sopenharmony_ci struct i915_vma *vma; 113062306a36Sopenharmony_ci int err; 113162306a36Sopenharmony_ci 113262306a36Sopenharmony_ci GEM_BUG_ON(ce->state); 113362306a36Sopenharmony_ci 113462306a36Sopenharmony_ci vma = __lrc_alloc_state(ce, engine); 113562306a36Sopenharmony_ci if (IS_ERR(vma)) 113662306a36Sopenharmony_ci return PTR_ERR(vma); 113762306a36Sopenharmony_ci 113862306a36Sopenharmony_ci ring = intel_engine_create_ring(engine, ce->ring_size); 113962306a36Sopenharmony_ci if (IS_ERR(ring)) { 114062306a36Sopenharmony_ci err = PTR_ERR(ring); 114162306a36Sopenharmony_ci goto err_vma; 114262306a36Sopenharmony_ci } 114362306a36Sopenharmony_ci 114462306a36Sopenharmony_ci if (!page_mask_bits(ce->timeline)) { 114562306a36Sopenharmony_ci struct intel_timeline *tl; 114662306a36Sopenharmony_ci 114762306a36Sopenharmony_ci /* 114862306a36Sopenharmony_ci * Use the static global HWSP for the kernel context, and 114962306a36Sopenharmony_ci * a dynamically allocated cacheline for everyone else. 115062306a36Sopenharmony_ci */ 115162306a36Sopenharmony_ci if (unlikely(ce->timeline)) 115262306a36Sopenharmony_ci tl = pinned_timeline(ce, engine); 115362306a36Sopenharmony_ci else 115462306a36Sopenharmony_ci tl = intel_timeline_create(engine->gt); 115562306a36Sopenharmony_ci if (IS_ERR(tl)) { 115662306a36Sopenharmony_ci err = PTR_ERR(tl); 115762306a36Sopenharmony_ci goto err_ring; 115862306a36Sopenharmony_ci } 115962306a36Sopenharmony_ci 116062306a36Sopenharmony_ci ce->timeline = tl; 116162306a36Sopenharmony_ci } 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_ci ce->ring = ring; 116462306a36Sopenharmony_ci ce->state = vma; 116562306a36Sopenharmony_ci 116662306a36Sopenharmony_ci return 0; 116762306a36Sopenharmony_ci 116862306a36Sopenharmony_cierr_ring: 116962306a36Sopenharmony_ci intel_ring_put(ring); 117062306a36Sopenharmony_cierr_vma: 117162306a36Sopenharmony_ci i915_vma_put(vma); 117262306a36Sopenharmony_ci return err; 117362306a36Sopenharmony_ci} 117462306a36Sopenharmony_ci 117562306a36Sopenharmony_civoid lrc_reset(struct intel_context *ce) 117662306a36Sopenharmony_ci{ 117762306a36Sopenharmony_ci GEM_BUG_ON(!intel_context_is_pinned(ce)); 117862306a36Sopenharmony_ci 117962306a36Sopenharmony_ci intel_ring_reset(ce->ring, ce->ring->emit); 118062306a36Sopenharmony_ci 118162306a36Sopenharmony_ci /* Scrub away the garbage */ 118262306a36Sopenharmony_ci lrc_init_regs(ce, ce->engine, true); 118362306a36Sopenharmony_ci ce->lrc.lrca = lrc_update_regs(ce, ce->engine, ce->ring->tail); 118462306a36Sopenharmony_ci} 118562306a36Sopenharmony_ci 118662306a36Sopenharmony_ciint 118762306a36Sopenharmony_cilrc_pre_pin(struct intel_context *ce, 118862306a36Sopenharmony_ci struct intel_engine_cs *engine, 118962306a36Sopenharmony_ci struct i915_gem_ww_ctx *ww, 119062306a36Sopenharmony_ci void **vaddr) 119162306a36Sopenharmony_ci{ 119262306a36Sopenharmony_ci GEM_BUG_ON(!ce->state); 119362306a36Sopenharmony_ci GEM_BUG_ON(!i915_vma_is_pinned(ce->state)); 119462306a36Sopenharmony_ci 119562306a36Sopenharmony_ci *vaddr = i915_gem_object_pin_map(ce->state->obj, 119662306a36Sopenharmony_ci intel_gt_coherent_map_type(ce->engine->gt, 119762306a36Sopenharmony_ci ce->state->obj, 119862306a36Sopenharmony_ci false) | 119962306a36Sopenharmony_ci I915_MAP_OVERRIDE); 120062306a36Sopenharmony_ci 120162306a36Sopenharmony_ci return PTR_ERR_OR_ZERO(*vaddr); 120262306a36Sopenharmony_ci} 120362306a36Sopenharmony_ci 120462306a36Sopenharmony_ciint 120562306a36Sopenharmony_cilrc_pin(struct intel_context *ce, 120662306a36Sopenharmony_ci struct intel_engine_cs *engine, 120762306a36Sopenharmony_ci void *vaddr) 120862306a36Sopenharmony_ci{ 120962306a36Sopenharmony_ci ce->lrc_reg_state = vaddr + LRC_STATE_OFFSET; 121062306a36Sopenharmony_ci 121162306a36Sopenharmony_ci if (!__test_and_set_bit(CONTEXT_INIT_BIT, &ce->flags)) 121262306a36Sopenharmony_ci lrc_init_state(ce, engine, vaddr); 121362306a36Sopenharmony_ci 121462306a36Sopenharmony_ci ce->lrc.lrca = lrc_update_regs(ce, engine, ce->ring->tail); 121562306a36Sopenharmony_ci return 0; 121662306a36Sopenharmony_ci} 121762306a36Sopenharmony_ci 121862306a36Sopenharmony_civoid lrc_unpin(struct intel_context *ce) 121962306a36Sopenharmony_ci{ 122062306a36Sopenharmony_ci if (unlikely(ce->parallel.last_rq)) { 122162306a36Sopenharmony_ci i915_request_put(ce->parallel.last_rq); 122262306a36Sopenharmony_ci ce->parallel.last_rq = NULL; 122362306a36Sopenharmony_ci } 122462306a36Sopenharmony_ci check_redzone((void *)ce->lrc_reg_state - LRC_STATE_OFFSET, 122562306a36Sopenharmony_ci ce->engine); 122662306a36Sopenharmony_ci} 122762306a36Sopenharmony_ci 122862306a36Sopenharmony_civoid lrc_post_unpin(struct intel_context *ce) 122962306a36Sopenharmony_ci{ 123062306a36Sopenharmony_ci i915_gem_object_unpin_map(ce->state->obj); 123162306a36Sopenharmony_ci} 123262306a36Sopenharmony_ci 123362306a36Sopenharmony_civoid lrc_fini(struct intel_context *ce) 123462306a36Sopenharmony_ci{ 123562306a36Sopenharmony_ci if (!ce->state) 123662306a36Sopenharmony_ci return; 123762306a36Sopenharmony_ci 123862306a36Sopenharmony_ci intel_ring_put(fetch_and_zero(&ce->ring)); 123962306a36Sopenharmony_ci i915_vma_put(fetch_and_zero(&ce->state)); 124062306a36Sopenharmony_ci} 124162306a36Sopenharmony_ci 124262306a36Sopenharmony_civoid lrc_destroy(struct kref *kref) 124362306a36Sopenharmony_ci{ 124462306a36Sopenharmony_ci struct intel_context *ce = container_of(kref, typeof(*ce), ref); 124562306a36Sopenharmony_ci 124662306a36Sopenharmony_ci GEM_BUG_ON(!i915_active_is_idle(&ce->active)); 124762306a36Sopenharmony_ci GEM_BUG_ON(intel_context_is_pinned(ce)); 124862306a36Sopenharmony_ci 124962306a36Sopenharmony_ci lrc_fini(ce); 125062306a36Sopenharmony_ci 125162306a36Sopenharmony_ci intel_context_fini(ce); 125262306a36Sopenharmony_ci intel_context_free(ce); 125362306a36Sopenharmony_ci} 125462306a36Sopenharmony_ci 125562306a36Sopenharmony_cistatic u32 * 125662306a36Sopenharmony_cigen12_emit_timestamp_wa(const struct intel_context *ce, u32 *cs) 125762306a36Sopenharmony_ci{ 125862306a36Sopenharmony_ci *cs++ = MI_LOAD_REGISTER_MEM_GEN8 | 125962306a36Sopenharmony_ci MI_SRM_LRM_GLOBAL_GTT | 126062306a36Sopenharmony_ci MI_LRI_LRM_CS_MMIO; 126162306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(GEN8_RING_CS_GPR(0, 0)); 126262306a36Sopenharmony_ci *cs++ = i915_ggtt_offset(ce->state) + LRC_STATE_OFFSET + 126362306a36Sopenharmony_ci CTX_TIMESTAMP * sizeof(u32); 126462306a36Sopenharmony_ci *cs++ = 0; 126562306a36Sopenharmony_ci 126662306a36Sopenharmony_ci *cs++ = MI_LOAD_REGISTER_REG | 126762306a36Sopenharmony_ci MI_LRR_SOURCE_CS_MMIO | 126862306a36Sopenharmony_ci MI_LRI_LRM_CS_MMIO; 126962306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(GEN8_RING_CS_GPR(0, 0)); 127062306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(RING_CTX_TIMESTAMP(0)); 127162306a36Sopenharmony_ci 127262306a36Sopenharmony_ci *cs++ = MI_LOAD_REGISTER_REG | 127362306a36Sopenharmony_ci MI_LRR_SOURCE_CS_MMIO | 127462306a36Sopenharmony_ci MI_LRI_LRM_CS_MMIO; 127562306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(GEN8_RING_CS_GPR(0, 0)); 127662306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(RING_CTX_TIMESTAMP(0)); 127762306a36Sopenharmony_ci 127862306a36Sopenharmony_ci return cs; 127962306a36Sopenharmony_ci} 128062306a36Sopenharmony_ci 128162306a36Sopenharmony_cistatic u32 * 128262306a36Sopenharmony_cigen12_emit_restore_scratch(const struct intel_context *ce, u32 *cs) 128362306a36Sopenharmony_ci{ 128462306a36Sopenharmony_ci GEM_BUG_ON(lrc_ring_gpr0(ce->engine) == -1); 128562306a36Sopenharmony_ci 128662306a36Sopenharmony_ci *cs++ = MI_LOAD_REGISTER_MEM_GEN8 | 128762306a36Sopenharmony_ci MI_SRM_LRM_GLOBAL_GTT | 128862306a36Sopenharmony_ci MI_LRI_LRM_CS_MMIO; 128962306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(GEN8_RING_CS_GPR(0, 0)); 129062306a36Sopenharmony_ci *cs++ = i915_ggtt_offset(ce->state) + LRC_STATE_OFFSET + 129162306a36Sopenharmony_ci (lrc_ring_gpr0(ce->engine) + 1) * sizeof(u32); 129262306a36Sopenharmony_ci *cs++ = 0; 129362306a36Sopenharmony_ci 129462306a36Sopenharmony_ci return cs; 129562306a36Sopenharmony_ci} 129662306a36Sopenharmony_ci 129762306a36Sopenharmony_cistatic u32 * 129862306a36Sopenharmony_cigen12_emit_cmd_buf_wa(const struct intel_context *ce, u32 *cs) 129962306a36Sopenharmony_ci{ 130062306a36Sopenharmony_ci GEM_BUG_ON(lrc_ring_cmd_buf_cctl(ce->engine) == -1); 130162306a36Sopenharmony_ci 130262306a36Sopenharmony_ci *cs++ = MI_LOAD_REGISTER_MEM_GEN8 | 130362306a36Sopenharmony_ci MI_SRM_LRM_GLOBAL_GTT | 130462306a36Sopenharmony_ci MI_LRI_LRM_CS_MMIO; 130562306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(GEN8_RING_CS_GPR(0, 0)); 130662306a36Sopenharmony_ci *cs++ = i915_ggtt_offset(ce->state) + LRC_STATE_OFFSET + 130762306a36Sopenharmony_ci (lrc_ring_cmd_buf_cctl(ce->engine) + 1) * sizeof(u32); 130862306a36Sopenharmony_ci *cs++ = 0; 130962306a36Sopenharmony_ci 131062306a36Sopenharmony_ci *cs++ = MI_LOAD_REGISTER_REG | 131162306a36Sopenharmony_ci MI_LRR_SOURCE_CS_MMIO | 131262306a36Sopenharmony_ci MI_LRI_LRM_CS_MMIO; 131362306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(GEN8_RING_CS_GPR(0, 0)); 131462306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(RING_CMD_BUF_CCTL(0)); 131562306a36Sopenharmony_ci 131662306a36Sopenharmony_ci return cs; 131762306a36Sopenharmony_ci} 131862306a36Sopenharmony_ci 131962306a36Sopenharmony_ci/* 132062306a36Sopenharmony_ci * On DG2 during context restore of a preempted context in GPGPU mode, 132162306a36Sopenharmony_ci * RCS restore hang is detected. This is extremely timing dependent. 132262306a36Sopenharmony_ci * To address this below sw wabb is implemented for DG2 A steppings. 132362306a36Sopenharmony_ci */ 132462306a36Sopenharmony_cistatic u32 * 132562306a36Sopenharmony_cidg2_emit_rcs_hang_wabb(const struct intel_context *ce, u32 *cs) 132662306a36Sopenharmony_ci{ 132762306a36Sopenharmony_ci *cs++ = MI_LOAD_REGISTER_IMM(1); 132862306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(GEN12_STATE_ACK_DEBUG(ce->engine->mmio_base)); 132962306a36Sopenharmony_ci *cs++ = 0x21; 133062306a36Sopenharmony_ci 133162306a36Sopenharmony_ci *cs++ = MI_LOAD_REGISTER_REG; 133262306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(RING_NOPID(ce->engine->mmio_base)); 133362306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(XEHP_CULLBIT1); 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci *cs++ = MI_LOAD_REGISTER_REG; 133662306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(RING_NOPID(ce->engine->mmio_base)); 133762306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(XEHP_CULLBIT2); 133862306a36Sopenharmony_ci 133962306a36Sopenharmony_ci return cs; 134062306a36Sopenharmony_ci} 134162306a36Sopenharmony_ci 134262306a36Sopenharmony_ci/* 134362306a36Sopenharmony_ci * The bspec's tuning guide asks us to program a vertical watermark value of 134462306a36Sopenharmony_ci * 0x3FF. However this register is not saved/restored properly by the 134562306a36Sopenharmony_ci * hardware, so we're required to apply the desired value via INDIRECT_CTX 134662306a36Sopenharmony_ci * batch buffer to ensure the value takes effect properly. All other bits 134762306a36Sopenharmony_ci * in this register should remain at 0 (the hardware default). 134862306a36Sopenharmony_ci */ 134962306a36Sopenharmony_cistatic u32 * 135062306a36Sopenharmony_cidg2_emit_draw_watermark_setting(u32 *cs) 135162306a36Sopenharmony_ci{ 135262306a36Sopenharmony_ci *cs++ = MI_LOAD_REGISTER_IMM(1); 135362306a36Sopenharmony_ci *cs++ = i915_mmio_reg_offset(DRAW_WATERMARK); 135462306a36Sopenharmony_ci *cs++ = REG_FIELD_PREP(VERT_WM_VAL, 0x3FF); 135562306a36Sopenharmony_ci 135662306a36Sopenharmony_ci return cs; 135762306a36Sopenharmony_ci} 135862306a36Sopenharmony_ci 135962306a36Sopenharmony_cistatic u32 * 136062306a36Sopenharmony_cigen12_emit_indirect_ctx_rcs(const struct intel_context *ce, u32 *cs) 136162306a36Sopenharmony_ci{ 136262306a36Sopenharmony_ci cs = gen12_emit_timestamp_wa(ce, cs); 136362306a36Sopenharmony_ci cs = gen12_emit_cmd_buf_wa(ce, cs); 136462306a36Sopenharmony_ci cs = gen12_emit_restore_scratch(ce, cs); 136562306a36Sopenharmony_ci 136662306a36Sopenharmony_ci /* Wa_22011450934:dg2 */ 136762306a36Sopenharmony_ci if (IS_DG2_GRAPHICS_STEP(ce->engine->i915, G10, STEP_A0, STEP_B0) || 136862306a36Sopenharmony_ci IS_DG2_GRAPHICS_STEP(ce->engine->i915, G11, STEP_A0, STEP_B0)) 136962306a36Sopenharmony_ci cs = dg2_emit_rcs_hang_wabb(ce, cs); 137062306a36Sopenharmony_ci 137162306a36Sopenharmony_ci /* Wa_16013000631:dg2 */ 137262306a36Sopenharmony_ci if (IS_DG2_GRAPHICS_STEP(ce->engine->i915, G10, STEP_B0, STEP_C0) || 137362306a36Sopenharmony_ci IS_DG2_G11(ce->engine->i915)) 137462306a36Sopenharmony_ci cs = gen8_emit_pipe_control(cs, PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE, 0); 137562306a36Sopenharmony_ci 137662306a36Sopenharmony_ci cs = gen12_emit_aux_table_inv(ce->engine, cs); 137762306a36Sopenharmony_ci 137862306a36Sopenharmony_ci /* Wa_16014892111 */ 137962306a36Sopenharmony_ci if (IS_MTL_GRAPHICS_STEP(ce->engine->i915, M, STEP_A0, STEP_B0) || 138062306a36Sopenharmony_ci IS_MTL_GRAPHICS_STEP(ce->engine->i915, P, STEP_A0, STEP_B0) || 138162306a36Sopenharmony_ci IS_DG2(ce->engine->i915)) 138262306a36Sopenharmony_ci cs = dg2_emit_draw_watermark_setting(cs); 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ci return cs; 138562306a36Sopenharmony_ci} 138662306a36Sopenharmony_ci 138762306a36Sopenharmony_cistatic u32 * 138862306a36Sopenharmony_cigen12_emit_indirect_ctx_xcs(const struct intel_context *ce, u32 *cs) 138962306a36Sopenharmony_ci{ 139062306a36Sopenharmony_ci cs = gen12_emit_timestamp_wa(ce, cs); 139162306a36Sopenharmony_ci cs = gen12_emit_restore_scratch(ce, cs); 139262306a36Sopenharmony_ci 139362306a36Sopenharmony_ci /* Wa_16013000631:dg2 */ 139462306a36Sopenharmony_ci if (IS_DG2_GRAPHICS_STEP(ce->engine->i915, G10, STEP_B0, STEP_C0) || 139562306a36Sopenharmony_ci IS_DG2_G11(ce->engine->i915)) 139662306a36Sopenharmony_ci if (ce->engine->class == COMPUTE_CLASS) 139762306a36Sopenharmony_ci cs = gen8_emit_pipe_control(cs, 139862306a36Sopenharmony_ci PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE, 139962306a36Sopenharmony_ci 0); 140062306a36Sopenharmony_ci 140162306a36Sopenharmony_ci return gen12_emit_aux_table_inv(ce->engine, cs); 140262306a36Sopenharmony_ci} 140362306a36Sopenharmony_ci 140462306a36Sopenharmony_cistatic void 140562306a36Sopenharmony_cisetup_indirect_ctx_bb(const struct intel_context *ce, 140662306a36Sopenharmony_ci const struct intel_engine_cs *engine, 140762306a36Sopenharmony_ci u32 *(*emit)(const struct intel_context *, u32 *)) 140862306a36Sopenharmony_ci{ 140962306a36Sopenharmony_ci u32 * const start = context_indirect_bb(ce); 141062306a36Sopenharmony_ci u32 *cs; 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci cs = emit(ce, start); 141362306a36Sopenharmony_ci GEM_BUG_ON(cs - start > I915_GTT_PAGE_SIZE / sizeof(*cs)); 141462306a36Sopenharmony_ci while ((unsigned long)cs % CACHELINE_BYTES) 141562306a36Sopenharmony_ci *cs++ = MI_NOOP; 141662306a36Sopenharmony_ci 141762306a36Sopenharmony_ci GEM_BUG_ON(cs - start > DG2_PREDICATE_RESULT_BB / sizeof(*start)); 141862306a36Sopenharmony_ci setup_predicate_disable_wa(ce, start + DG2_PREDICATE_RESULT_BB / sizeof(*start)); 141962306a36Sopenharmony_ci 142062306a36Sopenharmony_ci lrc_setup_indirect_ctx(ce->lrc_reg_state, engine, 142162306a36Sopenharmony_ci lrc_indirect_bb(ce), 142262306a36Sopenharmony_ci (cs - start) * sizeof(*cs)); 142362306a36Sopenharmony_ci} 142462306a36Sopenharmony_ci 142562306a36Sopenharmony_ci/* 142662306a36Sopenharmony_ci * The context descriptor encodes various attributes of a context, 142762306a36Sopenharmony_ci * including its GTT address and some flags. Because it's fairly 142862306a36Sopenharmony_ci * expensive to calculate, we'll just do it once and cache the result, 142962306a36Sopenharmony_ci * which remains valid until the context is unpinned. 143062306a36Sopenharmony_ci * 143162306a36Sopenharmony_ci * This is what a descriptor looks like, from LSB to MSB:: 143262306a36Sopenharmony_ci * 143362306a36Sopenharmony_ci * bits 0-11: flags, GEN8_CTX_* (cached in ctx->desc_template) 143462306a36Sopenharmony_ci * bits 12-31: LRCA, GTT address of (the HWSP of) this context 143562306a36Sopenharmony_ci * bits 32-52: ctx ID, a globally unique tag (highest bit used by GuC) 143662306a36Sopenharmony_ci * bits 53-54: mbz, reserved for use by hardware 143762306a36Sopenharmony_ci * bits 55-63: group ID, currently unused and set to 0 143862306a36Sopenharmony_ci * 143962306a36Sopenharmony_ci * Starting from Gen11, the upper dword of the descriptor has a new format: 144062306a36Sopenharmony_ci * 144162306a36Sopenharmony_ci * bits 32-36: reserved 144262306a36Sopenharmony_ci * bits 37-47: SW context ID 144362306a36Sopenharmony_ci * bits 48:53: engine instance 144462306a36Sopenharmony_ci * bit 54: mbz, reserved for use by hardware 144562306a36Sopenharmony_ci * bits 55-60: SW counter 144662306a36Sopenharmony_ci * bits 61-63: engine class 144762306a36Sopenharmony_ci * 144862306a36Sopenharmony_ci * On Xe_HP, the upper dword of the descriptor has a new format: 144962306a36Sopenharmony_ci * 145062306a36Sopenharmony_ci * bits 32-37: virtual function number 145162306a36Sopenharmony_ci * bit 38: mbz, reserved for use by hardware 145262306a36Sopenharmony_ci * bits 39-54: SW context ID 145362306a36Sopenharmony_ci * bits 55-57: reserved 145462306a36Sopenharmony_ci * bits 58-63: SW counter 145562306a36Sopenharmony_ci * 145662306a36Sopenharmony_ci * engine info, SW context ID and SW counter need to form a unique number 145762306a36Sopenharmony_ci * (Context ID) per lrc. 145862306a36Sopenharmony_ci */ 145962306a36Sopenharmony_cistatic u32 lrc_descriptor(const struct intel_context *ce) 146062306a36Sopenharmony_ci{ 146162306a36Sopenharmony_ci u32 desc; 146262306a36Sopenharmony_ci 146362306a36Sopenharmony_ci desc = INTEL_LEGACY_32B_CONTEXT; 146462306a36Sopenharmony_ci if (i915_vm_is_4lvl(ce->vm)) 146562306a36Sopenharmony_ci desc = INTEL_LEGACY_64B_CONTEXT; 146662306a36Sopenharmony_ci desc <<= GEN8_CTX_ADDRESSING_MODE_SHIFT; 146762306a36Sopenharmony_ci 146862306a36Sopenharmony_ci desc |= GEN8_CTX_VALID | GEN8_CTX_PRIVILEGE; 146962306a36Sopenharmony_ci if (GRAPHICS_VER(ce->vm->i915) == 8) 147062306a36Sopenharmony_ci desc |= GEN8_CTX_L3LLC_COHERENT; 147162306a36Sopenharmony_ci 147262306a36Sopenharmony_ci return i915_ggtt_offset(ce->state) | desc; 147362306a36Sopenharmony_ci} 147462306a36Sopenharmony_ci 147562306a36Sopenharmony_ciu32 lrc_update_regs(const struct intel_context *ce, 147662306a36Sopenharmony_ci const struct intel_engine_cs *engine, 147762306a36Sopenharmony_ci u32 head) 147862306a36Sopenharmony_ci{ 147962306a36Sopenharmony_ci struct intel_ring *ring = ce->ring; 148062306a36Sopenharmony_ci u32 *regs = ce->lrc_reg_state; 148162306a36Sopenharmony_ci 148262306a36Sopenharmony_ci GEM_BUG_ON(!intel_ring_offset_valid(ring, head)); 148362306a36Sopenharmony_ci GEM_BUG_ON(!intel_ring_offset_valid(ring, ring->tail)); 148462306a36Sopenharmony_ci 148562306a36Sopenharmony_ci regs[CTX_RING_START] = i915_ggtt_offset(ring->vma); 148662306a36Sopenharmony_ci regs[CTX_RING_HEAD] = head; 148762306a36Sopenharmony_ci regs[CTX_RING_TAIL] = ring->tail; 148862306a36Sopenharmony_ci regs[CTX_RING_CTL] = RING_CTL_SIZE(ring->size) | RING_VALID; 148962306a36Sopenharmony_ci 149062306a36Sopenharmony_ci /* RPCS */ 149162306a36Sopenharmony_ci if (engine->class == RENDER_CLASS) { 149262306a36Sopenharmony_ci regs[CTX_R_PWR_CLK_STATE] = 149362306a36Sopenharmony_ci intel_sseu_make_rpcs(engine->gt, &ce->sseu); 149462306a36Sopenharmony_ci 149562306a36Sopenharmony_ci i915_oa_init_reg_state(ce, engine); 149662306a36Sopenharmony_ci } 149762306a36Sopenharmony_ci 149862306a36Sopenharmony_ci if (ce->wa_bb_page) { 149962306a36Sopenharmony_ci u32 *(*fn)(const struct intel_context *ce, u32 *cs); 150062306a36Sopenharmony_ci 150162306a36Sopenharmony_ci fn = gen12_emit_indirect_ctx_xcs; 150262306a36Sopenharmony_ci if (ce->engine->class == RENDER_CLASS) 150362306a36Sopenharmony_ci fn = gen12_emit_indirect_ctx_rcs; 150462306a36Sopenharmony_ci 150562306a36Sopenharmony_ci /* Mutually exclusive wrt to global indirect bb */ 150662306a36Sopenharmony_ci GEM_BUG_ON(engine->wa_ctx.indirect_ctx.size); 150762306a36Sopenharmony_ci setup_indirect_ctx_bb(ce, engine, fn); 150862306a36Sopenharmony_ci } 150962306a36Sopenharmony_ci 151062306a36Sopenharmony_ci return lrc_descriptor(ce) | CTX_DESC_FORCE_RESTORE; 151162306a36Sopenharmony_ci} 151262306a36Sopenharmony_ci 151362306a36Sopenharmony_civoid lrc_update_offsets(struct intel_context *ce, 151462306a36Sopenharmony_ci struct intel_engine_cs *engine) 151562306a36Sopenharmony_ci{ 151662306a36Sopenharmony_ci set_offsets(ce->lrc_reg_state, reg_offsets(engine), engine, false); 151762306a36Sopenharmony_ci} 151862306a36Sopenharmony_ci 151962306a36Sopenharmony_civoid lrc_check_regs(const struct intel_context *ce, 152062306a36Sopenharmony_ci const struct intel_engine_cs *engine, 152162306a36Sopenharmony_ci const char *when) 152262306a36Sopenharmony_ci{ 152362306a36Sopenharmony_ci const struct intel_ring *ring = ce->ring; 152462306a36Sopenharmony_ci u32 *regs = ce->lrc_reg_state; 152562306a36Sopenharmony_ci bool valid = true; 152662306a36Sopenharmony_ci int x; 152762306a36Sopenharmony_ci 152862306a36Sopenharmony_ci if (regs[CTX_RING_START] != i915_ggtt_offset(ring->vma)) { 152962306a36Sopenharmony_ci pr_err("%s: context submitted with incorrect RING_START [%08x], expected %08x\n", 153062306a36Sopenharmony_ci engine->name, 153162306a36Sopenharmony_ci regs[CTX_RING_START], 153262306a36Sopenharmony_ci i915_ggtt_offset(ring->vma)); 153362306a36Sopenharmony_ci regs[CTX_RING_START] = i915_ggtt_offset(ring->vma); 153462306a36Sopenharmony_ci valid = false; 153562306a36Sopenharmony_ci } 153662306a36Sopenharmony_ci 153762306a36Sopenharmony_ci if ((regs[CTX_RING_CTL] & ~(RING_WAIT | RING_WAIT_SEMAPHORE)) != 153862306a36Sopenharmony_ci (RING_CTL_SIZE(ring->size) | RING_VALID)) { 153962306a36Sopenharmony_ci pr_err("%s: context submitted with incorrect RING_CTL [%08x], expected %08x\n", 154062306a36Sopenharmony_ci engine->name, 154162306a36Sopenharmony_ci regs[CTX_RING_CTL], 154262306a36Sopenharmony_ci (u32)(RING_CTL_SIZE(ring->size) | RING_VALID)); 154362306a36Sopenharmony_ci regs[CTX_RING_CTL] = RING_CTL_SIZE(ring->size) | RING_VALID; 154462306a36Sopenharmony_ci valid = false; 154562306a36Sopenharmony_ci } 154662306a36Sopenharmony_ci 154762306a36Sopenharmony_ci x = lrc_ring_mi_mode(engine); 154862306a36Sopenharmony_ci if (x != -1 && regs[x + 1] & (regs[x + 1] >> 16) & STOP_RING) { 154962306a36Sopenharmony_ci pr_err("%s: context submitted with STOP_RING [%08x] in RING_MI_MODE\n", 155062306a36Sopenharmony_ci engine->name, regs[x + 1]); 155162306a36Sopenharmony_ci regs[x + 1] &= ~STOP_RING; 155262306a36Sopenharmony_ci regs[x + 1] |= STOP_RING << 16; 155362306a36Sopenharmony_ci valid = false; 155462306a36Sopenharmony_ci } 155562306a36Sopenharmony_ci 155662306a36Sopenharmony_ci WARN_ONCE(!valid, "Invalid lrc state found %s submission\n", when); 155762306a36Sopenharmony_ci} 155862306a36Sopenharmony_ci 155962306a36Sopenharmony_ci/* 156062306a36Sopenharmony_ci * In this WA we need to set GEN8_L3SQCREG4[21:21] and reset it after 156162306a36Sopenharmony_ci * PIPE_CONTROL instruction. This is required for the flush to happen correctly 156262306a36Sopenharmony_ci * but there is a slight complication as this is applied in WA batch where the 156362306a36Sopenharmony_ci * values are only initialized once so we cannot take register value at the 156462306a36Sopenharmony_ci * beginning and reuse it further; hence we save its value to memory, upload a 156562306a36Sopenharmony_ci * constant value with bit21 set and then we restore it back with the saved value. 156662306a36Sopenharmony_ci * To simplify the WA, a constant value is formed by using the default value 156762306a36Sopenharmony_ci * of this register. This shouldn't be a problem because we are only modifying 156862306a36Sopenharmony_ci * it for a short period and this batch in non-premptible. We can ofcourse 156962306a36Sopenharmony_ci * use additional instructions that read the actual value of the register 157062306a36Sopenharmony_ci * at that time and set our bit of interest but it makes the WA complicated. 157162306a36Sopenharmony_ci * 157262306a36Sopenharmony_ci * This WA is also required for Gen9 so extracting as a function avoids 157362306a36Sopenharmony_ci * code duplication. 157462306a36Sopenharmony_ci */ 157562306a36Sopenharmony_cistatic u32 * 157662306a36Sopenharmony_cigen8_emit_flush_coherentl3_wa(struct intel_engine_cs *engine, u32 *batch) 157762306a36Sopenharmony_ci{ 157862306a36Sopenharmony_ci /* NB no one else is allowed to scribble over scratch + 256! */ 157962306a36Sopenharmony_ci *batch++ = MI_STORE_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT; 158062306a36Sopenharmony_ci *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4); 158162306a36Sopenharmony_ci *batch++ = intel_gt_scratch_offset(engine->gt, 158262306a36Sopenharmony_ci INTEL_GT_SCRATCH_FIELD_COHERENTL3_WA); 158362306a36Sopenharmony_ci *batch++ = 0; 158462306a36Sopenharmony_ci 158562306a36Sopenharmony_ci *batch++ = MI_LOAD_REGISTER_IMM(1); 158662306a36Sopenharmony_ci *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4); 158762306a36Sopenharmony_ci *batch++ = 0x40400000 | GEN8_LQSC_FLUSH_COHERENT_LINES; 158862306a36Sopenharmony_ci 158962306a36Sopenharmony_ci batch = gen8_emit_pipe_control(batch, 159062306a36Sopenharmony_ci PIPE_CONTROL_CS_STALL | 159162306a36Sopenharmony_ci PIPE_CONTROL_DC_FLUSH_ENABLE, 159262306a36Sopenharmony_ci 0); 159362306a36Sopenharmony_ci 159462306a36Sopenharmony_ci *batch++ = MI_LOAD_REGISTER_MEM_GEN8 | MI_SRM_LRM_GLOBAL_GTT; 159562306a36Sopenharmony_ci *batch++ = i915_mmio_reg_offset(GEN8_L3SQCREG4); 159662306a36Sopenharmony_ci *batch++ = intel_gt_scratch_offset(engine->gt, 159762306a36Sopenharmony_ci INTEL_GT_SCRATCH_FIELD_COHERENTL3_WA); 159862306a36Sopenharmony_ci *batch++ = 0; 159962306a36Sopenharmony_ci 160062306a36Sopenharmony_ci return batch; 160162306a36Sopenharmony_ci} 160262306a36Sopenharmony_ci 160362306a36Sopenharmony_ci/* 160462306a36Sopenharmony_ci * Typically we only have one indirect_ctx and per_ctx batch buffer which are 160562306a36Sopenharmony_ci * initialized at the beginning and shared across all contexts but this field 160662306a36Sopenharmony_ci * helps us to have multiple batches at different offsets and select them based 160762306a36Sopenharmony_ci * on a criteria. At the moment this batch always start at the beginning of the page 160862306a36Sopenharmony_ci * and at this point we don't have multiple wa_ctx batch buffers. 160962306a36Sopenharmony_ci * 161062306a36Sopenharmony_ci * The number of WA applied are not known at the beginning; we use this field 161162306a36Sopenharmony_ci * to return the no of DWORDS written. 161262306a36Sopenharmony_ci * 161362306a36Sopenharmony_ci * It is to be noted that this batch does not contain MI_BATCH_BUFFER_END 161462306a36Sopenharmony_ci * so it adds NOOPs as padding to make it cacheline aligned. 161562306a36Sopenharmony_ci * MI_BATCH_BUFFER_END will be added to perctx batch and both of them together 161662306a36Sopenharmony_ci * makes a complete batch buffer. 161762306a36Sopenharmony_ci */ 161862306a36Sopenharmony_cistatic u32 *gen8_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch) 161962306a36Sopenharmony_ci{ 162062306a36Sopenharmony_ci /* WaDisableCtxRestoreArbitration:bdw,chv */ 162162306a36Sopenharmony_ci *batch++ = MI_ARB_ON_OFF | MI_ARB_DISABLE; 162262306a36Sopenharmony_ci 162362306a36Sopenharmony_ci /* WaFlushCoherentL3CacheLinesAtContextSwitch:bdw */ 162462306a36Sopenharmony_ci if (IS_BROADWELL(engine->i915)) 162562306a36Sopenharmony_ci batch = gen8_emit_flush_coherentl3_wa(engine, batch); 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci /* WaClearSlmSpaceAtContextSwitch:bdw,chv */ 162862306a36Sopenharmony_ci /* Actual scratch location is at 128 bytes offset */ 162962306a36Sopenharmony_ci batch = gen8_emit_pipe_control(batch, 163062306a36Sopenharmony_ci PIPE_CONTROL_FLUSH_L3 | 163162306a36Sopenharmony_ci PIPE_CONTROL_STORE_DATA_INDEX | 163262306a36Sopenharmony_ci PIPE_CONTROL_CS_STALL | 163362306a36Sopenharmony_ci PIPE_CONTROL_QW_WRITE, 163462306a36Sopenharmony_ci LRC_PPHWSP_SCRATCH_ADDR); 163562306a36Sopenharmony_ci 163662306a36Sopenharmony_ci *batch++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; 163762306a36Sopenharmony_ci 163862306a36Sopenharmony_ci /* Pad to end of cacheline */ 163962306a36Sopenharmony_ci while ((unsigned long)batch % CACHELINE_BYTES) 164062306a36Sopenharmony_ci *batch++ = MI_NOOP; 164162306a36Sopenharmony_ci 164262306a36Sopenharmony_ci /* 164362306a36Sopenharmony_ci * MI_BATCH_BUFFER_END is not required in Indirect ctx BB because 164462306a36Sopenharmony_ci * execution depends on the length specified in terms of cache lines 164562306a36Sopenharmony_ci * in the register CTX_RCS_INDIRECT_CTX 164662306a36Sopenharmony_ci */ 164762306a36Sopenharmony_ci 164862306a36Sopenharmony_ci return batch; 164962306a36Sopenharmony_ci} 165062306a36Sopenharmony_ci 165162306a36Sopenharmony_cistruct lri { 165262306a36Sopenharmony_ci i915_reg_t reg; 165362306a36Sopenharmony_ci u32 value; 165462306a36Sopenharmony_ci}; 165562306a36Sopenharmony_ci 165662306a36Sopenharmony_cistatic u32 *emit_lri(u32 *batch, const struct lri *lri, unsigned int count) 165762306a36Sopenharmony_ci{ 165862306a36Sopenharmony_ci GEM_BUG_ON(!count || count > 63); 165962306a36Sopenharmony_ci 166062306a36Sopenharmony_ci *batch++ = MI_LOAD_REGISTER_IMM(count); 166162306a36Sopenharmony_ci do { 166262306a36Sopenharmony_ci *batch++ = i915_mmio_reg_offset(lri->reg); 166362306a36Sopenharmony_ci *batch++ = lri->value; 166462306a36Sopenharmony_ci } while (lri++, --count); 166562306a36Sopenharmony_ci *batch++ = MI_NOOP; 166662306a36Sopenharmony_ci 166762306a36Sopenharmony_ci return batch; 166862306a36Sopenharmony_ci} 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_cistatic u32 *gen9_init_indirectctx_bb(struct intel_engine_cs *engine, u32 *batch) 167162306a36Sopenharmony_ci{ 167262306a36Sopenharmony_ci static const struct lri lri[] = { 167362306a36Sopenharmony_ci /* WaDisableGatherAtSetShaderCommonSlice:skl,bxt,kbl,glk */ 167462306a36Sopenharmony_ci { 167562306a36Sopenharmony_ci COMMON_SLICE_CHICKEN2, 167662306a36Sopenharmony_ci __MASKED_FIELD(GEN9_DISABLE_GATHER_AT_SET_SHADER_COMMON_SLICE, 167762306a36Sopenharmony_ci 0), 167862306a36Sopenharmony_ci }, 167962306a36Sopenharmony_ci 168062306a36Sopenharmony_ci /* BSpec: 11391 */ 168162306a36Sopenharmony_ci { 168262306a36Sopenharmony_ci FF_SLICE_CHICKEN, 168362306a36Sopenharmony_ci __MASKED_FIELD(FF_SLICE_CHICKEN_CL_PROVOKING_VERTEX_FIX, 168462306a36Sopenharmony_ci FF_SLICE_CHICKEN_CL_PROVOKING_VERTEX_FIX), 168562306a36Sopenharmony_ci }, 168662306a36Sopenharmony_ci 168762306a36Sopenharmony_ci /* BSpec: 11299 */ 168862306a36Sopenharmony_ci { 168962306a36Sopenharmony_ci _3D_CHICKEN3, 169062306a36Sopenharmony_ci __MASKED_FIELD(_3D_CHICKEN_SF_PROVOKING_VERTEX_FIX, 169162306a36Sopenharmony_ci _3D_CHICKEN_SF_PROVOKING_VERTEX_FIX), 169262306a36Sopenharmony_ci } 169362306a36Sopenharmony_ci }; 169462306a36Sopenharmony_ci 169562306a36Sopenharmony_ci *batch++ = MI_ARB_ON_OFF | MI_ARB_DISABLE; 169662306a36Sopenharmony_ci 169762306a36Sopenharmony_ci /* WaFlushCoherentL3CacheLinesAtContextSwitch:skl,bxt,glk */ 169862306a36Sopenharmony_ci batch = gen8_emit_flush_coherentl3_wa(engine, batch); 169962306a36Sopenharmony_ci 170062306a36Sopenharmony_ci /* WaClearSlmSpaceAtContextSwitch:skl,bxt,kbl,glk,cfl */ 170162306a36Sopenharmony_ci batch = gen8_emit_pipe_control(batch, 170262306a36Sopenharmony_ci PIPE_CONTROL_FLUSH_L3 | 170362306a36Sopenharmony_ci PIPE_CONTROL_STORE_DATA_INDEX | 170462306a36Sopenharmony_ci PIPE_CONTROL_CS_STALL | 170562306a36Sopenharmony_ci PIPE_CONTROL_QW_WRITE, 170662306a36Sopenharmony_ci LRC_PPHWSP_SCRATCH_ADDR); 170762306a36Sopenharmony_ci 170862306a36Sopenharmony_ci batch = emit_lri(batch, lri, ARRAY_SIZE(lri)); 170962306a36Sopenharmony_ci 171062306a36Sopenharmony_ci /* WaMediaPoolStateCmdInWABB:bxt,glk */ 171162306a36Sopenharmony_ci if (HAS_POOLED_EU(engine->i915)) { 171262306a36Sopenharmony_ci /* 171362306a36Sopenharmony_ci * EU pool configuration is setup along with golden context 171462306a36Sopenharmony_ci * during context initialization. This value depends on 171562306a36Sopenharmony_ci * device type (2x6 or 3x6) and needs to be updated based 171662306a36Sopenharmony_ci * on which subslice is disabled especially for 2x6 171762306a36Sopenharmony_ci * devices, however it is safe to load default 171862306a36Sopenharmony_ci * configuration of 3x6 device instead of masking off 171962306a36Sopenharmony_ci * corresponding bits because HW ignores bits of a disabled 172062306a36Sopenharmony_ci * subslice and drops down to appropriate config. Please 172162306a36Sopenharmony_ci * see render_state_setup() in i915_gem_render_state.c for 172262306a36Sopenharmony_ci * possible configurations, to avoid duplication they are 172362306a36Sopenharmony_ci * not shown here again. 172462306a36Sopenharmony_ci */ 172562306a36Sopenharmony_ci *batch++ = GEN9_MEDIA_POOL_STATE; 172662306a36Sopenharmony_ci *batch++ = GEN9_MEDIA_POOL_ENABLE; 172762306a36Sopenharmony_ci *batch++ = 0x00777000; 172862306a36Sopenharmony_ci *batch++ = 0; 172962306a36Sopenharmony_ci *batch++ = 0; 173062306a36Sopenharmony_ci *batch++ = 0; 173162306a36Sopenharmony_ci } 173262306a36Sopenharmony_ci 173362306a36Sopenharmony_ci *batch++ = MI_ARB_ON_OFF | MI_ARB_ENABLE; 173462306a36Sopenharmony_ci 173562306a36Sopenharmony_ci /* Pad to end of cacheline */ 173662306a36Sopenharmony_ci while ((unsigned long)batch % CACHELINE_BYTES) 173762306a36Sopenharmony_ci *batch++ = MI_NOOP; 173862306a36Sopenharmony_ci 173962306a36Sopenharmony_ci return batch; 174062306a36Sopenharmony_ci} 174162306a36Sopenharmony_ci 174262306a36Sopenharmony_ci#define CTX_WA_BB_SIZE (PAGE_SIZE) 174362306a36Sopenharmony_ci 174462306a36Sopenharmony_cistatic int lrc_create_wa_ctx(struct intel_engine_cs *engine) 174562306a36Sopenharmony_ci{ 174662306a36Sopenharmony_ci struct drm_i915_gem_object *obj; 174762306a36Sopenharmony_ci struct i915_vma *vma; 174862306a36Sopenharmony_ci int err; 174962306a36Sopenharmony_ci 175062306a36Sopenharmony_ci obj = i915_gem_object_create_shmem(engine->i915, CTX_WA_BB_SIZE); 175162306a36Sopenharmony_ci if (IS_ERR(obj)) 175262306a36Sopenharmony_ci return PTR_ERR(obj); 175362306a36Sopenharmony_ci 175462306a36Sopenharmony_ci vma = i915_vma_instance(obj, &engine->gt->ggtt->vm, NULL); 175562306a36Sopenharmony_ci if (IS_ERR(vma)) { 175662306a36Sopenharmony_ci err = PTR_ERR(vma); 175762306a36Sopenharmony_ci goto err; 175862306a36Sopenharmony_ci } 175962306a36Sopenharmony_ci 176062306a36Sopenharmony_ci engine->wa_ctx.vma = vma; 176162306a36Sopenharmony_ci return 0; 176262306a36Sopenharmony_ci 176362306a36Sopenharmony_cierr: 176462306a36Sopenharmony_ci i915_gem_object_put(obj); 176562306a36Sopenharmony_ci return err; 176662306a36Sopenharmony_ci} 176762306a36Sopenharmony_ci 176862306a36Sopenharmony_civoid lrc_fini_wa_ctx(struct intel_engine_cs *engine) 176962306a36Sopenharmony_ci{ 177062306a36Sopenharmony_ci i915_vma_unpin_and_release(&engine->wa_ctx.vma, 0); 177162306a36Sopenharmony_ci} 177262306a36Sopenharmony_ci 177362306a36Sopenharmony_citypedef u32 *(*wa_bb_func_t)(struct intel_engine_cs *engine, u32 *batch); 177462306a36Sopenharmony_ci 177562306a36Sopenharmony_civoid lrc_init_wa_ctx(struct intel_engine_cs *engine) 177662306a36Sopenharmony_ci{ 177762306a36Sopenharmony_ci struct i915_ctx_workarounds *wa_ctx = &engine->wa_ctx; 177862306a36Sopenharmony_ci struct i915_wa_ctx_bb *wa_bb[] = { 177962306a36Sopenharmony_ci &wa_ctx->indirect_ctx, &wa_ctx->per_ctx 178062306a36Sopenharmony_ci }; 178162306a36Sopenharmony_ci wa_bb_func_t wa_bb_fn[ARRAY_SIZE(wa_bb)]; 178262306a36Sopenharmony_ci struct i915_gem_ww_ctx ww; 178362306a36Sopenharmony_ci void *batch, *batch_ptr; 178462306a36Sopenharmony_ci unsigned int i; 178562306a36Sopenharmony_ci int err; 178662306a36Sopenharmony_ci 178762306a36Sopenharmony_ci if (GRAPHICS_VER(engine->i915) >= 11 || 178862306a36Sopenharmony_ci !(engine->flags & I915_ENGINE_HAS_RCS_REG_STATE)) 178962306a36Sopenharmony_ci return; 179062306a36Sopenharmony_ci 179162306a36Sopenharmony_ci if (GRAPHICS_VER(engine->i915) == 9) { 179262306a36Sopenharmony_ci wa_bb_fn[0] = gen9_init_indirectctx_bb; 179362306a36Sopenharmony_ci wa_bb_fn[1] = NULL; 179462306a36Sopenharmony_ci } else if (GRAPHICS_VER(engine->i915) == 8) { 179562306a36Sopenharmony_ci wa_bb_fn[0] = gen8_init_indirectctx_bb; 179662306a36Sopenharmony_ci wa_bb_fn[1] = NULL; 179762306a36Sopenharmony_ci } 179862306a36Sopenharmony_ci 179962306a36Sopenharmony_ci err = lrc_create_wa_ctx(engine); 180062306a36Sopenharmony_ci if (err) { 180162306a36Sopenharmony_ci /* 180262306a36Sopenharmony_ci * We continue even if we fail to initialize WA batch 180362306a36Sopenharmony_ci * because we only expect rare glitches but nothing 180462306a36Sopenharmony_ci * critical to prevent us from using GPU 180562306a36Sopenharmony_ci */ 180662306a36Sopenharmony_ci drm_err(&engine->i915->drm, 180762306a36Sopenharmony_ci "Ignoring context switch w/a allocation error:%d\n", 180862306a36Sopenharmony_ci err); 180962306a36Sopenharmony_ci return; 181062306a36Sopenharmony_ci } 181162306a36Sopenharmony_ci 181262306a36Sopenharmony_ci if (!engine->wa_ctx.vma) 181362306a36Sopenharmony_ci return; 181462306a36Sopenharmony_ci 181562306a36Sopenharmony_ci i915_gem_ww_ctx_init(&ww, true); 181662306a36Sopenharmony_ciretry: 181762306a36Sopenharmony_ci err = i915_gem_object_lock(wa_ctx->vma->obj, &ww); 181862306a36Sopenharmony_ci if (!err) 181962306a36Sopenharmony_ci err = i915_ggtt_pin(wa_ctx->vma, &ww, 0, PIN_HIGH); 182062306a36Sopenharmony_ci if (err) 182162306a36Sopenharmony_ci goto err; 182262306a36Sopenharmony_ci 182362306a36Sopenharmony_ci batch = i915_gem_object_pin_map(wa_ctx->vma->obj, I915_MAP_WB); 182462306a36Sopenharmony_ci if (IS_ERR(batch)) { 182562306a36Sopenharmony_ci err = PTR_ERR(batch); 182662306a36Sopenharmony_ci goto err_unpin; 182762306a36Sopenharmony_ci } 182862306a36Sopenharmony_ci 182962306a36Sopenharmony_ci /* 183062306a36Sopenharmony_ci * Emit the two workaround batch buffers, recording the offset from the 183162306a36Sopenharmony_ci * start of the workaround batch buffer object for each and their 183262306a36Sopenharmony_ci * respective sizes. 183362306a36Sopenharmony_ci */ 183462306a36Sopenharmony_ci batch_ptr = batch; 183562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(wa_bb_fn); i++) { 183662306a36Sopenharmony_ci wa_bb[i]->offset = batch_ptr - batch; 183762306a36Sopenharmony_ci if (GEM_DEBUG_WARN_ON(!IS_ALIGNED(wa_bb[i]->offset, 183862306a36Sopenharmony_ci CACHELINE_BYTES))) { 183962306a36Sopenharmony_ci err = -EINVAL; 184062306a36Sopenharmony_ci break; 184162306a36Sopenharmony_ci } 184262306a36Sopenharmony_ci if (wa_bb_fn[i]) 184362306a36Sopenharmony_ci batch_ptr = wa_bb_fn[i](engine, batch_ptr); 184462306a36Sopenharmony_ci wa_bb[i]->size = batch_ptr - (batch + wa_bb[i]->offset); 184562306a36Sopenharmony_ci } 184662306a36Sopenharmony_ci GEM_BUG_ON(batch_ptr - batch > CTX_WA_BB_SIZE); 184762306a36Sopenharmony_ci 184862306a36Sopenharmony_ci __i915_gem_object_flush_map(wa_ctx->vma->obj, 0, batch_ptr - batch); 184962306a36Sopenharmony_ci __i915_gem_object_release_map(wa_ctx->vma->obj); 185062306a36Sopenharmony_ci 185162306a36Sopenharmony_ci /* Verify that we can handle failure to setup the wa_ctx */ 185262306a36Sopenharmony_ci if (!err) 185362306a36Sopenharmony_ci err = i915_inject_probe_error(engine->i915, -ENODEV); 185462306a36Sopenharmony_ci 185562306a36Sopenharmony_cierr_unpin: 185662306a36Sopenharmony_ci if (err) 185762306a36Sopenharmony_ci i915_vma_unpin(wa_ctx->vma); 185862306a36Sopenharmony_cierr: 185962306a36Sopenharmony_ci if (err == -EDEADLK) { 186062306a36Sopenharmony_ci err = i915_gem_ww_ctx_backoff(&ww); 186162306a36Sopenharmony_ci if (!err) 186262306a36Sopenharmony_ci goto retry; 186362306a36Sopenharmony_ci } 186462306a36Sopenharmony_ci i915_gem_ww_ctx_fini(&ww); 186562306a36Sopenharmony_ci 186662306a36Sopenharmony_ci if (err) { 186762306a36Sopenharmony_ci i915_vma_put(engine->wa_ctx.vma); 186862306a36Sopenharmony_ci 186962306a36Sopenharmony_ci /* Clear all flags to prevent further use */ 187062306a36Sopenharmony_ci memset(wa_ctx, 0, sizeof(*wa_ctx)); 187162306a36Sopenharmony_ci } 187262306a36Sopenharmony_ci} 187362306a36Sopenharmony_ci 187462306a36Sopenharmony_cistatic void st_runtime_underflow(struct intel_context_stats *stats, s32 dt) 187562306a36Sopenharmony_ci{ 187662306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) 187762306a36Sopenharmony_ci stats->runtime.num_underflow++; 187862306a36Sopenharmony_ci stats->runtime.max_underflow = 187962306a36Sopenharmony_ci max_t(u32, stats->runtime.max_underflow, -dt); 188062306a36Sopenharmony_ci#endif 188162306a36Sopenharmony_ci} 188262306a36Sopenharmony_ci 188362306a36Sopenharmony_cistatic u32 lrc_get_runtime(const struct intel_context *ce) 188462306a36Sopenharmony_ci{ 188562306a36Sopenharmony_ci /* 188662306a36Sopenharmony_ci * We can use either ppHWSP[16] which is recorded before the context 188762306a36Sopenharmony_ci * switch (and so excludes the cost of context switches) or use the 188862306a36Sopenharmony_ci * value from the context image itself, which is saved/restored earlier 188962306a36Sopenharmony_ci * and so includes the cost of the save. 189062306a36Sopenharmony_ci */ 189162306a36Sopenharmony_ci return READ_ONCE(ce->lrc_reg_state[CTX_TIMESTAMP]); 189262306a36Sopenharmony_ci} 189362306a36Sopenharmony_ci 189462306a36Sopenharmony_civoid lrc_update_runtime(struct intel_context *ce) 189562306a36Sopenharmony_ci{ 189662306a36Sopenharmony_ci struct intel_context_stats *stats = &ce->stats; 189762306a36Sopenharmony_ci u32 old; 189862306a36Sopenharmony_ci s32 dt; 189962306a36Sopenharmony_ci 190062306a36Sopenharmony_ci old = stats->runtime.last; 190162306a36Sopenharmony_ci stats->runtime.last = lrc_get_runtime(ce); 190262306a36Sopenharmony_ci dt = stats->runtime.last - old; 190362306a36Sopenharmony_ci if (!dt) 190462306a36Sopenharmony_ci return; 190562306a36Sopenharmony_ci 190662306a36Sopenharmony_ci if (unlikely(dt < 0)) { 190762306a36Sopenharmony_ci CE_TRACE(ce, "runtime underflow: last=%u, new=%u, delta=%d\n", 190862306a36Sopenharmony_ci old, stats->runtime.last, dt); 190962306a36Sopenharmony_ci st_runtime_underflow(stats, dt); 191062306a36Sopenharmony_ci return; 191162306a36Sopenharmony_ci } 191262306a36Sopenharmony_ci 191362306a36Sopenharmony_ci ewma_runtime_add(&stats->runtime.avg, dt); 191462306a36Sopenharmony_ci stats->runtime.total += dt; 191562306a36Sopenharmony_ci} 191662306a36Sopenharmony_ci 191762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST) 191862306a36Sopenharmony_ci#include "selftest_lrc.c" 191962306a36Sopenharmony_ci#endif 1920