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