0001
0002
0003
0004
0005
0006 #include "i915_drv.h"
0007 #include "intel_context.h"
0008 #include "intel_engine_pm.h"
0009 #include "intel_engine_regs.h"
0010 #include "intel_gpu_commands.h"
0011 #include "intel_gt.h"
0012 #include "intel_gt_mcr.h"
0013 #include "intel_gt_regs.h"
0014 #include "intel_ring.h"
0015 #include "intel_workarounds.h"
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058 static void wa_init_start(struct i915_wa_list *wal, const char *name, const char *engine_name)
0059 {
0060 wal->name = name;
0061 wal->engine_name = engine_name;
0062 }
0063
0064 #define WA_LIST_CHUNK (1 << 4)
0065
0066 static void wa_init_finish(struct i915_wa_list *wal)
0067 {
0068
0069 if (!IS_ALIGNED(wal->count, WA_LIST_CHUNK)) {
0070 struct i915_wa *list = kmemdup(wal->list,
0071 wal->count * sizeof(*list),
0072 GFP_KERNEL);
0073
0074 if (list) {
0075 kfree(wal->list);
0076 wal->list = list;
0077 }
0078 }
0079
0080 if (!wal->count)
0081 return;
0082
0083 DRM_DEBUG_DRIVER("Initialized %u %s workarounds on %s\n",
0084 wal->wa_count, wal->name, wal->engine_name);
0085 }
0086
0087 static void _wa_add(struct i915_wa_list *wal, const struct i915_wa *wa)
0088 {
0089 unsigned int addr = i915_mmio_reg_offset(wa->reg);
0090 unsigned int start = 0, end = wal->count;
0091 const unsigned int grow = WA_LIST_CHUNK;
0092 struct i915_wa *wa_;
0093
0094 GEM_BUG_ON(!is_power_of_2(grow));
0095
0096 if (IS_ALIGNED(wal->count, grow)) {
0097 struct i915_wa *list;
0098
0099 list = kmalloc_array(ALIGN(wal->count + 1, grow), sizeof(*wa),
0100 GFP_KERNEL);
0101 if (!list) {
0102 DRM_ERROR("No space for workaround init!\n");
0103 return;
0104 }
0105
0106 if (wal->list) {
0107 memcpy(list, wal->list, sizeof(*wa) * wal->count);
0108 kfree(wal->list);
0109 }
0110
0111 wal->list = list;
0112 }
0113
0114 while (start < end) {
0115 unsigned int mid = start + (end - start) / 2;
0116
0117 if (i915_mmio_reg_offset(wal->list[mid].reg) < addr) {
0118 start = mid + 1;
0119 } else if (i915_mmio_reg_offset(wal->list[mid].reg) > addr) {
0120 end = mid;
0121 } else {
0122 wa_ = &wal->list[mid];
0123
0124 if ((wa->clr | wa_->clr) && !(wa->clr & ~wa_->clr)) {
0125 DRM_ERROR("Discarding overwritten w/a for reg %04x (clear: %08x, set: %08x)\n",
0126 i915_mmio_reg_offset(wa_->reg),
0127 wa_->clr, wa_->set);
0128
0129 wa_->set &= ~wa->clr;
0130 }
0131
0132 wal->wa_count++;
0133 wa_->set |= wa->set;
0134 wa_->clr |= wa->clr;
0135 wa_->read |= wa->read;
0136 return;
0137 }
0138 }
0139
0140 wal->wa_count++;
0141 wa_ = &wal->list[wal->count++];
0142 *wa_ = *wa;
0143
0144 while (wa_-- > wal->list) {
0145 GEM_BUG_ON(i915_mmio_reg_offset(wa_[0].reg) ==
0146 i915_mmio_reg_offset(wa_[1].reg));
0147 if (i915_mmio_reg_offset(wa_[1].reg) >
0148 i915_mmio_reg_offset(wa_[0].reg))
0149 break;
0150
0151 swap(wa_[1], wa_[0]);
0152 }
0153 }
0154
0155 static void wa_add(struct i915_wa_list *wal, i915_reg_t reg,
0156 u32 clear, u32 set, u32 read_mask, bool masked_reg)
0157 {
0158 struct i915_wa wa = {
0159 .reg = reg,
0160 .clr = clear,
0161 .set = set,
0162 .read = read_mask,
0163 .masked_reg = masked_reg,
0164 };
0165
0166 _wa_add(wal, &wa);
0167 }
0168
0169 static void
0170 wa_write_clr_set(struct i915_wa_list *wal, i915_reg_t reg, u32 clear, u32 set)
0171 {
0172 wa_add(wal, reg, clear, set, clear, false);
0173 }
0174
0175 static void
0176 wa_write(struct i915_wa_list *wal, i915_reg_t reg, u32 set)
0177 {
0178 wa_write_clr_set(wal, reg, ~0, set);
0179 }
0180
0181 static void
0182 wa_write_or(struct i915_wa_list *wal, i915_reg_t reg, u32 set)
0183 {
0184 wa_write_clr_set(wal, reg, set, set);
0185 }
0186
0187 static void
0188 wa_write_clr(struct i915_wa_list *wal, i915_reg_t reg, u32 clr)
0189 {
0190 wa_write_clr_set(wal, reg, clr, 0);
0191 }
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204 static void
0205 wa_masked_en(struct i915_wa_list *wal, i915_reg_t reg, u32 val)
0206 {
0207 wa_add(wal, reg, 0, _MASKED_BIT_ENABLE(val), val, true);
0208 }
0209
0210 static void
0211 wa_masked_dis(struct i915_wa_list *wal, i915_reg_t reg, u32 val)
0212 {
0213 wa_add(wal, reg, 0, _MASKED_BIT_DISABLE(val), val, true);
0214 }
0215
0216 static void
0217 wa_masked_field_set(struct i915_wa_list *wal, i915_reg_t reg,
0218 u32 mask, u32 val)
0219 {
0220 wa_add(wal, reg, 0, _MASKED_FIELD(mask, val), mask, true);
0221 }
0222
0223 static void gen6_ctx_workarounds_init(struct intel_engine_cs *engine,
0224 struct i915_wa_list *wal)
0225 {
0226 wa_masked_en(wal, INSTPM, INSTPM_FORCE_ORDERING);
0227 }
0228
0229 static void gen7_ctx_workarounds_init(struct intel_engine_cs *engine,
0230 struct i915_wa_list *wal)
0231 {
0232 wa_masked_en(wal, INSTPM, INSTPM_FORCE_ORDERING);
0233 }
0234
0235 static void gen8_ctx_workarounds_init(struct intel_engine_cs *engine,
0236 struct i915_wa_list *wal)
0237 {
0238 wa_masked_en(wal, INSTPM, INSTPM_FORCE_ORDERING);
0239
0240
0241 wa_masked_en(wal, RING_MI_MODE(RENDER_RING_BASE), ASYNC_FLIP_PERF_DISABLE);
0242
0243
0244 wa_masked_en(wal, GEN8_ROW_CHICKEN,
0245 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
0246
0247
0248
0249
0250
0251
0252
0253 wa_masked_en(wal, HDC_CHICKEN0,
0254 HDC_DONOT_FETCH_MEM_WHEN_MASKED |
0255 HDC_FORCE_NON_COHERENT);
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265 wa_masked_dis(wal, CACHE_MODE_0_GEN7, HIZ_RAW_STALL_OPT_DISABLE);
0266
0267
0268 wa_masked_en(wal, CACHE_MODE_1, GEN8_4x4_STC_OPTIMIZATION_DISABLE);
0269
0270
0271
0272
0273
0274
0275
0276
0277
0278 wa_masked_field_set(wal, GEN7_GT_MODE,
0279 GEN6_WIZ_HASHING_MASK,
0280 GEN6_WIZ_HASHING_16x4);
0281 }
0282
0283 static void bdw_ctx_workarounds_init(struct intel_engine_cs *engine,
0284 struct i915_wa_list *wal)
0285 {
0286 struct drm_i915_private *i915 = engine->i915;
0287
0288 gen8_ctx_workarounds_init(engine, wal);
0289
0290
0291 wa_masked_en(wal, GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
0292
0293
0294
0295
0296
0297
0298 wa_masked_en(wal, GEN7_ROW_CHICKEN2,
0299 DOP_CLOCK_GATING_DISABLE);
0300
0301 wa_masked_en(wal, HALF_SLICE_CHICKEN3,
0302 GEN8_SAMPLER_POWER_BYPASS_DIS);
0303
0304 wa_masked_en(wal, HDC_CHICKEN0,
0305
0306 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
0307
0308 (IS_BDW_GT3(i915) ? HDC_FENCE_DEST_SLM_DISABLE : 0));
0309 }
0310
0311 static void chv_ctx_workarounds_init(struct intel_engine_cs *engine,
0312 struct i915_wa_list *wal)
0313 {
0314 gen8_ctx_workarounds_init(engine, wal);
0315
0316
0317 wa_masked_en(wal, GEN8_ROW_CHICKEN, STALL_DOP_GATING_DISABLE);
0318
0319
0320 wa_masked_en(wal, HIZ_CHICKEN, CHV_HZ_8X8_MODE_IN_1X);
0321 }
0322
0323 static void gen9_ctx_workarounds_init(struct intel_engine_cs *engine,
0324 struct i915_wa_list *wal)
0325 {
0326 struct drm_i915_private *i915 = engine->i915;
0327
0328 if (HAS_LLC(i915)) {
0329
0330
0331
0332
0333
0334 wa_masked_en(wal, COMMON_SLICE_CHICKEN2,
0335 GEN9_PBE_COMPRESSED_HASH_SELECTION);
0336 wa_masked_en(wal, GEN9_HALF_SLICE_CHICKEN7,
0337 GEN9_SAMPLER_HASH_COMPRESSED_READ_ADDR);
0338 }
0339
0340
0341
0342 wa_masked_en(wal, GEN8_ROW_CHICKEN,
0343 FLOW_CONTROL_ENABLE |
0344 PARTIAL_INSTRUCTION_SHOOTDOWN_DISABLE);
0345
0346
0347
0348 wa_masked_en(wal, GEN9_HALF_SLICE_CHICKEN7,
0349 GEN9_ENABLE_YV12_BUGFIX |
0350 GEN9_ENABLE_GPGPU_PREEMPTION);
0351
0352
0353
0354 wa_masked_en(wal, CACHE_MODE_1,
0355 GEN8_4x4_STC_OPTIMIZATION_DISABLE |
0356 GEN9_PARTIAL_RESOLVE_IN_VC_DISABLE);
0357
0358
0359 wa_masked_dis(wal, GEN9_HALF_SLICE_CHICKEN5,
0360 GEN9_CCS_TLB_PREFETCH_ENABLE);
0361
0362
0363 wa_masked_en(wal, HDC_CHICKEN0,
0364 HDC_FORCE_CONTEXT_SAVE_RESTORE_NON_COHERENT |
0365 HDC_FORCE_CSR_NON_COHERENT_OVR_DISABLE);
0366
0367
0368
0369
0370
0371
0372
0373
0374
0375
0376
0377
0378
0379
0380
0381 wa_masked_en(wal, HDC_CHICKEN0,
0382 HDC_FORCE_NON_COHERENT);
0383
0384
0385 if (IS_SKYLAKE(i915) ||
0386 IS_KABYLAKE(i915) ||
0387 IS_COFFEELAKE(i915) ||
0388 IS_COMETLAKE(i915))
0389 wa_masked_en(wal, HALF_SLICE_CHICKEN3,
0390 GEN8_SAMPLER_POWER_BYPASS_DIS);
0391
0392
0393 wa_masked_en(wal, HALF_SLICE_CHICKEN2, GEN8_ST_PO_DISABLE);
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406
0407 wa_masked_dis(wal, GEN8_CS_CHICKEN1, GEN9_PREEMPT_3D_OBJECT_LEVEL);
0408
0409
0410 wa_masked_field_set(wal, GEN8_CS_CHICKEN1,
0411 GEN9_PREEMPT_GPGPU_LEVEL_MASK,
0412 GEN9_PREEMPT_GPGPU_COMMAND_LEVEL);
0413
0414
0415 if (IS_GEN9_LP(i915))
0416 wa_masked_en(wal, GEN9_WM_CHICKEN3, GEN9_FACTOR_IN_CLR_VAL_HIZ);
0417 }
0418
0419 static void skl_tune_iz_hashing(struct intel_engine_cs *engine,
0420 struct i915_wa_list *wal)
0421 {
0422 struct intel_gt *gt = engine->gt;
0423 u8 vals[3] = { 0, 0, 0 };
0424 unsigned int i;
0425
0426 for (i = 0; i < 3; i++) {
0427 u8 ss;
0428
0429
0430
0431
0432
0433 if (!is_power_of_2(gt->info.sseu.subslice_7eu[i]))
0434 continue;
0435
0436
0437
0438
0439
0440
0441
0442 ss = ffs(gt->info.sseu.subslice_7eu[i]) - 1;
0443 vals[i] = 3 - ss;
0444 }
0445
0446 if (vals[0] == 0 && vals[1] == 0 && vals[2] == 0)
0447 return;
0448
0449
0450 wa_masked_field_set(wal, GEN7_GT_MODE,
0451 GEN9_IZ_HASHING_MASK(2) |
0452 GEN9_IZ_HASHING_MASK(1) |
0453 GEN9_IZ_HASHING_MASK(0),
0454 GEN9_IZ_HASHING(2, vals[2]) |
0455 GEN9_IZ_HASHING(1, vals[1]) |
0456 GEN9_IZ_HASHING(0, vals[0]));
0457 }
0458
0459 static void skl_ctx_workarounds_init(struct intel_engine_cs *engine,
0460 struct i915_wa_list *wal)
0461 {
0462 gen9_ctx_workarounds_init(engine, wal);
0463 skl_tune_iz_hashing(engine, wal);
0464 }
0465
0466 static void bxt_ctx_workarounds_init(struct intel_engine_cs *engine,
0467 struct i915_wa_list *wal)
0468 {
0469 gen9_ctx_workarounds_init(engine, wal);
0470
0471
0472 wa_masked_en(wal, GEN8_ROW_CHICKEN,
0473 STALL_DOP_GATING_DISABLE);
0474
0475
0476 wa_masked_en(wal, COMMON_SLICE_CHICKEN2,
0477 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
0478 }
0479
0480 static void kbl_ctx_workarounds_init(struct intel_engine_cs *engine,
0481 struct i915_wa_list *wal)
0482 {
0483 struct drm_i915_private *i915 = engine->i915;
0484
0485 gen9_ctx_workarounds_init(engine, wal);
0486
0487
0488 if (IS_KBL_GRAPHICS_STEP(i915, STEP_C0, STEP_FOREVER))
0489 wa_masked_en(wal, COMMON_SLICE_CHICKEN2,
0490 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
0491
0492
0493 wa_masked_en(wal, GEN7_HALF_SLICE_CHICKEN1,
0494 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
0495 }
0496
0497 static void glk_ctx_workarounds_init(struct intel_engine_cs *engine,
0498 struct i915_wa_list *wal)
0499 {
0500 gen9_ctx_workarounds_init(engine, wal);
0501
0502
0503 wa_masked_en(wal, COMMON_SLICE_CHICKEN2,
0504 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
0505 }
0506
0507 static void cfl_ctx_workarounds_init(struct intel_engine_cs *engine,
0508 struct i915_wa_list *wal)
0509 {
0510 gen9_ctx_workarounds_init(engine, wal);
0511
0512
0513 wa_masked_en(wal, COMMON_SLICE_CHICKEN2,
0514 GEN8_SBE_DISABLE_REPLAY_BUF_OPTIMIZATION);
0515
0516
0517 wa_masked_en(wal, GEN7_HALF_SLICE_CHICKEN1,
0518 GEN7_SBE_SS_CACHE_DISPATCH_PORT_SHARING_DISABLE);
0519 }
0520
0521 static void icl_ctx_workarounds_init(struct intel_engine_cs *engine,
0522 struct i915_wa_list *wal)
0523 {
0524
0525 wa_write(wal,
0526 GEN8_L3CNTLREG,
0527 intel_uncore_read(engine->uncore, GEN8_L3CNTLREG) |
0528 GEN8_ERRDETBCTRL);
0529
0530
0531
0532
0533
0534
0535
0536
0537 wa_masked_en(wal, ICL_HDC_MODE, HDC_FORCE_NON_COHERENT);
0538
0539
0540 wa_add(wal, GEN10_CACHE_MODE_SS, 0,
0541 _MASKED_BIT_ENABLE(FLOAT_BLEND_OPTIMIZATION_ENABLE),
0542 0 ,
0543 true);
0544
0545
0546 wa_masked_field_set(wal, GEN8_CS_CHICKEN1,
0547 GEN9_PREEMPT_GPGPU_LEVEL_MASK,
0548 GEN9_PREEMPT_GPGPU_THREAD_GROUP_LEVEL);
0549
0550
0551 wa_masked_en(wal, GEN10_SAMPLER_MODE,
0552 GEN11_SAMPLER_ENABLE_HEADLESS_MSG);
0553
0554
0555 wa_write(wal, IVB_FBC_RT_BASE, 0xFFFFFFFF & ~ILK_FBC_RT_VALID);
0556 wa_write_clr_set(wal, IVB_FBC_RT_BASE_UPPER,
0557 0,
0558 0xFFFFFFFF);
0559
0560
0561 wa_masked_en(wal, GEN9_ROW_CHICKEN4, GEN11_DIS_PICK_2ND_EU);
0562 }
0563
0564
0565
0566
0567
0568 static void dg2_ctx_gt_tuning_init(struct intel_engine_cs *engine,
0569 struct i915_wa_list *wal)
0570 {
0571 wa_write_clr_set(wal, GEN11_L3SQCREG5, L3_PWM_TIMER_INIT_VAL_MASK,
0572 REG_FIELD_PREP(L3_PWM_TIMER_INIT_VAL_MASK, 0x7f));
0573 wa_add(wal,
0574 FF_MODE2,
0575 FF_MODE2_TDS_TIMER_MASK,
0576 FF_MODE2_TDS_TIMER_128,
0577 0, false);
0578 }
0579
0580
0581
0582
0583
0584 static void gen12_ctx_gt_tuning_init(struct intel_engine_cs *engine,
0585 struct i915_wa_list *wal)
0586 {
0587
0588
0589
0590
0591
0592
0593
0594
0595
0596
0597
0598
0599
0600 wa_add(wal,
0601 FF_MODE2,
0602 FF_MODE2_TDS_TIMER_MASK,
0603 FF_MODE2_TDS_TIMER_128,
0604 0, false);
0605 }
0606
0607 static void gen12_ctx_workarounds_init(struct intel_engine_cs *engine,
0608 struct i915_wa_list *wal)
0609 {
0610 gen12_ctx_gt_tuning_init(engine, wal);
0611
0612
0613
0614
0615
0616
0617
0618
0619
0620
0621
0622
0623
0624 wa_masked_en(wal, GEN11_COMMON_SLICE_CHICKEN3,
0625 GEN12_DISABLE_CPS_AWARE_COLOR_PIPE);
0626
0627
0628 wa_masked_field_set(wal, GEN8_CS_CHICKEN1,
0629 GEN9_PREEMPT_GPGPU_LEVEL_MASK,
0630 GEN9_PREEMPT_GPGPU_THREAD_GROUP_LEVEL);
0631
0632
0633
0634
0635
0636
0637
0638 wa_add(wal,
0639 FF_MODE2,
0640 FF_MODE2_GS_TIMER_MASK,
0641 FF_MODE2_GS_TIMER_224,
0642 0, false);
0643 }
0644
0645 static void dg1_ctx_workarounds_init(struct intel_engine_cs *engine,
0646 struct i915_wa_list *wal)
0647 {
0648 gen12_ctx_workarounds_init(engine, wal);
0649
0650
0651 wa_masked_dis(wal, GEN11_COMMON_SLICE_CHICKEN3,
0652 DG1_FLOAT_POINT_BLEND_OPT_STRICT_MODE_EN);
0653
0654
0655 wa_masked_en(wal, HIZ_CHICKEN,
0656 DG1_HZ_READ_SUPPRESSION_OPTIMIZATION_DISABLE);
0657 }
0658
0659 static void dg2_ctx_workarounds_init(struct intel_engine_cs *engine,
0660 struct i915_wa_list *wal)
0661 {
0662 dg2_ctx_gt_tuning_init(engine, wal);
0663
0664
0665 if (IS_DG2_GRAPHICS_STEP(engine->i915, G11, STEP_A0, STEP_B0)) {
0666 wa_masked_dis(wal, VFLSKPD, DIS_MULT_MISS_RD_SQUASH);
0667 wa_masked_en(wal, VFLSKPD, DIS_OVER_FETCH_CACHE);
0668 }
0669
0670 if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_B0)) {
0671
0672 wa_masked_en(wal, GEN11_COMMON_SLICE_CHICKEN3,
0673 XEHP_DUAL_SIMD8_SEQ_MERGE_DISABLE);
0674
0675
0676
0677
0678
0679
0680 wa_masked_en(wal, GEN11_COMMON_SLICE_CHICKEN3,
0681 GEN12_DISABLE_CPS_AWARE_COLOR_PIPE);
0682 }
0683
0684
0685 wa_masked_en(wal, SLICE_COMMON_ECO_CHICKEN1,
0686 MSC_MSAA_REODER_BUF_BYPASS_DISABLE);
0687
0688
0689 if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_B0, STEP_FOREVER) ||
0690 IS_DG2_G11(engine->i915) || IS_DG2_G12(engine->i915))
0691 wa_masked_field_set(wal, VF_PREEMPTION, PREEMPTION_VERTEX_COUNT, 0x4000);
0692
0693
0694 wa_masked_en(wal, CHICKEN_RASTER_1, DIS_SF_ROUND_NEAREST_EVEN);
0695 }
0696
0697 static void fakewa_disable_nestedbb_mode(struct intel_engine_cs *engine,
0698 struct i915_wa_list *wal)
0699 {
0700
0701
0702
0703
0704
0705
0706
0707
0708
0709
0710
0711
0712
0713
0714
0715
0716
0717
0718
0719
0720
0721
0722
0723
0724
0725 wa_masked_dis(wal, RING_MI_MODE(engine->mmio_base), TGL_NESTED_BB_EN);
0726 }
0727
0728 static void gen12_ctx_gt_mocs_init(struct intel_engine_cs *engine,
0729 struct i915_wa_list *wal)
0730 {
0731 u8 mocs;
0732
0733
0734
0735
0736
0737
0738 if (engine->class == COPY_ENGINE_CLASS) {
0739 mocs = engine->gt->mocs.uc_index;
0740 wa_write_clr_set(wal,
0741 BLIT_CCTL(engine->mmio_base),
0742 BLIT_CCTL_MASK,
0743 BLIT_CCTL_MOCS(mocs, mocs));
0744 }
0745 }
0746
0747
0748
0749
0750
0751
0752
0753 static void
0754 gen12_ctx_gt_fake_wa_init(struct intel_engine_cs *engine,
0755 struct i915_wa_list *wal)
0756 {
0757 if (GRAPHICS_VER_FULL(engine->i915) >= IP_VER(12, 55))
0758 fakewa_disable_nestedbb_mode(engine, wal);
0759
0760 gen12_ctx_gt_mocs_init(engine, wal);
0761 }
0762
0763 static void
0764 __intel_engine_init_ctx_wa(struct intel_engine_cs *engine,
0765 struct i915_wa_list *wal,
0766 const char *name)
0767 {
0768 struct drm_i915_private *i915 = engine->i915;
0769
0770 wa_init_start(wal, name, engine->name);
0771
0772
0773
0774
0775
0776
0777 if (GRAPHICS_VER(i915) >= 12)
0778 gen12_ctx_gt_fake_wa_init(engine, wal);
0779
0780 if (engine->class != RENDER_CLASS)
0781 goto done;
0782
0783 if (IS_PONTEVECCHIO(i915))
0784 ;
0785 else if (IS_DG2(i915))
0786 dg2_ctx_workarounds_init(engine, wal);
0787 else if (IS_XEHPSDV(i915))
0788 ;
0789 else if (IS_DG1(i915))
0790 dg1_ctx_workarounds_init(engine, wal);
0791 else if (GRAPHICS_VER(i915) == 12)
0792 gen12_ctx_workarounds_init(engine, wal);
0793 else if (GRAPHICS_VER(i915) == 11)
0794 icl_ctx_workarounds_init(engine, wal);
0795 else if (IS_COFFEELAKE(i915) || IS_COMETLAKE(i915))
0796 cfl_ctx_workarounds_init(engine, wal);
0797 else if (IS_GEMINILAKE(i915))
0798 glk_ctx_workarounds_init(engine, wal);
0799 else if (IS_KABYLAKE(i915))
0800 kbl_ctx_workarounds_init(engine, wal);
0801 else if (IS_BROXTON(i915))
0802 bxt_ctx_workarounds_init(engine, wal);
0803 else if (IS_SKYLAKE(i915))
0804 skl_ctx_workarounds_init(engine, wal);
0805 else if (IS_CHERRYVIEW(i915))
0806 chv_ctx_workarounds_init(engine, wal);
0807 else if (IS_BROADWELL(i915))
0808 bdw_ctx_workarounds_init(engine, wal);
0809 else if (GRAPHICS_VER(i915) == 7)
0810 gen7_ctx_workarounds_init(engine, wal);
0811 else if (GRAPHICS_VER(i915) == 6)
0812 gen6_ctx_workarounds_init(engine, wal);
0813 else if (GRAPHICS_VER(i915) < 8)
0814 ;
0815 else
0816 MISSING_CASE(GRAPHICS_VER(i915));
0817
0818 done:
0819 wa_init_finish(wal);
0820 }
0821
0822 void intel_engine_init_ctx_wa(struct intel_engine_cs *engine)
0823 {
0824 __intel_engine_init_ctx_wa(engine, &engine->ctx_wa_list, "context");
0825 }
0826
0827 int intel_engine_emit_ctx_wa(struct i915_request *rq)
0828 {
0829 struct i915_wa_list *wal = &rq->engine->ctx_wa_list;
0830 struct i915_wa *wa;
0831 unsigned int i;
0832 u32 *cs;
0833 int ret;
0834
0835 if (wal->count == 0)
0836 return 0;
0837
0838 ret = rq->engine->emit_flush(rq, EMIT_BARRIER);
0839 if (ret)
0840 return ret;
0841
0842 cs = intel_ring_begin(rq, (wal->count * 2 + 2));
0843 if (IS_ERR(cs))
0844 return PTR_ERR(cs);
0845
0846 *cs++ = MI_LOAD_REGISTER_IMM(wal->count);
0847 for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {
0848 *cs++ = i915_mmio_reg_offset(wa->reg);
0849 *cs++ = wa->set;
0850 }
0851 *cs++ = MI_NOOP;
0852
0853 intel_ring_advance(rq, cs);
0854
0855 ret = rq->engine->emit_flush(rq, EMIT_BARRIER);
0856 if (ret)
0857 return ret;
0858
0859 return 0;
0860 }
0861
0862 static void
0863 gen4_gt_workarounds_init(struct intel_gt *gt,
0864 struct i915_wa_list *wal)
0865 {
0866
0867 wa_masked_dis(wal, CACHE_MODE_0, RC_OP_FLUSH_ENABLE);
0868 }
0869
0870 static void
0871 g4x_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
0872 {
0873 gen4_gt_workarounds_init(gt, wal);
0874
0875
0876 wa_masked_en(wal, CACHE_MODE_0, CM0_PIPELINED_RENDER_FLUSH_DISABLE);
0877 }
0878
0879 static void
0880 ilk_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
0881 {
0882 g4x_gt_workarounds_init(gt, wal);
0883
0884 wa_masked_en(wal, _3D_CHICKEN2, _3D_CHICKEN2_WM_READ_PIPELINED);
0885 }
0886
0887 static void
0888 snb_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
0889 {
0890 }
0891
0892 static void
0893 ivb_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
0894 {
0895
0896 wa_masked_dis(wal,
0897 GEN7_COMMON_SLICE_CHICKEN1,
0898 GEN7_CSC1_RHWO_OPT_DISABLE_IN_RCC);
0899
0900
0901 wa_write(wal, GEN7_L3CNTLREG1, GEN7_WA_FOR_GEN7_L3_CONTROL);
0902 wa_write(wal, GEN7_L3_CHICKEN_MODE_REGISTER, GEN7_WA_L3_CHICKEN_MODE);
0903
0904
0905 wa_write_clr(wal, GEN7_L3SQCREG4, L3SQ_URB_READ_CAM_MATCH_DISABLE);
0906 }
0907
0908 static void
0909 vlv_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
0910 {
0911
0912 wa_write_clr(wal, GEN7_L3SQCREG4, L3SQ_URB_READ_CAM_MATCH_DISABLE);
0913
0914
0915
0916
0917
0918 wa_write(wal, GEN7_L3SQCREG1, VLV_B0_WA_L3SQCREG1_VALUE);
0919 }
0920
0921 static void
0922 hsw_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
0923 {
0924
0925 wa_write(wal, HSW_SCRATCH1, HSW_SCRATCH1_L3_DATA_ATOMICS_DISABLE);
0926
0927 wa_add(wal,
0928 HSW_ROW_CHICKEN3, 0,
0929 _MASKED_BIT_ENABLE(HSW_ROW_CHICKEN3_L3_GLOBAL_ATOMICS_DISABLE),
0930 0 , true);
0931
0932
0933 wa_write_clr(wal, GEN7_FF_THREAD_MODE, GEN7_FF_VS_REF_CNT_FFME);
0934 }
0935
0936 static void
0937 gen9_wa_init_mcr(struct drm_i915_private *i915, struct i915_wa_list *wal)
0938 {
0939 const struct sseu_dev_info *sseu = &to_gt(i915)->info.sseu;
0940 unsigned int slice, subslice;
0941 u32 mcr, mcr_mask;
0942
0943 GEM_BUG_ON(GRAPHICS_VER(i915) != 9);
0944
0945
0946
0947
0948
0949
0950
0951
0952
0953
0954
0955
0956 slice = ffs(sseu->slice_mask) - 1;
0957 GEM_BUG_ON(slice >= ARRAY_SIZE(sseu->subslice_mask.hsw));
0958 subslice = ffs(intel_sseu_get_hsw_subslices(sseu, slice));
0959 GEM_BUG_ON(!subslice);
0960 subslice--;
0961
0962
0963
0964
0965
0966 mcr = GEN8_MCR_SLICE(slice) | GEN8_MCR_SUBSLICE(subslice);
0967 mcr_mask = GEN8_MCR_SLICE_MASK | GEN8_MCR_SUBSLICE_MASK;
0968
0969 drm_dbg(&i915->drm, "MCR slice:%d/subslice:%d = %x\n", slice, subslice, mcr);
0970
0971 wa_write_clr_set(wal, GEN8_MCR_SELECTOR, mcr_mask, mcr);
0972 }
0973
0974 static void
0975 gen9_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
0976 {
0977 struct drm_i915_private *i915 = gt->i915;
0978
0979
0980 gen9_wa_init_mcr(i915, wal);
0981
0982
0983 if (!IS_COFFEELAKE(i915) && !IS_COMETLAKE(i915))
0984 wa_write_or(wal,
0985 GAM_ECOCHK,
0986 ECOCHK_DIS_TLB);
0987
0988 if (HAS_LLC(i915)) {
0989
0990
0991
0992
0993
0994 wa_write_or(wal,
0995 MMCD_MISC_CTRL,
0996 MMCD_PCLA | MMCD_HOTSPOT_EN);
0997 }
0998
0999
1000 wa_write_or(wal,
1001 GAM_ECOCHK,
1002 BDW_DISABLE_HDC_INVALIDATION);
1003 }
1004
1005 static void
1006 skl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
1007 {
1008 gen9_gt_workarounds_init(gt, wal);
1009
1010
1011 wa_write_or(wal,
1012 GEN7_UCGCTL4,
1013 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
1014
1015
1016 if (IS_SKL_GRAPHICS_STEP(gt->i915, STEP_A0, STEP_H0))
1017 wa_write_or(wal,
1018 GEN9_GAMT_ECO_REG_RW_IA,
1019 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
1020 }
1021
1022 static void
1023 kbl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
1024 {
1025 gen9_gt_workarounds_init(gt, wal);
1026
1027
1028 if (IS_KBL_GRAPHICS_STEP(gt->i915, 0, STEP_C0))
1029 wa_write_or(wal,
1030 GAMT_CHKN_BIT_REG,
1031 GAMT_CHKN_DISABLE_DYNAMIC_CREDIT_SHARING);
1032
1033
1034 wa_write_or(wal,
1035 GEN7_UCGCTL4,
1036 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
1037
1038
1039 wa_write_or(wal,
1040 GEN9_GAMT_ECO_REG_RW_IA,
1041 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
1042 }
1043
1044 static void
1045 glk_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
1046 {
1047 gen9_gt_workarounds_init(gt, wal);
1048 }
1049
1050 static void
1051 cfl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
1052 {
1053 gen9_gt_workarounds_init(gt, wal);
1054
1055
1056 wa_write_or(wal,
1057 GEN7_UCGCTL4,
1058 GEN8_EU_GAUNIT_CLOCK_GATE_DISABLE);
1059
1060
1061 wa_write_or(wal,
1062 GEN9_GAMT_ECO_REG_RW_IA,
1063 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS);
1064 }
1065
1066 static void __set_mcr_steering(struct i915_wa_list *wal,
1067 i915_reg_t steering_reg,
1068 unsigned int slice, unsigned int subslice)
1069 {
1070 u32 mcr, mcr_mask;
1071
1072 mcr = GEN11_MCR_SLICE(slice) | GEN11_MCR_SUBSLICE(subslice);
1073 mcr_mask = GEN11_MCR_SLICE_MASK | GEN11_MCR_SUBSLICE_MASK;
1074
1075 wa_write_clr_set(wal, steering_reg, mcr_mask, mcr);
1076 }
1077
1078 static void __add_mcr_wa(struct intel_gt *gt, struct i915_wa_list *wal,
1079 unsigned int slice, unsigned int subslice)
1080 {
1081 struct drm_printer p = drm_debug_printer("MCR Steering:");
1082
1083 __set_mcr_steering(wal, GEN8_MCR_SELECTOR, slice, subslice);
1084
1085 gt->default_steering.groupid = slice;
1086 gt->default_steering.instanceid = subslice;
1087
1088 if (drm_debug_enabled(DRM_UT_DRIVER))
1089 intel_gt_mcr_report_steering(&p, gt, false);
1090 }
1091
1092 static void
1093 icl_wa_init_mcr(struct intel_gt *gt, struct i915_wa_list *wal)
1094 {
1095 const struct sseu_dev_info *sseu = >->info.sseu;
1096 unsigned int subslice;
1097
1098 GEM_BUG_ON(GRAPHICS_VER(gt->i915) < 11);
1099 GEM_BUG_ON(hweight8(sseu->slice_mask) > 1);
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110 subslice = __ffs(intel_sseu_get_hsw_subslices(sseu, 0));
1111
1112
1113
1114
1115
1116
1117 if (gt->info.l3bank_mask & BIT(subslice))
1118 gt->steering_table[L3BANK] = NULL;
1119
1120 __add_mcr_wa(gt, wal, 0, subslice);
1121 }
1122
1123 static void
1124 xehp_init_mcr(struct intel_gt *gt, struct i915_wa_list *wal)
1125 {
1126 const struct sseu_dev_info *sseu = >->info.sseu;
1127 unsigned long slice, subslice = 0, slice_mask = 0;
1128 u32 lncf_mask = 0;
1129 int i;
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158 slice_mask = intel_slicemask_from_xehp_dssmask(sseu->subslice_mask,
1159 GEN_DSS_PER_GSLICE);
1160
1161
1162
1163
1164
1165 for_each_set_bit(i, >->info.mslice_mask, GEN12_MAX_MSLICES)
1166 lncf_mask |= (0x3 << (i * 2));
1167
1168
1169
1170
1171
1172 if (slice_mask & lncf_mask) {
1173 slice_mask &= lncf_mask;
1174 gt->steering_table[LNCF] = NULL;
1175 }
1176
1177
1178 if (slice_mask & gt->info.mslice_mask) {
1179 slice_mask &= gt->info.mslice_mask;
1180 gt->steering_table[MSLICE] = NULL;
1181 }
1182
1183 slice = __ffs(slice_mask);
1184 subslice = intel_sseu_find_first_xehp_dss(sseu, GEN_DSS_PER_GSLICE, slice) %
1185 GEN_DSS_PER_GSLICE;
1186
1187 __add_mcr_wa(gt, wal, slice, subslice);
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198 __set_mcr_steering(wal, MCFG_MCR_SELECTOR, 0, 2);
1199 __set_mcr_steering(wal, SF_MCR_SELECTOR, 0, 2);
1200 }
1201
1202 static void
1203 pvc_init_mcr(struct intel_gt *gt, struct i915_wa_list *wal)
1204 {
1205 unsigned int dss;
1206
1207
1208
1209
1210
1211
1212 dss = intel_sseu_find_first_xehp_dss(>->info.sseu, 0, 0);
1213 __add_mcr_wa(gt, wal, dss / GEN_DSS_PER_CSLICE, dss % GEN_DSS_PER_CSLICE);
1214 }
1215
1216 static void
1217 icl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
1218 {
1219 struct drm_i915_private *i915 = gt->i915;
1220
1221 icl_wa_init_mcr(gt, wal);
1222
1223
1224 wa_write_clr_set(wal,
1225 GEN11_GACB_PERF_CTRL,
1226 GEN11_HASH_CTRL_MASK,
1227 GEN11_HASH_CTRL_BIT0 | GEN11_HASH_CTRL_BIT4);
1228
1229
1230
1231
1232 wa_write_or(wal,
1233 GEN11_LSN_UNSLCVC,
1234 GEN11_LSN_UNSLCVC_GAFS_HALF_SF_MAXALLOC |
1235 GEN11_LSN_UNSLCVC_GAFS_HALF_CL2_MAXALLOC);
1236
1237
1238
1239
1240 wa_write_or(wal,
1241 GEN8_GAMW_ECO_DEV_RW_IA,
1242 GAMW_ECO_DEV_CTX_RELOAD_DISABLE);
1243
1244
1245
1246
1247 wa_write_or(wal,
1248 GAMT_CHKN_BIT_REG,
1249 GAMT_CHKN_DISABLE_L3_COH_PIPE);
1250
1251
1252 wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2,
1253 PSDUNIT_CLKGATE_DIS);
1254
1255
1256 wa_write_or(wal,
1257 SUBSLICE_UNIT_LEVEL_CLKGATE,
1258 GWUNIT_CLKGATE_DIS);
1259
1260
1261 if (IS_ICELAKE(i915) ||
1262 IS_JSL_EHL_GRAPHICS_STEP(i915, STEP_A0, STEP_B0))
1263 wa_write_or(wal,
1264 SLICE_UNIT_LEVEL_CLKGATE,
1265 L3_CLKGATE_DIS | L3_CR2X_CLKGATE_DIS);
1266
1267
1268
1269
1270
1271 wa_write_clr(wal, GEN10_DFR_RATIO_EN_AND_CHICKEN, DFR_DISABLE);
1272 }
1273
1274
1275
1276
1277
1278
1279
1280 static void
1281 wa_14011060649(struct intel_gt *gt, struct i915_wa_list *wal)
1282 {
1283 struct intel_engine_cs *engine;
1284 int id;
1285
1286 for_each_engine(engine, gt, id) {
1287 if (engine->class != VIDEO_DECODE_CLASS ||
1288 (engine->instance % 2))
1289 continue;
1290
1291 wa_write_or(wal, VDBOX_CGCTL3F10(engine->mmio_base),
1292 IECPUNIT_CLKGATE_DIS);
1293 }
1294 }
1295
1296 static void
1297 gen12_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
1298 {
1299 icl_wa_init_mcr(gt, wal);
1300
1301
1302 wa_14011060649(gt, wal);
1303
1304
1305 wa_write_or(wal, GEN10_DFR_RATIO_EN_AND_CHICKEN, DFR_DISABLE);
1306 }
1307
1308 static void
1309 tgl_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
1310 {
1311 struct drm_i915_private *i915 = gt->i915;
1312
1313 gen12_gt_workarounds_init(gt, wal);
1314
1315
1316 if (IS_TGL_UY_GRAPHICS_STEP(i915, STEP_A0, STEP_B0))
1317 wa_write_or(wal,
1318 SUBSLICE_UNIT_LEVEL_CLKGATE2,
1319 CPSSUNIT_CLKGATE_DIS);
1320
1321
1322 if (IS_TGL_UY_GRAPHICS_STEP(i915, STEP_A0, STEP_B0))
1323 wa_write_or(wal,
1324 SLICE_UNIT_LEVEL_CLKGATE,
1325 L3_CLKGATE_DIS | L3_CR2X_CLKGATE_DIS);
1326
1327
1328 if (IS_TGL_UY_GRAPHICS_STEP(i915, STEP_A0, STEP_B0))
1329 wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2,
1330 VSUNIT_CLKGATE_DIS_TGL);
1331 }
1332
1333 static void
1334 dg1_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
1335 {
1336 struct drm_i915_private *i915 = gt->i915;
1337
1338 gen12_gt_workarounds_init(gt, wal);
1339
1340
1341 if (IS_DG1_GRAPHICS_STEP(i915, STEP_A0, STEP_B0))
1342 wa_write_or(wal,
1343 SLICE_UNIT_LEVEL_CLKGATE,
1344 L3_CLKGATE_DIS | L3_CR2X_CLKGATE_DIS);
1345
1346
1347 if (IS_DG1(i915))
1348 wa_write_or(wal,
1349 SUBSLICE_UNIT_LEVEL_CLKGATE2,
1350 CPSSUNIT_CLKGATE_DIS);
1351
1352
1353
1354 if (IS_DG1(i915))
1355 wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE2,
1356 VSUNIT_CLKGATE_DIS_TGL);
1357 }
1358
1359 static void
1360 xehpsdv_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
1361 {
1362 struct drm_i915_private *i915 = gt->i915;
1363
1364 xehp_init_mcr(gt, wal);
1365
1366
1367 wa_write_or(wal, SCCGCTL94DC, CG3DDISURB);
1368
1369
1370 if (IS_XEHPSDV_GRAPHICS_STEP(i915, STEP_A0, STEP_B0))
1371 wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE,
1372 TSGUNIT_CLKGATE_DIS);
1373
1374
1375 if (IS_XEHPSDV_GRAPHICS_STEP(i915, STEP_B0, STEP_FOREVER)) {
1376 wa_write_or(wal, UNSLCGCTL9440, GAMTLBOACS_CLKGATE_DIS |
1377 GAMTLBVDBOX7_CLKGATE_DIS |
1378 GAMTLBVDBOX6_CLKGATE_DIS |
1379 GAMTLBVDBOX5_CLKGATE_DIS |
1380 GAMTLBVDBOX4_CLKGATE_DIS |
1381 GAMTLBVDBOX3_CLKGATE_DIS |
1382 GAMTLBVDBOX2_CLKGATE_DIS |
1383 GAMTLBVDBOX1_CLKGATE_DIS |
1384 GAMTLBVDBOX0_CLKGATE_DIS |
1385 GAMTLBKCR_CLKGATE_DIS |
1386 GAMTLBGUC_CLKGATE_DIS |
1387 GAMTLBBLT_CLKGATE_DIS);
1388 wa_write_or(wal, UNSLCGCTL9444, GAMTLBGFXA0_CLKGATE_DIS |
1389 GAMTLBGFXA1_CLKGATE_DIS |
1390 GAMTLBCOMPA0_CLKGATE_DIS |
1391 GAMTLBCOMPA1_CLKGATE_DIS |
1392 GAMTLBCOMPB0_CLKGATE_DIS |
1393 GAMTLBCOMPB1_CLKGATE_DIS |
1394 GAMTLBCOMPC0_CLKGATE_DIS |
1395 GAMTLBCOMPC1_CLKGATE_DIS |
1396 GAMTLBCOMPD0_CLKGATE_DIS |
1397 GAMTLBCOMPD1_CLKGATE_DIS |
1398 GAMTLBMERT_CLKGATE_DIS |
1399 GAMTLBVEBOX3_CLKGATE_DIS |
1400 GAMTLBVEBOX2_CLKGATE_DIS |
1401 GAMTLBVEBOX1_CLKGATE_DIS |
1402 GAMTLBVEBOX0_CLKGATE_DIS);
1403 }
1404
1405
1406 if (IS_XEHPSDV_GRAPHICS_STEP(i915, STEP_A1, STEP_FOREVER))
1407 wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE, VFUNIT_CLKGATE_DIS);
1408
1409
1410 wa_14011060649(gt, wal);
1411 }
1412
1413 static void
1414 dg2_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
1415 {
1416 struct intel_engine_cs *engine;
1417 int id;
1418
1419 xehp_init_mcr(gt, wal);
1420
1421
1422 wa_14011060649(gt, wal);
1423
1424
1425
1426
1427
1428
1429
1430
1431 for_each_engine(engine, gt, id) {
1432 if (engine->class != VIDEO_DECODE_CLASS)
1433 continue;
1434
1435
1436 if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_B0))
1437 wa_write_or(wal, VDBOX_CGCTL3F18(engine->mmio_base),
1438 ALNUNIT_CLKGATE_DIS);
1439 }
1440
1441 if (IS_DG2_G10(gt->i915)) {
1442
1443 wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE,
1444 CG3DDISCFEG_CLKGATE_DIS);
1445
1446
1447 wa_write_or(wal, SUBSLICE_UNIT_LEVEL_CLKGATE,
1448 DSS_ROUTER_CLKGATE_DIS);
1449 }
1450
1451 if (IS_DG2_GRAPHICS_STEP(gt->i915, G10, STEP_A0, STEP_B0)) {
1452
1453 wa_write_or(wal, UNSLCGCTL9430, MSQDUNIT_CLKGATE_DIS);
1454
1455
1456 wa_write_or(wal, UNSLCGCTL9444, LTCDD_CLKGATE_DIS);
1457
1458
1459 wa_write_or(wal, SLICE_UNIT_LEVEL_CLKGATE, NODEDSS_CLKGATE_DIS);
1460
1461
1462 wa_write_or(wal, UNSLCGCTL9440, GAMTLBOACS_CLKGATE_DIS |
1463 GAMTLBVDBOX7_CLKGATE_DIS |
1464 GAMTLBVDBOX6_CLKGATE_DIS |
1465 GAMTLBVDBOX5_CLKGATE_DIS |
1466 GAMTLBVDBOX4_CLKGATE_DIS |
1467 GAMTLBVDBOX3_CLKGATE_DIS |
1468 GAMTLBVDBOX2_CLKGATE_DIS |
1469 GAMTLBVDBOX1_CLKGATE_DIS |
1470 GAMTLBVDBOX0_CLKGATE_DIS |
1471 GAMTLBKCR_CLKGATE_DIS |
1472 GAMTLBGUC_CLKGATE_DIS |
1473 GAMTLBBLT_CLKGATE_DIS);
1474 wa_write_or(wal, UNSLCGCTL9444, GAMTLBGFXA0_CLKGATE_DIS |
1475 GAMTLBGFXA1_CLKGATE_DIS |
1476 GAMTLBCOMPA0_CLKGATE_DIS |
1477 GAMTLBCOMPA1_CLKGATE_DIS |
1478 GAMTLBCOMPB0_CLKGATE_DIS |
1479 GAMTLBCOMPB1_CLKGATE_DIS |
1480 GAMTLBCOMPC0_CLKGATE_DIS |
1481 GAMTLBCOMPC1_CLKGATE_DIS |
1482 GAMTLBCOMPD0_CLKGATE_DIS |
1483 GAMTLBCOMPD1_CLKGATE_DIS |
1484 GAMTLBMERT_CLKGATE_DIS |
1485 GAMTLBVEBOX3_CLKGATE_DIS |
1486 GAMTLBVEBOX2_CLKGATE_DIS |
1487 GAMTLBVEBOX1_CLKGATE_DIS |
1488 GAMTLBVEBOX0_CLKGATE_DIS);
1489
1490
1491 wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE,
1492 GAMEDIA_CLKGATE_DIS);
1493
1494
1495 wa_write_or(wal, SSMCGCTL9530, RTFUNIT_CLKGATE_DIS);
1496 }
1497
1498
1499 wa_write_clr(wal, SARB_CHICKEN1, COMP_CKN_IN);
1500
1501
1502
1503
1504
1505
1506 wa_write_or(wal, GEN12_SQCM, EN_32B_ACCESS);
1507
1508
1509 wa_write_clr(wal, GEN7_MISCCPCTL, GEN12_DOP_CLOCK_GATE_RENDER_ENABLE);
1510 }
1511
1512 static void
1513 pvc_gt_workarounds_init(struct intel_gt *gt, struct i915_wa_list *wal)
1514 {
1515 pvc_init_mcr(gt, wal);
1516
1517
1518 wa_write_clr(wal, GEN7_MISCCPCTL, GEN12_DOP_CLOCK_GATE_RENDER_ENABLE);
1519 }
1520
1521 static void
1522 gt_init_workarounds(struct intel_gt *gt, struct i915_wa_list *wal)
1523 {
1524 struct drm_i915_private *i915 = gt->i915;
1525
1526 if (IS_PONTEVECCHIO(i915))
1527 pvc_gt_workarounds_init(gt, wal);
1528 else if (IS_DG2(i915))
1529 dg2_gt_workarounds_init(gt, wal);
1530 else if (IS_XEHPSDV(i915))
1531 xehpsdv_gt_workarounds_init(gt, wal);
1532 else if (IS_DG1(i915))
1533 dg1_gt_workarounds_init(gt, wal);
1534 else if (IS_TIGERLAKE(i915))
1535 tgl_gt_workarounds_init(gt, wal);
1536 else if (GRAPHICS_VER(i915) == 12)
1537 gen12_gt_workarounds_init(gt, wal);
1538 else if (GRAPHICS_VER(i915) == 11)
1539 icl_gt_workarounds_init(gt, wal);
1540 else if (IS_COFFEELAKE(i915) || IS_COMETLAKE(i915))
1541 cfl_gt_workarounds_init(gt, wal);
1542 else if (IS_GEMINILAKE(i915))
1543 glk_gt_workarounds_init(gt, wal);
1544 else if (IS_KABYLAKE(i915))
1545 kbl_gt_workarounds_init(gt, wal);
1546 else if (IS_BROXTON(i915))
1547 gen9_gt_workarounds_init(gt, wal);
1548 else if (IS_SKYLAKE(i915))
1549 skl_gt_workarounds_init(gt, wal);
1550 else if (IS_HASWELL(i915))
1551 hsw_gt_workarounds_init(gt, wal);
1552 else if (IS_VALLEYVIEW(i915))
1553 vlv_gt_workarounds_init(gt, wal);
1554 else if (IS_IVYBRIDGE(i915))
1555 ivb_gt_workarounds_init(gt, wal);
1556 else if (GRAPHICS_VER(i915) == 6)
1557 snb_gt_workarounds_init(gt, wal);
1558 else if (GRAPHICS_VER(i915) == 5)
1559 ilk_gt_workarounds_init(gt, wal);
1560 else if (IS_G4X(i915))
1561 g4x_gt_workarounds_init(gt, wal);
1562 else if (GRAPHICS_VER(i915) == 4)
1563 gen4_gt_workarounds_init(gt, wal);
1564 else if (GRAPHICS_VER(i915) <= 8)
1565 ;
1566 else
1567 MISSING_CASE(GRAPHICS_VER(i915));
1568 }
1569
1570 void intel_gt_init_workarounds(struct intel_gt *gt)
1571 {
1572 struct i915_wa_list *wal = >->wa_list;
1573
1574 wa_init_start(wal, "GT", "global");
1575 gt_init_workarounds(gt, wal);
1576 wa_init_finish(wal);
1577 }
1578
1579 static enum forcewake_domains
1580 wal_get_fw_for_rmw(struct intel_uncore *uncore, const struct i915_wa_list *wal)
1581 {
1582 enum forcewake_domains fw = 0;
1583 struct i915_wa *wa;
1584 unsigned int i;
1585
1586 for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
1587 fw |= intel_uncore_forcewake_for_reg(uncore,
1588 wa->reg,
1589 FW_REG_READ |
1590 FW_REG_WRITE);
1591
1592 return fw;
1593 }
1594
1595 static bool
1596 wa_verify(const struct i915_wa *wa, u32 cur, const char *name, const char *from)
1597 {
1598 if ((cur ^ wa->set) & wa->read) {
1599 DRM_ERROR("%s workaround lost on %s! (reg[%x]=0x%x, relevant bits were 0x%x vs expected 0x%x)\n",
1600 name, from, i915_mmio_reg_offset(wa->reg),
1601 cur, cur & wa->read, wa->set & wa->read);
1602
1603 return false;
1604 }
1605
1606 return true;
1607 }
1608
1609 static void
1610 wa_list_apply(struct intel_gt *gt, const struct i915_wa_list *wal)
1611 {
1612 struct intel_uncore *uncore = gt->uncore;
1613 enum forcewake_domains fw;
1614 unsigned long flags;
1615 struct i915_wa *wa;
1616 unsigned int i;
1617
1618 if (!wal->count)
1619 return;
1620
1621 fw = wal_get_fw_for_rmw(uncore, wal);
1622
1623 spin_lock_irqsave(&uncore->lock, flags);
1624 intel_uncore_forcewake_get__locked(uncore, fw);
1625
1626 for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {
1627 u32 val, old = 0;
1628
1629
1630 old = wa->clr ? intel_gt_mcr_read_any_fw(gt, wa->reg) : 0;
1631 val = (old & ~wa->clr) | wa->set;
1632 if (val != old || !wa->clr)
1633 intel_uncore_write_fw(uncore, wa->reg, val);
1634
1635 if (IS_ENABLED(CONFIG_DRM_I915_DEBUG_GEM))
1636 wa_verify(wa, intel_gt_mcr_read_any_fw(gt, wa->reg),
1637 wal->name, "application");
1638 }
1639
1640 intel_uncore_forcewake_put__locked(uncore, fw);
1641 spin_unlock_irqrestore(&uncore->lock, flags);
1642 }
1643
1644 void intel_gt_apply_workarounds(struct intel_gt *gt)
1645 {
1646 wa_list_apply(gt, >->wa_list);
1647 }
1648
1649 static bool wa_list_verify(struct intel_gt *gt,
1650 const struct i915_wa_list *wal,
1651 const char *from)
1652 {
1653 struct intel_uncore *uncore = gt->uncore;
1654 struct i915_wa *wa;
1655 enum forcewake_domains fw;
1656 unsigned long flags;
1657 unsigned int i;
1658 bool ok = true;
1659
1660 fw = wal_get_fw_for_rmw(uncore, wal);
1661
1662 spin_lock_irqsave(&uncore->lock, flags);
1663 intel_uncore_forcewake_get__locked(uncore, fw);
1664
1665 for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
1666 ok &= wa_verify(wa,
1667 intel_gt_mcr_read_any_fw(gt, wa->reg),
1668 wal->name, from);
1669
1670 intel_uncore_forcewake_put__locked(uncore, fw);
1671 spin_unlock_irqrestore(&uncore->lock, flags);
1672
1673 return ok;
1674 }
1675
1676 bool intel_gt_verify_workarounds(struct intel_gt *gt, const char *from)
1677 {
1678 return wa_list_verify(gt, >->wa_list, from);
1679 }
1680
1681 __maybe_unused
1682 static bool is_nonpriv_flags_valid(u32 flags)
1683 {
1684
1685 if (flags & ~RING_FORCE_TO_NONPRIV_MASK_VALID)
1686 return false;
1687
1688
1689 if ((flags & RING_FORCE_TO_NONPRIV_ACCESS_MASK) ==
1690 RING_FORCE_TO_NONPRIV_ACCESS_INVALID)
1691 return false;
1692
1693 return true;
1694 }
1695
1696 static void
1697 whitelist_reg_ext(struct i915_wa_list *wal, i915_reg_t reg, u32 flags)
1698 {
1699 struct i915_wa wa = {
1700 .reg = reg
1701 };
1702
1703 if (GEM_DEBUG_WARN_ON(wal->count >= RING_MAX_NONPRIV_SLOTS))
1704 return;
1705
1706 if (GEM_DEBUG_WARN_ON(!is_nonpriv_flags_valid(flags)))
1707 return;
1708
1709 wa.reg.reg |= flags;
1710 _wa_add(wal, &wa);
1711 }
1712
1713 static void
1714 whitelist_reg(struct i915_wa_list *wal, i915_reg_t reg)
1715 {
1716 whitelist_reg_ext(wal, reg, RING_FORCE_TO_NONPRIV_ACCESS_RW);
1717 }
1718
1719 static void gen9_whitelist_build(struct i915_wa_list *w)
1720 {
1721
1722 whitelist_reg(w, GEN9_CTX_PREEMPT_REG);
1723
1724
1725 whitelist_reg(w, GEN8_CS_CHICKEN1);
1726
1727
1728 whitelist_reg(w, GEN8_HDC_CHICKEN1);
1729
1730
1731 whitelist_reg(w, COMMON_SLICE_CHICKEN2);
1732 }
1733
1734 static void skl_whitelist_build(struct intel_engine_cs *engine)
1735 {
1736 struct i915_wa_list *w = &engine->whitelist;
1737
1738 if (engine->class != RENDER_CLASS)
1739 return;
1740
1741 gen9_whitelist_build(w);
1742
1743
1744 whitelist_reg(w, GEN8_L3SQCREG4);
1745 }
1746
1747 static void bxt_whitelist_build(struct intel_engine_cs *engine)
1748 {
1749 if (engine->class != RENDER_CLASS)
1750 return;
1751
1752 gen9_whitelist_build(&engine->whitelist);
1753 }
1754
1755 static void kbl_whitelist_build(struct intel_engine_cs *engine)
1756 {
1757 struct i915_wa_list *w = &engine->whitelist;
1758
1759 if (engine->class != RENDER_CLASS)
1760 return;
1761
1762 gen9_whitelist_build(w);
1763
1764
1765 whitelist_reg(w, GEN8_L3SQCREG4);
1766 }
1767
1768 static void glk_whitelist_build(struct intel_engine_cs *engine)
1769 {
1770 struct i915_wa_list *w = &engine->whitelist;
1771
1772 if (engine->class != RENDER_CLASS)
1773 return;
1774
1775 gen9_whitelist_build(w);
1776
1777
1778 whitelist_reg(w, GEN9_SLICE_COMMON_ECO_CHICKEN1);
1779 }
1780
1781 static void cfl_whitelist_build(struct intel_engine_cs *engine)
1782 {
1783 struct i915_wa_list *w = &engine->whitelist;
1784
1785 if (engine->class != RENDER_CLASS)
1786 return;
1787
1788 gen9_whitelist_build(w);
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799 whitelist_reg_ext(w, PS_INVOCATION_COUNT,
1800 RING_FORCE_TO_NONPRIV_ACCESS_RD |
1801 RING_FORCE_TO_NONPRIV_RANGE_4);
1802 }
1803
1804 static void allow_read_ctx_timestamp(struct intel_engine_cs *engine)
1805 {
1806 struct i915_wa_list *w = &engine->whitelist;
1807
1808 if (engine->class != RENDER_CLASS)
1809 whitelist_reg_ext(w,
1810 RING_CTX_TIMESTAMP(engine->mmio_base),
1811 RING_FORCE_TO_NONPRIV_ACCESS_RD);
1812 }
1813
1814 static void cml_whitelist_build(struct intel_engine_cs *engine)
1815 {
1816 allow_read_ctx_timestamp(engine);
1817
1818 cfl_whitelist_build(engine);
1819 }
1820
1821 static void icl_whitelist_build(struct intel_engine_cs *engine)
1822 {
1823 struct i915_wa_list *w = &engine->whitelist;
1824
1825 allow_read_ctx_timestamp(engine);
1826
1827 switch (engine->class) {
1828 case RENDER_CLASS:
1829
1830 whitelist_reg(w, GEN9_HALF_SLICE_CHICKEN7);
1831
1832
1833 whitelist_reg(w, GEN10_SAMPLER_MODE);
1834
1835
1836 whitelist_reg(w, GEN9_SLICE_COMMON_ECO_CHICKEN1);
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847 whitelist_reg_ext(w, PS_INVOCATION_COUNT,
1848 RING_FORCE_TO_NONPRIV_ACCESS_RD |
1849 RING_FORCE_TO_NONPRIV_RANGE_4);
1850 break;
1851
1852 case VIDEO_DECODE_CLASS:
1853
1854 whitelist_reg_ext(w, _MMIO(0x2000 + engine->mmio_base),
1855 RING_FORCE_TO_NONPRIV_ACCESS_RD);
1856
1857 whitelist_reg_ext(w, _MMIO(0x2014 + engine->mmio_base),
1858 RING_FORCE_TO_NONPRIV_ACCESS_RD);
1859
1860 whitelist_reg_ext(w, _MMIO(0x23B0 + engine->mmio_base),
1861 RING_FORCE_TO_NONPRIV_ACCESS_RD);
1862 break;
1863
1864 default:
1865 break;
1866 }
1867 }
1868
1869 static void tgl_whitelist_build(struct intel_engine_cs *engine)
1870 {
1871 struct i915_wa_list *w = &engine->whitelist;
1872
1873 allow_read_ctx_timestamp(engine);
1874
1875 switch (engine->class) {
1876 case RENDER_CLASS:
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887 whitelist_reg_ext(w, PS_INVOCATION_COUNT,
1888 RING_FORCE_TO_NONPRIV_ACCESS_RD |
1889 RING_FORCE_TO_NONPRIV_RANGE_4);
1890
1891
1892
1893
1894
1895
1896 whitelist_reg(w, GEN7_COMMON_SLICE_CHICKEN1);
1897
1898
1899 whitelist_reg(w, HIZ_CHICKEN);
1900 break;
1901 default:
1902 break;
1903 }
1904 }
1905
1906 static void dg1_whitelist_build(struct intel_engine_cs *engine)
1907 {
1908 struct i915_wa_list *w = &engine->whitelist;
1909
1910 tgl_whitelist_build(engine);
1911
1912
1913 if (IS_DG1_GRAPHICS_STEP(engine->i915, STEP_A0, STEP_B0) &&
1914 (engine->class == RENDER_CLASS ||
1915 engine->class == COPY_ENGINE_CLASS))
1916 whitelist_reg_ext(w, RING_ID(engine->mmio_base),
1917 RING_FORCE_TO_NONPRIV_ACCESS_RD);
1918 }
1919
1920 static void xehpsdv_whitelist_build(struct intel_engine_cs *engine)
1921 {
1922 allow_read_ctx_timestamp(engine);
1923 }
1924
1925 static void dg2_whitelist_build(struct intel_engine_cs *engine)
1926 {
1927 struct i915_wa_list *w = &engine->whitelist;
1928
1929 allow_read_ctx_timestamp(engine);
1930
1931 switch (engine->class) {
1932 case RENDER_CLASS:
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942 if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_B0))
1943 whitelist_reg_ext(w, PS_INVOCATION_COUNT,
1944 RING_FORCE_TO_NONPRIV_ACCESS_RD |
1945 RING_FORCE_TO_NONPRIV_RANGE_4);
1946
1947 break;
1948 case COMPUTE_CLASS:
1949
1950 if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_B0))
1951 whitelist_reg(w, GEN9_CTX_PREEMPT_REG);
1952 break;
1953 default:
1954 break;
1955 }
1956 }
1957
1958 static void blacklist_trtt(struct intel_engine_cs *engine)
1959 {
1960 struct i915_wa_list *w = &engine->whitelist;
1961
1962
1963
1964
1965
1966
1967
1968 whitelist_reg_ext(w, _MMIO(0x4400),
1969 RING_FORCE_TO_NONPRIV_DENY |
1970 RING_FORCE_TO_NONPRIV_RANGE_64);
1971 whitelist_reg_ext(w, _MMIO(0x4500),
1972 RING_FORCE_TO_NONPRIV_DENY |
1973 RING_FORCE_TO_NONPRIV_RANGE_64);
1974 }
1975
1976 static void pvc_whitelist_build(struct intel_engine_cs *engine)
1977 {
1978 allow_read_ctx_timestamp(engine);
1979
1980
1981 blacklist_trtt(engine);
1982 }
1983
1984 void intel_engine_init_whitelist(struct intel_engine_cs *engine)
1985 {
1986 struct drm_i915_private *i915 = engine->i915;
1987 struct i915_wa_list *w = &engine->whitelist;
1988
1989 wa_init_start(w, "whitelist", engine->name);
1990
1991 if (IS_PONTEVECCHIO(i915))
1992 pvc_whitelist_build(engine);
1993 else if (IS_DG2(i915))
1994 dg2_whitelist_build(engine);
1995 else if (IS_XEHPSDV(i915))
1996 xehpsdv_whitelist_build(engine);
1997 else if (IS_DG1(i915))
1998 dg1_whitelist_build(engine);
1999 else if (GRAPHICS_VER(i915) == 12)
2000 tgl_whitelist_build(engine);
2001 else if (GRAPHICS_VER(i915) == 11)
2002 icl_whitelist_build(engine);
2003 else if (IS_COMETLAKE(i915))
2004 cml_whitelist_build(engine);
2005 else if (IS_COFFEELAKE(i915))
2006 cfl_whitelist_build(engine);
2007 else if (IS_GEMINILAKE(i915))
2008 glk_whitelist_build(engine);
2009 else if (IS_KABYLAKE(i915))
2010 kbl_whitelist_build(engine);
2011 else if (IS_BROXTON(i915))
2012 bxt_whitelist_build(engine);
2013 else if (IS_SKYLAKE(i915))
2014 skl_whitelist_build(engine);
2015 else if (GRAPHICS_VER(i915) <= 8)
2016 ;
2017 else
2018 MISSING_CASE(GRAPHICS_VER(i915));
2019
2020 wa_init_finish(w);
2021 }
2022
2023 void intel_engine_apply_whitelist(struct intel_engine_cs *engine)
2024 {
2025 const struct i915_wa_list *wal = &engine->whitelist;
2026 struct intel_uncore *uncore = engine->uncore;
2027 const u32 base = engine->mmio_base;
2028 struct i915_wa *wa;
2029 unsigned int i;
2030
2031 if (!wal->count)
2032 return;
2033
2034 for (i = 0, wa = wal->list; i < wal->count; i++, wa++)
2035 intel_uncore_write(uncore,
2036 RING_FORCE_TO_NONPRIV(base, i),
2037 i915_mmio_reg_offset(wa->reg));
2038
2039
2040 for (; i < RING_MAX_NONPRIV_SLOTS; i++)
2041 intel_uncore_write(uncore,
2042 RING_FORCE_TO_NONPRIV(base, i),
2043 i915_mmio_reg_offset(RING_NOPID(base)));
2044 }
2045
2046
2047
2048
2049
2050
2051
2052
2053 static void
2054 engine_fake_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
2055 {
2056 u8 mocs_w, mocs_r;
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066 if (GRAPHICS_VER(engine->i915) >= 12) {
2067 mocs_r = engine->gt->mocs.uc_index;
2068 mocs_w = engine->gt->mocs.uc_index;
2069
2070 if (HAS_L3_CCS_READ(engine->i915) &&
2071 engine->class == COMPUTE_CLASS) {
2072 mocs_r = engine->gt->mocs.wb_index;
2073
2074
2075
2076
2077
2078
2079
2080 drm_WARN_ON(&engine->i915->drm, mocs_r == 0);
2081 }
2082
2083 wa_masked_field_set(wal,
2084 RING_CMD_CCTL(engine->mmio_base),
2085 CMD_CCTL_MOCS_MASK,
2086 CMD_CCTL_MOCS_OVERRIDE(mocs_w, mocs_r));
2087 }
2088 }
2089
2090 static bool needs_wa_1308578152(struct intel_engine_cs *engine)
2091 {
2092 return intel_sseu_find_first_xehp_dss(&engine->gt->info.sseu, 0, 0) >=
2093 GEN_DSS_PER_GSLICE;
2094 }
2095
2096 static void
2097 rcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
2098 {
2099 struct drm_i915_private *i915 = engine->i915;
2100
2101 if (IS_DG2(i915)) {
2102
2103 wa_write_or(wal, GEN12_GAMCNTRL_CTRL, INVALIDATION_BROADCAST_MODE_DIS |
2104 GLOBAL_INVALIDATION_MODE);
2105
2106
2107
2108
2109
2110
2111 wa_write_or(wal, XEHP_L3SCQREG7, BLEND_FILL_CACHING_OPT_DIS);
2112 }
2113
2114 if (IS_DG2_GRAPHICS_STEP(i915, G11, STEP_A0, STEP_B0)) {
2115
2116 wa_masked_en(wal, GEN7_ROW_CHICKEN2, GEN12_ENABLE_LARGE_GRF_MODE);
2117
2118
2119 wa_write_or(wal, LSC_CHICKEN_BIT_0_UDW, DIS_CHAIN_2XSIMD8);
2120 }
2121
2122 if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0) ||
2123 IS_DG2_GRAPHICS_STEP(i915, G11, STEP_A0, STEP_B0)) {
2124
2125 wa_masked_en(wal, GEN9_ROW_CHICKEN4,
2126 GEN12_DISABLE_HDR_PAST_PAYLOAD_HOLD_FIX);
2127 }
2128
2129 if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_B0, STEP_C0) ||
2130 IS_DG2_G11(i915)) {
2131
2132
2133
2134
2135 wa_write_clr_set(wal, LSC_CHICKEN_BIT_0_UDW,
2136 MAXREQS_PER_BANK,
2137 REG_FIELD_PREP(MAXREQS_PER_BANK, 2));
2138
2139
2140 wa_write_or(wal, LSC_CHICKEN_BIT_0,
2141 FORCE_1_SUB_MESSAGE_PER_FRAGMENT);
2142 }
2143
2144
2145 if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_B0, STEP_C0) &&
2146 needs_wa_1308578152(engine)) {
2147 wa_masked_dis(wal, GEN12_CS_DEBUG_MODE1_CCCSUNIT_BE_COMMON,
2148 GEN12_REPLAY_MODE_GRANULARITY);
2149 }
2150
2151 if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_B0, STEP_FOREVER) ||
2152 IS_DG2_G11(i915) || IS_DG2_G12(i915)) {
2153
2154 wa_write_or(wal, LSC_CHICKEN_BIT_0_UDW,
2155 DISABLE_128B_EVICTION_COMMAND_UDW);
2156
2157
2158 wa_masked_en(wal, GEN7_ROW_CHICKEN2,
2159 GEN12_DISABLE_READ_SUPPRESSION);
2160
2161
2162
2163
2164
2165 wa_masked_dis(wal, GEN12_HDC_CHICKEN0,
2166 LSC_L1_FLUSH_CTL_3D_DATAPORT_FLUSH_EVENTS_MASK);
2167 }
2168
2169 if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0)) {
2170
2171
2172
2173
2174 wa_masked_en(wal, GEN8_ROW_CHICKEN,
2175 MDQ_ARBITRATION_MODE | UGM_BACKUP_MODE);
2176
2177
2178
2179
2180
2181
2182
2183 wa_add(wal, LSC_CHICKEN_BIT_0_UDW, 0,
2184 FORCE_SLM_FENCE_SCOPE_TO_TILE | FORCE_UGM_FENCE_SCOPE_TO_TILE,
2185 0, false);
2186 }
2187
2188 if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_B0)) {
2189
2190 wa_masked_en(wal,
2191 GEN9_ROW_CHICKEN4,
2192 GEN12_DISABLE_GRF_CLEAR);
2193
2194
2195 wa_write_or(wal, XEHP_L3NODEARBCFG, XEHP_LNESPARE);
2196 }
2197
2198 if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_A0, STEP_C0) ||
2199 IS_DG2_G11(i915)) {
2200
2201 wa_add(wal, GEN10_CACHE_MODE_SS, 0,
2202 _MASKED_BIT_ENABLE(ENABLE_PREFETCH_INTO_IC),
2203 0 ,
2204 true);
2205 }
2206
2207
2208 if (IS_DG2_GRAPHICS_STEP(i915, G10, STEP_B0, STEP_C0) ||
2209 IS_DG2_GRAPHICS_STEP(i915, G11, STEP_A0, STEP_B0))
2210 wa_write_or(wal, RT_CTRL, DIS_NULL_QUERY);
2211
2212
2213 if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_C0) ||
2214 IS_DG2_GRAPHICS_STEP(engine->i915, G11, STEP_A0, STEP_B0))
2215 wa_masked_en(wal, GEN9_HALF_SLICE_CHICKEN7,
2216 DG2_DISABLE_ROUND_ENABLE_ALLOW_FOR_SSLA);
2217
2218 if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_B0)) {
2219
2220 wa_write_or(wal, GEN12_GAMSTLB_CTRL, CONTROL_BLOCK_CLKGATE_DIS |
2221 EGRESS_BLOCK_CLKGATE_DIS | TAG_BLOCK_CLKGATE_DIS);
2222 }
2223
2224 if (IS_DG2_GRAPHICS_STEP(engine->i915, G10, STEP_A0, STEP_B0) ||
2225 IS_DG2_GRAPHICS_STEP(engine->i915, G11, STEP_A0, STEP_B0)) {
2226
2227 wa_write_or(wal, GEN12_MERT_MOD_CTRL, FORCE_MISS_FTLB);
2228 }
2229
2230 if (IS_DG2_GRAPHICS_STEP(i915, G11, STEP_B0, STEP_FOREVER) ||
2231 IS_DG2_G10(i915)) {
2232
2233 wa_add(wal, GEN10_CACHE_MODE_SS, 0,
2234 _MASKED_BIT_ENABLE(ENABLE_EU_COUNT_FOR_TDL_FLUSH),
2235 0
2236 ,
2237 true);
2238 }
2239
2240 if (IS_DG1_GRAPHICS_STEP(i915, STEP_A0, STEP_B0) ||
2241 IS_TGL_UY_GRAPHICS_STEP(i915, STEP_A0, STEP_B0)) {
2242
2243
2244
2245
2246 wa_write_or(wal,
2247 GEN9_CTX_PREEMPT_REG,
2248 GEN12_DISABLE_POSH_BUSY_FF_DOP_CG);
2249 }
2250
2251 if (IS_TGL_UY_GRAPHICS_STEP(i915, STEP_A0, STEP_B0)) {
2252
2253
2254
2255
2256 wa_write_or(wal,
2257 GEN7_SARCHKMD,
2258 GEN7_DISABLE_SAMPLER_PREFETCH);
2259 }
2260
2261 if (IS_ALDERLAKE_P(i915) || IS_ALDERLAKE_S(i915) || IS_DG1(i915) ||
2262 IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {
2263
2264 wa_masked_en(wal, GEN7_ROW_CHICKEN2, GEN12_DISABLE_EARLY_READ);
2265
2266
2267
2268
2269
2270
2271
2272 wa_write_or(wal, GEN7_FF_THREAD_MODE,
2273 GEN12_FF_TESSELATION_DOP_GATE_DISABLE);
2274 }
2275
2276 if (IS_ALDERLAKE_P(i915) || IS_DG2(i915) || IS_ALDERLAKE_S(i915) ||
2277 IS_DG1(i915) || IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {
2278
2279
2280
2281
2282
2283
2284 wa_masked_en(wal,
2285 GEN9_CS_DEBUG_MODE1,
2286 FF_DOP_CLOCK_GATE_DISABLE);
2287 }
2288
2289 if (IS_ALDERLAKE_P(i915) || IS_ALDERLAKE_S(i915) ||
2290 IS_DG1_GRAPHICS_STEP(i915, STEP_A0, STEP_B0) ||
2291 IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {
2292
2293 wa_masked_en(wal, GEN7_ROW_CHICKEN2,
2294 GEN12_PUSH_CONST_DEREF_HOLD_DIS);
2295
2296
2297
2298
2299
2300 wa_masked_en(wal, GEN9_ROW_CHICKEN4, GEN12_DISABLE_TDL_PUSH);
2301 }
2302
2303 if (IS_DG1_GRAPHICS_STEP(i915, STEP_A0, STEP_B0) ||
2304 IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915)) {
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315 wa_masked_en(wal,
2316 RING_PSMI_CTL(RENDER_RING_BASE),
2317 GEN12_WAIT_FOR_EVENT_POWER_DOWN_DISABLE |
2318 GEN8_RC_SEMA_IDLE_MSG_DISABLE);
2319 }
2320
2321 if (IS_DG1(i915) || IS_ROCKETLAKE(i915) || IS_TIGERLAKE(i915) ||
2322 IS_ALDERLAKE_S(i915) || IS_ALDERLAKE_P(i915)) {
2323
2324 wa_masked_en(wal,
2325 GEN10_SAMPLER_MODE,
2326 ENABLE_SMALLPL);
2327 }
2328
2329 if (GRAPHICS_VER(i915) == 11) {
2330
2331 wa_masked_en(wal,
2332 _3D_CHICKEN3,
2333 _3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE);
2334
2335
2336
2337
2338
2339 wa_write_or(wal,
2340 GEN8_GARBCNTL,
2341 GEN11_ARBITRATION_PRIO_ORDER_MASK);
2342
2343
2344
2345
2346
2347 wa_write_clr_set(wal,
2348 GEN8_GARBCNTL,
2349 GEN11_HASH_CTRL_EXCL_MASK,
2350 GEN11_HASH_CTRL_EXCL_BIT0);
2351 wa_write_clr_set(wal,
2352 GEN11_GLBLINVL,
2353 GEN11_BANK_HASH_ADDR_EXCL_MASK,
2354 GEN11_BANK_HASH_ADDR_EXCL_BIT0);
2355
2356
2357
2358
2359
2360 wa_write_or(wal,
2361 GEN8_L3SQCREG4,
2362 GEN11_LQSC_CLEAN_EVICT_DISABLE);
2363
2364
2365 wa_write_or(wal,
2366 GEN7_SARCHKMD,
2367 GEN7_DISABLE_SAMPLER_PREFETCH);
2368
2369
2370 wa_write_clr_set(wal,
2371 GEN11_SCRATCH2,
2372 GEN11_COHERENT_PARTIAL_WRITE_MERGE_ENABLE,
2373 0);
2374
2375
2376 wa_masked_en(wal, GEN9_CSFE_CHICKEN1_RCS,
2377 GEN11_ENABLE_32_PLANE_MODE);
2378
2379
2380
2381
2382
2383 wa_write_or(wal, UNSLICE_UNIT_LEVEL_CLKGATE,
2384 VSUNIT_CLKGATE_DIS | HSUNIT_CLKGATE_DIS);
2385
2386
2387
2388
2389
2390 wa_write_or(wal,
2391 GEN7_FF_THREAD_MODE,
2392 GEN12_FF_TESSELATION_DOP_GATE_DISABLE);
2393
2394
2395 wa_masked_en(wal,
2396 GEN9_CS_DEBUG_MODE1,
2397 FF_DOP_CLOCK_GATE_DISABLE);
2398 }
2399
2400 if (HAS_PERCTX_PREEMPT_CTRL(i915)) {
2401
2402 wa_masked_en(wal,
2403 GEN7_FF_SLICE_CS_CHICKEN1,
2404 GEN9_FFSC_PERCTX_PREEMPT_CTRL);
2405 }
2406
2407 if (IS_SKYLAKE(i915) ||
2408 IS_KABYLAKE(i915) ||
2409 IS_COFFEELAKE(i915) ||
2410 IS_COMETLAKE(i915)) {
2411
2412 wa_write_or(wal,
2413 GEN8_GARBCNTL,
2414 GEN9_GAPS_TSV_CREDIT_DISABLE);
2415 }
2416
2417 if (IS_BROXTON(i915)) {
2418
2419 wa_masked_en(wal,
2420 FF_SLICE_CS_CHICKEN2,
2421 GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE);
2422 }
2423
2424 if (GRAPHICS_VER(i915) == 9) {
2425
2426 wa_masked_en(wal,
2427 GEN9_CSFE_CHICKEN1_RCS,
2428 GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE);
2429
2430
2431 wa_write_or(wal,
2432 BDW_SCRATCH1,
2433 GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE);
2434
2435
2436 if (IS_GEN9_LP(i915))
2437 wa_write_clr_set(wal,
2438 GEN8_L3SQCREG1,
2439 L3_PRIO_CREDITS_MASK,
2440 L3_GENERAL_PRIO_CREDITS(62) |
2441 L3_HIGH_PRIO_CREDITS(2));
2442
2443
2444 wa_write_or(wal,
2445 GEN8_L3SQCREG4,
2446 GEN8_LQSC_FLUSH_COHERENT_LINES);
2447
2448
2449 wa_write_clr_set(wal, GEN9_SCRATCH_LNCF1,
2450 GEN9_LNCF_NONIA_COHERENT_ATOMICS_ENABLE, 0);
2451 wa_write_clr_set(wal, GEN8_L3SQCREG4,
2452 GEN8_LQSQ_NONIA_COHERENT_ATOMICS_ENABLE, 0);
2453 wa_write_clr_set(wal, GEN9_SCRATCH1,
2454 EVICTION_PERF_FIX_ENABLE, 0);
2455 }
2456
2457 if (IS_HASWELL(i915)) {
2458
2459 wa_masked_en(wal,
2460 HALF_SLICE_CHICKEN3, HSW_SAMPLE_C_PERFORMANCE);
2461
2462 wa_masked_dis(wal,
2463 CACHE_MODE_0_GEN7,
2464
2465 HIZ_RAW_STALL_OPT_DISABLE);
2466 }
2467
2468 if (IS_VALLEYVIEW(i915)) {
2469
2470 wa_masked_en(wal,
2471 _3D_CHICKEN3,
2472 _3D_CHICKEN_SF_DISABLE_OBJEND_CULL);
2473
2474
2475
2476
2477
2478
2479
2480 wa_write_clr_set(wal,
2481 GEN7_FF_THREAD_MODE,
2482 GEN7_FF_SCHED_MASK,
2483 GEN7_FF_TS_SCHED_HW |
2484 GEN7_FF_VS_SCHED_HW |
2485 GEN7_FF_DS_SCHED_HW);
2486
2487
2488
2489 wa_masked_en(wal,
2490 GEN7_HALF_SLICE_CHICKEN1,
2491 GEN7_MAX_PS_THREAD_DEP |
2492 GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE);
2493 }
2494
2495 if (IS_IVYBRIDGE(i915)) {
2496
2497 wa_masked_en(wal,
2498 _3D_CHICKEN3,
2499 _3D_CHICKEN_SF_DISABLE_OBJEND_CULL);
2500
2501 if (0) {
2502
2503 wa_masked_dis(wal,
2504 CACHE_MODE_0_GEN7,
2505 HIZ_RAW_STALL_OPT_DISABLE);
2506 }
2507
2508
2509
2510
2511
2512
2513
2514 wa_write_clr_set(wal,
2515 GEN7_FF_THREAD_MODE,
2516 GEN7_FF_SCHED_MASK,
2517 GEN7_FF_TS_SCHED_HW |
2518 GEN7_FF_VS_SCHED_HW |
2519 GEN7_FF_DS_SCHED_HW);
2520
2521
2522 if (IS_IVB_GT1(i915))
2523 wa_masked_en(wal,
2524 GEN7_HALF_SLICE_CHICKEN1,
2525 GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE);
2526 }
2527
2528 if (GRAPHICS_VER(i915) == 7) {
2529
2530 wa_masked_en(wal,
2531 RING_MODE_GEN7(RENDER_RING_BASE),
2532 GFX_TLB_INVALIDATE_EXPLICIT | GFX_REPLAY_MODE);
2533
2534
2535 wa_masked_dis(wal, CACHE_MODE_0_GEN7, RC_OP_FLUSH_ENABLE);
2536
2537
2538
2539
2540
2541
2542 wa_masked_en(wal,
2543 CACHE_MODE_1,
2544 PIXEL_SUBSPAN_COLLECT_OPT_DISABLE);
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554 wa_masked_field_set(wal,
2555 GEN7_GT_MODE,
2556 GEN6_WIZ_HASHING_MASK,
2557 GEN6_WIZ_HASHING_16x4);
2558 }
2559
2560 if (IS_GRAPHICS_VER(i915, 6, 7))
2561
2562
2563
2564
2565
2566
2567
2568 wa_masked_en(wal,
2569 RING_MI_MODE(RENDER_RING_BASE),
2570 ASYNC_FLIP_PERF_DISABLE);
2571
2572 if (GRAPHICS_VER(i915) == 6) {
2573
2574
2575
2576
2577
2578 wa_masked_en(wal,
2579 GFX_MODE,
2580 GFX_TLB_INVALIDATE_EXPLICIT);
2581
2582
2583 wa_masked_en(wal,
2584 _3D_CHICKEN,
2585 _3D_CHICKEN_HIZ_PLANE_DISABLE_MSAA_4X_SNB);
2586
2587 wa_masked_en(wal,
2588 _3D_CHICKEN3,
2589
2590 _3D_CHICKEN3_SF_DISABLE_FASTCLIP_CULL |
2591
2592
2593
2594
2595
2596
2597 _3D_CHICKEN3_SF_DISABLE_PIPELINED_ATTR_FETCH);
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607 wa_masked_field_set(wal,
2608 GEN6_GT_MODE,
2609 GEN6_WIZ_HASHING_MASK,
2610 GEN6_WIZ_HASHING_16x4);
2611
2612
2613 wa_masked_dis(wal, CACHE_MODE_0, RC_OP_FLUSH_ENABLE);
2614
2615
2616
2617
2618
2619
2620
2621 wa_masked_dis(wal,
2622 CACHE_MODE_0,
2623 CM0_STC_EVICT_DISABLE_LRA_SNB);
2624 }
2625
2626 if (IS_GRAPHICS_VER(i915, 4, 6))
2627
2628 wa_add(wal, RING_MI_MODE(RENDER_RING_BASE),
2629 0, _MASKED_BIT_ENABLE(VS_TIMER_DISPATCH),
2630
2631 IS_I965G(i915) ? 0 : VS_TIMER_DISPATCH, true);
2632
2633 if (GRAPHICS_VER(i915) == 4)
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644 wa_add(wal, ECOSKPD(RENDER_RING_BASE),
2645 0, _MASKED_BIT_ENABLE(ECO_CONSTANT_BUFFER_SR_DISABLE),
2646 0 ,
2647 true);
2648 }
2649
2650 static void
2651 xcs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
2652 {
2653 struct drm_i915_private *i915 = engine->i915;
2654
2655
2656 if (IS_KBL_GRAPHICS_STEP(i915, STEP_A0, STEP_F0)) {
2657 wa_write(wal,
2658 RING_SEMA_WAIT_POLL(engine->mmio_base),
2659 1);
2660 }
2661 }
2662
2663 static void
2664 ccs_engine_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
2665 {
2666 if (IS_PVC_CT_STEP(engine->i915, STEP_A0, STEP_C0)) {
2667
2668 wa_masked_en(wal, GEN10_CACHE_MODE_SS, DISABLE_ECC);
2669 }
2670 }
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681 static void
2682 general_render_compute_wa_init(struct intel_engine_cs *engine, struct i915_wa_list *wal)
2683 {
2684 struct drm_i915_private *i915 = engine->i915;
2685
2686 if (IS_PONTEVECCHIO(i915)) {
2687
2688
2689
2690
2691
2692 wa_write(wal, XEHPC_L3SCRUB, SCRUB_CL_DWNGRADE_SHARED | SCRUB_RATE_4B_PER_CLK);
2693
2694
2695 wa_masked_en(wal, XEHPC_LNCFMISCCFGREG0, XEHPC_OVRLSCCC);
2696 }
2697
2698 if (IS_XEHPSDV(i915)) {
2699
2700 wa_masked_en(wal,
2701 GEN8_ROW_CHICKEN,
2702 SYSTOLIC_DOP_CLOCK_GATING_DIS);
2703
2704
2705 wa_masked_en(wal,
2706 GEN9_ROW_CHICKEN4,
2707 GEN12_DISABLE_GRF_CLEAR);
2708
2709
2710 wa_write_or(wal, XEHP_L3NODEARBCFG, XEHP_LNESPARE);
2711
2712
2713 wa_masked_en(wal, GEN7_HALF_SLICE_CHICKEN1,
2714 GEN7_PSD_SINGLE_PORT_DISPATCH_ENABLE);
2715
2716
2717 if (IS_XEHPSDV_GRAPHICS_STEP(i915, STEP_A1, STEP_B0)) {
2718 wa_masked_dis(wal, MLTICTXCTL, TDONRENDER);
2719 wa_write_or(wal, L3SQCREG1_CCS0, FLUSHALLNONCOH);
2720 }
2721
2722
2723 wa_write_or(wal, GEN12_MERT_MOD_CTRL, FORCE_MISS_FTLB);
2724
2725
2726 wa_write_or(wal, GEN12_GAMCNTRL_CTRL, INVALIDATION_BROADCAST_MODE_DIS |
2727 GLOBAL_INVALIDATION_MODE);
2728 }
2729
2730 if (IS_DG2(i915) || IS_PONTEVECCHIO(i915)) {
2731
2732 wa_masked_en(wal, GEN9_ROW_CHICKEN4, XEHP_DIS_BBL_SYSPIPE);
2733
2734
2735 wa_write_or(wal, LSC_CHICKEN_BIT_0, DISABLE_D8_D16_COASLESCE);
2736
2737
2738 wa_masked_en(wal, FF_SLICE_CS_CHICKEN2, GEN12_PERF_FIX_BALANCING_CFE_DISABLE);
2739
2740
2741 wa_write_or(wal, RENDER_MOD_CTRL, FORCE_MISS_FTLB);
2742 wa_write_or(wal, COMP_MOD_CTRL, FORCE_MISS_FTLB);
2743 wa_write_or(wal, VDBX_MOD_CTRL, FORCE_MISS_FTLB);
2744 wa_write_or(wal, VEBX_MOD_CTRL, FORCE_MISS_FTLB);
2745 }
2746 }
2747
2748 static void
2749 engine_init_workarounds(struct intel_engine_cs *engine, struct i915_wa_list *wal)
2750 {
2751 if (I915_SELFTEST_ONLY(GRAPHICS_VER(engine->i915) < 4))
2752 return;
2753
2754 engine_fake_wa_init(engine, wal);
2755
2756
2757
2758
2759
2760
2761 if (engine->flags & I915_ENGINE_FIRST_RENDER_COMPUTE)
2762 general_render_compute_wa_init(engine, wal);
2763
2764 if (engine->class == COMPUTE_CLASS)
2765 ccs_engine_wa_init(engine, wal);
2766 else if (engine->class == RENDER_CLASS)
2767 rcs_engine_wa_init(engine, wal);
2768 else
2769 xcs_engine_wa_init(engine, wal);
2770 }
2771
2772 void intel_engine_init_workarounds(struct intel_engine_cs *engine)
2773 {
2774 struct i915_wa_list *wal = &engine->wa_list;
2775
2776 if (GRAPHICS_VER(engine->i915) < 4)
2777 return;
2778
2779 wa_init_start(wal, "engine", engine->name);
2780 engine_init_workarounds(engine, wal);
2781 wa_init_finish(wal);
2782 }
2783
2784 void intel_engine_apply_workarounds(struct intel_engine_cs *engine)
2785 {
2786 wa_list_apply(engine->gt, &engine->wa_list);
2787 }
2788
2789 static const struct i915_range mcr_ranges_gen8[] = {
2790 { .start = 0x5500, .end = 0x55ff },
2791 { .start = 0x7000, .end = 0x7fff },
2792 { .start = 0x9400, .end = 0x97ff },
2793 { .start = 0xb000, .end = 0xb3ff },
2794 { .start = 0xe000, .end = 0xe7ff },
2795 {},
2796 };
2797
2798 static const struct i915_range mcr_ranges_gen12[] = {
2799 { .start = 0x8150, .end = 0x815f },
2800 { .start = 0x9520, .end = 0x955f },
2801 { .start = 0xb100, .end = 0xb3ff },
2802 { .start = 0xde80, .end = 0xe8ff },
2803 { .start = 0x24a00, .end = 0x24a7f },
2804 {},
2805 };
2806
2807 static const struct i915_range mcr_ranges_xehp[] = {
2808 { .start = 0x4000, .end = 0x4aff },
2809 { .start = 0x5200, .end = 0x52ff },
2810 { .start = 0x5400, .end = 0x7fff },
2811 { .start = 0x8140, .end = 0x815f },
2812 { .start = 0x8c80, .end = 0x8dff },
2813 { .start = 0x94d0, .end = 0x955f },
2814 { .start = 0x9680, .end = 0x96ff },
2815 { .start = 0xb000, .end = 0xb3ff },
2816 { .start = 0xc800, .end = 0xcfff },
2817 { .start = 0xd800, .end = 0xd8ff },
2818 { .start = 0xdc00, .end = 0xffff },
2819 { .start = 0x17000, .end = 0x17fff },
2820 { .start = 0x24a00, .end = 0x24a7f },
2821 {},
2822 };
2823
2824 static bool mcr_range(struct drm_i915_private *i915, u32 offset)
2825 {
2826 const struct i915_range *mcr_ranges;
2827 int i;
2828
2829 if (GRAPHICS_VER_FULL(i915) >= IP_VER(12, 50))
2830 mcr_ranges = mcr_ranges_xehp;
2831 else if (GRAPHICS_VER(i915) >= 12)
2832 mcr_ranges = mcr_ranges_gen12;
2833 else if (GRAPHICS_VER(i915) >= 8)
2834 mcr_ranges = mcr_ranges_gen8;
2835 else
2836 return false;
2837
2838
2839
2840
2841
2842
2843 for (i = 0; mcr_ranges[i].start; i++)
2844 if (offset >= mcr_ranges[i].start &&
2845 offset <= mcr_ranges[i].end)
2846 return true;
2847
2848 return false;
2849 }
2850
2851 static int
2852 wa_list_srm(struct i915_request *rq,
2853 const struct i915_wa_list *wal,
2854 struct i915_vma *vma)
2855 {
2856 struct drm_i915_private *i915 = rq->engine->i915;
2857 unsigned int i, count = 0;
2858 const struct i915_wa *wa;
2859 u32 srm, *cs;
2860
2861 srm = MI_STORE_REGISTER_MEM | MI_SRM_LRM_GLOBAL_GTT;
2862 if (GRAPHICS_VER(i915) >= 8)
2863 srm++;
2864
2865 for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {
2866 if (!mcr_range(i915, i915_mmio_reg_offset(wa->reg)))
2867 count++;
2868 }
2869
2870 cs = intel_ring_begin(rq, 4 * count);
2871 if (IS_ERR(cs))
2872 return PTR_ERR(cs);
2873
2874 for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {
2875 u32 offset = i915_mmio_reg_offset(wa->reg);
2876
2877 if (mcr_range(i915, offset))
2878 continue;
2879
2880 *cs++ = srm;
2881 *cs++ = offset;
2882 *cs++ = i915_ggtt_offset(vma) + sizeof(u32) * i;
2883 *cs++ = 0;
2884 }
2885 intel_ring_advance(rq, cs);
2886
2887 return 0;
2888 }
2889
2890 static int engine_wa_list_verify(struct intel_context *ce,
2891 const struct i915_wa_list * const wal,
2892 const char *from)
2893 {
2894 const struct i915_wa *wa;
2895 struct i915_request *rq;
2896 struct i915_vma *vma;
2897 struct i915_gem_ww_ctx ww;
2898 unsigned int i;
2899 u32 *results;
2900 int err;
2901
2902 if (!wal->count)
2903 return 0;
2904
2905 vma = __vm_create_scratch_for_read(&ce->engine->gt->ggtt->vm,
2906 wal->count * sizeof(u32));
2907 if (IS_ERR(vma))
2908 return PTR_ERR(vma);
2909
2910 intel_engine_pm_get(ce->engine);
2911 i915_gem_ww_ctx_init(&ww, false);
2912 retry:
2913 err = i915_gem_object_lock(vma->obj, &ww);
2914 if (err == 0)
2915 err = intel_context_pin_ww(ce, &ww);
2916 if (err)
2917 goto err_pm;
2918
2919 err = i915_vma_pin_ww(vma, &ww, 0, 0,
2920 i915_vma_is_ggtt(vma) ? PIN_GLOBAL : PIN_USER);
2921 if (err)
2922 goto err_unpin;
2923
2924 rq = i915_request_create(ce);
2925 if (IS_ERR(rq)) {
2926 err = PTR_ERR(rq);
2927 goto err_vma;
2928 }
2929
2930 err = i915_request_await_object(rq, vma->obj, true);
2931 if (err == 0)
2932 err = i915_vma_move_to_active(vma, rq, EXEC_OBJECT_WRITE);
2933 if (err == 0)
2934 err = wa_list_srm(rq, wal, vma);
2935
2936 i915_request_get(rq);
2937 if (err)
2938 i915_request_set_error_once(rq, err);
2939 i915_request_add(rq);
2940
2941 if (err)
2942 goto err_rq;
2943
2944 if (i915_request_wait(rq, 0, HZ / 5) < 0) {
2945 err = -ETIME;
2946 goto err_rq;
2947 }
2948
2949 results = i915_gem_object_pin_map(vma->obj, I915_MAP_WB);
2950 if (IS_ERR(results)) {
2951 err = PTR_ERR(results);
2952 goto err_rq;
2953 }
2954
2955 err = 0;
2956 for (i = 0, wa = wal->list; i < wal->count; i++, wa++) {
2957 if (mcr_range(rq->engine->i915, i915_mmio_reg_offset(wa->reg)))
2958 continue;
2959
2960 if (!wa_verify(wa, results[i], wal->name, from))
2961 err = -ENXIO;
2962 }
2963
2964 i915_gem_object_unpin_map(vma->obj);
2965
2966 err_rq:
2967 i915_request_put(rq);
2968 err_vma:
2969 i915_vma_unpin(vma);
2970 err_unpin:
2971 intel_context_unpin(ce);
2972 err_pm:
2973 if (err == -EDEADLK) {
2974 err = i915_gem_ww_ctx_backoff(&ww);
2975 if (!err)
2976 goto retry;
2977 }
2978 i915_gem_ww_ctx_fini(&ww);
2979 intel_engine_pm_put(ce->engine);
2980 i915_vma_put(vma);
2981 return err;
2982 }
2983
2984 int intel_engine_verify_workarounds(struct intel_engine_cs *engine,
2985 const char *from)
2986 {
2987 return engine_wa_list_verify(engine->kernel_context,
2988 &engine->wa_list,
2989 from);
2990 }
2991
2992 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
2993 #include "selftest_workarounds.c"
2994 #endif