2 * Copyright © 2014 Intel Corporation
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 * Daniel Vetter <daniel.vetter@ffwll.ch>
29 #include "intel_drv.h"
31 static bool ivb_can_enable_err_int(struct drm_device *dev)
33 struct drm_i915_private *dev_priv = dev->dev_private;
34 struct intel_crtc *crtc;
37 assert_spin_locked(&dev_priv->irq_lock);
39 for_each_pipe(dev_priv, pipe) {
40 crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
42 if (crtc->cpu_fifo_underrun_disabled)
49 static bool cpt_can_enable_serr_int(struct drm_device *dev)
51 struct drm_i915_private *dev_priv = dev->dev_private;
53 struct intel_crtc *crtc;
55 assert_spin_locked(&dev_priv->irq_lock);
57 for_each_pipe(dev_priv, pipe) {
58 crtc = to_intel_crtc(dev_priv->pipe_to_crtc_mapping[pipe]);
60 if (crtc->pch_fifo_underrun_disabled)
67 void i9xx_check_fifo_underruns(struct drm_i915_private *dev_priv)
69 struct intel_crtc *crtc;
71 spin_lock_irq(&dev_priv->irq_lock);
73 for_each_intel_crtc(dev_priv->dev, crtc) {
74 u32 reg = PIPESTAT(crtc->pipe);
77 if (crtc->cpu_fifo_underrun_disabled)
80 pipestat = I915_READ(reg) & 0xffff0000;
81 if ((pipestat & PIPE_FIFO_UNDERRUN_STATUS) == 0)
84 I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS);
87 DRM_ERROR("pipe %c underrun\n", pipe_name(crtc->pipe));
90 spin_unlock_irq(&dev_priv->irq_lock);
93 static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev,
95 bool enable, bool old)
97 struct drm_i915_private *dev_priv = dev->dev_private;
98 u32 reg = PIPESTAT(pipe);
99 u32 pipestat = I915_READ(reg) & 0xffff0000;
101 assert_spin_locked(&dev_priv->irq_lock);
104 I915_WRITE(reg, pipestat | PIPE_FIFO_UNDERRUN_STATUS);
107 if (old && pipestat & PIPE_FIFO_UNDERRUN_STATUS)
108 DRM_ERROR("pipe %c underrun\n", pipe_name(pipe));
112 static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev,
113 enum pipe pipe, bool enable)
115 struct drm_i915_private *dev_priv = dev->dev_private;
116 uint32_t bit = (pipe == PIPE_A) ? DE_PIPEA_FIFO_UNDERRUN :
117 DE_PIPEB_FIFO_UNDERRUN;
120 ironlake_enable_display_irq(dev_priv, bit);
122 ironlake_disable_display_irq(dev_priv, bit);
125 static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev,
127 bool enable, bool old)
129 struct drm_i915_private *dev_priv = dev->dev_private;
131 I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe));
133 if (!ivb_can_enable_err_int(dev))
136 ironlake_enable_display_irq(dev_priv, DE_ERR_INT_IVB);
138 ironlake_disable_display_irq(dev_priv, DE_ERR_INT_IVB);
141 I915_READ(GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) {
142 DRM_ERROR("uncleared fifo underrun on pipe %c\n",
148 static void broadwell_set_fifo_underrun_reporting(struct drm_device *dev,
149 enum pipe pipe, bool enable)
151 struct drm_i915_private *dev_priv = dev->dev_private;
153 assert_spin_locked(&dev_priv->irq_lock);
156 dev_priv->de_irq_mask[pipe] &= ~GEN8_PIPE_FIFO_UNDERRUN;
158 dev_priv->de_irq_mask[pipe] |= GEN8_PIPE_FIFO_UNDERRUN;
159 I915_WRITE(GEN8_DE_PIPE_IMR(pipe), dev_priv->de_irq_mask[pipe]);
160 POSTING_READ(GEN8_DE_PIPE_IMR(pipe));
163 static void ibx_set_fifo_underrun_reporting(struct drm_device *dev,
164 enum transcoder pch_transcoder,
167 struct drm_i915_private *dev_priv = dev->dev_private;
168 uint32_t bit = (pch_transcoder == TRANSCODER_A) ?
169 SDE_TRANSA_FIFO_UNDER : SDE_TRANSB_FIFO_UNDER;
172 ibx_enable_display_interrupt(dev_priv, bit);
174 ibx_disable_display_interrupt(dev_priv, bit);
177 static void cpt_set_fifo_underrun_reporting(struct drm_device *dev,
178 enum transcoder pch_transcoder,
179 bool enable, bool old)
181 struct drm_i915_private *dev_priv = dev->dev_private;
185 SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder));
187 if (!cpt_can_enable_serr_int(dev))
190 ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT);
192 ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT);
194 if (old && I915_READ(SERR_INT) &
195 SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) {
196 DRM_ERROR("uncleared pch fifo underrun on pch transcoder %c\n",
197 transcoder_name(pch_transcoder));
203 * intel_set_cpu_fifo_underrun_reporting - enable/disable FIFO underrun messages
206 * @enable: true if we want to report FIFO underrun errors, false otherwise
208 * This function makes us disable or enable CPU fifo underruns for a specific
209 * pipe. Notice that on some Gens (e.g. IVB, HSW), disabling FIFO underrun
210 * reporting for one pipe may also disable all the other CPU error interruts for
211 * the other pipes, due to the fact that there's just one interrupt mask/enable
212 * bit for all the pipes.
214 * Returns the previous state of underrun reporting.
216 static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
217 enum pipe pipe, bool enable)
219 struct drm_i915_private *dev_priv = dev->dev_private;
220 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
221 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
224 assert_spin_locked(&dev_priv->irq_lock);
226 old = !intel_crtc->cpu_fifo_underrun_disabled;
227 intel_crtc->cpu_fifo_underrun_disabled = !enable;
229 if (HAS_GMCH_DISPLAY(dev))
230 i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old);
231 else if (IS_GEN5(dev) || IS_GEN6(dev))
232 ironlake_set_fifo_underrun_reporting(dev, pipe, enable);
233 else if (IS_GEN7(dev))
234 ivybridge_set_fifo_underrun_reporting(dev, pipe, enable, old);
235 else if (IS_GEN8(dev) || IS_GEN9(dev))
236 broadwell_set_fifo_underrun_reporting(dev, pipe, enable);
241 bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
242 enum pipe pipe, bool enable)
247 spin_lock_irqsave(&dev_priv->irq_lock, flags);
248 ret = __intel_set_cpu_fifo_underrun_reporting(dev_priv->dev, pipe,
250 spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
256 __cpu_fifo_underrun_reporting_enabled(struct drm_i915_private *dev_priv,
259 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
260 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
262 return !intel_crtc->cpu_fifo_underrun_disabled;
266 * intel_set_pch_fifo_underrun_reporting - enable/disable FIFO underrun messages
268 * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older)
269 * @enable: true if we want to report FIFO underrun errors, false otherwise
271 * This function makes us disable or enable PCH fifo underruns for a specific
272 * PCH transcoder. Notice that on some PCHs (e.g. CPT/PPT), disabling FIFO
273 * underrun reporting for one transcoder may also disable all the other PCH
274 * error interruts for the other transcoders, due to the fact that there's just
275 * one interrupt mask/enable bit for all the transcoders.
277 * Returns the previous state of underrun reporting.
279 bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
280 enum transcoder pch_transcoder,
283 struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pch_transcoder];
284 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
289 * NOTE: Pre-LPT has a fixed cpu pipe -> pch transcoder mapping, but LPT
290 * has only one pch transcoder A that all pipes can use. To avoid racy
291 * pch transcoder -> pipe lookups from interrupt code simply store the
292 * underrun statistics in crtc A. Since we never expose this anywhere
293 * nor use it outside of the fifo underrun code here using the "wrong"
294 * crtc on LPT won't cause issues.
297 spin_lock_irqsave(&dev_priv->irq_lock, flags);
299 old = !intel_crtc->pch_fifo_underrun_disabled;
300 intel_crtc->pch_fifo_underrun_disabled = !enable;
302 if (HAS_PCH_IBX(dev_priv->dev))
303 ibx_set_fifo_underrun_reporting(dev_priv->dev, pch_transcoder,
306 cpt_set_fifo_underrun_reporting(dev_priv->dev, pch_transcoder,
309 spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
313 void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
316 /* GMCH can't disable fifo underruns, filter them. */
317 if (HAS_GMCH_DISPLAY(dev_priv->dev) &&
318 !__cpu_fifo_underrun_reporting_enabled(dev_priv, pipe))
321 if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false))
322 DRM_ERROR("CPU pipe %c FIFO underrun\n",
326 void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
327 enum transcoder pch_transcoder)
329 if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder,
331 DRM_ERROR("PCH transcoder %c FIFO underrun\n",
332 transcoder_name(pch_transcoder));