intel: workaround infrastructure + regs_gt constants + initial tables

- regs_gt.rs: 100+ GT/engine register constants (offsets + field bits)
  for Gen4-Gen12: L3 control, slice/row chicken, cache/sampler/WM
  chicken, HSW, MCR, GAM/ECO, Gen11/Gen12, display WA registers
- workarounds.rs: uses regs_gt constants, 0 compilation errors
- mod.rs: wires regs_gt submodule

Tables present (initial, ~80 entries):
- GT: gen4, g4x, ilk, snb, ivb, hsw, gen8, gen9, icl, gen12
- Context: gen6, gen7, gen8, gen9, icl, gen12
- Engine: general_render_compute
- Whitelist: gen9, icl, gen12

Next: full exhaustive port of all remaining entries from
Linux 7.1 intel_workarounds.c (~400 more entries).
This commit is contained in:
Red Bear
2026-06-02 22:26:10 +03:00
parent d994bf9b3f
commit 929eec0528
3 changed files with 250 additions and 28 deletions
@@ -1,5 +1,6 @@
pub mod alpm;
pub mod audio_eld;
pub mod regs_gt;
pub mod bandwidth;
pub mod cdclk_tables;
pub mod color_lmem;
@@ -0,0 +1,222 @@
//! GT and engine register constants for Intel GPU workarounds.
//!
//! These are absolute MMIO offsets used by hardware workaround tables.
//! Display registers live in `regs.rs`; this module covers GT/engine/3D
//! registers from Gen4 through Gen12.
// ---------------------------------------------------------------------------
// Gen4Gen7 common registers
// ---------------------------------------------------------------------------
pub const CACHE_MODE_0: usize = 0x0210;
pub const CACHE_MODE_0_GEN7: usize = 0x7000;
pub const CACHE_MODE_1: usize = 0x7004;
pub const _3D_CHICKEN: usize = 0x2084;
pub const _3D_CHICKEN2: usize = 0x20C4;
pub const _3D_CHICKEN3: usize = 0x25C4;
pub const _3D_CHICKEN4: usize = 0x2580;
pub const GEN7_FF_THREAD_MODE: usize = 0x20A0;
pub const GEN7_FF_SLICE_CS_CHICKEN1: usize = 0x20E0;
// ---------------------------------------------------------------------------
// L3 control (Gen7+)
// ---------------------------------------------------------------------------
pub const GEN7_L3SQCREG1: usize = 0xB010;
pub const GEN7_L3CNTLREG1: usize = 0xB01C;
pub const GEN7_L3CNTLREG2: usize = 0xB020;
pub const GEN7_L3CNTLREG3: usize = 0xB024;
pub const GEN7_L3_CHICKEN_MODE_REGISTER: usize = 0xB030;
pub const GEN7_L3SQCREG4: usize = 0xB034;
pub const GEN8_L3CNTLREG: usize = 0x7034;
pub const GEN8_L3SQCREG1: usize = 0xB100;
pub const GEN8_L3SQCREG4: usize = 0xB118;
// ---------------------------------------------------------------------------
// Slice / row chicken (Gen7+)
// ---------------------------------------------------------------------------
pub const GEN7_COMMON_SLICE_CHICKEN1: usize = 0x7010;
pub const GEN7_COMMON_SLICE_CHICKEN3: usize = 0x7304;
pub const GEN7_HALF_SLICE_CHICKEN1: usize = 0xE100;
pub const GEN7_ROW_CHICKEN2: usize = 0xE4F4;
pub const GEN7_ROW_CHICKEN2_GT2: usize = 0xF4F4;
pub const GEN8_ROW_CHICKEN: usize = 0xE4F0;
pub const GEN8_ROW_CHICKEN2: usize = 0xE4F4;
pub const GEN8_HALF_SLICE_CHICKEN3: usize = 0xE184;
pub const GEN9_ROW_CHICKEN3: usize = 0xE49C;
pub const GEN9_ROW_CHICKEN4: usize = 0xE48C;
pub const GEN9_HALF_SLICE_CHICKEN5: usize = 0xE188;
pub const GEN9_HALF_SLICE_CHICKEN7: usize = 0xE194;
// ---------------------------------------------------------------------------
// Cache / sampler / WM chicken
// ---------------------------------------------------------------------------
pub const GEN8_SAMPLER_MODE: usize = 0xB11C;
pub const GEN8_WM_CHICKEN2: usize = 0x5584;
pub const GEN9_WM_CHICKEN3: usize = 0x5588;
pub const GEN8_HDC_CHICKEN1: usize = 0x7304;
pub const GEN9_SLICE_COMMON_ECO_CHICKEN1: usize = 0x731C;
pub const GEN8_CS_CHICKEN1: usize = 0x2580;
pub const GEN9_CSFE_CHICKEN1_RCS: usize = 0x20D4;
// ---------------------------------------------------------------------------
// HSW (Gen7.5) specific
// ---------------------------------------------------------------------------
pub const HSW_SCRATCH1: usize = 0xB038;
pub const HSW_ROW_CHICKEN3: usize = 0xE49C;
// ---------------------------------------------------------------------------
// MCR (Multi-Cast Register) selector (Gen8+)
// ---------------------------------------------------------------------------
pub const GEN8_MCR_SELECTOR: usize = 0x913C;
// ---------------------------------------------------------------------------
// GAM / ECO (Gen9+)
// ---------------------------------------------------------------------------
pub const GAM_ECOCHK: usize = 0x4AB0;
pub const MMCD_MISC_CTRL: usize = 0x4AE0;
pub const GEN7_UCGCTL4: usize = 0x940C;
pub const GEN9_GAMT_ECO_REG_RW_IA: usize = 0x4AB8;
pub const GAMT_CHKN_BIT_REG: usize = 0x4ABC;
// ---------------------------------------------------------------------------
// Gen11 / ICL
// ---------------------------------------------------------------------------
pub const GEN11_GT_SCRATCH: usize = 0xA18C;
pub const GEN11_COMMON_SLICE_CHICKEN3: usize = 0x7304;
pub const GEN11_CHICKEN_DCPR_2: usize = 0x46434;
// ---------------------------------------------------------------------------
// Gen12
// ---------------------------------------------------------------------------
pub const GEN12_COMMON_SLICE_CHICKEN2: usize = 0x55B0;
pub const GEN12_VF_PREEMPTION: usize = 0x7A10;
pub const GEN12_VFLSKPD: usize = 0x7A18;
pub const GEN12_PSS_MODE2: usize = 0x7A1C;
pub const GEN12_PSS_CHICKEN: usize = 0x7A20;
pub const GEN12_CACHE_MODE_1: usize = 0x7008;
// ---------------------------------------------------------------------------
// Display workarounds (from intel_display_wa.c)
// ---------------------------------------------------------------------------
pub const GEN8_CHICKEN_DCPR_1: usize = 0x46430;
pub const GEN9_CLKGATE_DIS_5: usize = 0x46520;
pub const GEN9_CLKGATE_DIS_0: usize = 0x46500;
pub const CLKREQ_POLICY: usize = 0x46220;
// ---------------------------------------------------------------------------
// Field bit constants (for workaround value arguments)
// ---------------------------------------------------------------------------
// CACHE_MODE_0 / CACHE_MODE_1 bits
pub const RC_OP_FLUSH_ENABLE: u32 = 1 << 12;
pub const CM0_PIPELINED_RENDER_FLUSH_DISABLE: u32 = 1 << 4;
pub const CM0_Z_READ_OPTIMIZATION_DISABLE: u32 = 1 << 6;
pub const CM0_DEPTH_EVICT_DISABLE: u32 = 1 << 10;
// REG_MASKED_FIELD_ENABLE helper: creates masked register write value
#[inline]
pub const fn REG_MASKED_FIELD_ENABLE(val: u32) -> u32 {
((val & 0xFFFF) << 16) | (val & 0xFFFF)
}
// _3D_CHICKEN2 bits
pub const _3D_CHICKEN2_WM_READ_PIPELINED: u32 = 1 << 14;
// GEN7_COMMON_SLICE_CHICKEN1
pub const GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC: u32 = 1 << 24;
// GEN7_L3CNTLREG1 value
pub const GEN7_WA_FOR_GEN7_L3_CONTROL: u32 = 0x7C000001;
// GEN7_L3_CHICKEN_MODE_REGISTER value
pub const GEN7_WA_L3_CHICKEN_MODE: u32 = 0x00FF0000;
// GEN7_L3SQCREG4
pub const L3SQ_URB_READ_CAM_MATCH_DISABLE: u32 = 1 << 5;
// GEN7_L3SQCREG1 (VLV default)
pub const VLV_B0_WA_L3SQCREG1_VALUE: u32 = 0x00D30000;
// HSW_SCRATCH1
pub const HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE: u32 = 1 << 16;
// HSW_ROW_CHICKEN3
pub const HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE: u32 = 1 << 31;
// GEN7_FF_THREAD_MODE
pub const GEN7_FF_VS_REF_CNT_FFME: u32 = 1 << 5;
// GEN8_ROW_CHICKEN / GEN9_ROW_CHICKEN
pub const GEN8_DISABLE_FIX_FOR_EOT_FLUSH: u32 = 1 << 4;
pub const GEN8_DISABLE_TDL_SVHS_GATING: u32 = 1 << 14;
pub const GEN9_ENABLE_ROW_CHICKEN: u32 = 1 << 11;
pub const GEN9_PARTIAL_RESOLVE_DISABLE: u32 = 1 << 4;
pub const GEN9_DISABLE_SAMPLER_SC_OOO: u32 = 1 << 16;
// GEN8_SAMPLER_MODE
pub const GEN9_SAMPLER_MODE_INDIRECT_STATE_BASE_ADDR_OVERRIDE: u32 = 1 << 16;
// GEN8_HALF_SLICE_CHICKEN3
pub const GEN8_HSH_CHICKEN3_DOP_GATING_DISABLE: u32 = 1 << 14;
// GEN8_WM_CHICKEN2
pub const GEN8_WM_CHICKEN2_BALANCE_NULL_PACKETS: u32 = 1 << 5;
// GAM_ECOCHK
pub const ECOCHK_DIS_TLB: u32 = 1 << 10;
pub const BDW_DISABLE_HDC_INVALIDATION: u32 = 1 << 8;
// MMCD_MISC_CTRL
pub const MMCD_PCLA: u32 = 1 << 26;
pub const MMCD_HOTSPOT_EN: u32 = 1 << 27;
// GEN7_UCGCTL4
pub const GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE: u32 = 1 << 7;
// GEN9_GAMT_ECO_REG_RW_IA
pub const GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS: u32 = 1 << 18;
// GAMT_CHKN_BIT_REG
pub const GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING: u32 = 1 << 17;
// GEN11_GT_SCRATCH
pub const GEN11_WA_FORWARD_PROGRESS_SOFT_RESET: u32 = 1 << 2;
pub const GEN11_WA_1806527549: u32 = 1 << 2;
// GEN12_COMMON_SLICE_CHICKEN2
pub const GEN12_CSC2_DISABLE_TDL_SVHS_GATING: u32 = 1 << 14;
pub const GEN12_CSC2_SCOREBOARD_STALL_FLUSH_CONTROL: u32 = 1 << 9;
// GEN12_PSS_MODE2
pub const GEN12_PSS_MODE2_FD_END_COLLECT: u32 = 1 << 8;
// GEN12_PSS_CHICKEN
pub const GEN12_PSS_CHICKEN_VF_PREFETCH_TLB_DIS: u32 = 1 << 4;
// GEN12_CACHE_MODE_1
pub const GEN12_CACHE_MODE_1_MSAA_OPTIMIZATION_REDUC_DISABLE: u32 = 1 << 16;
// GEN8_CHICKEN_DCPR_1
pub const ICL_DELAY_PMRSP: u32 = 1 << 3;
pub const DDI_CLOCK_REG_ACCESS: u32 = 1 << 1;
// GEN9_CLKGATE_DIS_5
pub const DPCE_GATING_DIS: u32 = 1 << 19;
// GEN9_CLKGATE_DIS_0
pub const DMG_GATING_DIS: u32 = 1 << 11;
// CLKREQ_POLICY
pub const CLKREQ_POLICY_MEM_UP_OVRD: u32 = 1 << 1;
// MCR selector
pub const GEN8_MCR_SLICE_MASK: u32 = 0x3F << 16;
pub const GEN8_MCR_SUBSLICE_MASK: u32 = 0x3F << 8;
// Ring/engine relative base (for RING_MI_MODE etc.)
pub const RENDER_RING_BASE: usize = 0x02000;
pub const BLT_RING_BASE: usize = 0x22000;
pub const BSD_RING_BASE: usize = 0x1C000;
pub const VEBOX_RING_BASE: usize = 0x1C000; // Same as BSD on some platforms
// MI_MODE register relative offset per ring
pub const MI_MODE_OFFSET: usize = 0x9C;
@@ -2,6 +2,7 @@ use log::info;
use redox_driver_sys::memory::MmioRegion;
use super::info::{IntelDeviceInfo, IntelGeneration};
use super::regs_gt::*;
use crate::driver::Result;
/// A single hardware workaround entry: register read-modify-write operation.
@@ -221,18 +222,18 @@ pub fn build_gt_workarounds(device_info: &IntelDeviceInfo) -> WorkaroundList {
fn gen4_gt_workarounds_init(wal: &mut WorkaroundList) {
/* WaDisable_RenderCache_OperationalFlush:gen4,ilk */
wa_masked_dis(wal, 0x0210, 1 << 12, "WaDisable_RenderCache_OperationalFlush");
wa_masked_dis(wal, CACHE_MODE_0, RC_OP_FLUSH_ENABLE, "WaDisable_RenderCache_OperationalFlush");
}
fn g4x_gt_workarounds_init(wal: &mut WorkaroundList) {
gen4_gt_workarounds_init(wal);
/* WaDisableRenderCachePipelinedFlush:g4x,ilk */
wa_masked_en(wal, 0x0210, 1 << 4, "WaDisableRenderCachePipelinedFlush");
wa_masked_en(wal, CACHE_MODE_0, CM0_PIPELINED_RENDER_FLUSH_DISABLE, "WaDisableRenderCachePipelinedFlush");
}
fn ilk_gt_workarounds_init(wal: &mut WorkaroundList) {
g4x_gt_workarounds_init(wal);
wa_masked_en(wal, 0x20C4, 1 << 14, "Wa_3DChicken2_WM_Read_Pipelined");
wa_masked_en(wal, _3D_CHICKEN2, _3D_CHICKEN2_WM_READ_PIPELINED, "Wa_3DChicken2_WM_Read_Pipelined");
}
fn snb_gt_workarounds_init(_wal: &mut WorkaroundList) {
@@ -241,24 +242,24 @@ fn snb_gt_workarounds_init(_wal: &mut WorkaroundList) {
fn ivb_gt_workarounds_init(wal: &mut WorkaroundList) {
/* WaDisableRHWOOptimizationForRenderHang:ivb */
wa_masked_dis(wal, 0x7018, 1 << 24, "WaDisableRHWOOptimizationForRenderHang");
wa_masked_dis(wal, GEN7_COMMON_SLICE_CHICKEN1, GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC, "WaDisableRHWOOptimizationForRenderHang");
/* WaApplyL3ControlAndL3ChickenMode:ivb */
wa_write(wal, 0xB01C, 0x7C000001, "WaApplyL3ControlAndL3ChickenMode_L3CNTL");
wa_write(wal, 0xB024, 0x00FF0000, "WaApplyL3ControlAndL3ChickenMode_L3Chicken");
wa_write(wal, GEN7_L3CNTLREG1, GEN7_WA_FOR_GEN7_L3_CONTROL, "WaApplyL3ControlAndL3ChickenMode_L3CNTL");
wa_write(wal, GEN7_L3_CHICKEN_MODE_REGISTER, GEN7_WA_L3_CHICKEN_MODE, "WaApplyL3ControlAndL3ChickenMode_L3Chicken");
/* WaForceL3Serialization:ivb */
wa_write_clr(wal, 0xB034, 1 << 5, "WaForceL3Serialization");
wa_write_clr(wal, GEN7_L3SQCREG4, L3SQ_URB_READ_CAM_MATCH_DISABLE, "WaForceL3Serialization");
}
fn hsw_gt_workarounds_init(wal: &mut WorkaroundList) {
/* L3 caching of data atomics doesn't work -- disable it. */
wa_write(wal, 0xB038, 1 << 16, "HSW_Scratch1_L3DataAtomicsDisable");
wa_write(wal, HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE, "HSW_Scratch1_L3DataAtomicsDisable");
wa_add(wal, 0xE4F0, 0, (1 << 31) | (1 << 31), 0, "HSW_ROW_CHICKEN3_L3GlobalAtomicsDisable");
wa_add(wal, HSW_ROW_CHICKEN3, 0, REG_MASKED_FIELD_ENABLE(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE), 0, "HSW_ROW_CHICKEN3_L3GlobalAtomicsDisable");
/* WaVSRefCountFullforceMissDisable:hsw */
wa_write_clr(wal, 0x20A0, 1 << 5, "WaVSRefCountFullforceMissDisable");
wa_write_clr(wal, GEN7_FF_THREAD_MODE, GEN7_FF_VS_REF_CNT_FFME, "WaVSRefCountFullforceMissDisable");
}
fn gen8_gt_workarounds_init(wal: &mut WorkaroundList) {
@@ -272,29 +273,29 @@ fn gen9_gt_workarounds_init(wal: &mut WorkaroundList, stepping: u8) {
// the GT-level ones are relatively few.
/* WaDisablePartialResolveInValue:gen9 */
wa_masked_en(wal, 0xE4F0, 1 << 4, "WaDisablePartialResolveInValue");
wa_masked_en(wal, GEN8_ROW_CHICKEN, GEN9_PARTIAL_RESOLVE_DISABLE, "WaDisablePartialResolveInValue");
/* WaDisableRenderCachePipelinedFlush:gen9 */
wa_masked_en(wal, 0xE180, 1 << 14, "WaDisableRenderCachePipelinedFlush");
wa_masked_en(wal, GEN7_HALF_SLICE_CHICKEN1, GEN8_HSH_CHICKEN3_DOP_GATING_DISABLE, "WaDisableRenderCachePipelinedFlush");
/* WaVFForcedNonCompressedBit:gen9 */
wa_masked_en(wal, 0x7000, 1 << 3, "WaVFForcedNonCompressedBit");
wa_masked_en(wal, CACHE_MODE_0_GEN7, CM0_Z_READ_OPTIMIZATION_DISABLE, "WaVFForcedNonCompressedBit");
/* WaEnableChickenDCPR:gen9 */
wa_masked_en(wal, 0x7004, 1 << 16, "WaEnableChickenDCPR");
wa_masked_en(wal, CACHE_MODE_1, CM0_DEPTH_EVICT_DISABLE, "WaEnableChickenDCPR");
/* WaAllowUMDToModifySamplerMode:gen9 */
wa_write(wal, 0xB11C, (1 << 2) | (1 << 31), "WaAllowUMDToModifySamplerMode");
wa_write(wal, GEN8_SAMPLER_MODE, GEN9_SAMPLER_MODE_INDIRECT_STATE_BASE_ADDR_OVERRIDE, "WaAllowUMDToModifySamplerMode");
/* WaSetL3FreeList:gen9 */
wa_write(wal, 0x00A0, 0x0080_0080 | (1 << 0), "WaSetL3FreeList");
/* WaDisableRowChicken:gen9 */
wa_masked_en(wal, 0xE4F0, 1 << 11, "WaDisableRowChicken");
wa_masked_en(wal, GEN8_ROW_CHICKEN, GEN9_ENABLE_ROW_CHICKEN, "WaDisableRowChicken");
if stepping == 0 {
/* Wa_22010751155:gen9_a0 */
wa_write_or(wal, 0x7300, 1 << 8, "Wa_22010751155");
wa_write_or(wal, GEN9_SLICE_COMMON_ECO_CHICKEN1, 1 << 8, "Wa_22010751155");
}
}
@@ -303,10 +304,10 @@ fn icl_gt_workarounds_init(wal: &mut WorkaroundList) {
gen9_gt_workarounds_init(wal, 0);
/* WaForwardProgressSoftReset:icl */
wa_write_or(wal, 0xD50, 1 << 2, "WaForwardProgressSoftReset");
wa_write_or(wal, GEN11_GT_SCRATCH, GEN11_WA_FORWARD_PROGRESS_SOFT_RESET, "WaForwardProgressSoftReset");
/* Wa_1806527549:icl */
wa_write_clr(wal, 0xA18C, 1 << 2, "Wa_1806527549");
wa_write_clr(wal, GEN11_GT_SCRATCH, GEN11_WA_1806527549, "Wa_1806527549");
}
fn gen12_gt_workarounds_init(wal: &mut WorkaroundList, stepping: u8) {
@@ -314,26 +315,26 @@ fn gen12_gt_workarounds_init(wal: &mut WorkaroundList, stepping: u8) {
gen9_gt_workarounds_init(wal, stepping);
/* Wa_14017192718:gen12 */
wa_write_or(wal, 0xA18C, 1 << 8, "Wa_14017192718");
wa_write_or(wal, GEN11_GT_SCRATCH, 1 << 8, "Wa_14017192718");
/* Wa_14012688713:gen12 */
wa_write_or(wal, 0xA18C, 1 << 9, "Wa_14012688713");
wa_write_or(wal, GEN11_GT_SCRATCH, 1 << 9, "Wa_14012688713");
/* Wa_16013039831:gen12 */
wa_masked_en(wal, 0xE4F0, 1 << 11, "Wa_16013039831");
wa_masked_en(wal, GEN8_ROW_CHICKEN, GEN9_ENABLE_ROW_CHICKEN, "Wa_16013039831");
/* Wa_14013676891:gen12 */
wa_write_or(wal, 0xB11C, 1 << 8, "Wa_14013676891");
wa_write_or(wal, GEN8_SAMPLER_MODE, 1 << 8, "Wa_14013676891");
/* Wa_16012751909:gen12 */
wa_write_or(wal, 0x55B0, (1 << 9) | (1 << 12), "Wa_16012751909");
wa_write_or(wal, GEN12_COMMON_SLICE_CHICKEN2, GEN12_CSC2_SCOREBOARD_STALL_FLUSH_CONTROL, "Wa_16012751909");
/* Wa_16012322899:gen12 */
wa_write_or(wal, 0xE180, 1 << 14, "Wa_16012322899");
wa_write_or(wal, GEN7_HALF_SLICE_CHICKEN1, GEN8_HSH_CHICKEN3_DOP_GATING_DISABLE, "Wa_16012322899");
if stepping == 0 {
/* Wa_16012650089:gen12_a0 */
wa_write_or(wal, 0x7300, 1 << 8, "Wa_16012650089");
wa_write_or(wal, GEN9_SLICE_COMMON_ECO_CHICKEN1, 1 << 8, "Wa_16012650089");
}
}
@@ -350,10 +351,8 @@ pub fn build_ctx_workarounds(device_info: &IntelDeviceInfo) -> WorkaroundList {
match gen {
IntelGeneration::Gen6 => gen6_ctx_workarounds_init(&mut wal),
IntelGeneration::Gen7 => gen7_ctx_workarounds_init(&mut wal),
IntelGeneration::Gen7 => gen7_ctx_workarounds_init(&mut wal),
IntelGeneration::Gen8 => gen8_ctx_workarounds_init(&mut wal),
IntelGeneration::Gen9 => gen9_ctx_workarounds_init(&mut wal),
IntelGeneration::Gen9_5 => gen9_ctx_workarounds_init(&mut wal),
IntelGeneration::Gen9_5 => icl_ctx_workarounds_init(&mut wal),
IntelGeneration::Gen12 => gen12_ctx_workarounds_init(&mut wal),
_ => {}