0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028 #include "i915_drv.h"
0029 #include "intel_de.h"
0030 #include "intel_display_trace.h"
0031 #include "intel_display_types.h"
0032 #include "intel_fbc.h"
0033 #include "intel_fifo_underrun.h"
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055 static bool ivb_can_enable_err_int(struct drm_device *dev)
0056 {
0057 struct drm_i915_private *dev_priv = to_i915(dev);
0058 struct intel_crtc *crtc;
0059 enum pipe pipe;
0060
0061 lockdep_assert_held(&dev_priv->irq_lock);
0062
0063 for_each_pipe(dev_priv, pipe) {
0064 crtc = intel_crtc_for_pipe(dev_priv, pipe);
0065
0066 if (crtc->cpu_fifo_underrun_disabled)
0067 return false;
0068 }
0069
0070 return true;
0071 }
0072
0073 static bool cpt_can_enable_serr_int(struct drm_device *dev)
0074 {
0075 struct drm_i915_private *dev_priv = to_i915(dev);
0076 enum pipe pipe;
0077 struct intel_crtc *crtc;
0078
0079 lockdep_assert_held(&dev_priv->irq_lock);
0080
0081 for_each_pipe(dev_priv, pipe) {
0082 crtc = intel_crtc_for_pipe(dev_priv, pipe);
0083
0084 if (crtc->pch_fifo_underrun_disabled)
0085 return false;
0086 }
0087
0088 return true;
0089 }
0090
0091 static void i9xx_check_fifo_underruns(struct intel_crtc *crtc)
0092 {
0093 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
0094 i915_reg_t reg = PIPESTAT(crtc->pipe);
0095 u32 enable_mask;
0096
0097 lockdep_assert_held(&dev_priv->irq_lock);
0098
0099 if ((intel_de_read(dev_priv, reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0)
0100 return;
0101
0102 enable_mask = i915_pipestat_enable_mask(dev_priv, crtc->pipe);
0103 intel_de_write(dev_priv, reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
0104 intel_de_posting_read(dev_priv, reg);
0105
0106 trace_intel_cpu_fifo_underrun(dev_priv, crtc->pipe);
0107 drm_err(&dev_priv->drm, "pipe %c underrun\n", pipe_name(crtc->pipe));
0108 }
0109
0110 static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev,
0111 enum pipe pipe,
0112 bool enable, bool old)
0113 {
0114 struct drm_i915_private *dev_priv = to_i915(dev);
0115 i915_reg_t reg = PIPESTAT(pipe);
0116
0117 lockdep_assert_held(&dev_priv->irq_lock);
0118
0119 if (enable) {
0120 u32 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe);
0121
0122 intel_de_write(dev_priv, reg,
0123 enable_mask | PIPE_FIFO_UNDERRUN_STATUS);
0124 intel_de_posting_read(dev_priv, reg);
0125 } else {
0126 if (old && intel_de_read(dev_priv, reg) & PIPE_FIFO_UNDERRUN_STATUS)
0127 drm_err(&dev_priv->drm, "pipe %c underrun\n",
0128 pipe_name(pipe));
0129 }
0130 }
0131
0132 static void ilk_set_fifo_underrun_reporting(struct drm_device *dev,
0133 enum pipe pipe, bool enable)
0134 {
0135 struct drm_i915_private *dev_priv = to_i915(dev);
0136 u32 bit = (pipe == PIPE_A) ?
0137 DE_PIPEA_FIFO_UNDERRUN : DE_PIPEB_FIFO_UNDERRUN;
0138
0139 if (enable)
0140 ilk_enable_display_irq(dev_priv, bit);
0141 else
0142 ilk_disable_display_irq(dev_priv, bit);
0143 }
0144
0145 static void ivb_check_fifo_underruns(struct intel_crtc *crtc)
0146 {
0147 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
0148 enum pipe pipe = crtc->pipe;
0149 u32 err_int = intel_de_read(dev_priv, GEN7_ERR_INT);
0150
0151 lockdep_assert_held(&dev_priv->irq_lock);
0152
0153 if ((err_int & ERR_INT_FIFO_UNDERRUN(pipe)) == 0)
0154 return;
0155
0156 intel_de_write(dev_priv, GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe));
0157 intel_de_posting_read(dev_priv, GEN7_ERR_INT);
0158
0159 trace_intel_cpu_fifo_underrun(dev_priv, pipe);
0160 drm_err(&dev_priv->drm, "fifo underrun on pipe %c\n", pipe_name(pipe));
0161 }
0162
0163 static void ivb_set_fifo_underrun_reporting(struct drm_device *dev,
0164 enum pipe pipe, bool enable,
0165 bool old)
0166 {
0167 struct drm_i915_private *dev_priv = to_i915(dev);
0168 if (enable) {
0169 intel_de_write(dev_priv, GEN7_ERR_INT,
0170 ERR_INT_FIFO_UNDERRUN(pipe));
0171
0172 if (!ivb_can_enable_err_int(dev))
0173 return;
0174
0175 ilk_enable_display_irq(dev_priv, DE_ERR_INT_IVB);
0176 } else {
0177 ilk_disable_display_irq(dev_priv, DE_ERR_INT_IVB);
0178
0179 if (old &&
0180 intel_de_read(dev_priv, GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) {
0181 drm_err(&dev_priv->drm,
0182 "uncleared fifo underrun on pipe %c\n",
0183 pipe_name(pipe));
0184 }
0185 }
0186 }
0187
0188 static u32
0189 icl_pipe_status_underrun_mask(struct drm_i915_private *dev_priv)
0190 {
0191 u32 mask = PIPE_STATUS_UNDERRUN;
0192
0193 if (DISPLAY_VER(dev_priv) >= 13)
0194 mask |= PIPE_STATUS_SOFT_UNDERRUN_XELPD |
0195 PIPE_STATUS_HARD_UNDERRUN_XELPD |
0196 PIPE_STATUS_PORT_UNDERRUN_XELPD;
0197
0198 return mask;
0199 }
0200
0201 static void bdw_set_fifo_underrun_reporting(struct drm_device *dev,
0202 enum pipe pipe, bool enable)
0203 {
0204 struct drm_i915_private *dev_priv = to_i915(dev);
0205 u32 mask = gen8_de_pipe_underrun_mask(dev_priv);
0206
0207 if (enable) {
0208 if (DISPLAY_VER(dev_priv) >= 11)
0209 intel_de_write(dev_priv, ICL_PIPESTATUS(pipe),
0210 icl_pipe_status_underrun_mask(dev_priv));
0211
0212 bdw_enable_pipe_irq(dev_priv, pipe, mask);
0213 } else {
0214 bdw_disable_pipe_irq(dev_priv, pipe, mask);
0215 }
0216 }
0217
0218 static void ibx_set_fifo_underrun_reporting(struct drm_device *dev,
0219 enum pipe pch_transcoder,
0220 bool enable)
0221 {
0222 struct drm_i915_private *dev_priv = to_i915(dev);
0223 u32 bit = (pch_transcoder == PIPE_A) ?
0224 SDE_TRANSA_FIFO_UNDER : SDE_TRANSB_FIFO_UNDER;
0225
0226 if (enable)
0227 ibx_enable_display_interrupt(dev_priv, bit);
0228 else
0229 ibx_disable_display_interrupt(dev_priv, bit);
0230 }
0231
0232 static void cpt_check_pch_fifo_underruns(struct intel_crtc *crtc)
0233 {
0234 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
0235 enum pipe pch_transcoder = crtc->pipe;
0236 u32 serr_int = intel_de_read(dev_priv, SERR_INT);
0237
0238 lockdep_assert_held(&dev_priv->irq_lock);
0239
0240 if ((serr_int & SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) == 0)
0241 return;
0242
0243 intel_de_write(dev_priv, SERR_INT,
0244 SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder));
0245 intel_de_posting_read(dev_priv, SERR_INT);
0246
0247 trace_intel_pch_fifo_underrun(dev_priv, pch_transcoder);
0248 drm_err(&dev_priv->drm, "pch fifo underrun on pch transcoder %c\n",
0249 pipe_name(pch_transcoder));
0250 }
0251
0252 static void cpt_set_fifo_underrun_reporting(struct drm_device *dev,
0253 enum pipe pch_transcoder,
0254 bool enable, bool old)
0255 {
0256 struct drm_i915_private *dev_priv = to_i915(dev);
0257
0258 if (enable) {
0259 intel_de_write(dev_priv, SERR_INT,
0260 SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder));
0261
0262 if (!cpt_can_enable_serr_int(dev))
0263 return;
0264
0265 ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT);
0266 } else {
0267 ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT);
0268
0269 if (old && intel_de_read(dev_priv, SERR_INT) &
0270 SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) {
0271 drm_err(&dev_priv->drm,
0272 "uncleared pch fifo underrun on pch transcoder %c\n",
0273 pipe_name(pch_transcoder));
0274 }
0275 }
0276 }
0277
0278 static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev,
0279 enum pipe pipe, bool enable)
0280 {
0281 struct drm_i915_private *dev_priv = to_i915(dev);
0282 struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
0283 bool old;
0284
0285 lockdep_assert_held(&dev_priv->irq_lock);
0286
0287 old = !crtc->cpu_fifo_underrun_disabled;
0288 crtc->cpu_fifo_underrun_disabled = !enable;
0289
0290 if (HAS_GMCH(dev_priv))
0291 i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old);
0292 else if (IS_IRONLAKE(dev_priv) || IS_SANDYBRIDGE(dev_priv))
0293 ilk_set_fifo_underrun_reporting(dev, pipe, enable);
0294 else if (DISPLAY_VER(dev_priv) == 7)
0295 ivb_set_fifo_underrun_reporting(dev, pipe, enable, old);
0296 else if (DISPLAY_VER(dev_priv) >= 8)
0297 bdw_set_fifo_underrun_reporting(dev, pipe, enable);
0298
0299 return old;
0300 }
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318 bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
0319 enum pipe pipe, bool enable)
0320 {
0321 unsigned long flags;
0322 bool ret;
0323
0324 spin_lock_irqsave(&dev_priv->irq_lock, flags);
0325 ret = __intel_set_cpu_fifo_underrun_reporting(&dev_priv->drm, pipe,
0326 enable);
0327 spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
0328
0329 return ret;
0330 }
0331
0332
0333
0334
0335
0336
0337
0338
0339
0340
0341
0342
0343
0344
0345
0346 bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv,
0347 enum pipe pch_transcoder,
0348 bool enable)
0349 {
0350 struct intel_crtc *crtc =
0351 intel_crtc_for_pipe(dev_priv, pch_transcoder);
0352 unsigned long flags;
0353 bool old;
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364 spin_lock_irqsave(&dev_priv->irq_lock, flags);
0365
0366 old = !crtc->pch_fifo_underrun_disabled;
0367 crtc->pch_fifo_underrun_disabled = !enable;
0368
0369 if (HAS_PCH_IBX(dev_priv))
0370 ibx_set_fifo_underrun_reporting(&dev_priv->drm,
0371 pch_transcoder,
0372 enable);
0373 else
0374 cpt_set_fifo_underrun_reporting(&dev_priv->drm,
0375 pch_transcoder,
0376 enable, old);
0377
0378 spin_unlock_irqrestore(&dev_priv->irq_lock, flags);
0379 return old;
0380 }
0381
0382
0383
0384
0385
0386
0387
0388
0389
0390
0391 void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
0392 enum pipe pipe)
0393 {
0394 struct intel_crtc *crtc = intel_crtc_for_pipe(dev_priv, pipe);
0395 u32 underruns = 0;
0396
0397
0398 if (crtc == NULL)
0399 return;
0400
0401
0402 if (HAS_GMCH(dev_priv) &&
0403 crtc->cpu_fifo_underrun_disabled)
0404 return;
0405
0406
0407
0408
0409
0410
0411
0412
0413
0414
0415
0416
0417 if (DISPLAY_VER(dev_priv) >= 11) {
0418 underruns = intel_de_read(dev_priv, ICL_PIPESTATUS(pipe)) &
0419 icl_pipe_status_underrun_mask(dev_priv);
0420 intel_de_write(dev_priv, ICL_PIPESTATUS(pipe), underruns);
0421 }
0422
0423 if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) {
0424 trace_intel_cpu_fifo_underrun(dev_priv, pipe);
0425
0426 if (DISPLAY_VER(dev_priv) >= 11)
0427 drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun: %s%s%s%s\n",
0428 pipe_name(pipe),
0429 underruns & PIPE_STATUS_SOFT_UNDERRUN_XELPD ? "soft," : "",
0430 underruns & PIPE_STATUS_HARD_UNDERRUN_XELPD ? "hard," : "",
0431 underruns & PIPE_STATUS_PORT_UNDERRUN_XELPD ? "port," : "",
0432 underruns & PIPE_STATUS_UNDERRUN ? "transcoder," : "");
0433 else
0434 drm_err(&dev_priv->drm, "CPU pipe %c FIFO underrun\n", pipe_name(pipe));
0435 }
0436
0437 intel_fbc_handle_fifo_underrun_irq(dev_priv);
0438 }
0439
0440
0441
0442
0443
0444
0445
0446
0447
0448
0449 void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv,
0450 enum pipe pch_transcoder)
0451 {
0452 if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder,
0453 false)) {
0454 trace_intel_pch_fifo_underrun(dev_priv, pch_transcoder);
0455 drm_err(&dev_priv->drm, "PCH transcoder %c FIFO underrun\n",
0456 pipe_name(pch_transcoder));
0457 }
0458 }
0459
0460
0461
0462
0463
0464
0465
0466
0467
0468
0469 void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv)
0470 {
0471 struct intel_crtc *crtc;
0472
0473 spin_lock_irq(&dev_priv->irq_lock);
0474
0475 for_each_intel_crtc(&dev_priv->drm, crtc) {
0476 if (crtc->cpu_fifo_underrun_disabled)
0477 continue;
0478
0479 if (HAS_GMCH(dev_priv))
0480 i9xx_check_fifo_underruns(crtc);
0481 else if (DISPLAY_VER(dev_priv) == 7)
0482 ivb_check_fifo_underruns(crtc);
0483 }
0484
0485 spin_unlock_irq(&dev_priv->irq_lock);
0486 }
0487
0488
0489
0490
0491
0492
0493
0494
0495
0496 void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv)
0497 {
0498 struct intel_crtc *crtc;
0499
0500 spin_lock_irq(&dev_priv->irq_lock);
0501
0502 for_each_intel_crtc(&dev_priv->drm, crtc) {
0503 if (crtc->pch_fifo_underrun_disabled)
0504 continue;
0505
0506 if (HAS_PCH_CPT(dev_priv))
0507 cpt_check_pch_fifo_underruns(crtc);
0508 }
0509
0510 spin_unlock_irq(&dev_priv->irq_lock);
0511 }