Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+68 -87
+2
drivers/gpu/drm/i915/i915_drv.h
··· 3313 3313 return dev_priv->vgpu.active; 3314 3314 } 3315 3315 3316 + u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv, 3317 + enum pipe pipe); 3316 3318 void 3317 3319 i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, 3318 3320 u32 status_mask);
+58 -81
drivers/gpu/drm/i915/i915_irq.c
··· 567 567 POSTING_READ(SDEIMR); 568 568 } 569 569 570 - static void 571 - __i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, 572 - u32 enable_mask, u32 status_mask) 570 + u32 i915_pipestat_enable_mask(struct drm_i915_private *dev_priv, 571 + enum pipe pipe) 573 572 { 574 - i915_reg_t reg = PIPESTAT(pipe); 575 - u32 pipestat = I915_READ(reg) & PIPESTAT_INT_ENABLE_MASK; 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 - 597 - static 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 - 604 - 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 - 623 - static u32 vlv_get_pipestat_enable_mask(struct drm_device *dev, u32 status_mask) 624 - { 573 + u32 status_mask = dev_priv->pipestat_irq_mask[pipe]; 625 574 u32 enable_mask = status_mask << 16; 575 + 576 + lockdep_assert_held(&dev_priv->irq_lock); 577 + 578 + if (INTEL_GEN(dev_priv) < 5) 579 + goto out; 626 580 627 581 /* 628 582 * On pipe A we don't support the PSR interrupt yet, ··· 599 645 if (status_mask & SPRITE1_FLIP_DONE_INT_STATUS_VLV) 600 646 enable_mask |= SPRITE1_FLIP_DONE_INT_EN_VLV; 601 647 648 + out: 649 + WARN_ONCE(enable_mask & ~PIPESTAT_INT_ENABLE_MASK || 650 + status_mask & ~PIPESTAT_INT_STATUS_MASK, 651 + "pipe %c: enable_mask=0x%x, status_mask=0x%x\n", 652 + pipe_name(pipe), enable_mask, status_mask); 653 + 602 654 return enable_mask; 603 655 } 604 656 605 - void 606 - i915_enable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, 607 - u32 status_mask) 657 + void i915_enable_pipestat(struct drm_i915_private *dev_priv, 658 + enum pipe pipe, u32 status_mask) 608 659 { 660 + i915_reg_t reg = PIPESTAT(pipe); 609 661 u32 enable_mask; 610 662 611 - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) 612 - enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm, 613 - status_mask); 614 - else 615 - enable_mask = status_mask << 16; 616 - __i915_enable_pipestat(dev_priv, pipe, enable_mask, status_mask); 663 + WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK, 664 + "pipe %c: status_mask=0x%x\n", 665 + pipe_name(pipe), status_mask); 666 + 667 + lockdep_assert_held(&dev_priv->irq_lock); 668 + WARN_ON(!intel_irqs_enabled(dev_priv)); 669 + 670 + if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == status_mask) 671 + return; 672 + 673 + dev_priv->pipestat_irq_mask[pipe] |= status_mask; 674 + enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); 675 + 676 + I915_WRITE(reg, enable_mask | status_mask); 677 + POSTING_READ(reg); 617 678 } 618 679 619 - void 620 - i915_disable_pipestat(struct drm_i915_private *dev_priv, enum pipe pipe, 621 - u32 status_mask) 680 + void i915_disable_pipestat(struct drm_i915_private *dev_priv, 681 + enum pipe pipe, u32 status_mask) 622 682 { 683 + i915_reg_t reg = PIPESTAT(pipe); 623 684 u32 enable_mask; 624 685 625 - if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) 626 - enable_mask = vlv_get_pipestat_enable_mask(&dev_priv->drm, 627 - status_mask); 628 - else 629 - enable_mask = status_mask << 16; 630 - __i915_disable_pipestat(dev_priv, pipe, enable_mask, status_mask); 686 + WARN_ONCE(status_mask & ~PIPESTAT_INT_STATUS_MASK, 687 + "pipe %c: status_mask=0x%x\n", 688 + pipe_name(pipe), status_mask); 689 + 690 + lockdep_assert_held(&dev_priv->irq_lock); 691 + WARN_ON(!intel_irqs_enabled(dev_priv)); 692 + 693 + if ((dev_priv->pipestat_irq_mask[pipe] & status_mask) == 0) 694 + return; 695 + 696 + dev_priv->pipestat_irq_mask[pipe] &= ~status_mask; 697 + enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); 698 + 699 + I915_WRITE(reg, enable_mask | status_mask); 700 + POSTING_READ(reg); 631 701 } 632 702 633 703 /** ··· 1753 1775 1754 1776 for_each_pipe(dev_priv, pipe) { 1755 1777 i915_reg_t reg; 1756 - u32 mask, iir_bit = 0; 1778 + u32 status_mask, enable_mask, iir_bit = 0; 1757 1779 1758 1780 /* 1759 1781 * PIPESTAT bits get signalled even when the interrupt is ··· 1764 1786 */ 1765 1787 1766 1788 /* fifo underruns are filterered in the underrun handler. */ 1767 - mask = PIPE_FIFO_UNDERRUN_STATUS; 1789 + status_mask = PIPE_FIFO_UNDERRUN_STATUS; 1768 1790 1769 1791 switch (pipe) { 1770 1792 case PIPE_A: ··· 1778 1800 break; 1779 1801 } 1780 1802 if (iir & iir_bit) 1781 - mask |= dev_priv->pipestat_irq_mask[pipe]; 1803 + status_mask |= dev_priv->pipestat_irq_mask[pipe]; 1782 1804 1783 - if (!mask) 1805 + if (!status_mask) 1784 1806 continue; 1785 1807 1786 1808 reg = PIPESTAT(pipe); 1787 - mask |= PIPESTAT_INT_ENABLE_MASK; 1788 - pipe_stats[pipe] = I915_READ(reg) & mask; 1809 + pipe_stats[pipe] = I915_READ(reg) & status_mask; 1810 + enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); 1789 1811 1790 1812 /* 1791 1813 * Clear the PIPE*STAT regs before the IIR 1792 1814 */ 1793 - if (pipe_stats[pipe] & (PIPE_FIFO_UNDERRUN_STATUS | 1794 - PIPESTAT_INT_STATUS_MASK)) 1795 - I915_WRITE(reg, pipe_stats[pipe]); 1815 + if (pipe_stats[pipe]) 1816 + I915_WRITE(reg, enable_mask | pipe_stats[pipe]); 1796 1817 } 1797 1818 spin_unlock(&dev_priv->irq_lock); 1798 1819 }
+8 -6
drivers/gpu/drm/i915/intel_fifo_underrun.c
··· 88 88 { 89 89 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 90 90 i915_reg_t reg = PIPESTAT(crtc->pipe); 91 - u32 pipestat = I915_READ(reg) & 0xffff0000; 91 + u32 enable_mask; 92 92 93 93 lockdep_assert_held(&dev_priv->irq_lock); 94 94 95 - if ((pipestat & PIPE_FIFO_UNDERRUN_STATUS) == 0) 95 + if ((I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0) 96 96 return; 97 97 98 - I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS); 98 + enable_mask = i915_pipestat_enable_mask(dev_priv, crtc->pipe); 99 + I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS); 99 100 POSTING_READ(reg); 100 101 101 102 trace_intel_cpu_fifo_underrun(dev_priv, crtc->pipe); ··· 109 108 { 110 109 struct drm_i915_private *dev_priv = to_i915(dev); 111 110 i915_reg_t reg = PIPESTAT(pipe); 112 - u32 pipestat = I915_READ(reg) & 0xffff0000; 113 111 114 112 lockdep_assert_held(&dev_priv->irq_lock); 115 113 116 114 if (enable) { 117 - I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS); 115 + u32 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); 116 + 117 + I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS); 118 118 POSTING_READ(reg); 119 119 } else { 120 - if (old && pipestat & PIPE_FIFO_UNDERRUN_STATUS) 120 + if (old && I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS) 121 121 DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); 122 122 } 123 123 }