mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2025-01-19 03:26:23 +07:00
drm/i915: mask RPS IRQs properly when disabling RPS
Atm, igt/gem_reset_stats can trigger the recently added WARN on left-over PM_IIR bits in gen6_enable_rps_interrupts(). There are two reasons for this: 1. we call intel_enable_gt_powersave() without a preceeding intel_disable_gt_powersave() 2. gen6_disable_rps_interrupts() doesn't mask interrupts in PM_IMR 1. means RPS interrupts will remain enabled and can be serviced during the HW initialization after a GPU reset. 2. means even if we called gen6_disable_rps_interrupts() any new RPS interrupt during RPS initialization would still propagate to PM_IIR too early (though wouldn't be serviced). This patch solves the 2. issue by also masking interrupts in PM_IMR, the following patch fixes 1. getting rid of the WARN. This also makes intel_enable_gt_powersave() and intel_disable_gt_powersave() more symmetric. Since gen6_disable_rps_interrupts() is called during driver loading with i915 interrupts disabled add a new version of gen6_disable_pm_irq() that doesn't WARN for this. Also while at it, get the irq_lock around the whole PM_IMR/IER/IIR programming sequence and make sure that any queued PM_IIR bit is also cleared. The WARN was caught by PRTS after I sent my previous RPS sanitizing patchset and I could easily reproduce it on HSW. To actually fix it we also need the next patch. Reported-by: He, Shuang <shuang.he@intel.com> Signed-off-by: Imre Deak <imre.deak@intel.com> Reviewed-by: Paulo Zanoni <paulo.r.zanoni@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
This commit is contained in:
parent
34273620d9
commit
9939fba226
@ -231,9 +231,6 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv,
|
||||
|
||||
assert_spin_locked(&dev_priv->irq_lock);
|
||||
|
||||
if (WARN_ON(!intel_irqs_enabled(dev_priv)))
|
||||
return;
|
||||
|
||||
new_val = dev_priv->pm_irq_mask;
|
||||
new_val &= ~interrupt_mask;
|
||||
new_val |= (~enabled_irq_mask & interrupt_mask);
|
||||
@ -247,12 +244,24 @@ static void snb_update_pm_irq(struct drm_i915_private *dev_priv,
|
||||
|
||||
void gen6_enable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
|
||||
{
|
||||
if (WARN_ON(!intel_irqs_enabled(dev_priv)))
|
||||
return;
|
||||
|
||||
snb_update_pm_irq(dev_priv, mask, mask);
|
||||
}
|
||||
|
||||
static void __gen6_disable_pm_irq(struct drm_i915_private *dev_priv,
|
||||
uint32_t mask)
|
||||
{
|
||||
snb_update_pm_irq(dev_priv, mask, 0);
|
||||
}
|
||||
|
||||
void gen6_disable_pm_irq(struct drm_i915_private *dev_priv, uint32_t mask)
|
||||
{
|
||||
snb_update_pm_irq(dev_priv, mask, 0);
|
||||
if (WARN_ON(!intel_irqs_enabled(dev_priv)))
|
||||
return;
|
||||
|
||||
__gen6_disable_pm_irq(dev_priv, mask);
|
||||
}
|
||||
|
||||
void gen6_reset_rps_interrupts(struct drm_device *dev)
|
||||
@ -289,16 +298,20 @@ void gen6_disable_rps_interrupts(struct drm_device *dev)
|
||||
|
||||
cancel_work_sync(&dev_priv->rps.work);
|
||||
|
||||
spin_lock_irq(&dev_priv->irq_lock);
|
||||
|
||||
I915_WRITE(GEN6_PMINTRMSK, INTEL_INFO(dev_priv)->gen >= 8 ?
|
||||
~GEN8_PMINTR_REDIRECT_TO_NON_DISP : ~0);
|
||||
|
||||
__gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events);
|
||||
I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) &
|
||||
~dev_priv->pm_rps_events);
|
||||
|
||||
spin_lock_irq(&dev_priv->irq_lock);
|
||||
dev_priv->rps.pm_iir = 0;
|
||||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
|
||||
I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events);
|
||||
I915_WRITE(gen6_pm_iir(dev_priv), dev_priv->pm_rps_events);
|
||||
|
||||
dev_priv->rps.pm_iir = 0;
|
||||
|
||||
spin_unlock_irq(&dev_priv->irq_lock);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user