brintos

brintos / linux-shallow public Read only

0
0
Text · 89.8 KiB · e539a65 Raw
3113 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright © 2014-2018 Intel Corporation4 */5 6#include "i915_drv.h"7#include "i915_reg.h"8#include "intel_context.h"9#include "intel_engine_pm.h"10#include "intel_engine_regs.h"11#include "intel_gpu_commands.h"12#include "intel_gt.h"13#include "intel_gt_ccs_mode.h"14#include "intel_gt_mcr.h"15#include "intel_gt_print.h"16#include "intel_gt_regs.h"17#include "intel_ring.h"18#include "intel_workarounds.h"19 20#include "display/intel_fbc_regs.h"21 22/**23 * DOC: Hardware workarounds24 *25 * Hardware workarounds are register programming documented to be executed in26 * the driver that fall outside of the normal programming sequences for a27 * platform. There are some basic categories of workarounds, depending on28 * how/when they are applied:29 *30 * - Context workarounds: workarounds that touch registers that are31 *   saved/restored to/from the HW context image. The list is emitted (via Load32 *   Register Immediate commands) once when initializing the device and saved in33 *   the default context. That default context is then used on every context34 *   creation to have a "primed golden context", i.e. a context image that35 *   already contains the changes needed to all the registers.36 *37 *   Context workarounds should be implemented in the \*_ctx_workarounds_init()38 *   variants respective to the targeted platforms.39 *40 * - Engine workarounds: the list of these WAs is applied whenever the specific41 *   engine is reset. It's also possible that a set of engine classes share a42 *   common power domain and they are reset together. This happens on some43 *   platforms with render and compute engines. In this case (at least) one of44 *   them need to keeep the workaround programming: the approach taken in the45 *   driver is to tie those workarounds to the first compute/render engine that46 *   is registered.  When executing with GuC submission, engine resets are47 *   outside of kernel driver control, hence the list of registers involved in48 *   written once, on engine initialization, and then passed to GuC, that49 *   saves/restores their values before/after the reset takes place. See50 *   ``drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c`` for reference.51 *52 *   Workarounds for registers specific to RCS and CCS should be implemented in53 *   rcs_engine_wa_init() and ccs_engine_wa_init(), respectively; those for54 *   registers belonging to BCS, VCS or VECS should be implemented in55 *   xcs_engine_wa_init(). Workarounds for registers not belonging to a specific56 *   engine's MMIO range but that are part of of the common RCS/CCS reset domain57 *   should be implemented in general_render_compute_wa_init(). The settings58 *   about the CCS load balancing should be added in ccs_engine_wa_mode().59 *60 * - GT workarounds: the list of these WAs is applied whenever these registers61 *   revert to their default values: on GPU reset, suspend/resume [1]_, etc.62 *63 *   GT workarounds should be implemented in the \*_gt_workarounds_init()64 *   variants respective to the targeted platforms.65 *66 * - Register whitelist: some workarounds need to be implemented in userspace,67 *   but need to touch privileged registers. The whitelist in the kernel68 *   instructs the hardware to allow the access to happen. From the kernel side,69 *   this is just a special case of a MMIO workaround (as we write the list of70 *   these to/be-whitelisted registers to some special HW registers).71 *72 *   Register whitelisting should be done in the \*_whitelist_build() variants73 *   respective to the targeted platforms.74 *75 * - Workaround batchbuffers: buffers that get executed automatically by the76 *   hardware on every HW context restore. These buffers are created and77 *   programmed in the default context so the hardware always go through those78 *   programming sequences when switching contexts. The support for workaround79 *   batchbuffers is enabled these hardware mechanisms:80 *81 *   #. INDIRECT_CTX: A batchbuffer and an offset are provided in the default82 *      context, pointing the hardware to jump to that location when that offset83 *      is reached in the context restore. Workaround batchbuffer in the driver84 *      currently uses this mechanism for all platforms.85 *86 *   #. BB_PER_CTX_PTR: A batchbuffer is provided in the default context,87 *      pointing the hardware to a buffer to continue executing after the88 *      engine registers are restored in a context restore sequence. This is89 *      currently not used in the driver.90 *91 * - Other:  There are WAs that, due to their nature, cannot be applied from a92 *   central place. Those are peppered around the rest of the code, as needed.93 *   Workarounds related to the display IP are the main example.94 *95 * .. [1] Technically, some registers are powercontext saved & restored, so they96 *    survive a suspend/resume. In practice, writing them again is not too97 *    costly and simplifies things, so it's the approach taken in the driver.98 */99 100static void wa_init_start(struct i915_wa_list *wal, struct intel_gt *gt,101			  const char *name, const char *engine_name)102{103	wal->gt = gt;104	wal->name = name;105	wal->engine_name = engine_name;106}107 108#define WA_LIST_CHUNK (1 << 4)109 110static void wa_init_finish(struct i915_wa_list *wal)111{112	/* Trim unused entries. */113	if (!IS_ALIGNED(wal->count, WA_LIST_CHUNK)) {114		struct i915_wa *list = kmemdup_array(wal->list, wal->count,115						     sizeof(*list), GFP_KERNEL);116 117		if (list) {118			kfree(wal->list);119			wal->list = list;120		}121	}122 123	if (!wal->count)124		return;125 126	gt_dbg(wal->gt, "Initialized %u %s workarounds on %s\n",127	       wal->wa_count, wal->name, wal->engine_name);128}129 130static enum forcewake_domains131wal_get_fw_for_rmw(struct intel_uncore *uncore, const struct i915_wa_list *wal)132{133	enum forcewake_domains fw = 0;134	struct i915_wa *wa;135	unsigned int i;136 137	for (i = 0, wa = wal->list; i < wal->count; i++, wa++)138		fw |= intel_uncore_forcewake_for_reg(uncore,139						     wa->reg,140						     FW_REG_READ |141						     FW_REG_WRITE);142 143	return fw;144}145 146static void _wa_add(struct i915_wa_list *wal, const struct i915_wa *wa)147{148	unsigned int addr = i915_mmio_reg_offset(wa->reg);149	struct drm_i915_private *i915 = wal->gt->i915;150	unsigned int start = 0, end = wal->count;151	const unsigned int grow = WA_LIST_CHUNK;152	struct i915_wa *wa_;153 154	GEM_BUG_ON(!is_power_of_2(grow));155 156	if (IS_ALIGNED(wal->count, grow)) { /* Either uninitialized or full. */157		struct i915_wa *list;158 159		list = kmalloc_array(ALIGN(wal->count + 1, grow), sizeof(*wa),160				     GFP_KERNEL);161		if (!list) {162			drm_err(&i915->drm, "No space for workaround init!\n");163			return;164		}165 166		if (wal->list) {167			memcpy(list, wal->list, sizeof(*wa) * wal->count);168			kfree(wal->list);169		}170 171		wal->list = list;172	}173 174	while (start < end) {175		unsigned int mid = start + (end - start) / 2;176 177		if (i915_mmio_reg_offset(wal->list[mid].reg) < addr) {178			start = mid + 1;179		} else if (i915_mmio_reg_offset(wal->list[mid].reg) > addr) {180			end = mid;181		} else {182			wa_ = &wal->list[mid];183 184			if ((wa->clr | wa_->clr) && !(wa->clr & ~wa_->clr)) {185				drm_err(&i915->drm,186					"Discarding overwritten w/a for reg %04x (clear: %08x, set: %08x)\n",187					i915_mmio_reg_offset(wa_->reg),188					wa_->clr, wa_->set);189 190				wa_->set &= ~wa->clr;191			}192 193			wal->wa_count++;194			wa_->set |= wa->set;195			wa_->clr |= wa->clr;196			wa_->read |= wa->read;197			return;198		}199	}200 201	wal->wa_count++;202	wa_ = &wal->list[wal->count++];203	*wa_ = *wa;204 205	while (wa_-- > wal->list) {206		GEM_BUG_ON(i915_mmio_reg_offset(wa_[0].reg) ==207			   i915_mmio_reg_offset(wa_[1].reg));208		if (i915_mmio_reg_offset(wa_[1].reg) >209		    i915_mmio_reg_offset(wa_[0].reg))210			break;211 212		swap(wa_[1], wa_[0]);213	}214}215 216static void wa_add(struct i915_wa_list *wal, i915_reg_t reg,217		   u32 clear, u32 set, u32 read_mask, bool masked_reg)218{219	struct i915_wa wa = {220		.reg  = reg,221		.clr  = clear,222		.set  = set,223		.read = read_mask,224		.masked_reg = masked_reg,225	};226 227	_wa_add(wal, &wa);228}229 230static void wa_mcr_add(struct i915_wa_list *wal, i915_mcr_reg_t reg,231		       u32 clear, u32 set, u32 read_mask, bool masked_reg)232{233	struct i915_wa wa = {234		.mcr_reg = reg,235		.clr  = clear,236		.set  = set,237		.read = read_mask,238		.masked_reg = masked_reg,239		.is_mcr = 1,240	};241 242	_wa_add(wal, &wa);243}244 245static void246wa_write_clr_set(struct i915_wa_list *wal, i915_reg_t reg, u32 clear, u32 set)247{248	wa_add(wal, reg, clear, set, clear | set, false);249}250 251static void252wa_mcr_write_clr_set(struct i915_wa_list *wal, i915_mcr_reg_t reg, u32 clear, u32 set)253{254	wa_mcr_add(wal, reg, clear, set, clear | set, false);255}256 257static void258wa_write(struct i915_wa_list *wal, i915_reg_t reg, u32 set)259{260	wa_write_clr_set(wal, reg, ~0, set);261}262 263static void264wa_write_or(struct i915_wa_list *wal, i915_reg_t reg, u32 set)265{266	wa_write_clr_set(wal, reg, set, set);267}268 269static void270wa_mcr_write_or(struct i915_wa_list *wal, i915_mcr_reg_t reg, u32 set)271{272	wa_mcr_write_clr_set(wal, reg, set, set);273}274 275static void276wa_write_clr(struct i915_wa_list *wal, i915_reg_t reg, u32 clr)277{278	wa_write_clr_set(wal, reg, clr, 0);279}280 281static void282wa_mcr_write_clr(struct i915_wa_list *wal, i915_mcr_reg_t reg, u32 clr)283{284	wa_mcr_write_clr_set(wal, reg, clr, 0);285}286 287/*288 * WA operations on "masked register". A masked register has the upper 16 bits289 * documented as "masked" in b-spec. Its purpose is to allow writing to just a290 * portion of the register without a rmw: you simply write in the upper 16 bits291 * the mask of bits you are going to modify.292 *293 * The wa_masked_* family of functions already does the necessary operations to294 * calculate the mask based on the parameters passed, so user only has to295 * provide the lower 16 bits of that register.296 */297 298static void299wa_masked_en(struct i915_wa_list *wal, i915_reg_t reg, u32 val)300{301	wa_add(wal, reg, 0, _MASKED_BIT_ENABLE(val), val, true);302}303 304static void305wa_mcr_masked_en(struct i915_wa_list *wal, i915_mcr_reg_t reg, u32 val)306{307	wa_mcr_add(wal, reg, 0, _MASKED_BIT_ENABLE(val), val, true);308}309 310static void311wa_masked_dis(struct i915_wa_list *wal, i915_reg_t reg, u32 val)312{313	wa_add(wal, reg, 0, _MASKED_BIT_DISABLE(val), val, true);314}315 316static void317wa_mcr_masked_dis(struct i915_wa_list *wal, i915_mcr_reg_t reg, u32 val)318{319	wa_mcr_add(wal, reg, 0, _MASKED_BIT_DISABLE(val), val, true);320}321 322static void323wa_masked_field_set(struct i915_wa_list *wal, i915_reg_t reg,324		    u32 mask, u32 val)325{326	wa_add(wal, reg, 0, _MASKED_FIELD(mask, val), mask, true);327}328 329static void330wa_mcr_masked_field_set(struct i915_wa_list *wal, i915_mcr_reg_t reg,331			u32 mask, u32 val)332{333	wa_mcr_add(wal, reg, 0, _MASKED_FIELD(mask, val), mask, true);334}335 336static void gen6_ctx_workarounds_init(struct intel_engine_cs *engine,337				      struct i915_wa_list *wal)338{339	wa_masked_en(wal, INSTPM, INSTPM_FORCE_ORDERING);340}341 342static void gen7_ctx_workarounds_init(struct intel_engine_cs *engine,343				      struct i915_wa_list *wal)344{345	wa_masked_en(wal, INSTPM, INSTPM_FORCE_ORDERING);346}347 348static void gen8_ctx_workarounds_init(struct intel_engine_cs *engine,349				      struct i915_wa_list *wal)350{351	wa_masked_en(wal, INSTPM, INSTPM_FORCE_ORDERING);352 353	/* WaDisableAsyncFlipPerfMode:bdw,chv */354	wa_masked_en(wal, RING_MI_MODE(RENDER_RING_BASE), ASYNC_FLIP_PERF_DISABLE);355 356	/* WaDisablePartialInstShootdown:bdw,chv */357	wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN,358			 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);359 360	/* Use Force Non-Coherent whenever executing a 3D context. This is a361	 * workaround for a possible hang in the unlikely event a TLB362	 * invalidation occurs during a PSD flush.363	 */364	/* WaForceEnableNonCoherent:bdw,chv */365	/* WaHdcDisableFetchWhenMasked:bdw,chv */366	wa_masked_en(wal, HDC_CHICKEN0,367		     HDC_DONOT_FETCH_MEM_WHEN_MASKED |368		     HDC_FORCE_NON_COHERENT);369 370	/* From the Haswell PRM, Command Reference: Registers, CACHE_MODE_0:371	 * "The Hierarchical Z RAW Stall Optimization allows non-overlapping372	 *  polygons in the same 8x4 pixel/sample area to be processed without373	 *  stalling waiting for the earlier ones to write to Hierarchical Z374	 *  buffer."375	 *376	 * This optimization is off by default for BDW and CHV; turn it on.377	 */378	wa_masked_dis(wal, CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);379 380	/* Wa4x4STCOptimizationDisable:bdw,chv */381	wa_masked_en(wal, CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE);382 383	/*384	 * BSpec recommends 8x4 when MSAA is used,385	 * however in practice 16x4 seems fastest.386	 *387	 * Note that PS/WM thread counts depend on the WIZ hashing388	 * disable bit, which we don't touch here, but it's good389	 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).390	 */391	wa_masked_field_set(wal, GEN7_GT_MODE,392			    GEN6_WIZ_HASHING_MASK,393			    GEN6_WIZ_HASHING_16x4);394}395 396static void bdw_ctx_workarounds_init(struct intel_engine_cs *engine,397				     struct i915_wa_list *wal)398{399	struct drm_i915_private *i915 = engine->i915;400 401	gen8_ctx_workarounds_init(engine, wal);402 403	/* WaDisableThreadStallDopClockGating:bdw (pre-production) */404	wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);405 406	/* WaDisableDopClockGating:bdw407	 *408	 * Also see the related UCGTCL1 write in bdw_init_clock_gating()409	 * to disable EUTC clock gating.410	 */411	wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN2,412			 DOP_CLOCK_GATING_DISABLE);413 414	wa_mcr_masked_en(wal, GEN8_HALF_SLICE_CHICKEN3,415			 GEN8_SAMPLER_POWER_BYPASS_DIS);416 417	wa_masked_en(wal, HDC_CHICKEN0,418		     /* WaForceContextSaveRestoreNonCoherent:bdw */419		     HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |420		     /* WaDisableFenceDestinationToSLM:bdw (pre-prod) */421		     (IS_BROADWELL_GT3(i915) ? HDC_FENCE_DEST_SLM_DISABLE : 0));422}423 424static void chv_ctx_workarounds_init(struct intel_engine_cs *engine,425				     struct i915_wa_list *wal)426{427	gen8_ctx_workarounds_init(engine, wal);428 429	/* WaDisableThreadStallDopClockGating:chv */430	wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);431 432	/* Improve HiZ throughput on CHV. */433	wa_masked_en(wal, HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X);434}435 436static void gen9_ctx_workarounds_init(struct intel_engine_cs *engine,437				      struct i915_wa_list *wal)438{439	struct drm_i915_private *i915 = engine->i915;440 441	if (HAS_LLC(i915)) {442		/* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl443		 *444		 * Must match Display Engine. See445		 * WaCompressedResourceDisplayNewHashMode.446		 */447		wa_masked_en(wal, COMMON_SLICE_CHICKEN2,448			     GEN9_PBE_COMPRESSED_HASH_SELECTION);449		wa_mcr_masked_en(wal, GEN9_HALF_SLICE_CHICKEN7,450				 GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR);451	}452 453	/* WaClearFlowControlGpgpuContextSave:skl,bxt,kbl,glk,cfl */454	/* WaDisablePartialInstShootdown:skl,bxt,kbl,glk,cfl */455	wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN,456			 FLOW_CONTROL_ENABLE |457			 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);458 459	/* WaEnableYV12BugFixInHalfSliceChicken7:skl,bxt,kbl,glk,cfl */460	/* WaEnableSamplerGPGPUPreemptionSupport:skl,bxt,kbl,cfl */461	wa_mcr_masked_en(wal, GEN9_HALF_SLICE_CHICKEN7,462			 GEN9_ENABLE_YV12_BUGFIX |463			 GEN9_ENABLE_GPGPU_PREEMPTION);464 465	/* Wa4x4STCOptimizationDisable:skl,bxt,kbl,glk,cfl */466	/* WaDisablePartialResolveInVc:skl,bxt,kbl,cfl */467	wa_masked_en(wal, CACHE_MODE_1,468		     GEN8_4x4_STC_OPTIMIZATION_DISABLE |469		     GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE);470 471	/* WaCcsTlbPrefetchDisable:skl,bxt,kbl,glk,cfl */472	wa_mcr_masked_dis(wal, GEN9_HALF_SLICE_CHICKEN5,473			  GEN9_CCS_TLB_PREFETCH_ENABLE);474 475	/* WaForceContextSaveRestoreNonCoherent:skl,bxt,kbl,cfl */476	wa_masked_en(wal, HDC_CHICKEN0,477		     HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |478		     HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE);479 480	/* WaForceEnableNonCoherent and WaDisableHDCInvalidation are481	 * both tied to WaForceContextSaveRestoreNonCoherent482	 * in some hsds for skl. We keep the tie for all gen9. The483	 * documentation is a bit hazy and so we want to get common behaviour,484	 * even though there is no clear evidence we would need both on kbl/bxt.485	 * This area has been source of system hangs so we play it safe486	 * and mimic the skl regardless of what bspec says.487	 *488	 * Use Force Non-Coherent whenever executing a 3D context. This489	 * is a workaround for a possible hang in the unlikely event490	 * a TLB invalidation occurs during a PSD flush.491	 */492 493	/* WaForceEnableNonCoherent:skl,bxt,kbl,cfl */494	wa_masked_en(wal, HDC_CHICKEN0,495		     HDC_FORCE_NON_COHERENT);496 497	/* WaDisableSamplerPowerBypassForSOPingPong:skl,bxt,kbl,cfl */498	if (IS_SKYLAKE(i915) ||499	    IS_KABYLAKE(i915) ||500	    IS_COFFEELAKE(i915) ||501	    IS_COMETLAKE(i915))502		wa_mcr_masked_en(wal, GEN8_HALF_SLICE_CHICKEN3,503				 GEN8_SAMPLER_POWER_BYPASS_DIS);504 505	/* WaDisableSTUnitPowerOptimization:skl,bxt,kbl,glk,cfl */506	wa_mcr_masked_en(wal, HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE);507 508	/*509	 * Supporting preemption with fine-granularity requires changes in the510	 * batch buffer programming. Since we can't break old userspace, we511	 * need to set our default preemption level to safe value. Userspace is512	 * still able to use more fine-grained preemption levels, since in513	 * WaEnablePreemptionGranularityControlByUMD we're whitelisting the514	 * per-ctx register. As such, WaDisable{3D,GPGPU}MidCmdPreemption are515	 * not real HW workarounds, but merely a way to start using preemption516	 * while maintaining old contract with userspace.517	 */518 519	/* WaDisable3DMidCmdPreemption:skl,bxt,glk,cfl,[cnl] */520	wa_masked_dis(wal, GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL);521 522	/* WaDisableGPGPUMidCmdPreemption:skl,bxt,blk,cfl,[cnl] */523	wa_masked_field_set(wal, GEN8_CS_CHICKEN1,524			    GEN9_PREEMPT_GPGPU_LEVEL_MASK,525			    GEN9_PREEMPT_GPGPU_COMMAND_LEVEL);526 527	/* WaClearHIZ_WM_CHICKEN3:bxt,glk */528	if (IS_GEN9_LP(i915))529		wa_masked_en(wal, GEN9_WM_CHICKEN3, GEN9_FACTOR_IN_CLR_VAL_HIZ);530}531 532static void skl_tune_iz_hashing(struct intel_engine_cs *engine,533				struct i915_wa_list *wal)534{535	struct intel_gt *gt = engine->gt;536	u8 vals[3] = { 0, 0, 0 };537	unsigned int i;538 539	for (i = 0; i < 3; i++) {540		u8 ss;541 542		/*543		 * Only consider slices where one, and only one, subslice has 7544		 * EUs545		 */546		if (!is_power_of_2(gt->info.sseu.subslice_7eu[i]))547			continue;548 549		/*550		 * subslice_7eu[i] != 0 (because of the check above) and551		 * ss_max == 4 (maximum number of subslices possible per slice)552		 *553		 * ->    0 <= ss <= 3;554		 */555		ss = ffs(gt->info.sseu.subslice_7eu[i]) - 1;556		vals[i] = 3 - ss;557	}558 559	if (vals[0] == 0 && vals[1] == 0 && vals[2] == 0)560		return;561 562	/* Tune IZ hashing. See intel_device_info_runtime_init() */563	wa_masked_field_set(wal, GEN7_GT_MODE,564			    GEN9_IZ_HASHING_MASK(2) |565			    GEN9_IZ_HASHING_MASK(1) |566			    GEN9_IZ_HASHING_MASK(0),567			    GEN9_IZ_HASHING(2, vals[2]) |568			    GEN9_IZ_HASHING(1, vals[1]) |569			    GEN9_IZ_HASHING(0, vals[0]));570}571 572static void skl_ctx_workarounds_init(struct intel_engine_cs *engine,573				     struct i915_wa_list *wal)574{575	gen9_ctx_workarounds_init(engine, wal);576	skl_tune_iz_hashing(engine, wal);577}578 579static void bxt_ctx_workarounds_init(struct intel_engine_cs *engine,580				     struct i915_wa_list *wal)581{582	gen9_ctx_workarounds_init(engine, wal);583 584	/* WaDisableThreadStallDopClockGating:bxt */585	wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN,586			 STALL_DOP_GATING_DISABLE);587 588	/* WaToEnableHwFixForPushConstHWBug:bxt */589	wa_masked_en(wal, COMMON_SLICE_CHICKEN2,590		     GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);591}592 593static void kbl_ctx_workarounds_init(struct intel_engine_cs *engine,594				     struct i915_wa_list *wal)595{596	struct drm_i915_private *i915 = engine->i915;597 598	gen9_ctx_workarounds_init(engine, wal);599 600	/* WaToEnableHwFixForPushConstHWBug:kbl */601	if (IS_KABYLAKE(i915) && IS_GRAPHICS_STEP(i915, STEP_C0, STEP_FOREVER))602		wa_masked_en(wal, COMMON_SLICE_CHICKEN2,603			     GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);604 605	/* WaDisableSbeCacheDispatchPortSharing:kbl */606	wa_mcr_masked_en(wal, GEN8_HALF_SLICE_CHICKEN1,607			 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);608}609 610static void glk_ctx_workarounds_init(struct intel_engine_cs *engine,611				     struct i915_wa_list *wal)612{613	gen9_ctx_workarounds_init(engine, wal);614 615	/* WaToEnableHwFixForPushConstHWBug:glk */616	wa_masked_en(wal, COMMON_SLICE_CHICKEN2,617		     GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);618}619 620static void cfl_ctx_workarounds_init(struct intel_engine_cs *engine,621				     struct i915_wa_list *wal)622{623	gen9_ctx_workarounds_init(engine, wal);624 625	/* WaToEnableHwFixForPushConstHWBug:cfl */626	wa_masked_en(wal, COMMON_SLICE_CHICKEN2,627		     GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);628 629	/* WaDisableSbeCacheDispatchPortSharing:cfl */630	wa_mcr_masked_en(wal, GEN8_HALF_SLICE_CHICKEN1,631			 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);632}633 634static void icl_ctx_workarounds_init(struct intel_engine_cs *engine,635				     struct i915_wa_list *wal)636{637	/* Wa_1406697149 (WaDisableBankHangMode:icl) */638	wa_write(wal, GEN8_L3CNTLREG, GEN8_ERRDETBCTRL);639 640	/* WaForceEnableNonCoherent:icl641	 * This is not the same workaround as in early Gen9 platforms, where642	 * lacking this could cause system hangs, but coherency performance643	 * overhead is high and only a few compute workloads really need it644	 * (the register is whitelisted in hardware now, so UMDs can opt in645	 * for coherency if they have a good reason).646	 */647	wa_mcr_masked_en(wal, ICL_HDC_MODE, HDC_FORCE_NON_COHERENT);648 649	/* WaEnableFloatBlendOptimization:icl */650	wa_mcr_add(wal, GEN10_CACHE_MODE_SS, 0,651		   _MASKED_BIT_ENABLE(FLOAT_BLEND_OPTIMIZATION_ENABLE),652		   0 /* write-only, so skip validation */,653		   true);654 655	/* WaDisableGPGPUMidThreadPreemption:icl */656	wa_masked_field_set(wal, GEN8_CS_CHICKEN1,657			    GEN9_PREEMPT_GPGPU_LEVEL_MASK,658			    GEN9_PREEMPT_GPGPU_THREAD_GROUP_LEVEL);659 660	/* allow headerless messages for preemptible GPGPU context */661	wa_mcr_masked_en(wal, GEN10_SAMPLER_MODE,662			 GEN11_SAMPLER_ENABLE_HEADLESS_MSG);663 664	/* Wa_1604278689:icl,ehl */665	wa_write(wal, IVB_FBC_RT_BASE, 0xFFFFFFFF & ~ILK_FBC_RT_VALID);666	wa_write_clr_set(wal, IVB_FBC_RT_BASE_UPPER,667			 0,668			 0xFFFFFFFF);669 670	/* Wa_1406306137:icl,ehl */671	wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN4, GEN11_DIS_PICK_2ND_EU);672}673 674/*675 * These settings aren't actually workarounds, but general tuning settings that676 * need to be programmed on dg2 platform.677 */678static void dg2_ctx_gt_tuning_init(struct intel_engine_cs *engine,679				   struct i915_wa_list *wal)680{681	wa_mcr_masked_en(wal, CHICKEN_RASTER_2, TBIMR_FAST_CLIP);682	wa_mcr_write_clr_set(wal, XEHP_L3SQCREG5, L3_PWM_TIMER_INIT_VAL_MASK,683			     REG_FIELD_PREP(L3_PWM_TIMER_INIT_VAL_MASK, 0x7f));684	wa_mcr_write_clr_set(wal, XEHP_FF_MODE2, FF_MODE2_TDS_TIMER_MASK,685			     FF_MODE2_TDS_TIMER_128);686}687 688static void gen12_ctx_workarounds_init(struct intel_engine_cs *engine,689				       struct i915_wa_list *wal)690{691	struct drm_i915_private *i915 = engine->i915;692 693	/*694	 * Wa_1409142259:tgl,dg1,adl-p695	 * Wa_1409347922:tgl,dg1,adl-p696	 * Wa_1409252684:tgl,dg1,adl-p697	 * Wa_1409217633:tgl,dg1,adl-p698	 * Wa_1409207793:tgl,dg1,adl-p699	 * Wa_1409178076:tgl,dg1,adl-p700	 * Wa_1408979724:tgl,dg1,adl-p701	 * Wa_14010443199:tgl,rkl,dg1,adl-p702	 * Wa_14010698770:tgl,rkl,dg1,adl-s,adl-p703	 * Wa_1409342910:tgl,rkl,dg1,adl-s,adl-p704	 */705	wa_masked_en(wal, GEN11_COMMON_SLICE_CHICKEN3,706		     GEN12_DISABLE_CPS_AWARE_COLOR_PIPE);707 708	/* WaDisableGPGPUMidThreadPreemption:gen12 */709	wa_masked_field_set(wal, GEN8_CS_CHICKEN1,710			    GEN9_PREEMPT_GPGPU_LEVEL_MASK,711			    GEN9_PREEMPT_GPGPU_THREAD_GROUP_LEVEL);712 713	/*714	 * Wa_16011163337 - GS_TIMER715	 *716	 * TDS_TIMER: Although some platforms refer to it as Wa_1604555607, we717	 * need to program it even on those that don't explicitly list that718	 * workaround.719	 *720	 * Note that the programming of GEN12_FF_MODE2 is further modified721	 * according to the FF_MODE2 guidance given by Wa_1608008084.722	 * Wa_1608008084 tells us the FF_MODE2 register will return the wrong723	 * value when read from the CPU.724	 *725	 * The default value for this register is zero for all fields.726	 * So instead of doing a RMW we should just write the desired values727	 * for TDS and GS timers. Note that since the readback can't be trusted,728	 * the clear mask is just set to ~0 to make sure other bits are not729	 * inadvertently set. For the same reason read verification is ignored.730	 */731	wa_add(wal,732	       GEN12_FF_MODE2,733	       ~0,734	       FF_MODE2_TDS_TIMER_128 | FF_MODE2_GS_TIMER_224,735	       0, false);736 737	if (!IS_DG1(i915)) {738		/* Wa_1806527549 */739		wa_masked_en(wal, HIZ_CHICKEN, HZ_DEPTH_TEST_LE_GE_OPT_DISABLE);740 741		/* Wa_1606376872 */742		wa_masked_en(wal, COMMON_SLICE_CHICKEN4, DISABLE_TDC_LOAD_BALANCING_CALC);743	}744}745 746static void dg1_ctx_workarounds_init(struct intel_engine_cs *engine,747				     struct i915_wa_list *wal)748{749	gen12_ctx_workarounds_init(engine, wal);750 751	/* Wa_1409044764 */752	wa_masked_dis(wal, GEN11_COMMON_SLICE_CHICKEN3,753		      DG1_FLOAT_POINT_BLEND_OPT_STRICT_MODE_EN);754 755	/* Wa_22010493298 */756	wa_masked_en(wal, HIZ_CHICKEN,757		     DG1_HZ_READ_SUPPRESSION_OPTIMIZATION_DISABLE);758}759 760static void dg2_ctx_workarounds_init(struct intel_engine_cs *engine,761				     struct i915_wa_list *wal)762{763	dg2_ctx_gt_tuning_init(engine, wal);764 765	/* Wa_16013271637:dg2 */766	wa_mcr_masked_en(wal, XEHP_SLICE_COMMON_ECO_CHICKEN1,767			 MSC_MSAA_REODER_BUF_BYPASS_DISABLE);768 769	/* Wa_14014947963:dg2 */770	wa_masked_field_set(wal, VF_PREEMPTION, PREEMPTION_VERTEX_COUNT, 0x4000);771 772	/* Wa_18018764978:dg2 */773	wa_mcr_masked_en(wal, XEHP_PSS_MODE2, SCOREBOARD_STALL_FLUSH_CONTROL);774 775	/* Wa_18019271663:dg2 */776	wa_masked_en(wal, CACHE_MODE_1, MSAA_OPTIMIZATION_REDUC_DISABLE);777 778	/* Wa_14019877138:dg2 */779	wa_mcr_masked_en(wal, XEHP_PSS_CHICKEN, FD_END_COLLECT);780}781 782static void xelpg_ctx_gt_tuning_init(struct intel_engine_cs *engine,783				     struct i915_wa_list *wal)784{785	struct intel_gt *gt = engine->gt;786 787	dg2_ctx_gt_tuning_init(engine, wal);788 789	/*790	 * Due to Wa_16014892111, the DRAW_WATERMARK tuning must be done in791	 * gen12_emit_indirect_ctx_rcs() rather than here on some early792	 * steppings.793	 */794	if (!(IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||795	      IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0)))796		wa_add(wal, DRAW_WATERMARK, VERT_WM_VAL, 0x3FF, 0, false);797}798 799static void xelpg_ctx_workarounds_init(struct intel_engine_cs *engine,800				       struct i915_wa_list *wal)801{802	struct intel_gt *gt = engine->gt;803 804	xelpg_ctx_gt_tuning_init(engine, wal);805 806	if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||807	    IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0)) {808		/* Wa_14014947963 */809		wa_masked_field_set(wal, VF_PREEMPTION,810				    PREEMPTION_VERTEX_COUNT, 0x4000);811 812		/* Wa_16013271637 */813		wa_mcr_masked_en(wal, XEHP_SLICE_COMMON_ECO_CHICKEN1,814				 MSC_MSAA_REODER_BUF_BYPASS_DISABLE);815 816		/* Wa_18019627453 */817		wa_mcr_masked_en(wal, VFLSKPD, VF_PREFETCH_TLB_DIS);818 819		/* Wa_18018764978 */820		wa_mcr_masked_en(wal, XEHP_PSS_MODE2, SCOREBOARD_STALL_FLUSH_CONTROL);821	}822 823	/* Wa_18019271663 */824	wa_masked_en(wal, CACHE_MODE_1, MSAA_OPTIMIZATION_REDUC_DISABLE);825 826	/* Wa_14019877138 */827	wa_mcr_masked_en(wal, XEHP_PSS_CHICKEN, FD_END_COLLECT);828}829 830static void fakewa_disable_nestedbb_mode(struct intel_engine_cs *engine,831					 struct i915_wa_list *wal)832{833	/*834	 * This is a "fake" workaround defined by software to ensure we835	 * maintain reliable, backward-compatible behavior for userspace with836	 * regards to how nested MI_BATCH_BUFFER_START commands are handled.837	 *838	 * The per-context setting of MI_MODE[12] determines whether the bits839	 * of a nested MI_BATCH_BUFFER_START instruction should be interpreted840	 * in the traditional manner or whether they should instead use a new841	 * tgl+ meaning that breaks backward compatibility, but allows nesting842	 * into 3rd-level batchbuffers.  When this new capability was first843	 * added in TGL, it remained off by default unless a context844	 * intentionally opted in to the new behavior.  However Xe_HPG now845	 * flips this on by default and requires that we explicitly opt out if846	 * we don't want the new behavior.847	 *848	 * From a SW perspective, we want to maintain the backward-compatible849	 * behavior for userspace, so we'll apply a fake workaround to set it850	 * back to the legacy behavior on platforms where the hardware default851	 * is to break compatibility.  At the moment there is no Linux852	 * userspace that utilizes third-level batchbuffers, so this will avoid853	 * userspace from needing to make any changes.  using the legacy854	 * meaning is the correct thing to do.  If/when we have userspace855	 * consumers that want to utilize third-level batch nesting, we can856	 * provide a context parameter to allow them to opt-in.857	 */858	wa_masked_dis(wal, RING_MI_MODE(engine->mmio_base), TGL_NESTED_BB_EN);859}860 861static void gen12_ctx_gt_mocs_init(struct intel_engine_cs *engine,862				   struct i915_wa_list *wal)863{864	u8 mocs;865 866	/*867	 * Some blitter commands do not have a field for MOCS, those868	 * commands will use MOCS index pointed by BLIT_CCTL.869	 * BLIT_CCTL registers are needed to be programmed to un-cached.870	 */871	if (engine->class == COPY_ENGINE_CLASS) {872		mocs = engine->gt->mocs.uc_index;873		wa_write_clr_set(wal,874				 BLIT_CCTL(engine->mmio_base),875				 BLIT_CCTL_MASK,876				 BLIT_CCTL_MOCS(mocs, mocs));877	}878}879 880/*881 * gen12_ctx_gt_fake_wa_init() aren't programmingan official workaround882 * defined by the hardware team, but it programming general context registers.883 * Adding those context register programming in context workaround884 * allow us to use the wa framework for proper application and validation.885 */886static void887gen12_ctx_gt_fake_wa_init(struct intel_engine_cs *engine,888			  struct i915_wa_list *wal)889{890	if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 55))891		fakewa_disable_nestedbb_mode(engine, wal);892 893	gen12_ctx_gt_mocs_init(engine, wal);894}895 896static void897__intel_engine_init_ctx_wa(struct intel_engine_cs *engine,898			   struct i915_wa_list *wal,899			   const char *name)900{901	struct drm_i915_private *i915 = engine->i915;902 903	wa_init_start(wal, engine->gt, name, engine->name);904 905	/* Applies to all engines */906	/*907	 * Fake workarounds are not the actual workaround but908	 * programming of context registers using workaround framework.909	 */910	if (GRAPHICS_VER(i915) >= 12)911		gen12_ctx_gt_fake_wa_init(engine, wal);912 913	if (engine->class != RENDER_CLASS)914		goto done;915 916	if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 74)))917		xelpg_ctx_workarounds_init(engine, wal);918	else if (IS_DG2(i915))919		dg2_ctx_workarounds_init(engine, wal);920	else if (IS_DG1(i915))921		dg1_ctx_workarounds_init(engine, wal);922	else if (GRAPHICS_VER(i915) == 12)923		gen12_ctx_workarounds_init(engine, wal);924	else if (GRAPHICS_VER(i915) == 11)925		icl_ctx_workarounds_init(engine, wal);926	else if (IS_COFFEELAKE(i915) || IS_COMETLAKE(i915))927		cfl_ctx_workarounds_init(engine, wal);928	else if (IS_GEMINILAKE(i915))929		glk_ctx_workarounds_init(engine, wal);930	else if (IS_KABYLAKE(i915))931		kbl_ctx_workarounds_init(engine, wal);932	else if (IS_BROXTON(i915))933		bxt_ctx_workarounds_init(engine, wal);934	else if (IS_SKYLAKE(i915))935		skl_ctx_workarounds_init(engine, wal);936	else if (IS_CHERRYVIEW(i915))937		chv_ctx_workarounds_init(engine, wal);938	else if (IS_BROADWELL(i915))939		bdw_ctx_workarounds_init(engine, wal);940	else if (GRAPHICS_VER(i915) == 7)941		gen7_ctx_workarounds_init(engine, wal);942	else if (GRAPHICS_VER(i915) == 6)943		gen6_ctx_workarounds_init(engine, wal);944	else if (GRAPHICS_VER(i915) < 8)945		;946	else947		MISSING_CASE(GRAPHICS_VER(i915));948 949done:950	wa_init_finish(wal);951}952 953void intel_engine_init_ctx_wa(struct intel_engine_cs *engine)954{955	__intel_engine_init_ctx_wa(engine, &engine->ctx_wa_list, "context");956}957 958int intel_engine_emit_ctx_wa(struct i915_request *rq)959{960	struct i915_wa_list *wal = &rq->engine->ctx_wa_list;961	struct intel_uncore *uncore = rq->engine->uncore;962	enum forcewake_domains fw;963	unsigned long flags;964	struct i915_wa *wa;965	unsigned int i;966	u32 *cs;967	int ret;968 969	if (wal->count == 0)970		return 0;971 972	ret = rq->engine->emit_flush(rq, EMIT_BARRIER);973	if (ret)974		return ret;975 976	if ((IS_GFX_GT_IP_RANGE(rq->engine->gt, IP_VER(12, 70), IP_VER(12, 74)) ||977	     IS_DG2(rq->i915)) && rq->engine->class == RENDER_CLASS)978		cs = intel_ring_begin(rq, (wal->count * 2 + 6));979	else980		cs = intel_ring_begin(rq, (wal->count * 2 + 2));981 982	if (IS_ERR(cs))983		return PTR_ERR(cs);984 985	fw = wal_get_fw_for_rmw(uncore, wal);986 987	intel_gt_mcr_lock(wal->gt, &flags);988	spin_lock(&uncore->lock);989	intel_uncore_forcewake_get__locked(uncore, fw);990 991	*cs++ = MI_LOAD_REGISTER_IMM(wal->count);992	for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {993		u32 val;994 995		/* Skip reading the register if it's not really needed */996		if (wa->masked_reg || (wa->clr | wa->set) == U32_MAX) {997			val = wa->set;998		} else {999			val = wa->is_mcr ?1000				intel_gt_mcr_read_any_fw(wal->gt, wa->mcr_reg) :1001				intel_uncore_read_fw(uncore, wa->reg);1002			val &= ~wa->clr;1003			val |= wa->set;1004		}1005 1006		*cs++ = i915_mmio_reg_offset(wa->reg);1007		*cs++ = val;1008	}1009	*cs++ = MI_NOOP;1010 1011	/* Wa_14019789679 */1012	if ((IS_GFX_GT_IP_RANGE(rq->engine->gt, IP_VER(12, 70), IP_VER(12, 74)) ||1013	     IS_DG2(rq->i915)) && rq->engine->class == RENDER_CLASS) {1014		*cs++ = CMD_3DSTATE_MESH_CONTROL;1015		*cs++ = 0;1016		*cs++ = 0;1017		*cs++ = MI_NOOP;1018	}1019 1020	intel_uncore_forcewake_put__locked(uncore, fw);1021	spin_unlock(&uncore->lock);1022	intel_gt_mcr_unlock(wal->gt, flags);1023 1024	intel_ring_advance(rq, cs);1025 1026	ret = rq->engine->emit_flush(rq, EMIT_BARRIER);1027	if (ret)1028		return ret;1029 1030	return 0;1031}1032 1033static void1034gen4_gt_workarounds_init(struct intel_gt *gt,1035			 struct i915_wa_list *wal)1036{1037	/* WaDisable_RenderCache_OperationalFlush:gen4,ilk */1038	wa_masked_dis(wal, CACHE_MODE_0, RC_OP_FLUSH_ENABLE);1039}1040 1041static void1042g4x_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1043{1044	gen4_gt_workarounds_init(gt, wal);1045 1046	/* WaDisableRenderCachePipelinedFlush:g4x,ilk */1047	wa_masked_en(wal, CACHE_MODE_0, CM0_PIPELINED_RENDER_FLUSH_DISABLE);1048}1049 1050static void1051ilk_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1052{1053	g4x_gt_workarounds_init(gt, wal);1054 1055	wa_masked_en(wal, _3D_CHICKEN2, _3D_CHICKEN2_WM_READ_PIPELINED);1056}1057 1058static void1059snb_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1060{1061}1062 1063static void1064ivb_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1065{1066	/* Apply the WaDisableRHWOOptimizationForRenderHang:ivb workaround. */1067	wa_masked_dis(wal,1068		      GEN7_COMMON_SLICE_CHICKEN1,1069		      GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);1070 1071	/* WaApplyL3ControlAndL3ChickenMode:ivb */1072	wa_write(wal, GEN7_L3CNTLREG1, GEN7_WA_FOR_GEN7_L3_CONTROL);1073	wa_write(wal, GEN7_L3_CHICKEN_MODE_REGISTER, GEN7_WA_L3_CHICKEN_MODE);1074 1075	/* WaForceL3Serialization:ivb */1076	wa_write_clr(wal, GEN7_L3SQCREG4, L3SQ_URB_READ_CAM_MATCH_DISABLE);1077}1078 1079static void1080vlv_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1081{1082	/* WaForceL3Serialization:vlv */1083	wa_write_clr(wal, GEN7_L3SQCREG4, L3SQ_URB_READ_CAM_MATCH_DISABLE);1084 1085	/*1086	 * WaIncreaseL3CreditsForVLVB0:vlv1087	 * This is the hardware default actually.1088	 */1089	wa_write(wal, GEN7_L3SQCREG1, VLV_B0_WA_L3SQCREG1_VALUE);1090}1091 1092static void1093hsw_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1094{1095	/* L3 caching of data atomics doesn't work -- disable it. */1096	wa_write(wal, HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE);1097 1098	wa_add(wal,1099	       HSW_ROW_CHICKEN3, 0,1100	       _MASKED_BIT_ENABLE(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE),1101	       0 /* XXX does this reg exist? */, true);1102 1103	/* WaVSRefCountFullforceMissDisable:hsw */1104	wa_write_clr(wal, GEN7_FF_THREAD_MODE, GEN7_FF_VS_REF_CNT_FFME);1105}1106 1107static void1108gen9_wa_init_mcr(struct drm_i915_private *i915, struct i915_wa_list *wal)1109{1110	const struct sseu_dev_info *sseu = &to_gt(i915)->info.sseu;1111	unsigned int slice, subslice;1112	u32 mcr, mcr_mask;1113 1114	GEM_BUG_ON(GRAPHICS_VER(i915) != 9);1115 1116	/*1117	 * WaProgramMgsrForCorrectSliceSpecificMmioReads:gen9,glk,kbl,cml1118	 * Before any MMIO read into slice/subslice specific registers, MCR1119	 * packet control register needs to be programmed to point to any1120	 * enabled s/ss pair. Otherwise, incorrect values will be returned.1121	 * This means each subsequent MMIO read will be forwarded to an1122	 * specific s/ss combination, but this is OK since these registers1123	 * are consistent across s/ss in almost all cases. In the rare1124	 * occasions, such as INSTDONE, where this value is dependent1125	 * on s/ss combo, the read should be done with read_subslice_reg.1126	 */1127	slice = ffs(sseu->slice_mask) - 1;1128	GEM_BUG_ON(slice >= ARRAY_SIZE(sseu->subslice_mask.hsw));1129	subslice = ffs(intel_sseu_get_hsw_subslices(sseu, slice));1130	GEM_BUG_ON(!subslice);1131	subslice--;1132 1133	/*1134	 * We use GEN8_MCR..() macros to calculate the |mcr| value for1135	 * Gen9 to address WaProgramMgsrForCorrectSliceSpecificMmioReads1136	 */1137	mcr = GEN8_MCR_SLICE(slice) | GEN8_MCR_SUBSLICE(subslice);1138	mcr_mask = GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK;1139 1140	drm_dbg(&i915->drm, "MCR slice:%d/subslice:%d = %x\n", slice, subslice, mcr);1141 1142	wa_write_clr_set(wal, GEN8_MCR_SELECTOR, mcr_mask, mcr);1143}1144 1145static void1146gen9_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1147{1148	struct drm_i915_private *i915 = gt->i915;1149 1150	/* WaProgramMgsrForCorrectSliceSpecificMmioReads:glk,kbl,cml,gen9 */1151	gen9_wa_init_mcr(i915, wal);1152 1153	/* WaDisableKillLogic:bxt,skl,kbl */1154	if (!IS_COFFEELAKE(i915) && !IS_COMETLAKE(i915))1155		wa_write_or(wal,1156			    GAM_ECOCHK,1157			    ECOCHK_DIS_TLB);1158 1159	if (HAS_LLC(i915)) {1160		/* WaCompressedResourceSamplerPbeMediaNewHashMode:skl,kbl1161		 *1162		 * Must match Display Engine. See1163		 * WaCompressedResourceDisplayNewHashMode.1164		 */1165		wa_write_or(wal,1166			    MMCD_MISC_CTRL,1167			    MMCD_PCLA | MMCD_HOTSPOT_EN);1168	}1169 1170	/* WaDisableHDCInvalidation:skl,bxt,kbl,cfl */1171	wa_write_or(wal,1172		    GAM_ECOCHK,1173		    BDW_DISABLE_HDC_INVALIDATION);1174}1175 1176static void1177skl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1178{1179	gen9_gt_workarounds_init(gt, wal);1180 1181	/* WaDisableGafsUnitClkGating:skl */1182	wa_write_or(wal,1183		    GEN7_UCGCTL4,1184		    GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);1185 1186	/* WaInPlaceDecompressionHang:skl */1187	if (IS_SKYLAKE(gt->i915) && IS_GRAPHICS_STEP(gt->i915, STEP_A0, STEP_H0))1188		wa_write_or(wal,1189			    GEN9_GAMT_ECO_REG_RW_IA,1190			    GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);1191}1192 1193static void1194kbl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1195{1196	gen9_gt_workarounds_init(gt, wal);1197 1198	/* WaDisableDynamicCreditSharing:kbl */1199	if (IS_KABYLAKE(gt->i915) && IS_GRAPHICS_STEP(gt->i915, 0, STEP_C0))1200		wa_write_or(wal,1201			    GAMT_CHKN_BIT_REG,1202			    GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING);1203 1204	/* WaDisableGafsUnitClkGating:kbl */1205	wa_write_or(wal,1206		    GEN7_UCGCTL4,1207		    GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);1208 1209	/* WaInPlaceDecompressionHang:kbl */1210	wa_write_or(wal,1211		    GEN9_GAMT_ECO_REG_RW_IA,1212		    GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);1213}1214 1215static void1216glk_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1217{1218	gen9_gt_workarounds_init(gt, wal);1219}1220 1221static void1222cfl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1223{1224	gen9_gt_workarounds_init(gt, wal);1225 1226	/* WaDisableGafsUnitClkGating:cfl */1227	wa_write_or(wal,1228		    GEN7_UCGCTL4,1229		    GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);1230 1231	/* WaInPlaceDecompressionHang:cfl */1232	wa_write_or(wal,1233		    GEN9_GAMT_ECO_REG_RW_IA,1234		    GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);1235}1236 1237static void __set_mcr_steering(struct i915_wa_list *wal,1238			       i915_reg_t steering_reg,1239			       unsigned int slice, unsigned int subslice)1240{1241	u32 mcr, mcr_mask;1242 1243	mcr = GEN11_MCR_SLICE(slice) | GEN11_MCR_SUBSLICE(subslice);1244	mcr_mask = GEN11_MCR_SLICE_MASK | GEN11_MCR_SUBSLICE_MASK;1245 1246	wa_write_clr_set(wal, steering_reg, mcr_mask, mcr);1247}1248 1249static void debug_dump_steering(struct intel_gt *gt)1250{1251	struct drm_printer p = drm_dbg_printer(&gt->i915->drm, DRM_UT_DRIVER,1252					       "MCR Steering:");1253 1254	if (drm_debug_enabled(DRM_UT_DRIVER))1255		intel_gt_mcr_report_steering(&p, gt, false);1256}1257 1258static void __add_mcr_wa(struct intel_gt *gt, struct i915_wa_list *wal,1259			 unsigned int slice, unsigned int subslice)1260{1261	__set_mcr_steering(wal, GEN8_MCR_SELECTOR, slice, subslice);1262 1263	gt->default_steering.groupid = slice;1264	gt->default_steering.instanceid = subslice;1265 1266	debug_dump_steering(gt);1267}1268 1269static void1270icl_wa_init_mcr(struct intel_gt *gt, struct i915_wa_list *wal)1271{1272	const struct sseu_dev_info *sseu = &gt->info.sseu;1273	unsigned int subslice;1274 1275	GEM_BUG_ON(GRAPHICS_VER(gt->i915) < 11);1276	GEM_BUG_ON(hweight8(sseu->slice_mask) > 1);1277 1278	/*1279	 * Although a platform may have subslices, we need to always steer1280	 * reads to the lowest instance that isn't fused off.  When Render1281	 * Power Gating is enabled, grabbing forcewake will only power up a1282	 * single subslice (the "minconfig") if there isn't a real workload1283	 * that needs to be run; this means that if we steer register reads to1284	 * one of the higher subslices, we run the risk of reading back 0's or1285	 * random garbage.1286	 */1287	subslice = __ffs(intel_sseu_get_hsw_subslices(sseu, 0));1288 1289	/*1290	 * If the subslice we picked above also steers us to a valid L3 bank,1291	 * then we can just rely on the default steering and won't need to1292	 * worry about explicitly re-steering L3BANK reads later.1293	 */1294	if (gt->info.l3bank_mask & BIT(subslice))1295		gt->steering_table[L3BANK] = NULL;1296 1297	__add_mcr_wa(gt, wal, 0, subslice);1298}1299 1300static void1301xehp_init_mcr(struct intel_gt *gt, struct i915_wa_list *wal)1302{1303	const struct sseu_dev_info *sseu = &gt->info.sseu;1304	unsigned long slice, subslice = 0, slice_mask = 0;1305	u32 lncf_mask = 0;1306	int i;1307 1308	/*1309	 * On Xe_HP the steering increases in complexity. There are now several1310	 * more units that require steering and we're not guaranteed to be able1311	 * to find a common setting for all of them. These are:1312	 * - GSLICE (fusable)1313	 * - DSS (sub-unit within gslice; fusable)1314	 * - L3 Bank (fusable)1315	 * - MSLICE (fusable)1316	 * - LNCF (sub-unit within mslice; always present if mslice is present)1317	 *1318	 * We'll do our default/implicit steering based on GSLICE (in the1319	 * sliceid field) and DSS (in the subsliceid field).  If we can1320	 * find overlap between the valid MSLICE and/or LNCF values with1321	 * a suitable GSLICE, then we can just re-use the default value and1322	 * skip and explicit steering at runtime.1323	 *1324	 * We only need to look for overlap between GSLICE/MSLICE/LNCF to find1325	 * a valid sliceid value.  DSS steering is the only type of steering1326	 * that utilizes the 'subsliceid' bits.1327	 *1328	 * Also note that, even though the steering domain is called "GSlice"1329	 * and it is encoded in the register using the gslice format, the spec1330	 * says that the combined (geometry | compute) fuse should be used to1331	 * select the steering.1332	 */1333 1334	/* Find the potential gslice candidates */1335	slice_mask = intel_slicemask_from_xehp_dssmask(sseu->subslice_mask,1336						       GEN_DSS_PER_GSLICE);1337 1338	/*1339	 * Find the potential LNCF candidates.  Either LNCF within a valid1340	 * mslice is fine.1341	 */1342	for_each_set_bit(i, &gt->info.mslice_mask, GEN12_MAX_MSLICES)1343		lncf_mask |= (0x3 << (i * 2));1344 1345	/*1346	 * Are there any sliceid values that work for both GSLICE and LNCF1347	 * steering?1348	 */1349	if (slice_mask & lncf_mask) {1350		slice_mask &= lncf_mask;1351		gt->steering_table[LNCF] = NULL;1352	}1353 1354	/* How about sliceid values that also work for MSLICE steering? */1355	if (slice_mask & gt->info.mslice_mask) {1356		slice_mask &= gt->info.mslice_mask;1357		gt->steering_table[MSLICE] = NULL;1358	}1359 1360	slice = __ffs(slice_mask);1361	subslice = intel_sseu_find_first_xehp_dss(sseu, GEN_DSS_PER_GSLICE, slice) %1362		GEN_DSS_PER_GSLICE;1363 1364	__add_mcr_wa(gt, wal, slice, subslice);1365 1366	/*1367	 * SQIDI ranges are special because they use different steering1368	 * registers than everything else we work with.  On XeHP SDV and1369	 * DG2-G10, any value in the steering registers will work fine since1370	 * all instances are present, but DG2-G11 only has SQIDI instances at1371	 * ID's 2 and 3, so we need to steer to one of those.  For simplicity1372	 * we'll just steer to a hardcoded "2" since that value will work1373	 * everywhere.1374	 */1375	__set_mcr_steering(wal, MCFG_MCR_SELECTOR, 0, 2);1376	__set_mcr_steering(wal, SF_MCR_SELECTOR, 0, 2);1377 1378	/*1379	 * On DG2, GAM registers have a dedicated steering control register1380	 * and must always be programmed to a hardcoded groupid of "1."1381	 */1382	if (IS_DG2(gt->i915))1383		__set_mcr_steering(wal, GAM_MCR_SELECTOR, 1, 0);1384}1385 1386static void1387icl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1388{1389	struct drm_i915_private *i915 = gt->i915;1390 1391	icl_wa_init_mcr(gt, wal);1392 1393	/* WaModifyGamTlbPartitioning:icl */1394	wa_write_clr_set(wal,1395			 GEN11_GACB_PERF_CTRL,1396			 GEN11_HASH_CTRL_MASK,1397			 GEN11_HASH_CTRL_BIT0 | GEN11_HASH_CTRL_BIT4);1398 1399	/* Wa_1405766107:icl1400	 * Formerly known as WaCL2SFHalfMaxAlloc1401	 */1402	wa_write_or(wal,1403		    GEN11_LSN_UNSLCVC,1404		    GEN11_LSN_UNSLCVC_GAFS_HALF_SF_MAXALLOC |1405		    GEN11_LSN_UNSLCVC_GAFS_HALF_CL2_MAXALLOC);1406 1407	/* Wa_220166154:icl1408	 * Formerly known as WaDisCtxReload1409	 */1410	wa_write_or(wal,1411		    GEN8_GAMW_ECO_DEV_RW_IA,1412		    GAMW_ECO_DEV_CTX_RELOAD_DISABLE);1413 1414	/* Wa_1406463099:icl1415	 * Formerly known as WaGamTlbPendError1416	 */1417	wa_write_or(wal,1418		    GAMT_CHKN_BIT_REG,1419		    GAMT_CHKN_DISABLE_L3_COH_PIPE);1420 1421	/*1422	 * Wa_1408615072:icl,ehl  (vsunit)1423	 * Wa_1407596294:icl,ehl  (hsunit)1424	 */1425	wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE,1426		    VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS);1427 1428	/* Wa_1407352427:icl,ehl */1429	wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2,1430		    PSDUNIT_CLKGATE_DIS);1431 1432	/* Wa_1406680159:icl,ehl */1433	wa_mcr_write_or(wal,1434			GEN11_SUBSLICE_UNIT_LEVEL_CLKGATE,1435			GWUNIT_CLKGATE_DIS);1436 1437	/* Wa_1607087056:icl,ehl,jsl */1438	if (IS_ICELAKE(i915) ||1439		((IS_JASPERLAKE(i915) || IS_ELKHARTLAKE(i915)) &&1440		IS_GRAPHICS_STEP(i915, STEP_A0, STEP_B0)))1441		wa_write_or(wal,1442			    GEN11_SLICE_UNIT_LEVEL_CLKGATE,1443			    L3_CLKGATE_DIS | L3_CR2X_CLKGATE_DIS);1444 1445	/*1446	 * This is not a documented workaround, but rather an optimization1447	 * to reduce sampler power.1448	 */1449	wa_mcr_write_clr(wal, GEN10_DFR_RATIO_EN_AND_CHICKEN, DFR_DISABLE);1450}1451 1452/*1453 * Though there are per-engine instances of these registers,1454 * they retain their value through engine resets and should1455 * only be provided on the GT workaround list rather than1456 * the engine-specific workaround list.1457 */1458static void1459wa_14011060649(struct intel_gt *gt, struct i915_wa_list *wal)1460{1461	struct intel_engine_cs *engine;1462	int id;1463 1464	for_each_engine(engine, gt, id) {1465		if (engine->class != VIDEO_DECODE_CLASS ||1466		    (engine->instance % 2))1467			continue;1468 1469		wa_write_or(wal, VDBOX_CGCTL3F10(engine->mmio_base),1470			    IECPUNIT_CLKGATE_DIS);1471	}1472}1473 1474static void1475gen12_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1476{1477	icl_wa_init_mcr(gt, wal);1478 1479	/* Wa_14011060649:tgl,rkl,dg1,adl-s,adl-p */1480	wa_14011060649(gt, wal);1481 1482	/* Wa_14011059788:tgl,rkl,adl-s,dg1,adl-p */1483	wa_mcr_write_or(wal, GEN10_DFR_RATIO_EN_AND_CHICKEN, DFR_DISABLE);1484 1485	/*1486	 * Wa_140157950831487	 *1488	 * Firmware on some gen12 platforms locks the MISCCPCTL register,1489	 * preventing i915 from modifying it for this workaround.  Skip the1490	 * readback verification for this workaround on debug builds; if the1491	 * workaround doesn't stick due to firmware behavior, it's not an error1492	 * that we want CI to flag.1493	 */1494	wa_add(wal, GEN7_MISCCPCTL, GEN12_DOP_CLOCK_GATE_RENDER_ENABLE,1495	       0, 0, false);1496}1497 1498static void1499dg1_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1500{1501	gen12_gt_workarounds_init(gt, wal);1502 1503	/* Wa_1409420604:dg1 */1504	wa_mcr_write_or(wal, SUBSLICE_UNIT_LEVEL_CLKGATE2,1505			CPSSUNIT_CLKGATE_DIS);1506 1507	/* Wa_1408615072:dg1 */1508	/* Empirical testing shows this register is unaffected by engine reset. */1509	wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2, VSUNIT_CLKGATE_DIS_TGL);1510}1511 1512static void1513dg2_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1514{1515	xehp_init_mcr(gt, wal);1516 1517	/* Wa_14011060649:dg2 */1518	wa_14011060649(gt, wal);1519 1520	if (IS_DG2_G10(gt->i915)) {1521		/* Wa_22010523718:dg2 */1522		wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE,1523			    CG3DDISCFEG_CLKGATE_DIS);1524 1525		/* Wa_14011006942:dg2 */1526		wa_mcr_write_or(wal, GEN11_SUBSLICE_UNIT_LEVEL_CLKGATE,1527				DSS_ROUTER_CLKGATE_DIS);1528	}1529 1530	/* Wa_14014830051:dg2 */1531	wa_mcr_write_clr(wal, SARB_CHICKEN1, COMP_CKN_IN);1532 1533	/*1534	 * Wa_140157950831535	 * Skip verification for possibly locked register.1536	 */1537	wa_add(wal, GEN7_MISCCPCTL, GEN12_DOP_CLOCK_GATE_RENDER_ENABLE,1538	       0, 0, false);1539 1540	/* Wa_18018781329 */1541	wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);1542	wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);1543	wa_mcr_write_or(wal, XEHP_VDBX_MOD_CTRL, FORCE_MISS_FTLB);1544	wa_mcr_write_or(wal, XEHP_VEBX_MOD_CTRL, FORCE_MISS_FTLB);1545 1546	/* Wa_1509235366:dg2 */1547	wa_mcr_write_or(wal, XEHP_GAMCNTRL_CTRL,1548			INVALIDATION_BROADCAST_MODE_DIS | GLOBAL_INVALIDATION_MODE);1549 1550	/* Wa_14010648519:dg2 */1551	wa_mcr_write_or(wal, XEHP_L3NODEARBCFG, XEHP_LNESPARE);1552}1553 1554static void1555xelpg_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1556{1557	/* Wa_14018575942 / Wa_18018781329 */1558	wa_mcr_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);1559	wa_mcr_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);1560 1561	/* Wa_22016670082 */1562	wa_write_or(wal, GEN12_SQCNT1, GEN12_STRICT_RAR_ENABLE);1563 1564	if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||1565	    IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0)) {1566		/* Wa_14014830051 */1567		wa_mcr_write_clr(wal, SARB_CHICKEN1, COMP_CKN_IN);1568 1569		/* Wa_14015795083 */1570		wa_write_clr(wal, GEN7_MISCCPCTL, GEN12_DOP_CLOCK_GATE_RENDER_ENABLE);1571	}1572 1573	/*1574	 * Unlike older platforms, we no longer setup implicit steering here;1575	 * all MCR accesses are explicitly steered.1576	 */1577	debug_dump_steering(gt);1578}1579 1580static void1581wa_16021867713(struct intel_gt *gt, struct i915_wa_list *wal)1582{1583	struct intel_engine_cs *engine;1584	int id;1585 1586	for_each_engine(engine, gt, id)1587		if (engine->class == VIDEO_DECODE_CLASS)1588			wa_write_or(wal, VDBOX_CGCTL3F1C(engine->mmio_base),1589				    MFXPIPE_CLKGATE_DIS);1590}1591 1592static void1593xelpmp_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)1594{1595	wa_16021867713(gt, wal);1596 1597	/*1598	 * Wa_140187786411599	 * Wa_180187813291600	 *1601	 * Note that although these registers are MCR on the primary1602	 * GT, the media GT's versions are regular singleton registers.1603	 */1604	wa_write_or(wal, XELPMP_GSC_MOD_CTRL, FORCE_MISS_FTLB);1605 1606	/*1607	 * Wa_140185759421608	 *1609	 * Issue is seen on media KPI test running on VDBOX engine1610	 * especially VP9 encoding WLs1611	 */1612	wa_write_or(wal, XELPMP_VDBX_MOD_CTRL, FORCE_MISS_FTLB);1613 1614	/* Wa_22016670082 */1615	wa_write_or(wal, GEN12_SQCNT1, GEN12_STRICT_RAR_ENABLE);1616 1617	debug_dump_steering(gt);1618}1619 1620/*1621 * The bspec performance guide has recommended MMIO tuning settings.  These1622 * aren't truly "workarounds" but we want to program them through the1623 * workaround infrastructure to make sure they're (re)applied at the proper1624 * times.1625 *1626 * The programming in this function is for settings that persist through1627 * engine resets and also are not part of any engine's register state context.1628 * I.e., settings that only need to be re-applied in the event of a full GT1629 * reset.1630 */1631static void gt_tuning_settings(struct intel_gt *gt, struct i915_wa_list *wal)1632{1633	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74))) {1634		wa_mcr_write_or(wal, XEHP_L3SCQREG7, BLEND_FILL_CACHING_OPT_DIS);1635		wa_mcr_write_or(wal, XEHP_SQCM, EN_32B_ACCESS);1636	}1637 1638	if (IS_DG2(gt->i915)) {1639		wa_mcr_write_or(wal, XEHP_L3SCQREG7, BLEND_FILL_CACHING_OPT_DIS);1640		wa_mcr_write_or(wal, XEHP_SQCM, EN_32B_ACCESS);1641	}1642}1643 1644static void1645gt_init_workarounds(struct intel_gt *gt, struct i915_wa_list *wal)1646{1647	struct drm_i915_private *i915 = gt->i915;1648 1649	gt_tuning_settings(gt, wal);1650 1651	if (gt->type == GT_MEDIA) {1652		if (MEDIA_VER_FULL(i915) == IP_VER(13, 0))1653			xelpmp_gt_workarounds_init(gt, wal);1654		else1655			MISSING_CASE(MEDIA_VER_FULL(i915));1656 1657		return;1658	}1659 1660	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)))1661		xelpg_gt_workarounds_init(gt, wal);1662	else if (IS_DG2(i915))1663		dg2_gt_workarounds_init(gt, wal);1664	else if (IS_DG1(i915))1665		dg1_gt_workarounds_init(gt, wal);1666	else if (GRAPHICS_VER(i915) == 12)1667		gen12_gt_workarounds_init(gt, wal);1668	else if (GRAPHICS_VER(i915) == 11)1669		icl_gt_workarounds_init(gt, wal);1670	else if (IS_COFFEELAKE(i915) || IS_COMETLAKE(i915))1671		cfl_gt_workarounds_init(gt, wal);1672	else if (IS_GEMINILAKE(i915))1673		glk_gt_workarounds_init(gt, wal);1674	else if (IS_KABYLAKE(i915))1675		kbl_gt_workarounds_init(gt, wal);1676	else if (IS_BROXTON(i915))1677		gen9_gt_workarounds_init(gt, wal);1678	else if (IS_SKYLAKE(i915))1679		skl_gt_workarounds_init(gt, wal);1680	else if (IS_HASWELL(i915))1681		hsw_gt_workarounds_init(gt, wal);1682	else if (IS_VALLEYVIEW(i915))1683		vlv_gt_workarounds_init(gt, wal);1684	else if (IS_IVYBRIDGE(i915))1685		ivb_gt_workarounds_init(gt, wal);1686	else if (GRAPHICS_VER(i915) == 6)1687		snb_gt_workarounds_init(gt, wal);1688	else if (GRAPHICS_VER(i915) == 5)1689		ilk_gt_workarounds_init(gt, wal);1690	else if (IS_G4X(i915))1691		g4x_gt_workarounds_init(gt, wal);1692	else if (GRAPHICS_VER(i915) == 4)1693		gen4_gt_workarounds_init(gt, wal);1694	else if (GRAPHICS_VER(i915) <= 8)1695		;1696	else1697		MISSING_CASE(GRAPHICS_VER(i915));1698}1699 1700void intel_gt_init_workarounds(struct intel_gt *gt)1701{1702	struct i915_wa_list *wal = &gt->wa_list;1703 1704	wa_init_start(wal, gt, "GT", "global");1705	gt_init_workarounds(gt, wal);1706	wa_init_finish(wal);1707}1708 1709static bool1710wa_verify(struct intel_gt *gt, const struct i915_wa *wa, u32 cur,1711	  const char *name, const char *from)1712{1713	if ((cur ^ wa->set) & wa->read) {1714		gt_err(gt,1715		       "%s workaround lost on %s! (reg[%x]=0x%x, relevant bits were 0x%x vs expected 0x%x)\n",1716		       name, from, i915_mmio_reg_offset(wa->reg),1717		       cur, cur & wa->read, wa->set & wa->read);1718 1719		return false;1720	}1721 1722	return true;1723}1724 1725static void wa_list_apply(const struct i915_wa_list *wal)1726{1727	struct intel_gt *gt = wal->gt;1728	struct intel_uncore *uncore = gt->uncore;1729	enum forcewake_domains fw;1730	unsigned long flags;1731	struct i915_wa *wa;1732	unsigned int i;1733 1734	if (!wal->count)1735		return;1736 1737	fw = wal_get_fw_for_rmw(uncore, wal);1738 1739	intel_gt_mcr_lock(gt, &flags);1740	spin_lock(&uncore->lock);1741	intel_uncore_forcewake_get__locked(uncore, fw);1742 1743	for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {1744		u32 val, old = 0;1745 1746		/* open-coded rmw due to steering */1747		if (wa->clr)1748			old = wa->is_mcr ?1749				intel_gt_mcr_read_any_fw(gt, wa->mcr_reg) :1750				intel_uncore_read_fw(uncore, wa->reg);1751		val = (old & ~wa->clr) | wa->set;1752		if (val != old || !wa->clr) {1753			if (wa->is_mcr)1754				intel_gt_mcr_multicast_write_fw(gt, wa->mcr_reg, val);1755			else1756				intel_uncore_write_fw(uncore, wa->reg, val);1757		}1758 1759		if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM)) {1760			u32 val = wa->is_mcr ?1761				intel_gt_mcr_read_any_fw(gt, wa->mcr_reg) :1762				intel_uncore_read_fw(uncore, wa->reg);1763 1764			wa_verify(gt, wa, val, wal->name, "application");1765		}1766	}1767 1768	intel_uncore_forcewake_put__locked(uncore, fw);1769	spin_unlock(&uncore->lock);1770	intel_gt_mcr_unlock(gt, flags);1771}1772 1773void intel_gt_apply_workarounds(struct intel_gt *gt)1774{1775	wa_list_apply(&gt->wa_list);1776}1777 1778static bool wa_list_verify(struct intel_gt *gt,1779			   const struct i915_wa_list *wal,1780			   const char *from)1781{1782	struct intel_uncore *uncore = gt->uncore;1783	struct i915_wa *wa;1784	enum forcewake_domains fw;1785	unsigned long flags;1786	unsigned int i;1787	bool ok = true;1788 1789	fw = wal_get_fw_for_rmw(uncore, wal);1790 1791	intel_gt_mcr_lock(gt, &flags);1792	spin_lock(&uncore->lock);1793	intel_uncore_forcewake_get__locked(uncore, fw);1794 1795	for (i = 0, wa = wal->list; i < wal->count; i++, wa++)1796		ok &= wa_verify(wal->gt, wa, wa->is_mcr ?1797				intel_gt_mcr_read_any_fw(gt, wa->mcr_reg) :1798				intel_uncore_read_fw(uncore, wa->reg),1799				wal->name, from);1800 1801	intel_uncore_forcewake_put__locked(uncore, fw);1802	spin_unlock(&uncore->lock);1803	intel_gt_mcr_unlock(gt, flags);1804 1805	return ok;1806}1807 1808bool intel_gt_verify_workarounds(struct intel_gt *gt, const char *from)1809{1810	return wa_list_verify(gt, &gt->wa_list, from);1811}1812 1813__maybe_unused1814static bool is_nonpriv_flags_valid(u32 flags)1815{1816	/* Check only valid flag bits are set */1817	if (flags & ~RING_FORCE_TO_NONPRIV_MASK_VALID)1818		return false;1819 1820	/* NB: Only 3 out of 4 enum values are valid for access field */1821	if ((flags & RING_FORCE_TO_NONPRIV_ACCESS_MASK) ==1822	    RING_FORCE_TO_NONPRIV_ACCESS_INVALID)1823		return false;1824 1825	return true;1826}1827 1828static void1829whitelist_reg_ext(struct i915_wa_list *wal, i915_reg_t reg, u32 flags)1830{1831	struct i915_wa wa = {1832		.reg = reg1833	};1834 1835	if (GEM_DEBUG_WARN_ON(wal->count >= RING_MAX_NONPRIV_SLOTS))1836		return;1837 1838	if (GEM_DEBUG_WARN_ON(!is_nonpriv_flags_valid(flags)))1839		return;1840 1841	wa.reg.reg |= flags;1842	_wa_add(wal, &wa);1843}1844 1845static void1846whitelist_mcr_reg_ext(struct i915_wa_list *wal, i915_mcr_reg_t reg, u32 flags)1847{1848	struct i915_wa wa = {1849		.mcr_reg = reg,1850		.is_mcr = 1,1851	};1852 1853	if (GEM_DEBUG_WARN_ON(wal->count >= RING_MAX_NONPRIV_SLOTS))1854		return;1855 1856	if (GEM_DEBUG_WARN_ON(!is_nonpriv_flags_valid(flags)))1857		return;1858 1859	wa.mcr_reg.reg |= flags;1860	_wa_add(wal, &wa);1861}1862 1863static void1864whitelist_reg(struct i915_wa_list *wal, i915_reg_t reg)1865{1866	whitelist_reg_ext(wal, reg, RING_FORCE_TO_NONPRIV_ACCESS_RW);1867}1868 1869static void1870whitelist_mcr_reg(struct i915_wa_list *wal, i915_mcr_reg_t reg)1871{1872	whitelist_mcr_reg_ext(wal, reg, RING_FORCE_TO_NONPRIV_ACCESS_RW);1873}1874 1875static void gen9_whitelist_build(struct i915_wa_list *w)1876{1877	/* WaVFEStateAfterPipeControlwithMediaStateClear:skl,bxt,glk,cfl */1878	whitelist_reg(w, GEN9_CTX_PREEMPT_REG);1879 1880	/* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */1881	whitelist_reg(w, GEN8_CS_CHICKEN1);1882 1883	/* WaAllowUMDToModifyHDCChicken1:skl,bxt,kbl,glk,cfl */1884	whitelist_reg(w, GEN8_HDC_CHICKEN1);1885 1886	/* WaSendPushConstantsFromMMIO:skl,bxt */1887	whitelist_reg(w, COMMON_SLICE_CHICKEN2);1888}1889 1890static void skl_whitelist_build(struct intel_engine_cs *engine)1891{1892	struct i915_wa_list *w = &engine->whitelist;1893 1894	if (engine->class != RENDER_CLASS)1895		return;1896 1897	gen9_whitelist_build(w);1898 1899	/* WaDisableLSQCROPERFforOCL:skl */1900	whitelist_mcr_reg(w, GEN8_L3SQCREG4);1901}1902 1903static void bxt_whitelist_build(struct intel_engine_cs *engine)1904{1905	if (engine->class != RENDER_CLASS)1906		return;1907 1908	gen9_whitelist_build(&engine->whitelist);1909}1910 1911static void kbl_whitelist_build(struct intel_engine_cs *engine)1912{1913	struct i915_wa_list *w = &engine->whitelist;1914 1915	if (engine->class != RENDER_CLASS)1916		return;1917 1918	gen9_whitelist_build(w);1919 1920	/* WaDisableLSQCROPERFforOCL:kbl */1921	whitelist_mcr_reg(w, GEN8_L3SQCREG4);1922}1923 1924static void glk_whitelist_build(struct intel_engine_cs *engine)1925{1926	struct i915_wa_list *w = &engine->whitelist;1927 1928	if (engine->class != RENDER_CLASS)1929		return;1930 1931	gen9_whitelist_build(w);1932 1933	/* WA #0862: Userspace has to set "Barrier Mode" to avoid hangs. */1934	whitelist_reg(w, GEN9_SLICE_COMMON_ECO_CHICKEN1);1935}1936 1937static void cfl_whitelist_build(struct intel_engine_cs *engine)1938{1939	struct i915_wa_list *w = &engine->whitelist;1940 1941	if (engine->class != RENDER_CLASS)1942		return;1943 1944	gen9_whitelist_build(w);1945 1946	/*1947	 * WaAllowPMDepthAndInvocationCountAccessFromUMD:cfl,whl,cml,aml1948	 *1949	 * This covers 4 register which are next to one another :1950	 *   - PS_INVOCATION_COUNT1951	 *   - PS_INVOCATION_COUNT_UDW1952	 *   - PS_DEPTH_COUNT1953	 *   - PS_DEPTH_COUNT_UDW1954	 */1955	whitelist_reg_ext(w, PS_INVOCATION_COUNT,1956			  RING_FORCE_TO_NONPRIV_ACCESS_RD |1957			  RING_FORCE_TO_NONPRIV_RANGE_4);1958}1959 1960static void allow_read_ctx_timestamp(struct intel_engine_cs *engine)1961{1962	struct i915_wa_list *w = &engine->whitelist;1963 1964	if (engine->class != RENDER_CLASS)1965		whitelist_reg_ext(w,1966				  RING_CTX_TIMESTAMP(engine->mmio_base),1967				  RING_FORCE_TO_NONPRIV_ACCESS_RD);1968}1969 1970static void cml_whitelist_build(struct intel_engine_cs *engine)1971{1972	allow_read_ctx_timestamp(engine);1973 1974	cfl_whitelist_build(engine);1975}1976 1977static void icl_whitelist_build(struct intel_engine_cs *engine)1978{1979	struct i915_wa_list *w = &engine->whitelist;1980 1981	allow_read_ctx_timestamp(engine);1982 1983	switch (engine->class) {1984	case RENDER_CLASS:1985		/* WaAllowUMDToModifyHalfSliceChicken7:icl */1986		whitelist_mcr_reg(w, GEN9_HALF_SLICE_CHICKEN7);1987 1988		/* WaAllowUMDToModifySamplerMode:icl */1989		whitelist_mcr_reg(w, GEN10_SAMPLER_MODE);1990 1991		/* WaEnableStateCacheRedirectToCS:icl */1992		whitelist_reg(w, GEN9_SLICE_COMMON_ECO_CHICKEN1);1993 1994		/*1995		 * WaAllowPMDepthAndInvocationCountAccessFromUMD:icl1996		 *1997		 * This covers 4 register which are next to one another :1998		 *   - PS_INVOCATION_COUNT1999		 *   - PS_INVOCATION_COUNT_UDW2000		 *   - PS_DEPTH_COUNT2001		 *   - PS_DEPTH_COUNT_UDW2002		 */2003		whitelist_reg_ext(w, PS_INVOCATION_COUNT,2004				  RING_FORCE_TO_NONPRIV_ACCESS_RD |2005				  RING_FORCE_TO_NONPRIV_RANGE_4);2006		break;2007 2008	case VIDEO_DECODE_CLASS:2009		/* hucStatusRegOffset */2010		whitelist_reg_ext(w, _MMIO(0x2000 + engine->mmio_base),2011				  RING_FORCE_TO_NONPRIV_ACCESS_RD);2012		/* hucUKernelHdrInfoRegOffset */2013		whitelist_reg_ext(w, _MMIO(0x2014 + engine->mmio_base),2014				  RING_FORCE_TO_NONPRIV_ACCESS_RD);2015		/* hucStatus2RegOffset */2016		whitelist_reg_ext(w, _MMIO(0x23B0 + engine->mmio_base),2017				  RING_FORCE_TO_NONPRIV_ACCESS_RD);2018		break;2019 2020	default:2021		break;2022	}2023}2024 2025static void tgl_whitelist_build(struct intel_engine_cs *engine)2026{2027	struct i915_wa_list *w = &engine->whitelist;2028 2029	allow_read_ctx_timestamp(engine);2030 2031	switch (engine->class) {2032	case RENDER_CLASS:2033		/*2034		 * WaAllowPMDepthAndInvocationCountAccessFromUMD:tgl2035		 * Wa_1408556865:tgl2036		 *2037		 * This covers 4 registers which are next to one another :2038		 *   - PS_INVOCATION_COUNT2039		 *   - PS_INVOCATION_COUNT_UDW2040		 *   - PS_DEPTH_COUNT2041		 *   - PS_DEPTH_COUNT_UDW2042		 */2043		whitelist_reg_ext(w, PS_INVOCATION_COUNT,2044				  RING_FORCE_TO_NONPRIV_ACCESS_RD |2045				  RING_FORCE_TO_NONPRIV_RANGE_4);2046 2047		/*2048		 * Wa_1808121037:tgl2049		 * Wa_14012131227:dg12050		 * Wa_1508744258:tgl,rkl,dg1,adl-s,adl-p2051		 */2052		whitelist_reg(w, GEN7_COMMON_SLICE_CHICKEN1);2053 2054		/* Wa_1806527549:tgl */2055		whitelist_reg(w, HIZ_CHICKEN);2056 2057		/* Required by recommended tuning setting (not a workaround) */2058		whitelist_reg(w, GEN11_COMMON_SLICE_CHICKEN3);2059 2060		break;2061	default:2062		break;2063	}2064}2065 2066static void dg2_whitelist_build(struct intel_engine_cs *engine)2067{2068	struct i915_wa_list *w = &engine->whitelist;2069 2070	switch (engine->class) {2071	case RENDER_CLASS:2072		/* Required by recommended tuning setting (not a workaround) */2073		whitelist_mcr_reg(w, XEHP_COMMON_SLICE_CHICKEN3);2074		whitelist_reg(w, GEN7_COMMON_SLICE_CHICKEN1);2075		break;2076	default:2077		break;2078	}2079}2080 2081static void xelpg_whitelist_build(struct intel_engine_cs *engine)2082{2083	struct i915_wa_list *w = &engine->whitelist;2084 2085	switch (engine->class) {2086	case RENDER_CLASS:2087		/* Required by recommended tuning setting (not a workaround) */2088		whitelist_mcr_reg(w, XEHP_COMMON_SLICE_CHICKEN3);2089		whitelist_reg(w, GEN7_COMMON_SLICE_CHICKEN1);2090		break;2091	default:2092		break;2093	}2094}2095 2096void intel_engine_init_whitelist(struct intel_engine_cs *engine)2097{2098	struct drm_i915_private *i915 = engine->i915;2099	struct i915_wa_list *w = &engine->whitelist;2100 2101	wa_init_start(w, engine->gt, "whitelist", engine->name);2102 2103	if (engine->gt->type == GT_MEDIA)2104		; /* none yet */2105	else if (IS_GFX_GT_IP_RANGE(engine->gt, IP_VER(12, 70), IP_VER(12, 74)))2106		xelpg_whitelist_build(engine);2107	else if (IS_DG2(i915))2108		dg2_whitelist_build(engine);2109	else if (GRAPHICS_VER(i915) == 12)2110		tgl_whitelist_build(engine);2111	else if (GRAPHICS_VER(i915) == 11)2112		icl_whitelist_build(engine);2113	else if (IS_COMETLAKE(i915))2114		cml_whitelist_build(engine);2115	else if (IS_COFFEELAKE(i915))2116		cfl_whitelist_build(engine);2117	else if (IS_GEMINILAKE(i915))2118		glk_whitelist_build(engine);2119	else if (IS_KABYLAKE(i915))2120		kbl_whitelist_build(engine);2121	else if (IS_BROXTON(i915))2122		bxt_whitelist_build(engine);2123	else if (IS_SKYLAKE(i915))2124		skl_whitelist_build(engine);2125	else if (GRAPHICS_VER(i915) <= 8)2126		;2127	else2128		MISSING_CASE(GRAPHICS_VER(i915));2129 2130	wa_init_finish(w);2131}2132 2133void intel_engine_apply_whitelist(struct intel_engine_cs *engine)2134{2135	const struct i915_wa_list *wal = &engine->whitelist;2136	struct intel_uncore *uncore = engine->uncore;2137	const u32 base = engine->mmio_base;2138	struct i915_wa *wa;2139	unsigned int i;2140 2141	if (!wal->count)2142		return;2143 2144	for (i = 0, wa = wal->list; i < wal->count; i++, wa++)2145		intel_uncore_write(uncore,2146				   RING_FORCE_TO_NONPRIV(base, i),2147				   i915_mmio_reg_offset(wa->reg));2148 2149	/* And clear the rest just in case of garbage */2150	for (; i < RING_MAX_NONPRIV_SLOTS; i++)2151		intel_uncore_write(uncore,2152				   RING_FORCE_TO_NONPRIV(base, i),2153				   i915_mmio_reg_offset(RING_NOPID(base)));2154}2155 2156/*2157 * engine_fake_wa_init(), a place holder to program the registers2158 * which are not part of an official workaround defined by the2159 * hardware team.2160 * Adding programming of those register inside workaround will2161 * allow utilizing wa framework to proper application and verification.2162 */2163static void2164engine_fake_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)2165{2166	u8 mocs_w, mocs_r;2167 2168	/*2169	 * RING_CMD_CCTL specifies the default MOCS entry that will be used2170	 * by the command streamer when executing commands that don't have2171	 * a way to explicitly specify a MOCS setting.  The default should2172	 * usually reference whichever MOCS entry corresponds to uncached2173	 * behavior, although use of a WB cached entry is recommended by the2174	 * spec in certain circumstances on specific platforms.2175	 */2176	if (GRAPHICS_VER(engine->i915) >= 12) {2177		mocs_r = engine->gt->mocs.uc_index;2178		mocs_w = engine->gt->mocs.uc_index;2179 2180		if (HAS_L3_CCS_READ(engine->i915) &&2181		    engine->class == COMPUTE_CLASS) {2182			mocs_r = engine->gt->mocs.wb_index;2183 2184			/*2185			 * Even on the few platforms where MOCS 0 is a2186			 * legitimate table entry, it's never the correct2187			 * setting to use here; we can assume the MOCS init2188			 * just forgot to initialize wb_index.2189			 */2190			drm_WARN_ON(&engine->i915->drm, mocs_r == 0);2191		}2192 2193		wa_masked_field_set(wal,2194				    RING_CMD_CCTL(engine->mmio_base),2195				    CMD_CCTL_MOCS_MASK,2196				    CMD_CCTL_MOCS_OVERRIDE(mocs_w, mocs_r));2197	}2198}2199 2200static void2201rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)2202{2203	struct drm_i915_private *i915 = engine->i915;2204	struct intel_gt *gt = engine->gt;2205 2206	if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||2207	    IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0)) {2208		/* Wa_22014600077 */2209		wa_mcr_masked_en(wal, GEN10_CACHE_MODE_SS,2210				 ENABLE_EU_COUNT_FOR_TDL_FLUSH);2211	}2212 2213	if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||2214	    IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0) ||2215	    IS_DG2(i915)) {2216		/* Wa_1509727124 */2217		wa_mcr_masked_en(wal, GEN10_SAMPLER_MODE,2218				 SC_DISABLE_POWER_OPTIMIZATION_EBB);2219	}2220 2221	if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||2222	    IS_DG2(i915)) {2223		/* Wa_22012856258 */2224		wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN2,2225				 GEN12_DISABLE_READ_SUPPRESSION);2226	}2227 2228	if (IS_DG2(i915)) {2229		/*2230		 * Wa_22010960976:dg22231		 * Wa_14013347512:dg22232		 */2233		wa_mcr_masked_dis(wal, XEHP_HDC_CHICKEN0,2234				  LSC_L1_FLUSH_CTL_3D_DATAPORT_FLUSH_EVENTS_MASK);2235	}2236 2237	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 71)) ||2238	    IS_DG2(i915)) {2239		/* Wa_14015150844 */2240		wa_mcr_add(wal, XEHP_HDC_CHICKEN0, 0,2241			   _MASKED_BIT_ENABLE(DIS_ATOMIC_CHAINING_TYPED_WRITES),2242			   0, true);2243	}2244 2245	if (IS_DG2(i915) || IS_ALDERLAKE_P(i915) || IS_ALDERLAKE_S(i915) ||2246	    IS_DG1(i915) || IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {2247		/*2248		 * Wa_1606700617:tgl,dg1,adl-p2249		 * Wa_22010271021:tgl,rkl,dg1,adl-s,adl-p2250		 * Wa_14010826681:tgl,dg1,rkl,adl-p2251		 * Wa_18019627453:dg22252		 */2253		wa_masked_en(wal,2254			     GEN9_CS_DEBUG_MODE1,2255			     FF_DOP_CLOCK_GATE_DISABLE);2256	}2257 2258	if (IS_ALDERLAKE_P(i915) || IS_ALDERLAKE_S(i915) || IS_DG1(i915) ||2259	    IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {2260		/* Wa_1606931601:tgl,rkl,dg1,adl-s,adl-p */2261		wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN2, GEN12_DISABLE_EARLY_READ);2262 2263		/*2264		 * Wa_1407928979:tgl A*2265		 * Wa_18011464164:tgl[B0+],dg1[B0+]2266		 * Wa_22010931296:tgl[B0+],dg1[B0+]2267		 * Wa_14010919138:rkl,dg1,adl-s,adl-p2268		 */2269		wa_write_or(wal, GEN7_FF_THREAD_MODE,2270			    GEN12_FF_TESSELATION_DOP_GATE_DISABLE);2271 2272		/* Wa_1406941453:tgl,rkl,dg1,adl-s,adl-p */2273		wa_mcr_masked_en(wal,2274				 GEN10_SAMPLER_MODE,2275				 ENABLE_SMALLPL);2276	}2277 2278	if (IS_ALDERLAKE_P(i915) || IS_ALDERLAKE_S(i915) ||2279	    IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {2280		/* Wa_1409804808 */2281		wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN2,2282				 GEN12_PUSH_CONST_DEREF_HOLD_DIS);2283 2284		/* Wa_14010229206 */2285		wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN4, GEN12_DISABLE_TDL_PUSH);2286	}2287 2288	if (IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915) || IS_ALDERLAKE_P(i915)) {2289		/*2290		 * Wa_16072976272291		 *2292		 * On TGL and RKL there are multiple entries for this WA in the2293		 * BSpec; some indicate this is an A0-only WA, others indicate2294		 * it applies to all steppings so we trust the "all steppings."2295		 */2296		wa_masked_en(wal,2297			     RING_PSMI_CTL(RENDER_RING_BASE),2298			     GEN12_WAIT_FOR_EVENT_POWER_DOWN_DISABLE |2299			     GEN8_RC_SEMA_IDLE_MSG_DISABLE);2300	}2301 2302	if (GRAPHICS_VER(i915) == 11) {2303		/* This is not an Wa. Enable for better image quality */2304		wa_masked_en(wal,2305			     _3D_CHICKEN3,2306			     _3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE);2307 2308		/*2309		 * Wa_1405543622:icl2310		 * Formerly known as WaGAPZPriorityScheme2311		 */2312		wa_write_or(wal,2313			    GEN8_GARBCNTL,2314			    GEN11_ARBITRATION_PRIO_ORDER_MASK);2315 2316		/*2317		 * Wa_1604223664:icl2318		 * Formerly known as WaL3BankAddressHashing2319		 */2320		wa_write_clr_set(wal,2321				 GEN8_GARBCNTL,2322				 GEN11_HASH_CTRL_EXCL_MASK,2323				 GEN11_HASH_CTRL_EXCL_BIT0);2324		wa_write_clr_set(wal,2325				 GEN11_GLBLINVL,2326				 GEN11_BANK_HASH_ADDR_EXCL_MASK,2327				 GEN11_BANK_HASH_ADDR_EXCL_BIT0);2328 2329		/*2330		 * Wa_1405733216:icl2331		 * Formerly known as WaDisableCleanEvicts2332		 */2333		wa_mcr_write_or(wal,2334				GEN8_L3SQCREG4,2335				GEN11_LQSC_CLEAN_EVICT_DISABLE);2336 2337		/* Wa_1606682166:icl */2338		wa_write_or(wal,2339			    GEN7_SARCHKMD,2340			    GEN7_DISABLE_SAMPLER_PREFETCH);2341 2342		/* Wa_1409178092:icl */2343		wa_mcr_write_clr_set(wal,2344				     GEN11_SCRATCH2,2345				     GEN11_COHERENT_PARTIAL_WRITE_MERGE_ENABLE,2346				     0);2347 2348		/* WaEnable32PlaneMode:icl */2349		wa_masked_en(wal, GEN9_CSFE_CHICKEN1_RCS,2350			     GEN11_ENABLE_32_PLANE_MODE);2351 2352		/*2353		 * Wa_1408767742:icl[a2..forever],ehl[all]2354		 * Wa_1605460711:icl[a0..c0]2355		 */2356		wa_write_or(wal,2357			    GEN7_FF_THREAD_MODE,2358			    GEN12_FF_TESSELATION_DOP_GATE_DISABLE);2359 2360		/* Wa_22010271021 */2361		wa_masked_en(wal,2362			     GEN9_CS_DEBUG_MODE1,2363			     FF_DOP_CLOCK_GATE_DISABLE);2364	}2365 2366	/*2367	 * Intel platforms that support fine-grained preemption (i.e., gen9 and2368	 * beyond) allow the kernel-mode driver to choose between two different2369	 * options for controlling preemption granularity and behavior.2370	 *2371	 * Option 1 (hardware default):2372	 *   Preemption settings are controlled in a global manner via2373	 *   kernel-only register CS_DEBUG_MODE1 (0x20EC).  Any granularity2374	 *   and settings chosen by the kernel-mode driver will apply to all2375	 *   userspace clients.2376	 *2377	 * Option 2:2378	 *   Preemption settings are controlled on a per-context basis via2379	 *   register CS_CHICKEN1 (0x2580).  CS_CHICKEN1 is saved/restored on2380	 *   context switch and is writable by userspace (e.g., via2381	 *   MI_LOAD_REGISTER_IMMEDIATE instructions placed in a batch buffer)2382	 *   which allows different userspace drivers/clients to select2383	 *   different settings, or to change those settings on the fly in2384	 *   response to runtime needs.  This option was known by name2385	 *   "FtrPerCtxtPreemptionGranularityControl" at one time, although2386	 *   that name is somewhat misleading as other non-granularity2387	 *   preemption settings are also impacted by this decision.2388	 *2389	 * On Linux, our policy has always been to let userspace drivers2390	 * control preemption granularity/settings (Option 2).  This was2391	 * originally mandatory on gen9 to prevent ABI breakage (old gen92392	 * userspace developed before object-level preemption was enabled would2393	 * not behave well if i915 were to go with Option 1 and enable that2394	 * preemption in a global manner).  On gen9 each context would have2395	 * object-level preemption disabled by default (see2396	 * WaDisable3DMidCmdPreemption in gen9_ctx_workarounds_init), but2397	 * userspace drivers could opt-in to object-level preemption as they2398	 * saw fit.  For post-gen9 platforms, we continue to utilize Option 2;2399	 * even though it is no longer necessary for ABI compatibility when2400	 * enabling a new platform, it does ensure that userspace will be able2401	 * to implement any workarounds that show up requiring temporary2402	 * adjustments to preemption behavior at runtime.2403	 *2404	 * Notes/Workarounds:2405	 *  - Wa_14015141709:  On DG2 and early steppings of MTL,2406	 *      CS_CHICKEN1[0] does not disable object-level preemption as2407	 *      it is supposed to (nor does CS_DEBUG_MODE1[0] if we had been2408	 *      using Option 1).  Effectively this means userspace is unable2409	 *      to disable object-level preemption on these platforms/steppings2410	 *      despite the setting here.2411	 *2412	 *  - Wa_16013994831:  May require that userspace program2413	 *      CS_CHICKEN1[10] when certain runtime conditions are true.2414	 *      Userspace requires Option 2 to be in effect for their update of2415	 *      CS_CHICKEN1[10] to be effective.2416	 *2417	 * Other workarounds may appear in the future that will also require2418	 * Option 2 behavior to allow proper userspace implementation.2419	 */2420	if (GRAPHICS_VER(i915) >= 9)2421		wa_masked_en(wal,2422			     GEN7_FF_SLICE_CS_CHICKEN1,2423			     GEN9_FFSC_PERCTX_PREEMPT_CTRL);2424 2425	if (IS_SKYLAKE(i915) ||2426	    IS_KABYLAKE(i915) ||2427	    IS_COFFEELAKE(i915) ||2428	    IS_COMETLAKE(i915)) {2429		/* WaEnableGapsTsvCreditFix:skl,kbl,cfl */2430		wa_write_or(wal,2431			    GEN8_GARBCNTL,2432			    GEN9_GAPS_TSV_CREDIT_DISABLE);2433	}2434 2435	if (IS_BROXTON(i915)) {2436		/* WaDisablePooledEuLoadBalancingFix:bxt */2437		wa_masked_en(wal,2438			     FF_SLICE_CS_CHICKEN2,2439			     GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE);2440	}2441 2442	if (GRAPHICS_VER(i915) == 9) {2443		/* WaContextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */2444		wa_masked_en(wal,2445			     GEN9_CSFE_CHICKEN1_RCS,2446			     GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE);2447 2448		/* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */2449		wa_mcr_write_or(wal,2450				BDW_SCRATCH1,2451				GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);2452 2453		/* WaProgramL3SqcReg1DefaultForPerf:bxt,glk */2454		if (IS_GEN9_LP(i915))2455			wa_mcr_write_clr_set(wal,2456					     GEN8_L3SQCREG1,2457					     L3_PRIO_CREDITS_MASK,2458					     L3_GENERAL_PRIO_CREDITS(62) |2459					     L3_HIGH_PRIO_CREDITS(2));2460 2461		/* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */2462		wa_mcr_write_or(wal,2463				GEN8_L3SQCREG4,2464				GEN8_LQSC_FLUSH_COHERENT_LINES);2465 2466		/* Disable atomics in L3 to prevent unrecoverable hangs */2467		wa_write_clr_set(wal, GEN9_SCRATCH_LNCF1,2468				 GEN9_LNCF_NONIA_COHERENT_ATOMICS_ENABLE, 0);2469		wa_mcr_write_clr_set(wal, GEN8_L3SQCREG4,2470				     GEN8_LQSQ_NONIA_COHERENT_ATOMICS_ENABLE, 0);2471		wa_mcr_write_clr_set(wal, GEN9_SCRATCH1,2472				     EVICTION_PERF_FIX_ENABLE, 0);2473	}2474 2475	if (IS_HASWELL(i915)) {2476		/* WaSampleCChickenBitEnable:hsw */2477		wa_masked_en(wal,2478			     HSW_HALF_SLICE_CHICKEN3, HSW_SAMPLE_C_PERFORMANCE);2479 2480		wa_masked_dis(wal,2481			      CACHE_MODE_0_GEN7,2482			      /* enable HiZ Raw Stall Optimization */2483			      HIZ_RAW_STALL_OPT_DISABLE);2484	}2485 2486	if (IS_VALLEYVIEW(i915)) {2487		/* WaDisableEarlyCull:vlv */2488		wa_masked_en(wal,2489			     _3D_CHICKEN3,2490			     _3D_CHICKEN_SF_DISABLE_OBJEND_CULL);2491 2492		/*2493		 * WaVSThreadDispatchOverride:ivb,vlv2494		 *2495		 * This actually overrides the dispatch2496		 * mode for all thread types.2497		 */2498		wa_write_clr_set(wal,2499				 GEN7_FF_THREAD_MODE,2500				 GEN7_FF_SCHED_MASK,2501				 GEN7_FF_TS_SCHED_HW |2502				 GEN7_FF_VS_SCHED_HW |2503				 GEN7_FF_DS_SCHED_HW);2504 2505		/* WaPsdDispatchEnable:vlv */2506		/* WaDisablePSDDualDispatchEnable:vlv */2507		wa_masked_en(wal,2508			     GEN7_HALF_SLICE_CHICKEN1,2509			     GEN7_MAX_PS_THREAD_DEP |2510			     GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE);2511	}2512 2513	if (IS_IVYBRIDGE(i915)) {2514		/* WaDisableEarlyCull:ivb */2515		wa_masked_en(wal,2516			     _3D_CHICKEN3,2517			     _3D_CHICKEN_SF_DISABLE_OBJEND_CULL);2518 2519		if (0) { /* causes HiZ corruption on ivb:gt1 */2520			/* enable HiZ Raw Stall Optimization */2521			wa_masked_dis(wal,2522				      CACHE_MODE_0_GEN7,2523				      HIZ_RAW_STALL_OPT_DISABLE);2524		}2525 2526		/*2527		 * WaVSThreadDispatchOverride:ivb,vlv2528		 *2529		 * This actually overrides the dispatch2530		 * mode for all thread types.2531		 */2532		wa_write_clr_set(wal,2533				 GEN7_FF_THREAD_MODE,2534				 GEN7_FF_SCHED_MASK,2535				 GEN7_FF_TS_SCHED_HW |2536				 GEN7_FF_VS_SCHED_HW |2537				 GEN7_FF_DS_SCHED_HW);2538 2539		/* WaDisablePSDDualDispatchEnable:ivb */2540		if (IS_IVB_GT1(i915))2541			wa_masked_en(wal,2542				     GEN7_HALF_SLICE_CHICKEN1,2543				     GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE);2544	}2545 2546	if (GRAPHICS_VER(i915) == 7) {2547		/* WaBCSVCSTlbInvalidationMode:ivb,vlv,hsw */2548		wa_masked_en(wal,2549			     RING_MODE_GEN7(RENDER_RING_BASE),2550			     GFX_TLB_INVALIDATE_EXPLICIT | GFX_REPLAY_MODE);2551 2552		/* WaDisable_RenderCache_OperationalFlush:ivb,vlv,hsw */2553		wa_masked_dis(wal, CACHE_MODE_0_GEN7, RC_OP_FLUSH_ENABLE);2554 2555		/*2556		 * BSpec says this must be set, even though2557		 * WaDisable4x2SubspanOptimization:ivb,hsw2558		 * WaDisable4x2SubspanOptimization isn't listed for VLV.2559		 */2560		wa_masked_en(wal,2561			     CACHE_MODE_1,2562			     PIXEL_SUBSPAN_COLLECT_OPT_DISABLE);2563 2564		/*2565		 * BSpec recommends 8x4 when MSAA is used,2566		 * however in practice 16x4 seems fastest.2567		 *2568		 * Note that PS/WM thread counts depend on the WIZ hashing2569		 * disable bit, which we don't touch here, but it's good2570		 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).2571		 */2572		wa_masked_field_set(wal,2573				    GEN7_GT_MODE,2574				    GEN6_WIZ_HASHING_MASK,2575				    GEN6_WIZ_HASHING_16x4);2576	}2577 2578	if (IS_GRAPHICS_VER(i915, 6, 7))2579		/*2580		 * We need to disable the AsyncFlip performance optimisations in2581		 * order to use MI_WAIT_FOR_EVENT within the CS. It should2582		 * already be programmed to '1' on all products.2583		 *2584		 * WaDisableAsyncFlipPerfMode:snb,ivb,hsw,vlv2585		 */2586		wa_masked_en(wal,2587			     RING_MI_MODE(RENDER_RING_BASE),2588			     ASYNC_FLIP_PERF_DISABLE);2589 2590	if (GRAPHICS_VER(i915) == 6) {2591		/*2592		 * Required for the hardware to program scanline values for2593		 * waiting2594		 * WaEnableFlushTlbInvalidationMode:snb2595		 */2596		wa_masked_en(wal,2597			     GFX_MODE,2598			     GFX_TLB_INVALIDATE_EXPLICIT);2599 2600		/* WaDisableHiZPlanesWhenMSAAEnabled:snb */2601		wa_masked_en(wal,2602			     _3D_CHICKEN,2603			     _3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB);2604 2605		wa_masked_en(wal,2606			     _3D_CHICKEN3,2607			     /* WaStripsFansDisableFastClipPerformanceFix:snb */2608			     _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL |2609			     /*2610			      * Bspec says:2611			      * "This bit must be set if 3DSTATE_CLIP clip mode is set2612			      * to normal and 3DSTATE_SF number of SF output attributes2613			      * is more than 16."2614			      */2615			     _3D_CHICKEN3_SF_DISABLE_PIPELINED_ATTR_FETCH);2616 2617		/*2618		 * BSpec recommends 8x4 when MSAA is used,2619		 * however in practice 16x4 seems fastest.2620		 *2621		 * Note that PS/WM thread counts depend on the WIZ hashing2622		 * disable bit, which we don't touch here, but it's good2623		 * to keep in mind (see 3DSTATE_PS and 3DSTATE_WM).2624		 */2625		wa_masked_field_set(wal,2626				    GEN6_GT_MODE,2627				    GEN6_WIZ_HASHING_MASK,2628				    GEN6_WIZ_HASHING_16x4);2629 2630		/* WaDisable_RenderCache_OperationalFlush:snb */2631		wa_masked_dis(wal, CACHE_MODE_0, RC_OP_FLUSH_ENABLE);2632 2633		/*2634		 * From the Sandybridge PRM, volume 1 part 3, page 24:2635		 * "If this bit is set, STCunit will have LRA as replacement2636		 *  policy. [...] This bit must be reset. LRA replacement2637		 *  policy is not supported."2638		 */2639		wa_masked_dis(wal,2640			      CACHE_MODE_0,2641			      CM0_STC_EVICT_DISABLE_LRA_SNB);2642	}2643 2644	if (IS_GRAPHICS_VER(i915, 4, 6))2645		/* WaTimedSingleVertexDispatch:cl,bw,ctg,elk,ilk,snb */2646		wa_add(wal, RING_MI_MODE(RENDER_RING_BASE),2647		       0, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH),2648		       /* XXX bit doesn't stick on Broadwater */2649		       IS_I965G(i915) ? 0 : VS_TIMER_DISPATCH, true);2650 2651	if (GRAPHICS_VER(i915) == 4)2652		/*2653		 * Disable CONSTANT_BUFFER before it is loaded from the context2654		 * image. For as it is loaded, it is executed and the stored2655		 * address may no longer be valid, leading to a GPU hang.2656		 *2657		 * This imposes the requirement that userspace reload their2658		 * CONSTANT_BUFFER on every batch, fortunately a requirement2659		 * they are already accustomed to from before contexts were2660		 * enabled.2661		 */2662		wa_add(wal, ECOSKPD(RENDER_RING_BASE),2663		       0, _MASKED_BIT_ENABLE(ECO_CONSTANT_BUFFER_SR_DISABLE),2664		       0 /* XXX bit doesn't stick on Broadwater */,2665		       true);2666}2667 2668static void2669xcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)2670{2671	struct drm_i915_private *i915 = engine->i915;2672 2673	/* WaKBLVECSSemaphoreWaitPoll:kbl */2674	if (IS_KABYLAKE(i915) && IS_GRAPHICS_STEP(i915, STEP_A0, STEP_F0)) {2675		wa_write(wal,2676			 RING_SEMA_WAIT_POLL(engine->mmio_base),2677			 1);2678	}2679	/* Wa_16018031267, Wa_16018063123 */2680	if (NEEDS_FASTCOLOR_BLT_WABB(engine))2681		wa_masked_field_set(wal, ECOSKPD(engine->mmio_base),2682				    XEHP_BLITTER_SCHEDULING_MODE_MASK,2683				    XEHP_BLITTER_ROUND_ROBIN_MODE);2684}2685 2686static void2687ccs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)2688{2689	/* boilerplate for any CCS engine workaround */2690}2691 2692/*2693 * The bspec performance guide has recommended MMIO tuning settings.  These2694 * aren't truly "workarounds" but we want to program them with the same2695 * workaround infrastructure to ensure that they're automatically added to2696 * the GuC save/restore lists, re-applied at the right times, and checked for2697 * any conflicting programming requested by real workarounds.2698 *2699 * Programming settings should be added here only if their registers are not2700 * part of an engine's register state context.  If a register is part of a2701 * context, then any tuning settings should be programmed in an appropriate2702 * function invoked by __intel_engine_init_ctx_wa().2703 */2704static void2705add_render_compute_tuning_settings(struct intel_gt *gt,2706				   struct i915_wa_list *wal)2707{2708	struct drm_i915_private *i915 = gt->i915;2709 2710	if (IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 70), IP_VER(12, 74)) || IS_DG2(i915))2711		wa_mcr_write_clr_set(wal, RT_CTRL, STACKID_CTRL, STACKID_CTRL_512);2712 2713	/*2714	 * This tuning setting proves beneficial only on ATS-M designs; the2715	 * default "age based" setting is optimal on regular DG2 and other2716	 * platforms.2717	 */2718	if (INTEL_INFO(i915)->tuning_thread_rr_after_dep)2719		wa_mcr_masked_field_set(wal, GEN9_ROW_CHICKEN4, THREAD_EX_ARB_MODE,2720					THREAD_EX_ARB_MODE_RR_AFTER_DEP);2721 2722	if (GRAPHICS_VER(i915) == 12 && GRAPHICS_VER_FULL(i915) < IP_VER(12, 55))2723		wa_write_clr(wal, GEN8_GARBCNTL, GEN12_BUS_HASH_CTL_BIT_EXC);2724}2725 2726static void ccs_engine_wa_mode(struct intel_engine_cs *engine, struct i915_wa_list *wal)2727{2728	struct intel_gt *gt = engine->gt;2729	u32 mode;2730 2731	if (!IS_DG2(gt->i915))2732		return;2733 2734	/*2735	 * Wa_14019159160: This workaround, along with others, leads to2736	 * significant challenges in utilizing load balancing among the2737	 * CCS slices. Consequently, an architectural decision has been2738	 * made to completely disable automatic CCS load balancing.2739	 */2740	wa_masked_en(wal, GEN12_RCU_MODE, XEHP_RCU_MODE_FIXED_SLICE_CCS_MODE);2741 2742	/*2743	 * After having disabled automatic load balancing we need to2744	 * assign all slices to a single CCS. We will call it CCS mode 12745	 */2746	mode = intel_gt_apply_ccs_mode(gt);2747	wa_masked_en(wal, XEHP_CCS_MODE, mode);2748}2749 2750/*2751 * The workarounds in this function apply to shared registers in2752 * the general render reset domain that aren't tied to a2753 * specific engine.  Since all render+compute engines get reset2754 * together, and the contents of these registers are lost during2755 * the shared render domain reset, we'll define such workarounds2756 * here and then add them to just a single RCS or CCS engine's2757 * workaround list (whichever engine has the XXXX flag).2758 */2759static void2760general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)2761{2762	struct drm_i915_private *i915 = engine->i915;2763	struct intel_gt *gt = engine->gt;2764 2765	add_render_compute_tuning_settings(gt, wal);2766 2767	if (GRAPHICS_VER(i915) >= 11) {2768		/* This is not a Wa (although referred to as2769		 * WaSetInidrectStateOverride in places), this allows2770		 * applications that reference sampler states through2771		 * the BindlessSamplerStateBaseAddress to have their2772		 * border color relative to DynamicStateBaseAddress2773		 * rather than BindlessSamplerStateBaseAddress.2774		 *2775		 * Otherwise SAMPLER_STATE border colors have to be2776		 * copied in multiple heaps (DynamicStateBaseAddress &2777		 * BindlessSamplerStateBaseAddress)2778		 *2779		 * BSpec: 460522780		 */2781		wa_mcr_masked_en(wal,2782				 GEN10_SAMPLER_MODE,2783				 GEN11_INDIRECT_STATE_BASE_ADDR_OVERRIDE);2784	}2785 2786	if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_B0, STEP_FOREVER) ||2787	    IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_B0, STEP_FOREVER) ||2788	    IS_GFX_GT_IP_RANGE(gt, IP_VER(12, 74), IP_VER(12, 74))) {2789		/* Wa_14017856879 */2790		wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN3, MTL_DISABLE_FIX_FOR_EOT_FLUSH);2791 2792		/* Wa_14020495402 */2793		wa_mcr_masked_en(wal, GEN8_ROW_CHICKEN2, XELPG_DISABLE_TDL_SVHS_GATING);2794	}2795 2796	if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||2797	    IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0))2798		/*2799		 * Wa_140170660712800		 * Wa_140176542032801		 */2802		wa_mcr_masked_en(wal, GEN10_SAMPLER_MODE,2803				 MTL_DISABLE_SAMPLER_SC_OOO);2804 2805	if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0))2806		/* Wa_22015279794 */2807		wa_mcr_masked_en(wal, GEN10_CACHE_MODE_SS,2808				 DISABLE_PREFETCH_INTO_IC);2809 2810	if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||2811	    IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0) ||2812	    IS_DG2(i915)) {2813		/* Wa_22013037850 */2814		wa_mcr_write_or(wal, LSC_CHICKEN_BIT_0_UDW,2815				DISABLE_128B_EVICTION_COMMAND_UDW);2816 2817		/* Wa_18017747507 */2818		wa_masked_en(wal, VFG_PREEMPTION_CHICKEN, POLYGON_TRIFAN_LINELOOP_DISABLE);2819	}2820 2821	if (IS_GFX_GT_IP_STEP(gt, IP_VER(12, 70), STEP_A0, STEP_B0) ||2822	    IS_GFX_GT_IP_STEP(gt, IP_VER(12, 71), STEP_A0, STEP_B0) ||2823	    IS_DG2(i915)) {2824		/* Wa_22014226127 */2825		wa_mcr_write_or(wal, LSC_CHICKEN_BIT_0, DISABLE_D8_D16_COASLESCE);2826	}2827 2828	if (IS_DG2(i915)) {2829		/* Wa_14015227452:dg2,pvc */2830		wa_mcr_masked_en(wal, GEN9_ROW_CHICKEN4, XEHP_DIS_BBL_SYSPIPE);2831 2832		/*2833		 * Wa_16011620976:dg2_g112834		 * Wa_22015475538:dg22835		 */2836		wa_mcr_write_or(wal, LSC_CHICKEN_BIT_0_UDW, DIS_CHAIN_2XSIMD8);2837 2838		/* Wa_18028616096 */2839		wa_mcr_write_or(wal, LSC_CHICKEN_BIT_0_UDW, UGM_FRAGMENT_THRESHOLD_TO_3);2840	}2841 2842	if (IS_DG2_G11(i915)) {2843		/*2844		 * Wa_22012826095:dg22845		 * Wa_22013059131:dg22846		 */2847		wa_mcr_write_clr_set(wal, LSC_CHICKEN_BIT_0_UDW,2848				     MAXREQS_PER_BANK,2849				     REG_FIELD_PREP(MAXREQS_PER_BANK, 2));2850 2851		/* Wa_22013059131:dg2 */2852		wa_mcr_write_or(wal, LSC_CHICKEN_BIT_0,2853				FORCE_1_SUB_MESSAGE_PER_FRAGMENT);2854 2855		/*2856		 * Wa_220126541322857		 *2858		 * Note that register 0xE420 is write-only and cannot be read2859		 * back for verification on DG2 (due to Wa_14012342262), so2860		 * we need to explicitly skip the readback.2861		 */2862		wa_mcr_add(wal, GEN10_CACHE_MODE_SS, 0,2863			   _MASKED_BIT_ENABLE(ENABLE_PREFETCH_INTO_IC),2864			   0 /* write-only, so skip validation */,2865			   true);2866	}2867}2868 2869static void2870engine_init_workarounds(struct intel_engine_cs *engine, struct i915_wa_list *wal)2871{2872	if (GRAPHICS_VER(engine->i915) < 4)2873		return;2874 2875	engine_fake_wa_init(engine, wal);2876 2877	/*2878	 * These are common workarounds that just need to applied2879	 * to a single RCS/CCS engine's workaround list since2880	 * they're reset as part of the general render domain reset.2881	 */2882	if (engine->flags & I915_ENGINE_FIRST_RENDER_COMPUTE) {2883		general_render_compute_wa_init(engine, wal);2884		ccs_engine_wa_mode(engine, wal);2885	}2886 2887	if (engine->class == COMPUTE_CLASS)2888		ccs_engine_wa_init(engine, wal);2889	else if (engine->class == RENDER_CLASS)2890		rcs_engine_wa_init(engine, wal);2891	else2892		xcs_engine_wa_init(engine, wal);2893}2894 2895void intel_engine_init_workarounds(struct intel_engine_cs *engine)2896{2897	struct i915_wa_list *wal = &engine->wa_list;2898 2899	wa_init_start(wal, engine->gt, "engine", engine->name);2900	engine_init_workarounds(engine, wal);2901	wa_init_finish(wal);2902}2903 2904void intel_engine_apply_workarounds(struct intel_engine_cs *engine)2905{2906	wa_list_apply(&engine->wa_list);2907}2908 2909static const struct i915_range mcr_ranges_gen8[] = {2910	{ .start = 0x5500, .end = 0x55ff },2911	{ .start = 0x7000, .end = 0x7fff },2912	{ .start = 0x9400, .end = 0x97ff },2913	{ .start = 0xb000, .end = 0xb3ff },2914	{ .start = 0xe000, .end = 0xe7ff },2915	{},2916};2917 2918static const struct i915_range mcr_ranges_gen12[] = {2919	{ .start =  0x8150, .end =  0x815f },2920	{ .start =  0x9520, .end =  0x955f },2921	{ .start =  0xb100, .end =  0xb3ff },2922	{ .start =  0xde80, .end =  0xe8ff },2923	{ .start = 0x24a00, .end = 0x24a7f },2924	{},2925};2926 2927static const struct i915_range mcr_ranges_xehp[] = {2928	{ .start =  0x4000, .end =  0x4aff },2929	{ .start =  0x5200, .end =  0x52ff },2930	{ .start =  0x5400, .end =  0x7fff },2931	{ .start =  0x8140, .end =  0x815f },2932	{ .start =  0x8c80, .end =  0x8dff },2933	{ .start =  0x94d0, .end =  0x955f },2934	{ .start =  0x9680, .end =  0x96ff },2935	{ .start =  0xb000, .end =  0xb3ff },2936	{ .start =  0xc800, .end =  0xcfff },2937	{ .start =  0xd800, .end =  0xd8ff },2938	{ .start =  0xdc00, .end =  0xffff },2939	{ .start = 0x17000, .end = 0x17fff },2940	{ .start = 0x24a00, .end = 0x24a7f },2941	{},2942};2943 2944static bool mcr_range(struct drm_i915_private *i915, u32 offset)2945{2946	const struct i915_range *mcr_ranges;2947	int i;2948 2949	if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 55))2950		mcr_ranges = mcr_ranges_xehp;2951	else if (GRAPHICS_VER(i915) >= 12)2952		mcr_ranges = mcr_ranges_gen12;2953	else if (GRAPHICS_VER(i915) >= 8)2954		mcr_ranges = mcr_ranges_gen8;2955	else2956		return false;2957 2958	/*2959	 * Registers in these ranges are affected by the MCR selector2960	 * which only controls CPU initiated MMIO. Routing does not2961	 * work for CS access so we cannot verify them on this path.2962	 */2963	for (i = 0; mcr_ranges[i].start; i++)2964		if (offset >= mcr_ranges[i].start &&2965		    offset <= mcr_ranges[i].end)2966			return true;2967 2968	return false;2969}2970 2971static int2972wa_list_srm(struct i915_request *rq,2973	    const struct i915_wa_list *wal,2974	    struct i915_vma *vma)2975{2976	struct drm_i915_private *i915 = rq->i915;2977	unsigned int i, count = 0;2978	const struct i915_wa *wa;2979	u32 srm, *cs;2980 2981	srm = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;2982	if (GRAPHICS_VER(i915) >= 8)2983		srm++;2984 2985	for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {2986		if (!mcr_range(i915, i915_mmio_reg_offset(wa->reg)))2987			count++;2988	}2989 2990	cs = intel_ring_begin(rq, 4 * count);2991	if (IS_ERR(cs))2992		return PTR_ERR(cs);2993 2994	for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {2995		u32 offset = i915_mmio_reg_offset(wa->reg);2996 2997		if (mcr_range(i915, offset))2998			continue;2999 3000		*cs++ = srm;3001		*cs++ = offset;3002		*cs++ = i915_ggtt_offset(vma) + sizeof(u32) * i;3003		*cs++ = 0;3004	}3005	intel_ring_advance(rq, cs);3006 3007	return 0;3008}3009 3010static int engine_wa_list_verify(struct intel_context *ce,3011				 const struct i915_wa_list * const wal,3012				 const char *from)3013{3014	const struct i915_wa *wa;3015	struct i915_request *rq;3016	struct i915_vma *vma;3017	struct i915_gem_ww_ctx ww;3018	unsigned int i;3019	u32 *results;3020	int err;3021 3022	if (!wal->count)3023		return 0;3024 3025	vma = __vm_create_scratch_for_read(&ce->engine->gt->ggtt->vm,3026					   wal->count * sizeof(u32));3027	if (IS_ERR(vma))3028		return PTR_ERR(vma);3029 3030	intel_engine_pm_get(ce->engine);3031	i915_gem_ww_ctx_init(&ww, false);3032retry:3033	err = i915_gem_object_lock(vma->obj, &ww);3034	if (err == 0)3035		err = intel_context_pin_ww(ce, &ww);3036	if (err)3037		goto err_pm;3038 3039	err = i915_vma_pin_ww(vma, &ww, 0, 0,3040			   i915_vma_is_ggtt(vma) ? PIN_GLOBAL : PIN_USER);3041	if (err)3042		goto err_unpin;3043 3044	rq = i915_request_create(ce);3045	if (IS_ERR(rq)) {3046		err = PTR_ERR(rq);3047		goto err_vma;3048	}3049 3050	err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);3051	if (err == 0)3052		err = wa_list_srm(rq, wal, vma);3053 3054	i915_request_get(rq);3055	if (err)3056		i915_request_set_error_once(rq, err);3057	i915_request_add(rq);3058 3059	if (err)3060		goto err_rq;3061 3062	if (i915_request_wait(rq, 0, HZ / 5) < 0) {3063		err = -ETIME;3064		goto err_rq;3065	}3066 3067	results = i915_gem_object_pin_map(vma->obj, I915_MAP_WB);3068	if (IS_ERR(results)) {3069		err = PTR_ERR(results);3070		goto err_rq;3071	}3072 3073	err = 0;3074	for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {3075		if (mcr_range(rq->i915, i915_mmio_reg_offset(wa->reg)))3076			continue;3077 3078		if (!wa_verify(wal->gt, wa, results[i], wal->name, from))3079			err = -ENXIO;3080	}3081 3082	i915_gem_object_unpin_map(vma->obj);3083 3084err_rq:3085	i915_request_put(rq);3086err_vma:3087	i915_vma_unpin(vma);3088err_unpin:3089	intel_context_unpin(ce);3090err_pm:3091	if (err == -EDEADLK) {3092		err = i915_gem_ww_ctx_backoff(&ww);3093		if (!err)3094			goto retry;3095	}3096	i915_gem_ww_ctx_fini(&ww);3097	intel_engine_pm_put(ce->engine);3098	i915_vma_put(vma);3099	return err;3100}3101 3102int intel_engine_verify_workarounds(struct intel_engine_cs *engine,3103				    const char *from)3104{3105	return engine_wa_list_verify(engine->kernel_context,3106				     &engine->wa_list,3107				     from);3108}3109 3110#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)3111#include "selftest_workarounds.c"3112#endif3113