|
@@ -1998,10 +1998,38 @@ static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
|
|
|
|
|
|
static u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv)
|
|
static u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv)
|
|
{
|
|
{
|
|
- u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
|
|
|
|
|
|
+ u32 hotplug_status = 0, hotplug_status_mask;
|
|
|
|
+ int i;
|
|
|
|
+
|
|
|
|
+ if (IS_G4X(dev_priv) ||
|
|
|
|
+ IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv))
|
|
|
|
+ hotplug_status_mask = HOTPLUG_INT_STATUS_G4X |
|
|
|
|
+ DP_AUX_CHANNEL_MASK_INT_STATUS_G4X;
|
|
|
|
+ else
|
|
|
|
+ hotplug_status_mask = HOTPLUG_INT_STATUS_I915;
|
|
|
|
|
|
- if (hotplug_status)
|
|
|
|
|
|
+ /*
|
|
|
|
+ * We absolutely have to clear all the pending interrupt
|
|
|
|
+ * bits in PORT_HOTPLUG_STAT. Otherwise the ISR port
|
|
|
|
+ * interrupt bit won't have an edge, and the i965/g4x
|
|
|
|
+ * edge triggered IIR will not notice that an interrupt
|
|
|
|
+ * is still pending. We can't use PORT_HOTPLUG_EN to
|
|
|
|
+ * guarantee the edge as the act of toggling the enable
|
|
|
|
+ * bits can itself generate a new hotplug interrupt :(
|
|
|
|
+ */
|
|
|
|
+ for (i = 0; i < 10; i++) {
|
|
|
|
+ u32 tmp = I915_READ(PORT_HOTPLUG_STAT) & hotplug_status_mask;
|
|
|
|
+
|
|
|
|
+ if (tmp == 0)
|
|
|
|
+ return hotplug_status;
|
|
|
|
+
|
|
|
|
+ hotplug_status |= tmp;
|
|
I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
|
|
I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ WARN_ONCE(1,
|
|
|
|
+ "PORT_HOTPLUG_STAT did not clear (0x%08x)\n",
|
|
|
|
+ I915_READ(PORT_HOTPLUG_STAT));
|
|
|
|
|
|
return hotplug_status;
|
|
return hotplug_status;
|
|
}
|
|
}
|