|
@@ -944,8 +944,15 @@ static void hsw_pm_irq_handler(struct drm_i915_private *dev_priv,
|
|
|
}
|
|
|
spin_unlock_irqrestore(&dev_priv->rps.lock, flags);
|
|
|
|
|
|
- if (pm_iir & ~GEN6_PM_RPS_EVENTS)
|
|
|
- DRM_ERROR("Unexpected PM interrupted\n");
|
|
|
+ if (pm_iir & ~GEN6_PM_RPS_EVENTS) {
|
|
|
+ if (pm_iir & PM_VEBOX_USER_INTERRUPT)
|
|
|
+ notify_ring(dev_priv->dev, &dev_priv->ring[VECS]);
|
|
|
+
|
|
|
+ if (pm_iir & PM_VEBOX_CS_ERROR_INTERRUPT) {
|
|
|
+ DRM_ERROR("VEBOX CS error interrupt 0x%08x\n", pm_iir);
|
|
|
+ i915_handle_error(dev_priv->dev, false);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
static irqreturn_t valleyview_irq_handler(int irq, void *arg)
|
|
@@ -2690,6 +2697,7 @@ static int ivybridge_irq_postinstall(struct drm_device *dev)
|
|
|
DE_PLANEA_FLIP_DONE_IVB |
|
|
|
DE_AUX_CHANNEL_A_IVB |
|
|
|
DE_ERR_INT_IVB;
|
|
|
+ u32 pm_irqs = GEN6_PM_RPS_EVENTS;
|
|
|
u32 gt_irqs;
|
|
|
|
|
|
dev_priv->irq_mask = ~display_mask;
|
|
@@ -2715,10 +2723,21 @@ static int ivybridge_irq_postinstall(struct drm_device *dev)
|
|
|
I915_WRITE(GTIER, gt_irqs);
|
|
|
POSTING_READ(GTIER);
|
|
|
|
|
|
- /* Power management */
|
|
|
- I915_WRITE(GEN6_PMIMR, ~GEN6_PM_RPS_EVENTS);
|
|
|
- I915_WRITE(GEN6_PMIER, GEN6_PM_RPS_EVENTS);
|
|
|
- POSTING_READ(GEN6_PMIMR);
|
|
|
+ I915_WRITE(GEN6_PMIIR, I915_READ(GEN6_PMIIR));
|
|
|
+ if (HAS_VEBOX(dev))
|
|
|
+ pm_irqs |= PM_VEBOX_USER_INTERRUPT |
|
|
|
+ PM_VEBOX_CS_ERROR_INTERRUPT;
|
|
|
+
|
|
|
+ /* Our enable/disable rps functions may touch these registers so
|
|
|
+ * make sure to set a known state for only the non-RPS bits.
|
|
|
+ * The RMW is extra paranoia since this should be called after being set
|
|
|
+ * to a known state in preinstall.
|
|
|
+ * */
|
|
|
+ I915_WRITE(GEN6_PMIMR,
|
|
|
+ (I915_READ(GEN6_PMIMR) | ~GEN6_PM_RPS_EVENTS) & ~pm_irqs);
|
|
|
+ I915_WRITE(GEN6_PMIER,
|
|
|
+ (I915_READ(GEN6_PMIER) & GEN6_PM_RPS_EVENTS) | pm_irqs);
|
|
|
+ POSTING_READ(GEN6_PMIER);
|
|
|
|
|
|
ibx_irq_postinstall(dev);
|
|
|
|