aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/i915_irq.c
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2014-03-07 14:34:46 -0500
committerJani Nikula <jani.nikula@intel.com>2014-03-12 11:20:34 -0400
commit5c673b60a9b3b23486f4eda75c72e91d31d26a2b (patch)
tree383750b1fafb85063ffd0a2399c513a851dda5b6 /drivers/gpu/drm/i915/i915_irq.c
parent243026249324b2c958b67ab387fe6813a9836fe0 (diff)
drm/i915: Don't enable display error interrupts from the start
We need to enable interrupt processing before all the modeset state is set up. But that means we can fall over when we get a pipe underrun. This shouldn't happen as long as the bios works correctly but as usual this turns out to be wishful thinking. So disable error interrupts at irq install time and rely on the re-enabling code in the modeset functions to take care of this. Note that due to the SDE interrupt handling race we must uncondtionally enable all interrupt sources in SDEIER, hence no need to enable the SERR bit specifically. On gmch platforms we don't have an explicit enable/mask bit for fifo underruns. Fixing this up would require a bit of software tracking, hence is material for a separate patch. To make this possible we need to switch all gmch platforms to the new pipestat interrupt handling scheme Imre implemented for vlv, and then also add a safe form of sw state checking to __cpu_fifo_underrun_reporting_enabled a bit. v2: Also handle the ilk/snb cpu fifo underrun bits accordingly. Spotted by Ville. v3: Also handle the south interrupt underrun bits on ibx. Again spotted by Ville. Reported-by: Rob Clark <robdclark@gmail.com> Cc: Rob Clark <robdclark@gmail.com> Cc: Ville Syrjälä <ville.syrjala@linux.intel.com> Cc: stable@vger.kernel.org Tested-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Reviewed-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch> Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c18
1 files changed, 8 insertions, 10 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c
index ec9b8a4b04ed..d554169ac592 100644
--- a/drivers/gpu/drm/i915/i915_irq.c
+++ b/drivers/gpu/drm/i915/i915_irq.c
@@ -2782,10 +2782,9 @@ static void ibx_irq_postinstall(struct drm_device *dev)
2782 return; 2782 return;
2783 2783
2784 if (HAS_PCH_IBX(dev)) { 2784 if (HAS_PCH_IBX(dev)) {
2785 mask = SDE_GMBUS | SDE_AUX_MASK | SDE_TRANSB_FIFO_UNDER | 2785 mask = SDE_GMBUS | SDE_AUX_MASK | SDE_POISON;
2786 SDE_TRANSA_FIFO_UNDER | SDE_POISON;
2787 } else { 2786 } else {
2788 mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT | SDE_ERROR_CPT; 2787 mask = SDE_GMBUS_CPT | SDE_AUX_MASK_CPT;
2789 2788
2790 I915_WRITE(SERR_INT, I915_READ(SERR_INT)); 2789 I915_WRITE(SERR_INT, I915_READ(SERR_INT));
2791 } 2790 }
@@ -2845,20 +2844,19 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
2845 display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB | 2844 display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE_IVB |
2846 DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB | 2845 DE_PCH_EVENT_IVB | DE_PLANEC_FLIP_DONE_IVB |
2847 DE_PLANEB_FLIP_DONE_IVB | 2846 DE_PLANEB_FLIP_DONE_IVB |
2848 DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB | 2847 DE_PLANEA_FLIP_DONE_IVB | DE_AUX_CHANNEL_A_IVB);
2849 DE_ERR_INT_IVB);
2850 extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB | 2848 extra_mask = (DE_PIPEC_VBLANK_IVB | DE_PIPEB_VBLANK_IVB |
2851 DE_PIPEA_VBLANK_IVB); 2849 DE_PIPEA_VBLANK_IVB | DE_ERR_INT_IVB);
2852 2850
2853 I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT)); 2851 I915_WRITE(GEN7_ERR_INT, I915_READ(GEN7_ERR_INT));
2854 } else { 2852 } else {
2855 display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT | 2853 display_mask = (DE_MASTER_IRQ_CONTROL | DE_GSE | DE_PCH_EVENT |
2856 DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE | 2854 DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE |
2857 DE_AUX_CHANNEL_A | 2855 DE_AUX_CHANNEL_A |
2858 DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN |
2859 DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE | 2856 DE_PIPEB_CRC_DONE | DE_PIPEA_CRC_DONE |
2860 DE_POISON); 2857 DE_POISON);
2861 extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT; 2858 extra_mask = DE_PIPEA_VBLANK | DE_PIPEB_VBLANK | DE_PCU_EVENT |
2859 DE_PIPEB_FIFO_UNDERRUN | DE_PIPEA_FIFO_UNDERRUN;
2862 } 2860 }
2863 2861
2864 dev_priv->irq_mask = ~display_mask; 2862 dev_priv->irq_mask = ~display_mask;
@@ -2974,9 +2972,9 @@ static void gen8_de_irq_postinstall(struct drm_i915_private *dev_priv)
2974 struct drm_device *dev = dev_priv->dev; 2972 struct drm_device *dev = dev_priv->dev;
2975 uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE | 2973 uint32_t de_pipe_masked = GEN8_PIPE_FLIP_DONE |
2976 GEN8_PIPE_CDCLK_CRC_DONE | 2974 GEN8_PIPE_CDCLK_CRC_DONE |
2977 GEN8_PIPE_FIFO_UNDERRUN |
2978 GEN8_DE_PIPE_IRQ_FAULT_ERRORS; 2975 GEN8_DE_PIPE_IRQ_FAULT_ERRORS;
2979 uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK; 2976 uint32_t de_pipe_enables = de_pipe_masked | GEN8_PIPE_VBLANK |
2977 GEN8_PIPE_FIFO_UNDERRUN;
2980 int pipe; 2978 int pipe;
2981 dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked; 2979 dev_priv->de_irq_mask[PIPE_A] = ~de_pipe_masked;
2982 dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked; 2980 dev_priv->de_irq_mask[PIPE_B] = ~de_pipe_masked;