Commit 1ae3c34c authored by Ville Syrjälä's avatar Ville Syrjälä

drm/i915: Split PORT_HOTPLUG_STAT ack out from i9xx_hpd_irq_handler()

Split the VLV/CHV hoplug irq handling to ack and handler phases. This
way we can move the actual irq handling outside the section where
we have disabled the interrupt sources.

For now, we leave things as is for pre-VLV GMCH platforms, but
eventually they could get the same treatment.
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1460571598-24452-9-git-send-email-ville.syrjala@linux.intel.comReviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 6e814800
...@@ -1723,21 +1723,20 @@ static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir) ...@@ -1723,21 +1723,20 @@ static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir)
gmbus_irq_handler(dev); gmbus_irq_handler(dev);
} }
static void i9xx_hpd_irq_handler(struct drm_device *dev) static u32 i9xx_hpd_irq_ack(struct drm_i915_private *dev_priv)
{ {
struct drm_i915_private *dev_priv = dev->dev_private;
u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT); u32 hotplug_status = I915_READ(PORT_HOTPLUG_STAT);
u32 pin_mask = 0, long_mask = 0;
if (!hotplug_status) if (hotplug_status)
return; I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status);
I915_WRITE(PORT_HOTPLUG_STAT, hotplug_status); return hotplug_status;
/* }
* Make sure hotplug status is cleared before we clear IIR, or else we
* may miss hotplug events. static void i9xx_hpd_irq_handler(struct drm_device *dev,
*/ u32 hotplug_status)
POSTING_READ(PORT_HOTPLUG_STAT); {
u32 pin_mask = 0, long_mask = 0;
if (IS_G4X(dev) || IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) { if (IS_G4X(dev) || IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_G4X; u32 hotplug_trigger = hotplug_status & HOTPLUG_INT_STATUS_G4X;
...@@ -1778,6 +1777,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) ...@@ -1778,6 +1777,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
do { do {
u32 iir, gt_iir, pm_iir; u32 iir, gt_iir, pm_iir;
u32 hotplug_status = 0;
u32 ier = 0; u32 ier = 0;
gt_iir = I915_READ(GTIIR); gt_iir = I915_READ(GTIIR);
...@@ -1817,7 +1817,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) ...@@ -1817,7 +1817,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
gen6_rps_irq_handler(dev_priv, pm_iir); gen6_rps_irq_handler(dev_priv, pm_iir);
if (iir & I915_DISPLAY_PORT_INTERRUPT) if (iir & I915_DISPLAY_PORT_INTERRUPT)
i9xx_hpd_irq_handler(dev); hotplug_status = i9xx_hpd_irq_ack(dev_priv);
/* Call regardless, as some status bits might not be /* Call regardless, as some status bits might not be
* signalled in iir */ * signalled in iir */
...@@ -1833,6 +1833,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg) ...@@ -1833,6 +1833,9 @@ static irqreturn_t valleyview_irq_handler(int irq, void *arg)
I915_WRITE(VLV_IER, ier); I915_WRITE(VLV_IER, ier);
I915_WRITE(VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); I915_WRITE(VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE);
POSTING_READ(VLV_MASTER_IER); POSTING_READ(VLV_MASTER_IER);
if (hotplug_status)
i9xx_hpd_irq_handler(dev, hotplug_status);
} while (0); } while (0);
enable_rpm_wakeref_asserts(dev_priv); enable_rpm_wakeref_asserts(dev_priv);
...@@ -1854,6 +1857,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) ...@@ -1854,6 +1857,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
do { do {
u32 master_ctl, iir; u32 master_ctl, iir;
u32 hotplug_status = 0;
u32 ier = 0; u32 ier = 0;
master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL; master_ctl = I915_READ(GEN8_MASTER_IRQ) & ~GEN8_MASTER_IRQ_CONTROL;
...@@ -1884,7 +1888,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) ...@@ -1884,7 +1888,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
gen8_gt_irq_handler(dev_priv, master_ctl); gen8_gt_irq_handler(dev_priv, master_ctl);
if (iir & I915_DISPLAY_PORT_INTERRUPT) if (iir & I915_DISPLAY_PORT_INTERRUPT)
i9xx_hpd_irq_handler(dev); hotplug_status = i9xx_hpd_irq_ack(dev_priv);
/* Call regardless, as some status bits might not be /* Call regardless, as some status bits might not be
* signalled in iir */ * signalled in iir */
...@@ -1900,6 +1904,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg) ...@@ -1900,6 +1904,9 @@ static irqreturn_t cherryview_irq_handler(int irq, void *arg)
I915_WRITE(VLV_IER, ier); I915_WRITE(VLV_IER, ier);
I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL); I915_WRITE(GEN8_MASTER_IRQ, GEN8_MASTER_IRQ_CONTROL);
POSTING_READ(GEN8_MASTER_IRQ); POSTING_READ(GEN8_MASTER_IRQ);
if (hotplug_status)
i9xx_hpd_irq_handler(dev, hotplug_status);
} while (0); } while (0);
enable_rpm_wakeref_asserts(dev_priv); enable_rpm_wakeref_asserts(dev_priv);
...@@ -4240,8 +4247,11 @@ static irqreturn_t i915_irq_handler(int irq, void *arg) ...@@ -4240,8 +4247,11 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
/* Consume port. Then clear IIR or we'll miss events */ /* Consume port. Then clear IIR or we'll miss events */
if (I915_HAS_HOTPLUG(dev) && if (I915_HAS_HOTPLUG(dev) &&
iir & I915_DISPLAY_PORT_INTERRUPT) iir & I915_DISPLAY_PORT_INTERRUPT) {
i9xx_hpd_irq_handler(dev); u32 hotplug_status = i9xx_hpd_irq_ack(dev_priv);
if (hotplug_status)
i9xx_hpd_irq_handler(dev, hotplug_status);
}
I915_WRITE(IIR, iir & ~flip_mask); I915_WRITE(IIR, iir & ~flip_mask);
new_iir = I915_READ(IIR); /* Flush posted writes */ new_iir = I915_READ(IIR); /* Flush posted writes */
...@@ -4470,8 +4480,11 @@ static irqreturn_t i965_irq_handler(int irq, void *arg) ...@@ -4470,8 +4480,11 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
ret = IRQ_HANDLED; ret = IRQ_HANDLED;
/* Consume port. Then clear IIR or we'll miss events */ /* Consume port. Then clear IIR or we'll miss events */
if (iir & I915_DISPLAY_PORT_INTERRUPT) if (iir & I915_DISPLAY_PORT_INTERRUPT) {
i9xx_hpd_irq_handler(dev); u32 hotplug_status = i9xx_hpd_irq_ack(dev_priv);
if (hotplug_status)
i9xx_hpd_irq_handler(dev, hotplug_status);
}
I915_WRITE(IIR, iir & ~flip_mask); I915_WRITE(IIR, iir & ~flip_mask);
new_iir = I915_READ(IIR); /* Flush posted writes */ new_iir = I915_READ(IIR); /* Flush posted writes */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment