1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55static 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
73static 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
91static 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
110static 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
132static 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
145static 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
163static 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
188static u32
189icl_pipe_status_underrun_mask(struct drm_i915_private *dev_priv)
190{
191 u32 mask = PIPE_STATUS_UNDERRUN;
192
193 if (DISPLAY_VER(dev_priv) >= 13)
194 mask |= PIPE_STATUS_SOFT_UNDERRUN_XELPD |
195 PIPE_STATUS_HARD_UNDERRUN_XELPD |
196 PIPE_STATUS_PORT_UNDERRUN_XELPD;
197
198 return mask;
199}
200
201static void bdw_set_fifo_underrun_reporting(struct drm_device *dev,
202 enum pipe pipe, bool enable)
203{
204 struct drm_i915_private *dev_priv = to_i915(dev);
205 u32 mask = gen8_de_pipe_underrun_mask(dev_priv);
206
207 if (enable) {
208 if (DISPLAY_VER(dev_priv) >= 11)
209 intel_de_write(dev_priv, ICL_PIPESTATUS(pipe),
210 icl_pipe_status_underrun_mask(dev_priv));
211
212 bdw_enable_pipe_irq(dev_priv, pipe, mask);
213 } else {
214 bdw_disable_pipe_irq(dev_priv, pipe, mask);
215 }
216}
217
218static void ibx_set_fifo_underrun_reporting(struct drm_device *dev,
219 enum pipe pch_transcoder,
220 bool enable)
221{
222 struct drm_i915_private *dev_priv = to_i915(dev);
223 u32 bit = (pch_transcoder == PIPE_A) ?
224 SDE_TRANSA_FIFO_UNDER : SDE_TRANSB_FIFO_UNDER;
225
226 if (enable)
227 ibx_enable_display_interrupt(dev_priv, bit);
228 else
229 ibx_disable_display_interrupt(dev_priv, bit);
230}
231
232static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc)
233{
234 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
235 enum pipe pch_transcoder = crtc->pipe;
236 u32 serr_int = intel_de_read(dev_priv, SERR_INT);
237
238 lockdep_assert_held(&dev_priv->irq_lock);
239
240 if ((serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) == 0)
241 return;
242
243 intel_de_write(dev_priv, SERR_INT,
244 SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder));
245 intel_de_posting_read(dev_priv, SERR_INT);
246
247 trace_intel_pch_fifo_underrun(dev_priv, pch_transcoder);
248 drm_err(&dev_priv->drm, "pch fifo underrun on pch transcoder %c\n",
249 pipe_name(pch_transcoder));
250}
251
252static void cpt_set_fifo_underrun_reporting(struct drm_device *dev,
253 enum pipe pch_transcoder,
254 bool enable, bool old)
255{
256 struct drm_i915_private *dev_priv = to_i915(dev);
257
258 if (enable) {
259 intel_de_write(dev_priv, SERR_INT,
260 SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder));
261
262 if (!cpt_can_enable_serr_int(dev))
263 return;
264
265 ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT);
266 } else {
267 ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT);
268
269 if (old && intel_de_read(dev_priv, SERR_INT) &
270 SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) {
271 drm_err(&dev_priv->drm,
272 "uncleared pch fifo underrun on pch transcoder %c\n",
273 pipe_name(pch_transcoder));
274 }
275 }
276}
277
278static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
279 enum pipe pipe, bool enable)
280{
281 struct drm_i915_private *dev_priv = to_i915(dev);
282 struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
283 bool old;
284
285 lockdep_assert_held(&dev_priv->irq_lock);
286
287 old = !crtc->cpu_fifo_underrun_disabled;
288 crtc->cpu_fifo_underrun_disabled = !enable;
289
290 if (HAS_GMCH(dev_priv))
291 i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old);
292 else if (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv))
293 ilk_set_fifo_underrun_reporting(dev, pipe, enable);
294 else if (DISPLAY_VER(dev_priv) == 7)
295 ivb_set_fifo_underrun_reporting(dev, pipe, enable, old);
296 else if (DISPLAY_VER(dev_priv) >= 8)
297 bdw_set_fifo_underrun_reporting(dev, pipe, enable);
298
299 return old;
300}
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
319 enum pipe pipe, bool enable)
320{
321 unsigned long flags;
322 bool ret;
323
324 spin_lock_irqsave(&dev_priv->irq_lock, flags);
325 ret = __intel_set_cpu_fifo_underrun_reporting(&dev_priv->drm, pipe,
326 enable);
327 spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
328
329 return ret;
330}
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
347 enum pipe pch_transcoder,
348 bool enable)
349{
350 struct intel_crtc *crtc =
351 intel_get_crtc_for_pipe(dev_priv, pch_transcoder);
352 unsigned long flags;
353 bool old;
354
355
356
357
358
359
360
361
362
363
364 spin_lock_irqsave(&dev_priv->irq_lock, flags);
365
366 old = !crtc->pch_fifo_underrun_disabled;
367 crtc->pch_fifo_underrun_disabled = !enable;
368
369 if (HAS_PCH_IBX(dev_priv))
370 ibx_set_fifo_underrun_reporting(&dev_priv->drm,
371 pch_transcoder,
372 enable);
373 else
374 cpt_set_fifo_underrun_reporting(&dev_priv->drm,
375 pch_transcoder,
376 enable, old);
377
378 spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
379 return old;
380}
381
382
383
384
385
386
387
388
389
390
391void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
392 enum pipe pipe)
393{
394 struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe);
395 u32 underruns = 0;
396
397
398 if (crtc == NULL)
399 return;
400
401
402 if (HAS_GMCH(dev_priv) &&
403 crtc->cpu_fifo_underrun_disabled)
404 return;
405
406
407
408
409
410
411
412
413
414
415
416
417 if (DISPLAY_VER(dev_priv) >= 11) {
418 underruns = intel_de_read(dev_priv, ICL_PIPESTATUS(pipe)) &
419 icl_pipe_status_underrun_mask(dev_priv);
420 intel_de_write(dev_priv, ICL_PIPESTATUS(pipe), underruns);
421 }
422
423 if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) {
424 trace_intel_cpu_fifo_underrun(dev_priv, pipe);
425
426 if (DISPLAY_VER(dev_priv) >= 11)
427 drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun: %s%s%s%s\n",
428 pipe_name(pipe),
429 underruns & PIPE_STATUS_SOFT_UNDERRUN_XELPD ? "soft," : "",
430 underruns & PIPE_STATUS_HARD_UNDERRUN_XELPD ? "hard," : "",
431 underruns & PIPE_STATUS_PORT_UNDERRUN_XELPD ? "port," : "",
432 underruns & PIPE_STATUS_UNDERRUN ? "transcoder," : "");
433 else
434 drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe));
435 }
436
437 intel_fbc_handle_fifo_underrun_irq(dev_priv);
438}
439
440
441
442
443
444
445
446
447
448
449void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
450 enum pipe pch_transcoder)
451{
452 if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder,
453 false)) {
454 trace_intel_pch_fifo_underrun(dev_priv, pch_transcoder);
455 drm_err(&dev_priv->drm, "PCH transcoder %c FIFO underrun\n",
456 pipe_name(pch_transcoder));
457 }
458}
459
460
461
462
463
464
465
466
467
468
469void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv)
470{
471 struct intel_crtc *crtc;
472
473 spin_lock_irq(&dev_priv->irq_lock);
474
475 for_each_intel_crtc(&dev_priv->drm, crtc) {
476 if (crtc->cpu_fifo_underrun_disabled)
477 continue;
478
479 if (HAS_GMCH(dev_priv))
480 i9xx_check_fifo_underruns(crtc);
481 else if (DISPLAY_VER(dev_priv) == 7)
482 ivb_check_fifo_underruns(crtc);
483 }
484
485 spin_unlock_irq(&dev_priv->irq_lock);
486}
487
488
489
490
491
492
493
494
495
496void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv)
497{
498 struct intel_crtc *crtc;
499
500 spin_lock_irq(&dev_priv->irq_lock);
501
502 for_each_intel_crtc(&dev_priv->drm, crtc) {
503 if (crtc->pch_fifo_underrun_disabled)
504 continue;
505
506 if (HAS_PCH_CPT(dev_priv))
507 cpt_check_pch_fifo_underruns(crtc);
508 }
509
510 spin_unlock_irq(&dev_priv->irq_lock);
511}
512