diff options
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_reg.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_guc_loader.c | 27 |
4 files changed, 25 insertions, 9 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 1e2dda88a483..d01a50e8e57c 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1184,6 +1184,7 @@ struct intel_gen6_power_mgmt { | |||
1184 | bool interrupts_enabled; | 1184 | bool interrupts_enabled; |
1185 | u32 pm_iir; | 1185 | u32 pm_iir; |
1186 | 1186 | ||
1187 | /* PM interrupt bits that should never be masked */ | ||
1187 | u32 pm_intr_keep; | 1188 | u32 pm_intr_keep; |
1188 | 1189 | ||
1189 | /* Frequencies are stored in potentially platform dependent multiples. | 1190 | /* Frequencies are stored in potentially platform dependent multiples. |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 8462817a7dae..c128fdbd24e4 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -371,7 +371,7 @@ void gen6_disable_rps_interrupts(struct drm_i915_private *dev_priv) | |||
371 | spin_lock_irq(&dev_priv->irq_lock); | 371 | spin_lock_irq(&dev_priv->irq_lock); |
372 | dev_priv->rps.interrupts_enabled = false; | 372 | dev_priv->rps.interrupts_enabled = false; |
373 | 373 | ||
374 | I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0)); | 374 | I915_WRITE(GEN6_PMINTRMSK, gen6_sanitize_rps_pm_mask(dev_priv, ~0u)); |
375 | 375 | ||
376 | __gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events); | 376 | __gen6_disable_pm_irq(dev_priv, dev_priv->pm_rps_events); |
377 | I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & | 377 | I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & |
@@ -4500,7 +4500,7 @@ void intel_irq_init(struct drm_i915_private *dev_priv) | |||
4500 | dev_priv->rps.pm_intr_keep |= GEN6_PM_RP_UP_EI_EXPIRED; | 4500 | dev_priv->rps.pm_intr_keep |= GEN6_PM_RP_UP_EI_EXPIRED; |
4501 | 4501 | ||
4502 | if (INTEL_INFO(dev_priv)->gen >= 8) | 4502 | if (INTEL_INFO(dev_priv)->gen >= 8) |
4503 | dev_priv->rps.pm_intr_keep |= GEN8_PMINTR_REDIRECT_TO_NON_DISP; | 4503 | dev_priv->rps.pm_intr_keep |= GEN8_PMINTR_REDIRECT_TO_GUC; |
4504 | 4504 | ||
4505 | INIT_DELAYED_WORK(&dev_priv->gpu_error.hangcheck_work, | 4505 | INIT_DELAYED_WORK(&dev_priv->gpu_error.hangcheck_work, |
4506 | i915_hangcheck_elapsed); | 4506 | i915_hangcheck_elapsed); |
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h index a29d707f0932..70d96162def6 100644 --- a/drivers/gpu/drm/i915/i915_reg.h +++ b/drivers/gpu/drm/i915/i915_reg.h | |||
@@ -7067,7 +7067,7 @@ enum { | |||
7067 | #define VLV_RCEDATA _MMIO(0xA0BC) | 7067 | #define VLV_RCEDATA _MMIO(0xA0BC) |
7068 | #define GEN6_RC6pp_THRESHOLD _MMIO(0xA0C0) | 7068 | #define GEN6_RC6pp_THRESHOLD _MMIO(0xA0C0) |
7069 | #define GEN6_PMINTRMSK _MMIO(0xA168) | 7069 | #define GEN6_PMINTRMSK _MMIO(0xA168) |
7070 | #define GEN8_PMINTR_REDIRECT_TO_NON_DISP (1<<31) | 7070 | #define GEN8_PMINTR_REDIRECT_TO_GUC (1<<31) |
7071 | #define GEN8_MISC_CTRL0 _MMIO(0xA180) | 7071 | #define GEN8_MISC_CTRL0 _MMIO(0xA180) |
7072 | #define VLV_PWRDWNUPCTL _MMIO(0xA294) | 7072 | #define VLV_PWRDWNUPCTL _MMIO(0xA294) |
7073 | #define GEN9_MEDIA_PG_IDLE_HYSTERESIS _MMIO(0xA0C4) | 7073 | #define GEN9_MEDIA_PG_IDLE_HYSTERESIS _MMIO(0xA0C4) |
diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index 853928f21596..00217481f1fa 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c | |||
@@ -134,13 +134,28 @@ static void direct_interrupts_to_guc(struct drm_i915_private *dev_priv) | |||
134 | I915_WRITE(GUC_WD_VECS_IER, ~irqs); | 134 | I915_WRITE(GUC_WD_VECS_IER, ~irqs); |
135 | 135 | ||
136 | /* | 136 | /* |
137 | * If GuC has routed PM interrupts to itself, don't keep it. | 137 | * The REDIRECT_TO_GUC bit of the PMINTRMSK register directs all |
138 | * and keep other interrupts those are unmasked by GuC. | 138 | * (unmasked) PM interrupts to the GuC. All other bits of this |
139 | */ | 139 | * register *disable* generation of a specific interrupt. |
140 | * | ||
141 | * 'pm_intr_keep' indicates bits that are NOT to be set when | ||
142 | * writing to the PM interrupt mask register, i.e. interrupts | ||
143 | * that must not be disabled. | ||
144 | * | ||
145 | * If the GuC is handling these interrupts, then we must not let | ||
146 | * the PM code disable ANY interrupt that the GuC is expecting. | ||
147 | * So for each ENABLED (0) bit in this register, we must SET the | ||
148 | * bit in pm_intr_keep so that it's left enabled for the GuC. | ||
149 | * | ||
150 | * OTOH the REDIRECT_TO_GUC bit is initially SET in pm_intr_keep | ||
151 | * (so interrupts go to the DISPLAY unit at first); but here we | ||
152 | * need to CLEAR that bit, which will result in the register bit | ||
153 | * being left SET! | ||
154 | */ | ||
140 | tmp = I915_READ(GEN6_PMINTRMSK); | 155 | tmp = I915_READ(GEN6_PMINTRMSK); |
141 | if (tmp & GEN8_PMINTR_REDIRECT_TO_NON_DISP) { | 156 | if (tmp & GEN8_PMINTR_REDIRECT_TO_GUC) { |
142 | dev_priv->rps.pm_intr_keep |= ~(tmp & ~GEN8_PMINTR_REDIRECT_TO_NON_DISP); | 157 | dev_priv->rps.pm_intr_keep |= ~tmp; |
143 | dev_priv->rps.pm_intr_keep &= ~GEN8_PMINTR_REDIRECT_TO_NON_DISP; | 158 | dev_priv->rps.pm_intr_keep &= ~GEN8_PMINTR_REDIRECT_TO_GUC; |
144 | } | 159 | } |
145 | } | 160 | } |
146 | 161 | ||