aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2017-09-14 11:17:31 -0400
committerVille Syrjälä <ville.syrjala@linux.intel.com>2017-09-25 09:54:09 -0400
commit6b12ca569bb2f864892c41dbbb0f88f3f9952bf3 (patch)
tree59b29795a209e6b84a0fcf4f3ae411c11e82f849 /drivers/gpu/drm/i915/i915_irq.c
parentdff457d74e7eaf8c5280967467597ebfc3e2e44a (diff)
drm/i915: Don't rmw PIPESTAT enable bits
i830 seems to occasionally forget the PIPESTAT enable bits when we read the register. These aren't the only registers on i830 that have problems with RMW, as reading the double buffered plane registers returns the latched value rather than the last written value. So something similar is perhaps going on with PIPESTAT. This corruption results on vblank interrupts occasionally turning off on their own, which leads to vblank timeouts and generally a stuck display subsystem. So let's not RMW the pipestat enable bits, and instead use the cached copy we have around. Cc: Imre Deak <imre.deak@intel.com> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20170914151731.5034-1-ville.syrjala@linux.intel.com Reviewed-by: Imre Deak <imre.deak@intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c135
1 files changed, 56 insertions, 79 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index af82bd721dbc..6a07ef38fb47 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -567,62 +567,16 @@ void ibx_display_interrupt_update(struct drm_i915_private *dev_priv,
567 POSTING_READ(SDEIMR); 567 POSTING_READ(SDEIMR);
568} 568}
569 569
570static void 570u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv,
571__i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, 571 enum pipe pipe)
572 u32 enable_mask, u32 status_mask)
573{ 572{
574 i915_reg_t reg = PIPESTAT(pipe); 573 u32 status_mask = dev_priv->pipestat_irq_mask[pipe];
575 u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK; 574 u32 enable_mask = status_mask << 16;
576
577 lockdep_assert_held(&dev_priv->irq_lock);
578 WARN_ON(!intel_irqs_enabled(dev_priv));
579
580 if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
581 status_mask & ~PIPESTAT_INT_STATUS_MASK,
582 "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
583 pipe_name(pipe), enable_mask, status_mask))
584 return;
585
586 if ((pipestat & enable_mask) == enable_mask)
587 return;
588
589 dev_priv->pipestat_irq_mask[pipe] |= status_mask;
590
591 /* Enable the interrupt, clear any pending status */
592 pipestat |= enable_mask | status_mask;
593 I915_WRITE(reg, pipestat);
594 POSTING_READ(reg);
595}
596
597static void
598__i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe,
599 u32 enable_mask, u32 status_mask)
600{
601 i915_reg_t reg = PIPESTAT(pipe);
602 u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK;
603 575
604 lockdep_assert_held(&dev_priv->irq_lock); 576 lockdep_assert_held(&dev_priv->irq_lock);
605 WARN_ON(!intel_irqs_enabled(dev_priv));
606
607 if (WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
608 status_mask & ~PIPESTAT_INT_STATUS_MASK,
609 "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
610 pipe_name(pipe), enable_mask, status_mask))
611 return;
612
613 if ((pipestat & enable_mask) == 0)
614 return;
615
616 dev_priv->pipestat_irq_mask[pipe] &= ~status_mask;
617
618 pipestat &= ~enable_mask;
619 I915_WRITE(reg, pipestat);
620 POSTING_READ(reg);
621}
622 577
623static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask) 578 if (INTEL_GEN(dev_priv) < 5)
624{ 579 goto out;
625 u32 enable_mask = status_mask << 16;
626 580
627 /* 581 /*
628 * On pipe A we don't support the PSR interrupt yet, 582 * On pipe A we don't support the PSR interrupt yet,
@@ -645,35 +599,59 @@ static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask)
645 if (status_mask & SPRITE1_FLIP_DONE_INT_STATUS_VLV) 599 if (status_mask & SPRITE1_FLIP_DONE_INT_STATUS_VLV)
646 enable_mask |= SPRITE1_FLIP_DONE_INT_EN_VLV; 600 enable_mask |= SPRITE1_FLIP_DONE_INT_EN_VLV;
647 601
602out:
603 WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK ||
604 status_mask & ~PIPESTAT_INT_STATUS_MASK,
605 "pipe %c: enable_mask=0x%x, status_mask=0x%x\n",
606 pipe_name(pipe), enable_mask, status_mask);
607
648 return enable_mask; 608 return enable_mask;
649} 609}
650 610
651void 611void i915_enable_pipestat(struct drm_i915_private *dev_priv,
652i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, 612 enum pipe pipe, u32 status_mask)
653 u32 status_mask)
654{ 613{
614 i915_reg_t reg = PIPESTAT(pipe);
655 u32 enable_mask; 615 u32 enable_mask;
656 616
657 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) 617 WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK,
658 enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm, 618 "pipe %c: status_mask=0x%x\n",
659 status_mask); 619 pipe_name(pipe), status_mask);
660 else 620
661 enable_mask = status_mask << 16; 621 lockdep_assert_held(&dev_priv->irq_lock);
662 __i915_enable_pipestat(dev_priv, pipe, enable_mask, status_mask); 622 WARN_ON(!intel_irqs_enabled(dev_priv));
623
624 if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == status_mask)
625 return;
626
627 dev_priv->pipestat_irq_mask[pipe] |= status_mask;
628 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
629
630 I915_WRITE(reg, enable_mask | status_mask);
631 POSTING_READ(reg);
663} 632}
664 633
665void 634void i915_disable_pipestat(struct drm_i915_private *dev_priv,
666i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, 635 enum pipe pipe, u32 status_mask)
667 u32 status_mask)
668{ 636{
637 i915_reg_t reg = PIPESTAT(pipe);
669 u32 enable_mask; 638 u32 enable_mask;
670 639
671 if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) 640 WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK,
672 enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm, 641 "pipe %c: status_mask=0x%x\n",
673 status_mask); 642 pipe_name(pipe), status_mask);
674 else 643
675 enable_mask = status_mask << 16; 644 lockdep_assert_held(&dev_priv->irq_lock);
676 __i915_disable_pipestat(dev_priv, pipe, enable_mask, status_mask); 645 WARN_ON(!intel_irqs_enabled(dev_priv));
646
647 if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == 0)
648 return;
649
650 dev_priv->pipestat_irq_mask[pipe] &= ~status_mask;
651 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
652
653 I915_WRITE(reg, enable_mask | status_mask);
654 POSTING_READ(reg);
677} 655}
678 656
679/** 657/**
@@ -1775,7 +1753,7 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
1775 1753
1776 for_each_pipe(dev_priv, pipe) { 1754 for_each_pipe(dev_priv, pipe) {
1777 i915_reg_t reg; 1755 i915_reg_t reg;
1778 u32 mask, iir_bit = 0; 1756 u32 status_mask, enable_mask, iir_bit = 0;
1779 1757
1780 /* 1758 /*
1781 * PIPESTAT bits get signalled even when the interrupt is 1759 * PIPESTAT bits get signalled even when the interrupt is
@@ -1786,7 +1764,7 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
1786 */ 1764 */
1787 1765
1788 /* fifo underruns are filterered in the underrun handler. */ 1766 /* fifo underruns are filterered in the underrun handler. */
1789 mask = PIPE_FIFO_UNDERRUN_STATUS; 1767 status_mask = PIPE_FIFO_UNDERRUN_STATUS;
1790 1768
1791 switch (pipe) { 1769 switch (pipe) {
1792 case PIPE_A: 1770 case PIPE_A:
@@ -1800,21 +1778,20 @@ static void i9xx_pipestat_irq_ack(struct drm_i915_private *dev_priv,
1800 break; 1778 break;
1801 } 1779 }
1802 if (iir & iir_bit) 1780 if (iir & iir_bit)
1803 mask |= dev_priv->pipestat_irq_mask[pipe]; 1781 status_mask |= dev_priv->pipestat_irq_mask[pipe];
1804 1782
1805 if (!mask) 1783 if (!status_mask)
1806 continue; 1784 continue;
1807 1785
1808 reg = PIPESTAT(pipe); 1786 reg = PIPESTAT(pipe);
1809 mask |= PIPESTAT_INT_ENABLE_MASK; 1787 pipe_stats[pipe] = I915_READ(reg) & status_mask;
1810 pipe_stats[pipe] = I915_READ(reg) & mask; 1788 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
1811 1789
1812 /* 1790 /*
1813 * Clear the PIPE*STAT regs before the IIR 1791 * Clear the PIPE*STAT regs before the IIR
1814 */ 1792 */
1815 if (pipe_stats[pipe] & (PIPE_FIFO_UNDERRUN_STATUS | 1793 if (pipe_stats[pipe])
1816 PIPESTAT_INT_STATUS_MASK)) 1794 I915_WRITE(reg, enable_mask | pipe_stats[pipe]);
1817 I915_WRITE(reg, pipe_stats[pipe]);
1818 } 1795 }
1819 spin_unlock(&dev_priv->irq_lock); 1796 spin_unlock(&dev_priv->irq_lock);
1820} 1797}