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

Configure Feed

Select the types of activity you want to include in your feed.

drm/i915/gen8+: Add RC6 CTX corruption WA

In some circumstances the RC6 context can get corrupted. We can detect
this and take the required action, that is disable RC6 and runtime PM.
The HW recovers from the corrupted state after a system suspend/resume
cycle, so detect the recovery and re-enable RC6 and runtime PM.

v2: rebase (Mika)
v3:
- Move intel_suspend_gt_powersave() to the end of the GEM suspend
sequence.
- Add commit message.
v4:
- Rebased on intel_uncore_forcewake_put(i915->uncore, ...) API
change.
v5:
- Rebased on latest upstream gt_pm refactoring.
v6:
- s/i915_rc6_/intel_rc6_/
- Don't return a value from i915_rc6_ctx_wa_check().
v7:
- Rebased on latest gt rc6 refactoring.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Mika Kuoppala <mika.kuoppala@linux.intel.com>
[airlied: pull this later version of this patch into drm-next
to make resolving the conflict mess easier.]
Signed-off-by: Dave Airlie <airlied@redhat.com>

authored by

Imre Deak and committed by
Dave Airlie
2248a283 94bc7f56

+86 -2
+8
drivers/gpu/drm/i915/gt/intel_gt_pm.c
··· 61 61 gt->awake = intel_display_power_get(i915, POWER_DOMAIN_GT_IRQ); 62 62 GEM_BUG_ON(!gt->awake); 63 63 64 + if (NEEDS_RC6_CTX_CORRUPTION_WA(i915)) 65 + intel_uncore_forcewake_get(&i915->uncore, FORCEWAKE_ALL); 66 + 64 67 intel_rps_unpark(&gt->rps); 65 68 i915_pmu_gt_unparked(i915); 66 69 ··· 88 85 89 86 /* Everything switched off, flush any residual interrupt just in case */ 90 87 intel_synchronize_irq(i915); 88 + 89 + if (NEEDS_RC6_CTX_CORRUPTION_WA(i915)) { 90 + intel_rc6_ctx_wa_check(&i915->gt.rc6); 91 + intel_uncore_forcewake_put(&i915->uncore, FORCEWAKE_ALL); 92 + } 91 93 92 94 GEM_BUG_ON(!wakeref); 93 95 intel_display_power_put(i915, POWER_DOMAIN_GT_IRQ, wakeref);
+65
drivers/gpu/drm/i915/gt/intel_rc6.c
··· 486 486 rc6->wakeref = false; 487 487 } 488 488 489 + static bool intel_rc6_ctx_corrupted(struct intel_rc6 *rc6) 490 + { 491 + return !intel_uncore_read(rc6_to_uncore(rc6), GEN8_RC6_CTX_INFO); 492 + } 493 + 494 + static void intel_rc6_ctx_wa_init(struct intel_rc6 *rc6) 495 + { 496 + struct drm_i915_private *i915 = rc6_to_i915(rc6); 497 + 498 + if (!NEEDS_RC6_CTX_CORRUPTION_WA(i915)) 499 + return; 500 + 501 + if (intel_rc6_ctx_corrupted(rc6)) { 502 + DRM_INFO("RC6 context corrupted, disabling runtime power management\n"); 503 + rc6->ctx_corrupted = true; 504 + } 505 + } 506 + 507 + /** 508 + * intel_rc6_ctx_wa_resume - system resume sequence for the RC6 CTX WA 509 + * @rc6: rc6 state 510 + * 511 + * Perform any steps needed to re-init the RC6 CTX WA after system resume. 512 + */ 513 + void intel_rc6_ctx_wa_resume(struct intel_rc6 *rc6) 514 + { 515 + if (rc6->ctx_corrupted && !intel_rc6_ctx_corrupted(rc6)) { 516 + DRM_INFO("RC6 context restored, re-enabling runtime power management\n"); 517 + rc6->ctx_corrupted = false; 518 + } 519 + } 520 + 521 + /** 522 + * intel_rc6_ctx_wa_check - check for a new RC6 CTX corruption 523 + * @rc6: rc6 state 524 + * 525 + * Check if an RC6 CTX corruption has happened since the last check and if so 526 + * disable RC6 and runtime power management. 527 + */ 528 + void intel_rc6_ctx_wa_check(struct intel_rc6 *rc6) 529 + { 530 + struct drm_i915_private *i915 = rc6_to_i915(rc6); 531 + 532 + if (!NEEDS_RC6_CTX_CORRUPTION_WA(i915)) 533 + return; 534 + 535 + if (rc6->ctx_corrupted) 536 + return; 537 + 538 + if (!intel_rc6_ctx_corrupted(rc6)) 539 + return; 540 + 541 + DRM_NOTE("RC6 context corruption, disabling runtime power management\n"); 542 + 543 + intel_rc6_disable(rc6); 544 + rc6->ctx_corrupted = true; 545 + 546 + return; 547 + } 548 + 489 549 static void __intel_rc6_disable(struct intel_rc6 *rc6) 490 550 { 491 551 struct drm_i915_private *i915 = rc6_to_i915(rc6); ··· 569 509 570 510 if (!rc6_supported(rc6)) 571 511 return; 512 + 513 + intel_rc6_ctx_wa_init(rc6); 572 514 573 515 if (IS_CHERRYVIEW(i915)) 574 516 err = chv_rc6_init(rc6); ··· 605 543 return; 606 544 607 545 GEM_BUG_ON(rc6->enabled); 546 + 547 + if (rc6->ctx_corrupted) 548 + return; 608 549 609 550 intel_uncore_forcewake_get(uncore, FORCEWAKE_ALL); 610 551
+3
drivers/gpu/drm/i915/gt/intel_rc6.h
··· 22 22 u64 intel_rc6_residency_ns(struct intel_rc6 *rc6, i915_reg_t reg); 23 23 u64 intel_rc6_residency_us(struct intel_rc6 *rc6, i915_reg_t reg); 24 24 25 + void intel_rc6_ctx_wa_check(struct intel_rc6 *rc6); 26 + void intel_rc6_ctx_wa_resume(struct intel_rc6 *rc6); 27 + 25 28 #endif /* INTEL_RC6_H */
+1
drivers/gpu/drm/i915/gt/intel_rc6_types.h
··· 23 23 bool supported : 1; 24 24 bool enabled : 1; 25 25 bool wakeref : 1; 26 + bool ctx_corrupted : 1; 26 27 }; 27 28 28 29 #endif /* INTEL_RC6_TYPES_H */
+3
drivers/gpu/drm/i915/i915_drv.c
··· 63 63 #include "gem/i915_gem_ioctls.h" 64 64 #include "gt/intel_gt.h" 65 65 #include "gt/intel_gt_pm.h" 66 + #include "gt/intel_rc6.h" 66 67 67 68 #include "i915_debugfs.h" 68 69 #include "i915_drv.h" ··· 1819 1818 int ret; 1820 1819 1821 1820 disable_rpm_wakeref_asserts(&dev_priv->runtime_pm); 1821 + 1822 + intel_rc6_ctx_wa_resume(&dev_priv->gt.rc6); 1822 1823 1823 1824 intel_gt_sanitize(&dev_priv->gt, true); 1824 1825
+4 -2
drivers/gpu/drm/i915/i915_drv.h
··· 1649 1649 /* Early gen2 have a totally busted CS tlb and require pinned batches. */ 1650 1650 #define HAS_BROKEN_CS_TLB(dev_priv) (IS_I830(dev_priv) || IS_I845G(dev_priv)) 1651 1651 1652 + #define NEEDS_RC6_CTX_CORRUPTION_WA(dev_priv) \ 1653 + (IS_BROADWELL(dev_priv) || IS_GEN(dev_priv, 9)) 1654 + 1652 1655 /* WaRsDisableCoarsePowerGating:skl,cnl */ 1653 1656 #define NEEDS_WaRsDisableCoarsePowerGating(dev_priv) \ 1654 - (IS_CANNONLAKE(dev_priv) || \ 1655 - IS_SKL_GT3(dev_priv) || IS_SKL_GT4(dev_priv)) 1657 + (IS_CANNONLAKE(dev_priv) || IS_GEN(dev_priv, 9)) 1656 1658 1657 1659 #define HAS_GMBUS_IRQ(dev_priv) (INTEL_GEN(dev_priv) >= 4) 1658 1660 #define HAS_GMBUS_BURST_READ(dev_priv) (INTEL_GEN(dev_priv) >= 10 || \
+2
drivers/gpu/drm/i915/i915_reg.h
··· 474 474 #define ECOCHK_PPGTT_WT_HSW (0x2 << 3) 475 475 #define ECOCHK_PPGTT_WB_HSW (0x3 << 3) 476 476 477 + #define GEN8_RC6_CTX_INFO _MMIO(0x8504) 478 + 477 479 #define GAC_ECO_BITS _MMIO(0x14090) 478 480 #define ECOBITS_SNB_BIT (1 << 13) 479 481 #define ECOBITS_PPGTT_CACHE64B (3 << 8)