Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/i915: Introduce per-engine workarounds

We stopped re-applying the GT workarounds after engine reset since commit
59b449d5c82a ("drm/i915: Split out functions for different kinds of
workarounds").

Issue with this is that some of the GT workarounds live in the MMIO space
which gets lost during engine resets. So far the registers in 0x2xxx and
0xbxxx address range have been identified to be affected.

This losing of applied workarounds has obvious negative effects and can
even lead to hard system hangs (see the linked Bugzilla).

Rather than just restoring this re-application, because we have also
observed that it is not safe to just re-write all GT workarounds after
engine resets (GPU might be live and weird hardware states can happen),
we introduce a new class of per-engine workarounds and move only the
affected GT workarounds over.

Using the framework introduced in the previous patch, we therefore after
engine reset, re-apply only the workarounds living in the affected MMIO
address ranges.

v2:
* Move Wa_1406609255:icl to engine workarounds as well.
* Rename API. (Chris Wilson)
* Drop redundant IS_KABYLAKE. (Chris Wilson)
* Re-order engine wa/ init so latest platforms are first. (Rodrigo Vivi)

Signed-off-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Bugzilla: https://bugzilla.freedesktop.org/show_bug.cgi?id=107945
Fixes: 59b449d5c82a ("drm/i915: Split out functions for different kinds of workarounds")
Cc: Mika Kuoppala <mika.kuoppala@linux.intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Cc: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: intel-gfx@lists.freedesktop.org
Acked-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20181203133341.10258-1-tvrtko.ursulin@linux.intel.com
(cherry picked from commit 4a15c75c42460252a63d30f03b4766a52945fb47)
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>

authored by

Tvrtko Ursulin and committed by
Joonas Lahtinen
90098efa 00936779

+151 -117
+2
drivers/gpu/drm/i915/intel_engine_cs.c
··· 720 720 __intel_context_unpin(i915->kernel_context, engine); 721 721 722 722 i915_timeline_fini(&engine->timeline); 723 + 724 + intel_wa_list_free(&engine->wa_list); 723 725 } 724 726 725 727 u64 intel_engine_get_active_head(const struct intel_engine_cs *engine)
+4
drivers/gpu/drm/i915/intel_lrc.c
··· 1793 1793 1794 1794 static int gen8_init_common_ring(struct intel_engine_cs *engine) 1795 1795 { 1796 + intel_engine_apply_workarounds(engine); 1797 + 1796 1798 intel_mocs_init_engine(engine); 1797 1799 1798 1800 intel_engine_reset_breadcrumbs(engine); ··· 2492 2490 DRM_ERROR("WA batch buffer initialization failed: %d\n", 2493 2491 ret); 2494 2492 } 2493 + 2494 + intel_engine_init_workarounds(engine); 2495 2495 2496 2496 return 0; 2497 2497
+2
drivers/gpu/drm/i915/intel_ringbuffer.h
··· 15 15 #include "i915_selftest.h" 16 16 #include "i915_timeline.h" 17 17 #include "intel_gpu_commands.h" 18 + #include "intel_workarounds.h" 18 19 19 20 struct drm_printer; 20 21 struct i915_sched_attr; ··· 441 440 442 441 struct intel_hw_status_page status_page; 443 442 struct i915_ctx_workarounds wa_ctx; 443 + struct i915_wa_list wa_list; 444 444 struct i915_vma *scratch; 445 445 446 446 u32 irq_keep_mask; /* always keep these interrupts */
+140 -117
drivers/gpu/drm/i915/intel_workarounds.c
··· 661 661 { 662 662 struct i915_wa_list *wal = &i915->gt_wa_list; 663 663 664 - /* WaContextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */ 665 - wa_masked_en(wal, 666 - GEN9_CSFE_CHICKEN1_RCS, 667 - GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE); 668 - 669 - 670 - /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */ 671 - wa_write_or(wal, 672 - BDW_SCRATCH1, 673 - GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); 674 - 675 664 /* WaDisableKillLogic:bxt,skl,kbl */ 676 665 if (!IS_COFFEELAKE(i915)) 677 666 wa_write_or(wal, ··· 682 693 wa_write_or(wal, 683 694 GAM_ECOCHK, 684 695 BDW_DISABLE_HDC_INVALIDATION); 685 - 686 - /* WaProgramL3SqcReg1DefaultForPerf:bxt,glk */ 687 - if (IS_GEN9_LP(i915)) 688 - wa_write_masked_or(wal, 689 - GEN8_L3SQCREG1, 690 - L3_PRIO_CREDITS_MASK, 691 - L3_GENERAL_PRIO_CREDITS(62) | 692 - L3_HIGH_PRIO_CREDITS(2)); 693 - 694 - /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */ 695 - wa_write_or(wal, 696 - GEN8_L3SQCREG4, 697 - GEN8_LQSC_FLUSH_COHERENT_LINES); 698 - 699 - /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,[cnl] */ 700 - wa_masked_en(wal, 701 - GEN7_FF_SLICE_CS_CHICKEN1, 702 - GEN9_FFSC_PERCTX_PREEMPT_CTRL); 703 696 } 704 697 705 698 static void skl_gt_workarounds_init(struct drm_i915_private *i915) ··· 689 718 struct i915_wa_list *wal = &i915->gt_wa_list; 690 719 691 720 gen9_gt_workarounds_init(i915); 692 - 693 - /* WaEnableGapsTsvCreditFix:skl */ 694 - wa_write_or(wal, 695 - GEN8_GARBCNTL, 696 - GEN9_GAPS_TSV_CREDIT_DISABLE); 697 721 698 722 /* WaDisableGafsUnitClkGating:skl */ 699 723 wa_write_or(wal, ··· 708 742 709 743 gen9_gt_workarounds_init(i915); 710 744 711 - /* WaDisablePooledEuLoadBalancingFix:bxt */ 712 - wa_masked_en(wal, 713 - FF_SLICE_CS_CHICKEN2, 714 - GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE); 715 - 716 745 /* WaInPlaceDecompressionHang:bxt */ 717 746 wa_write_or(wal, 718 747 GEN9_GAMT_ECO_REG_RW_IA, ··· 719 758 struct i915_wa_list *wal = &i915->gt_wa_list; 720 759 721 760 gen9_gt_workarounds_init(i915); 722 - 723 - /* WaEnableGapsTsvCreditFix:kbl */ 724 - wa_write_or(wal, 725 - GEN8_GARBCNTL, 726 - GEN9_GAPS_TSV_CREDIT_DISABLE); 727 761 728 762 /* WaDisableDynamicCreditSharing:kbl */ 729 763 if (IS_KBL_REVID(i915, 0, KBL_REVID_B0)) ··· 735 779 wa_write_or(wal, 736 780 GEN9_GAMT_ECO_REG_RW_IA, 737 781 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 738 - 739 - /* WaKBLVECSSemaphoreWaitPoll:kbl */ 740 - if (IS_KBL_REVID(i915, KBL_REVID_A0, KBL_REVID_E0)) { 741 - struct intel_engine_cs *engine; 742 - unsigned int tmp; 743 - 744 - for_each_engine(engine, i915, tmp) { 745 - if (engine->id == RCS) 746 - continue; 747 - 748 - wa_write(wal, 749 - RING_SEMA_WAIT_POLL(engine->mmio_base), 750 - 1); 751 - } 752 - } 753 782 } 754 783 755 784 static void glk_gt_workarounds_init(struct drm_i915_private *i915) ··· 747 806 struct i915_wa_list *wal = &i915->gt_wa_list; 748 807 749 808 gen9_gt_workarounds_init(i915); 750 - 751 - /* WaEnableGapsTsvCreditFix:cfl */ 752 - wa_write_or(wal, 753 - GEN8_GARBCNTL, 754 - GEN9_GAPS_TSV_CREDIT_DISABLE); 755 809 756 810 /* WaDisableGafsUnitClkGating:cfl */ 757 811 wa_write_or(wal, ··· 838 902 wa_write_or(wal, 839 903 GEN9_GAMT_ECO_REG_RW_IA, 840 904 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 841 - 842 - /* WaEnablePreemptionGranularityControlByUMD:cnl */ 843 - wa_masked_en(wal, 844 - GEN7_FF_SLICE_CS_CHICKEN1, 845 - GEN9_FFSC_PERCTX_PREEMPT_CTRL); 846 905 } 847 906 848 907 static void icl_gt_workarounds_init(struct drm_i915_private *i915) ··· 846 915 847 916 wa_init_mcr(i915); 848 917 849 - /* This is not an Wa. Enable for better image quality */ 850 - wa_masked_en(wal, 851 - _3D_CHICKEN3, 852 - _3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE); 853 - 854 918 /* WaInPlaceDecompressionHang:icl */ 855 919 wa_write_or(wal, 856 920 GEN9_GAMT_ECO_REG_RW_IA, 857 921 GAMT_ECO_ENABLE_IN_PLACE_DECOMPRESS); 858 - 859 - /* WaPipelineFlushCoherentLines:icl */ 860 - wa_write_or(wal, 861 - GEN8_L3SQCREG4, 862 - GEN8_LQSC_FLUSH_COHERENT_LINES); 863 - 864 - /* Wa_1405543622:icl 865 - * Formerly known as WaGAPZPriorityScheme 866 - */ 867 - wa_write_or(wal, 868 - GEN8_GARBCNTL, 869 - GEN11_ARBITRATION_PRIO_ORDER_MASK); 870 - 871 - /* Wa_1604223664:icl 872 - * Formerly known as WaL3BankAddressHashing 873 - */ 874 - wa_write_masked_or(wal, 875 - GEN8_GARBCNTL, 876 - GEN11_HASH_CTRL_EXCL_MASK, 877 - GEN11_HASH_CTRL_EXCL_BIT0); 878 - wa_write_masked_or(wal, 879 - GEN11_GLBLINVL, 880 - GEN11_BANK_HASH_ADDR_EXCL_MASK, 881 - GEN11_BANK_HASH_ADDR_EXCL_BIT0); 882 922 883 923 /* WaModifyGamTlbPartitioning:icl */ 884 924 wa_write_masked_or(wal, 885 925 GEN11_GACB_PERF_CTRL, 886 926 GEN11_HASH_CTRL_MASK, 887 927 GEN11_HASH_CTRL_BIT0 | GEN11_HASH_CTRL_BIT4); 888 - 889 - /* Wa_1405733216:icl 890 - * Formerly known as WaDisableCleanEvicts 891 - */ 892 - wa_write_or(wal, 893 - GEN8_L3SQCREG4, 894 - GEN11_LQSC_CLEAN_EVICT_DISABLE); 895 928 896 929 /* Wa_1405766107:icl 897 930 * Formerly known as WaCL2SFHalfMaxAlloc ··· 883 988 SUBSLICE_UNIT_LEVEL_CLKGATE, 884 989 GWUNIT_CLKGATE_DIS); 885 990 886 - /* Wa_1604302699:icl */ 887 - wa_write_or(wal, 888 - GEN10_L3_CHICKEN_MODE_REGISTER, 889 - GEN11_I2M_WRITE_DISABLE); 890 - 891 991 /* Wa_1406838659:icl (pre-prod) */ 892 992 if (IS_ICL_REVID(i915, ICL_REVID_A0, ICL_REVID_B0)) 893 993 wa_write_or(wal, 894 994 INF_UNIT_LEVEL_CLKGATE, 895 995 CGPSF_CLKGATE_DIS); 896 - 897 - /* WaForwardProgressSoftReset:icl */ 898 - wa_write_or(wal, 899 - GEN10_SCRATCH_LNCF2, 900 - PMFLUSHDONE_LNICRSDROP | 901 - PMFLUSH_GAPL3UNBLOCK | 902 - PMFLUSHDONE_LNEBLK); 903 996 904 997 /* Wa_1406463099:icl 905 998 * Formerly known as WaGamTlbPendError ··· 1124 1241 struct whitelist w; 1125 1242 1126 1243 whitelist_apply(engine, whitelist_build(engine, &w)); 1244 + } 1245 + 1246 + static void rcs_engine_wa_init(struct intel_engine_cs *engine) 1247 + { 1248 + struct drm_i915_private *i915 = engine->i915; 1249 + struct i915_wa_list *wal = &engine->wa_list; 1250 + 1251 + if (IS_ICELAKE(i915)) { 1252 + /* This is not an Wa. Enable for better image quality */ 1253 + wa_masked_en(wal, 1254 + _3D_CHICKEN3, 1255 + _3D_CHICKEN3_AA_LINE_QUALITY_FIX_ENABLE); 1256 + 1257 + /* WaPipelineFlushCoherentLines:icl */ 1258 + wa_write_or(wal, 1259 + GEN8_L3SQCREG4, 1260 + GEN8_LQSC_FLUSH_COHERENT_LINES); 1261 + 1262 + /* 1263 + * Wa_1405543622:icl 1264 + * Formerly known as WaGAPZPriorityScheme 1265 + */ 1266 + wa_write_or(wal, 1267 + GEN8_GARBCNTL, 1268 + GEN11_ARBITRATION_PRIO_ORDER_MASK); 1269 + 1270 + /* 1271 + * Wa_1604223664:icl 1272 + * Formerly known as WaL3BankAddressHashing 1273 + */ 1274 + wa_write_masked_or(wal, 1275 + GEN8_GARBCNTL, 1276 + GEN11_HASH_CTRL_EXCL_MASK, 1277 + GEN11_HASH_CTRL_EXCL_BIT0); 1278 + wa_write_masked_or(wal, 1279 + GEN11_GLBLINVL, 1280 + GEN11_BANK_HASH_ADDR_EXCL_MASK, 1281 + GEN11_BANK_HASH_ADDR_EXCL_BIT0); 1282 + 1283 + /* 1284 + * Wa_1405733216:icl 1285 + * Formerly known as WaDisableCleanEvicts 1286 + */ 1287 + wa_write_or(wal, 1288 + GEN8_L3SQCREG4, 1289 + GEN11_LQSC_CLEAN_EVICT_DISABLE); 1290 + 1291 + /* Wa_1604302699:icl */ 1292 + wa_write_or(wal, 1293 + GEN10_L3_CHICKEN_MODE_REGISTER, 1294 + GEN11_I2M_WRITE_DISABLE); 1295 + 1296 + /* WaForwardProgressSoftReset:icl */ 1297 + wa_write_or(wal, 1298 + GEN10_SCRATCH_LNCF2, 1299 + PMFLUSHDONE_LNICRSDROP | 1300 + PMFLUSH_GAPL3UNBLOCK | 1301 + PMFLUSHDONE_LNEBLK); 1302 + } 1303 + 1304 + if (IS_GEN9(i915) || IS_CANNONLAKE(i915)) { 1305 + /* WaEnablePreemptionGranularityControlByUMD:skl,bxt,kbl,cfl,cnl */ 1306 + wa_masked_en(wal, 1307 + GEN7_FF_SLICE_CS_CHICKEN1, 1308 + GEN9_FFSC_PERCTX_PREEMPT_CTRL); 1309 + } 1310 + 1311 + if (IS_SKYLAKE(i915) || IS_KABYLAKE(i915) || IS_COFFEELAKE(i915)) { 1312 + /* WaEnableGapsTsvCreditFix:skl,kbl,cfl */ 1313 + wa_write_or(wal, 1314 + GEN8_GARBCNTL, 1315 + GEN9_GAPS_TSV_CREDIT_DISABLE); 1316 + } 1317 + 1318 + if (IS_BROXTON(i915)) { 1319 + /* WaDisablePooledEuLoadBalancingFix:bxt */ 1320 + wa_masked_en(wal, 1321 + FF_SLICE_CS_CHICKEN2, 1322 + GEN9_POOLED_EU_LOAD_BALANCING_FIX_DISABLE); 1323 + } 1324 + 1325 + if (IS_GEN9(i915)) { 1326 + /* WaContextSwitchWithConcurrentTLBInvalidate:skl,bxt,kbl,glk,cfl */ 1327 + wa_masked_en(wal, 1328 + GEN9_CSFE_CHICKEN1_RCS, 1329 + GEN9_PREEMPT_GPGPU_SYNC_SWITCH_DISABLE); 1330 + 1331 + /* WaEnableLbsSlaRetryTimerDecrement:skl,bxt,kbl,glk,cfl */ 1332 + wa_write_or(wal, 1333 + BDW_SCRATCH1, 1334 + GEN9_LBS_SLA_RETRY_TIMER_DECREMENT_ENABLE); 1335 + 1336 + /* WaProgramL3SqcReg1DefaultForPerf:bxt,glk */ 1337 + if (IS_GEN9_LP(i915)) 1338 + wa_write_masked_or(wal, 1339 + GEN8_L3SQCREG1, 1340 + L3_PRIO_CREDITS_MASK, 1341 + L3_GENERAL_PRIO_CREDITS(62) | 1342 + L3_HIGH_PRIO_CREDITS(2)); 1343 + 1344 + /* WaOCLCoherentLineFlush:skl,bxt,kbl,cfl */ 1345 + wa_write_or(wal, 1346 + GEN8_L3SQCREG4, 1347 + GEN8_LQSC_FLUSH_COHERENT_LINES); 1348 + } 1349 + } 1350 + 1351 + static void xcs_engine_wa_init(struct intel_engine_cs *engine) 1352 + { 1353 + struct drm_i915_private *i915 = engine->i915; 1354 + struct i915_wa_list *wal = &engine->wa_list; 1355 + 1356 + /* WaKBLVECSSemaphoreWaitPoll:kbl */ 1357 + if (IS_KBL_REVID(i915, KBL_REVID_A0, KBL_REVID_E0)) { 1358 + wa_write(wal, 1359 + RING_SEMA_WAIT_POLL(engine->mmio_base), 1360 + 1); 1361 + } 1362 + } 1363 + 1364 + void intel_engine_init_workarounds(struct intel_engine_cs *engine) 1365 + { 1366 + struct i915_wa_list *wal = &engine->wa_list; 1367 + 1368 + if (GEM_WARN_ON(INTEL_GEN(engine->i915) < 8)) 1369 + return; 1370 + 1371 + wa_init_start(wal, engine->name); 1372 + 1373 + if (engine->id == RCS) 1374 + rcs_engine_wa_init(engine); 1375 + else 1376 + xcs_engine_wa_init(engine); 1377 + 1378 + wa_init_finish(wal); 1379 + } 1380 + 1381 + void intel_engine_apply_workarounds(struct intel_engine_cs *engine) 1382 + { 1383 + wa_list_apply(engine->i915, &engine->wa_list); 1127 1384 } 1128 1385 1129 1386 #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
+3
drivers/gpu/drm/i915/intel_workarounds.h
··· 35 35 36 36 void intel_whitelist_workarounds_apply(struct intel_engine_cs *engine); 37 37 38 + void intel_engine_init_workarounds(struct intel_engine_cs *engine); 39 + void intel_engine_apply_workarounds(struct intel_engine_cs *engine); 40 + 38 41 #endif