From: Ville Syrjälä <ville.syrj...@linux.intel.com>

Extract the gen2-4 PIPESTAT irq handling into separate functions just
like we already do on VLV/CHV.

We can share valleyview_pipestat_irq_ack() on all gmch platforms to
actually read and clear the PIPESTAT status bits, so let's rename
it to i9xx_pipestat_irq_ack().

Signed-off-by: Ville Syrjälä <ville.syrj...@linux.intel.com>
---
 drivers/gpu/drm/i915/i915_irq.c | 219 ++++++++++++++++++----------------------
 1 file changed, 99 insertions(+), 120 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b75b0790e9df..f00e20902e1c 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1841,8 +1841,8 @@ static void i9xx_pipestat_irq_reset(struct 
drm_i915_private *dev_priv)
        }
 }
 
-static void valleyview_pipestat_irq_ack(struct drm_i915_private *dev_priv,
-                                       u32 iir, u32 pipe_stats[I915_MAX_PIPES])
+static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
+                                 u32 iir, u32 pipe_stats[I915_MAX_PIPES])
 {
        int pipe;
 
@@ -1899,6 +1899,82 @@ static void valleyview_pipestat_irq_ack(struct 
drm_i915_private *dev_priv,
        spin_unlock(&dev_priv->irq_lock);
 }
 
+static void i8xx_pipestat_irq_handler(struct drm_i915_private *dev_priv,
+                                     u16 iir, u32 pipe_stats[I915_MAX_PIPES])
+{
+       enum pipe pipe;
+
+       for_each_pipe(dev_priv, pipe) {
+               enum plane plane = pipe;
+               if (HAS_FBC(dev_priv))
+                       plane = !plane;
+
+               if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
+                       i8xx_handle_vblank(dev_priv, plane, pipe, iir);
+
+               if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
+                       i9xx_pipe_crc_irq_handler(dev_priv, pipe);
+
+               if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
+                       intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
+       }
+}
+
+static void i915_pipestat_irq_handler(struct drm_i915_private *dev_priv,
+                                     u32 iir, u32 pipe_stats[I915_MAX_PIPES])
+{
+       bool blc_event = false;
+       enum pipe pipe;
+
+       for_each_pipe(dev_priv, pipe) {
+               enum plane plane = pipe;
+               if (HAS_FBC(dev_priv))
+                       plane = !plane;
+
+               if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
+                       i915_handle_vblank(dev_priv, plane, pipe, iir);
+
+               if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
+                       blc_event = true;
+
+               if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
+                       i9xx_pipe_crc_irq_handler(dev_priv, pipe);
+
+               if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
+                       intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
+       }
+
+       if (blc_event || (iir & I915_ASLE_INTERRUPT))
+               intel_opregion_asle_intr(dev_priv);
+}
+
+static void i965_pipestat_irq_handler(struct drm_i915_private *dev_priv,
+                                     u32 iir, u32 pipe_stats[I915_MAX_PIPES])
+{
+       bool blc_event = false;
+       enum pipe pipe;
+
+       for_each_pipe(dev_priv, pipe) {
+               if (pipe_stats[pipe] & PIPE_START_VBLANK_INTERRUPT_STATUS)
+                       i915_handle_vblank(dev_priv, pipe, pipe, iir);
+
+               if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
+                       blc_event = true;
+
+               if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
+                       i9xx_pipe_crc_irq_handler(dev_priv, pipe);
+
+               if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
+                       intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe);
+       }
+
+       if (blc_event || (iir & I915_ASLE_INTERRUPT))
+               intel_opregion_asle_intr(dev_priv);
+
+       if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS)
+               gmbus_irq_handler(dev_priv);
+}
+
 static void valleyview_pipestat_irq_handler(struct drm_i915_private *dev_priv,
                                            u32 pipe_stats[I915_MAX_PIPES])
 {
@@ -2017,7 +2093,7 @@ static irqreturn_t valleyview_irq_handler(int irq, void 
*arg)
 
                /* Call regardless, as some status bits might not be
                 * signalled in iir */
-               valleyview_pipestat_irq_ack(dev_priv, iir, pipe_stats);
+               i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats);
 
                if (iir & (I915_LPE_PIPE_A_INTERRUPT |
                           I915_LPE_PIPE_B_INTERRUPT))
@@ -2101,7 +2177,7 @@ static irqreturn_t cherryview_irq_handler(int irq, void 
*arg)
 
                /* Call regardless, as some status bits might not be
                 * signalled in iir */
-               valleyview_pipestat_irq_ack(dev_priv, iir, pipe_stats);
+               i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats);
 
                if (iir & (I915_LPE_PIPE_A_INTERRUPT |
                           I915_LPE_PIPE_B_INTERRUPT |
@@ -3685,8 +3761,6 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
        struct drm_device *dev = arg;
        struct drm_i915_private *dev_priv = to_i915(dev);
        u16 iir, new_iir;
-       u32 pipe_stats[2];
-       int pipe;
        const u16 flip_mask =
                I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
                I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
@@ -3704,26 +3778,14 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
                goto out;
 
        while (iir & ~flip_mask) {
-               /* Can't rely on pipestat interrupt bit in iir as it might
-                * have been cleared after the pipestat interrupt was received.
-                * It doesn't set the bit in iir again, but it still produces
-                * interrupts (for non-MSI).
-                */
-               spin_lock(&dev_priv->irq_lock);
+               u32 pipe_stats[I915_MAX_PIPES] = {};
+
                if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
                        DRM_DEBUG("Command parser error, iir 0x%08x\n", iir);
 
-               for_each_pipe(dev_priv, pipe) {
-                       i915_reg_t reg = PIPESTAT(pipe);
-                       pipe_stats[pipe] = I915_READ(reg);
-
-                       /*
-                        * Clear the PIPE*STAT regs before the IIR
-                        */
-                       if (pipe_stats[pipe] & 0x8000ffff)
-                               I915_WRITE(reg, pipe_stats[pipe]);
-               }
-               spin_unlock(&dev_priv->irq_lock);
+               /* Call regardless, as some status bits might not be
+                * signalled in iir */
+               i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats);
 
                I915_WRITE16(IIR, iir & ~flip_mask);
                new_iir = I915_READ16(IIR); /* Flush posted writes */
@@ -3731,21 +3793,7 @@ static irqreturn_t i8xx_irq_handler(int irq, void *arg)
                if (iir & I915_USER_INTERRUPT)
                        notify_ring(dev_priv->engine[RCS]);
 
-               for_each_pipe(dev_priv, pipe) {
-                       int plane = pipe;
-                       if (HAS_FBC(dev_priv))
-                               plane = !plane;
-
-                       if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
-                               i8xx_handle_vblank(dev_priv, plane, pipe, iir);
-
-                       if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
-                               i9xx_pipe_crc_irq_handler(dev_priv, pipe);
-
-                       if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
-                               intel_cpu_fifo_underrun_irq_handler(dev_priv,
-                                                                   pipe);
-               }
+               i8xx_pipestat_irq_handler(dev_priv, iir, pipe_stats);
 
                iir = new_iir;
        }
@@ -3820,11 +3868,11 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
 {
        struct drm_device *dev = arg;
        struct drm_i915_private *dev_priv = to_i915(dev);
-       u32 iir, new_iir, pipe_stats[I915_MAX_PIPES];
+       u32 iir, new_iir;
        const u32 flip_mask =
                I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
                I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
-       int pipe, ret = IRQ_NONE;
+       int ret = IRQ_NONE;
 
        if (!intel_irqs_enabled(dev_priv))
                return IRQ_NONE;
@@ -3834,29 +3882,15 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
 
        iir = I915_READ(IIR);
        do {
+               u32 pipe_stats[I915_MAX_PIPES] = {};
                bool irq_received = (iir & ~flip_mask) != 0;
-               bool blc_event = false;
 
-               /* Can't rely on pipestat interrupt bit in iir as it might
-                * have been cleared after the pipestat interrupt was received.
-                * It doesn't set the bit in iir again, but it still produces
-                * interrupts (for non-MSI).
-                */
-               spin_lock(&dev_priv->irq_lock);
                if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
                        DRM_DEBUG("Command parser error, iir 0x%08x\n", iir);
 
-               for_each_pipe(dev_priv, pipe) {
-                       i915_reg_t reg = PIPESTAT(pipe);
-                       pipe_stats[pipe] = I915_READ(reg);
-
-                       /* Clear the PIPE*STAT regs before the IIR */
-                       if (pipe_stats[pipe] & 0x8000ffff) {
-                               I915_WRITE(reg, pipe_stats[pipe]);
-                               irq_received = true;
-                       }
-               }
-               spin_unlock(&dev_priv->irq_lock);
+               /* Call regardless, as some status bits might not be
+                * signalled in iir */
+               i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats);
 
                if (!irq_received)
                        break;
@@ -3875,27 +3909,7 @@ static irqreturn_t i915_irq_handler(int irq, void *arg)
                if (iir & I915_USER_INTERRUPT)
                        notify_ring(dev_priv->engine[RCS]);
 
-               for_each_pipe(dev_priv, pipe) {
-                       int plane = pipe;
-                       if (HAS_FBC(dev_priv))
-                               plane = !plane;
-
-                       if (pipe_stats[pipe] & PIPE_VBLANK_INTERRUPT_STATUS)
-                               i915_handle_vblank(dev_priv, plane, pipe, iir);
-
-                       if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
-                               blc_event = true;
-
-                       if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
-                               i9xx_pipe_crc_irq_handler(dev_priv, pipe);
-
-                       if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
-                               intel_cpu_fifo_underrun_irq_handler(dev_priv,
-                                                                   pipe);
-               }
-
-               if (blc_event || (iir & I915_ASLE_INTERRUPT))
-                       intel_opregion_asle_intr(dev_priv);
+               i915_pipestat_irq_handler(dev_priv, iir, pipe_stats);
 
                /* With MSI, interrupts are only generated when iir
                 * transitions from zero to nonzero.  If another bit got
@@ -4022,8 +4036,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
        struct drm_device *dev = arg;
        struct drm_i915_private *dev_priv = to_i915(dev);
        u32 iir, new_iir;
-       u32 pipe_stats[I915_MAX_PIPES];
-       int ret = IRQ_NONE, pipe;
+       int ret = IRQ_NONE;
        const u32 flip_mask =
                I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT |
                I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
@@ -4037,31 +4050,15 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
        iir = I915_READ(IIR);
 
        for (;;) {
+               u32 pipe_stats[I915_MAX_PIPES] = {};
                bool irq_received = (iir & ~flip_mask) != 0;
-               bool blc_event = false;
 
-               /* Can't rely on pipestat interrupt bit in iir as it might
-                * have been cleared after the pipestat interrupt was received.
-                * It doesn't set the bit in iir again, but it still produces
-                * interrupts (for non-MSI).
-                */
-               spin_lock(&dev_priv->irq_lock);
                if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
                        DRM_DEBUG("Command parser error, iir 0x%08x\n", iir);
 
-               for_each_pipe(dev_priv, pipe) {
-                       i915_reg_t reg = PIPESTAT(pipe);
-                       pipe_stats[pipe] = I915_READ(reg);
-
-                       /*
-                        * Clear the PIPE*STAT regs before the IIR
-                        */
-                       if (pipe_stats[pipe] & 0x8000ffff) {
-                               I915_WRITE(reg, pipe_stats[pipe]);
-                               irq_received = true;
-                       }
-               }
-               spin_unlock(&dev_priv->irq_lock);
+               /* Call regardless, as some status bits might not be
+                * signalled in iir */
+               i9xx_pipestat_irq_ack(dev_priv, iir, pipe_stats);
 
                if (!irq_received)
                        break;
@@ -4083,25 +4080,7 @@ static irqreturn_t i965_irq_handler(int irq, void *arg)
                if (iir & I915_BSD_USER_INTERRUPT)
                        notify_ring(dev_priv->engine[VCS]);
 
-               for_each_pipe(dev_priv, pipe) {
-                       if (pipe_stats[pipe] & 
PIPE_START_VBLANK_INTERRUPT_STATUS)
-                               i915_handle_vblank(dev_priv, pipe, pipe, iir);
-
-                       if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
-                               blc_event = true;
-
-                       if (pipe_stats[pipe] & PIPE_CRC_DONE_INTERRUPT_STATUS)
-                               i9xx_pipe_crc_irq_handler(dev_priv, pipe);
-
-                       if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
-                               intel_cpu_fifo_underrun_irq_handler(dev_priv, 
pipe);
-               }
-
-               if (blc_event || (iir & I915_ASLE_INTERRUPT))
-                       intel_opregion_asle_intr(dev_priv);
-
-               if (pipe_stats[0] & PIPE_GMBUS_INTERRUPT_STATUS)
-                       gmbus_irq_handler(dev_priv);
+               i965_pipestat_irq_handler(dev_priv, iir, pipe_stats);
 
                /* With MSI, interrupts are only generated when iir
                 * transitions from zero to nonzero.  If another bit got
-- 
2.13.0

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to