]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/i915/intel_fifo_underrun.c
Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
[linux.git] / drivers / gpu / drm / i915 / intel_fifo_underrun.c
1 /*
2  * Copyright © 2014 Intel Corporation
3  *
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:
10  *
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
13  * Software.
14  *
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
21  * IN THE SOFTWARE.
22  *
23  * Authors:
24  *    Daniel Vetter <daniel.vetter@ffwll.ch>
25  *
26  */
27
28 #include "i915_drv.h"
29 #include "intel_drv.h"
30 #include "intel_fbc.h"
31
32 /**
33  * DOC: fifo underrun handling
34  *
35  * The i915 driver checks for display fifo underruns using the interrupt signals
36  * provided by the hardware. This is enabled by default and fairly useful to
37  * debug display issues, especially watermark settings.
38  *
39  * If an underrun is detected this is logged into dmesg. To avoid flooding logs
40  * and occupying the cpu underrun interrupts are disabled after the first
41  * occurrence until the next modeset on a given pipe.
42  *
43  * Note that underrun detection on gmch platforms is a bit more ugly since there
44  * is no interrupt (despite that the signalling bit is in the PIPESTAT pipe
45  * interrupt register). Also on some other platforms underrun interrupts are
46  * shared, which means that if we detect an underrun we need to disable underrun
47  * reporting on all pipes.
48  *
49  * The code also supports underrun detection on the PCH transcoder.
50  */
51
52 static bool ivb_can_enable_err_int(struct drm_device *dev)
53 {
54         struct drm_i915_private *dev_priv = to_i915(dev);
55         struct intel_crtc *crtc;
56         enum pipe pipe;
57
58         lockdep_assert_held(&dev_priv->irq_lock);
59
60         for_each_pipe(dev_priv, pipe) {
61                 crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
62
63                 if (crtc->cpu_fifo_underrun_disabled)
64                         return false;
65         }
66
67         return true;
68 }
69
70 static bool cpt_can_enable_serr_int(struct drm_device *dev)
71 {
72         struct drm_i915_private *dev_priv = to_i915(dev);
73         enum pipe pipe;
74         struct intel_crtc *crtc;
75
76         lockdep_assert_held(&dev_priv->irq_lock);
77
78         for_each_pipe(dev_priv, pipe) {
79                 crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
80
81                 if (crtc->pch_fifo_underrun_disabled)
82                         return false;
83         }
84
85         return true;
86 }
87
88 static void i9xx_check_fifo_underruns(struct intel_crtc *crtc)
89 {
90         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
91         i915_reg_t reg = PIPESTAT(crtc->pipe);
92         u32 enable_mask;
93
94         lockdep_assert_held(&dev_priv->irq_lock);
95
96         if ((I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0)
97                 return;
98
99         enable_mask = i915_pipestat_enable_mask(dev_priv, crtc->pipe);
100         I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
101         POSTING_READ(reg);
102
103         trace_intel_cpu_fifo_underrun(dev_priv, crtc->pipe);
104         DRM_ERROR("pipe %c underrun\n", pipe_name(crtc->pipe));
105 }
106
107 static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev,
108                                              enum pipe pipe,
109                                              bool enable, bool old)
110 {
111         struct drm_i915_private *dev_priv = to_i915(dev);
112         i915_reg_t reg = PIPESTAT(pipe);
113
114         lockdep_assert_held(&dev_priv->irq_lock);
115
116         if (enable) {
117                 u32 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
118
119                 I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
120                 POSTING_READ(reg);
121         } else {
122                 if (old && I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS)
123                         DRM_ERROR("pipe %c underrun\n", pipe_name(pipe));
124         }
125 }
126
127 static void ironlake_set_fifo_underrun_reporting(struct drm_device *dev,
128                                                  enum pipe pipe, bool enable)
129 {
130         struct drm_i915_private *dev_priv = to_i915(dev);
131         u32 bit = (pipe == PIPE_A) ?
132                 DE_PIPEA_FIFO_UNDERRUN : DE_PIPEB_FIFO_UNDERRUN;
133
134         if (enable)
135                 ilk_enable_display_irq(dev_priv, bit);
136         else
137                 ilk_disable_display_irq(dev_priv, bit);
138 }
139
140 static void ivybridge_check_fifo_underruns(struct intel_crtc *crtc)
141 {
142         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
143         enum pipe pipe = crtc->pipe;
144         u32 err_int = I915_READ(GEN7_ERR_INT);
145
146         lockdep_assert_held(&dev_priv->irq_lock);
147
148         if ((err_int & ERR_INT_FIFO_UNDERRUN(pipe)) == 0)
149                 return;
150
151         I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe));
152         POSTING_READ(GEN7_ERR_INT);
153
154         trace_intel_cpu_fifo_underrun(dev_priv, pipe);
155         DRM_ERROR("fifo underrun on pipe %c\n", pipe_name(pipe));
156 }
157
158 static void ivybridge_set_fifo_underrun_reporting(struct drm_device *dev,
159                                                   enum pipe pipe,
160                                                   bool enable, bool old)
161 {
162         struct drm_i915_private *dev_priv = to_i915(dev);
163         if (enable) {
164                 I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe));
165
166                 if (!ivb_can_enable_err_int(dev))
167                         return;
168
169                 ilk_enable_display_irq(dev_priv, DE_ERR_INT_IVB);
170         } else {
171                 ilk_disable_display_irq(dev_priv, DE_ERR_INT_IVB);
172
173                 if (old &&
174                     I915_READ(GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) {
175                         DRM_ERROR("uncleared fifo underrun on pipe %c\n",
176                                   pipe_name(pipe));
177                 }
178         }
179 }
180
181 static void broadwell_set_fifo_underrun_reporting(struct drm_device *dev,
182                                                   enum pipe pipe, bool enable)
183 {
184         struct drm_i915_private *dev_priv = to_i915(dev);
185
186         if (enable)
187                 bdw_enable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN);
188         else
189                 bdw_disable_pipe_irq(dev_priv, pipe, GEN8_PIPE_FIFO_UNDERRUN);
190 }
191
192 static void ibx_set_fifo_underrun_reporting(struct drm_device *dev,
193                                             enum pipe pch_transcoder,
194                                             bool enable)
195 {
196         struct drm_i915_private *dev_priv = to_i915(dev);
197         u32 bit = (pch_transcoder == PIPE_A) ?
198                 SDE_TRANSA_FIFO_UNDER : SDE_TRANSB_FIFO_UNDER;
199
200         if (enable)
201                 ibx_enable_display_interrupt(dev_priv, bit);
202         else
203                 ibx_disable_display_interrupt(dev_priv, bit);
204 }
205
206 static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc)
207 {
208         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
209         enum pipe pch_transcoder = crtc->pipe;
210         u32 serr_int = I915_READ(SERR_INT);
211
212         lockdep_assert_held(&dev_priv->irq_lock);
213
214         if ((serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) == 0)
215                 return;
216
217         I915_WRITE(SERR_INT, SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder));
218         POSTING_READ(SERR_INT);
219
220         trace_intel_pch_fifo_underrun(dev_priv, pch_transcoder);
221         DRM_ERROR("pch fifo underrun on pch transcoder %c\n",
222                   pipe_name(pch_transcoder));
223 }
224
225 static void cpt_set_fifo_underrun_reporting(struct drm_device *dev,
226                                             enum pipe pch_transcoder,
227                                             bool enable, bool old)
228 {
229         struct drm_i915_private *dev_priv = to_i915(dev);
230
231         if (enable) {
232                 I915_WRITE(SERR_INT,
233                            SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder));
234
235                 if (!cpt_can_enable_serr_int(dev))
236                         return;
237
238                 ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT);
239         } else {
240                 ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT);
241
242                 if (old && I915_READ(SERR_INT) &
243                     SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) {
244                         DRM_ERROR("uncleared pch fifo underrun on pch transcoder %c\n",
245                                   pipe_name(pch_transcoder));
246                 }
247         }
248 }
249
250 static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
251                                                     enum pipe pipe, bool enable)
252 {
253         struct drm_i915_private *dev_priv = to_i915(dev);
254         struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
255         bool old;
256
257         lockdep_assert_held(&dev_priv->irq_lock);
258
259         old = !crtc->cpu_fifo_underrun_disabled;
260         crtc->cpu_fifo_underrun_disabled = !enable;
261
262         if (HAS_GMCH(dev_priv))
263                 i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old);
264         else if (IS_GEN_RANGE(dev_priv, 5, 6))
265                 ironlake_set_fifo_underrun_reporting(dev, pipe, enable);
266         else if (IS_GEN(dev_priv, 7))
267                 ivybridge_set_fifo_underrun_reporting(dev, pipe, enable, old);
268         else if (INTEL_GEN(dev_priv) >= 8)
269                 broadwell_set_fifo_underrun_reporting(dev, pipe, enable);
270
271         return old;
272 }
273
274 /**
275  * intel_set_cpu_fifo_underrun_reporting - set cpu fifo underrrun reporting state
276  * @dev_priv: i915 device instance
277  * @pipe: (CPU) pipe to set state for
278  * @enable: whether underruns should be reported or not
279  *
280  * This function sets the fifo underrun state for @pipe. It is used in the
281  * modeset code to avoid false positives since on many platforms underruns are
282  * expected when disabling or enabling the pipe.
283  *
284  * Notice that on some platforms disabling underrun reports for one pipe
285  * disables for all due to shared interrupts. Actual reporting is still per-pipe
286  * though.
287  *
288  * Returns the previous state of underrun reporting.
289  */
290 bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
291                                            enum pipe pipe, bool enable)
292 {
293         unsigned long flags;
294         bool ret;
295
296         spin_lock_irqsave(&dev_priv->irq_lock, flags);
297         ret = __intel_set_cpu_fifo_underrun_reporting(&dev_priv->drm, pipe,
298                                                       enable);
299         spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
300
301         return ret;
302 }
303
304 /**
305  * intel_set_pch_fifo_underrun_reporting - set PCH fifo underrun reporting state
306  * @dev_priv: i915 device instance
307  * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older)
308  * @enable: whether underruns should be reported or not
309  *
310  * This function makes us disable or enable PCH fifo underruns for a specific
311  * PCH transcoder. Notice that on some PCHs (e.g. CPT/PPT), disabling FIFO
312  * underrun reporting for one transcoder may also disable all the other PCH
313  * error interruts for the other transcoders, due to the fact that there's just
314  * one interrupt mask/enable bit for all the transcoders.
315  *
316  * Returns the previous state of underrun reporting.
317  */
318 bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
319                                            enum pipe pch_transcoder,
320                                            bool enable)
321 {
322         struct intel_crtc *crtc =
323                 intel_get_crtc_for_pipe(dev_priv, pch_transcoder);
324         unsigned long flags;
325         bool old;
326
327         /*
328          * NOTE: Pre-LPT has a fixed cpu pipe -> pch transcoder mapping, but LPT
329          * has only one pch transcoder A that all pipes can use. To avoid racy
330          * pch transcoder -> pipe lookups from interrupt code simply store the
331          * underrun statistics in crtc A. Since we never expose this anywhere
332          * nor use it outside of the fifo underrun code here using the "wrong"
333          * crtc on LPT won't cause issues.
334          */
335
336         spin_lock_irqsave(&dev_priv->irq_lock, flags);
337
338         old = !crtc->pch_fifo_underrun_disabled;
339         crtc->pch_fifo_underrun_disabled = !enable;
340
341         if (HAS_PCH_IBX(dev_priv))
342                 ibx_set_fifo_underrun_reporting(&dev_priv->drm,
343                                                 pch_transcoder,
344                                                 enable);
345         else
346                 cpt_set_fifo_underrun_reporting(&dev_priv->drm,
347                                                 pch_transcoder,
348                                                 enable, old);
349
350         spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
351         return old;
352 }
353
354 /**
355  * intel_cpu_fifo_underrun_irq_handler - handle CPU fifo underrun interrupt
356  * @dev_priv: i915 device instance
357  * @pipe: (CPU) pipe to set state for
358  *
359  * This handles a CPU fifo underrun interrupt, generating an underrun warning
360  * into dmesg if underrun reporting is enabled and then disables the underrun
361  * interrupt to avoid an irq storm.
362  */
363 void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
364                                          enum pipe pipe)
365 {
366         struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
367
368         /* We may be called too early in init, thanks BIOS! */
369         if (crtc == NULL)
370                 return;
371
372         /* GMCH can't disable fifo underruns, filter them. */
373         if (HAS_GMCH(dev_priv) &&
374             crtc->cpu_fifo_underrun_disabled)
375                 return;
376
377         if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) {
378                 trace_intel_cpu_fifo_underrun(dev_priv, pipe);
379                 DRM_ERROR("CPU pipe %c FIFO underrun\n",
380                           pipe_name(pipe));
381         }
382
383         intel_fbc_handle_fifo_underrun_irq(dev_priv);
384 }
385
386 /**
387  * intel_pch_fifo_underrun_irq_handler - handle PCH fifo underrun interrupt
388  * @dev_priv: i915 device instance
389  * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older)
390  *
391  * This handles a PCH fifo underrun interrupt, generating an underrun warning
392  * into dmesg if underrun reporting is enabled and then disables the underrun
393  * interrupt to avoid an irq storm.
394  */
395 void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
396                                          enum pipe pch_transcoder)
397 {
398         if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder,
399                                                   false)) {
400                 trace_intel_pch_fifo_underrun(dev_priv, pch_transcoder);
401                 DRM_ERROR("PCH transcoder %c FIFO underrun\n",
402                           pipe_name(pch_transcoder));
403         }
404 }
405
406 /**
407  * intel_check_cpu_fifo_underruns - check for CPU fifo underruns immediately
408  * @dev_priv: i915 device instance
409  *
410  * Check for CPU fifo underruns immediately. Useful on IVB/HSW where the shared
411  * error interrupt may have been disabled, and so CPU fifo underruns won't
412  * necessarily raise an interrupt, and on GMCH platforms where underruns never
413  * raise an interrupt.
414  */
415 void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv)
416 {
417         struct intel_crtc *crtc;
418
419         spin_lock_irq(&dev_priv->irq_lock);
420
421         for_each_intel_crtc(&dev_priv->drm, crtc) {
422                 if (crtc->cpu_fifo_underrun_disabled)
423                         continue;
424
425                 if (HAS_GMCH(dev_priv))
426                         i9xx_check_fifo_underruns(crtc);
427                 else if (IS_GEN(dev_priv, 7))
428                         ivybridge_check_fifo_underruns(crtc);
429         }
430
431         spin_unlock_irq(&dev_priv->irq_lock);
432 }
433
434 /**
435  * intel_check_pch_fifo_underruns - check for PCH fifo underruns immediately
436  * @dev_priv: i915 device instance
437  *
438  * Check for PCH fifo underruns immediately. Useful on CPT/PPT where the shared
439  * error interrupt may have been disabled, and so PCH fifo underruns won't
440  * necessarily raise an interrupt.
441  */
442 void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv)
443 {
444         struct intel_crtc *crtc;
445
446         spin_lock_irq(&dev_priv->irq_lock);
447
448         for_each_intel_crtc(&dev_priv->drm, crtc) {
449                 if (crtc->pch_fifo_underrun_disabled)
450                         continue;
451
452                 if (HAS_PCH_CPT(dev_priv))
453                         cpt_check_pch_fifo_underruns(crtc);
454         }
455
456         spin_unlock_irq(&dev_priv->irq_lock);
457 }