aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2014-02-12 11:55:36 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-02-12 17:42:02 -0500
commitbbb5eebf034be22fb4de6e9879a0933d3292cf2f (patch)
tree082aa624f557b755758f5d50dba8e3f5d63d068f
parentf6a8328898291a2dd0709acd08c039ccaac19554 (diff)
drm/i915: Some polish for the new pipestat_irq_handler
Just a bit of polish which I hope will help me with massaging some internal patches to use Imre's reworked pipestat handling: - Don't check for underrun reporting or enable pipestat interrupts twice. - Frob the comments a bit. - Do the iir PIPE_EVENT to pipe mapping explicitly with a switch. We only have one place which does this, so better to make it explicit. v2: Ville noticed that I've broken the logic a bit with trying to avoid checking whether we're interested in a given pipe twice. push the PIPESTAT read down after we've computed the mask of interesting bits first to avoid that duplication properly. v3: Squash in fixups from Imre on irc. Cc: Imre Deak <imre.deak@intel.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c37
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h4
2 files changed, 26 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index b2c5c2b04f59..69f2ebbd6af1 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -1560,25 +1560,40 @@ static void valleyview_pipestat_irq_handler(struct drm_device *dev, u32 iir)
1560 spin_lock(&dev_priv->irq_lock); 1560 spin_lock(&dev_priv->irq_lock);
1561 for_each_pipe(pipe) { 1561 for_each_pipe(pipe) {
1562 int reg; 1562 int reg;
1563 u32 mask; 1563 u32 mask, iir_bit = 0;
1564 1564
1565 if (!dev_priv->pipestat_irq_mask[pipe] && 1565 /*
1566 !__cpu_fifo_underrun_reporting_enabled(dev, pipe)) 1566 * PIPESTAT bits get signalled even when the interrupt is
1567 * disabled with the mask bits, and some of the status bits do
1568 * not generate interrupts at all (like the underrun bit). Hence
1569 * we need to be careful that we only handle what we want to
1570 * handle.
1571 */
1572 mask = 0;
1573 if (__cpu_fifo_underrun_reporting_enabled(dev, pipe))
1574 mask |= PIPE_FIFO_UNDERRUN_STATUS;
1575
1576 switch (pipe) {
1577 case PIPE_A:
1578 iir_bit = I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
1579 break;
1580 case PIPE_B:
1581 iir_bit = I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
1582 break;
1583 }
1584 if (iir & iir_bit)
1585 mask |= dev_priv->pipestat_irq_mask[pipe];
1586
1587 if (!mask)
1567 continue; 1588 continue;
1568 1589
1569 reg = PIPESTAT(pipe); 1590 reg = PIPESTAT(pipe);
1570 pipe_stats[pipe] = I915_READ(reg); 1591 mask |= PIPESTAT_INT_ENABLE_MASK;
1592 pipe_stats[pipe] = I915_READ(reg) & mask;
1571 1593
1572 /* 1594 /*
1573 * Clear the PIPE*STAT regs before the IIR 1595 * Clear the PIPE*STAT regs before the IIR
1574 */ 1596 */
1575 mask = PIPESTAT_INT_ENABLE_MASK;
1576 if (__cpu_fifo_underrun_reporting_enabled(dev, pipe))
1577 mask |= PIPE_FIFO_UNDERRUN_STATUS;
1578 if (iir & I915_DISPLAY_PIPE_EVENT_INTERRUPT(pipe))
1579 mask |= dev_priv->pipestat_irq_mask[pipe];
1580 pipe_stats[pipe] &= mask;
1581
1582 if (pipe_stats[pipe] & (PIPE_FIFO_UNDERRUN_STATUS | 1597 if (pipe_stats[pipe] & (PIPE_FIFO_UNDERRUN_STATUS |
1583 PIPESTAT_INT_STATUS_MASK)) 1598 PIPESTAT_INT_STATUS_MASK))
1584 I915_WRITE(reg, pipe_stats[pipe]); 1599 I915_WRITE(reg, pipe_stats[pipe]);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index fc03142e4ae7..3579a9ce9ce2 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -997,10 +997,6 @@
997#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6) 997#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6)
998#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5) 998#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5)
999#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4) 999#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4)
1000#define I915_DISPLAY_PIPE_EVENT_INTERRUPT(pipe) \
1001 ((pipe) == PIPE_A ? I915_DISPLAY_PIPE_A_EVENT_INTERRUPT : \
1002 I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
1003
1004#define I915_DEBUG_INTERRUPT (1<<2) 1000#define I915_DEBUG_INTERRUPT (1<<2)
1005#define I915_USER_INTERRUPT (1<<1) 1001#define I915_USER_INTERRUPT (1<<1)
1006#define I915_ASLE_INTERRUPT (1<<0) 1002#define I915_ASLE_INTERRUPT (1<<0)