1 /* $NetBSD: intel_fifo_underrun.c,v 1.2 2021/12/18 23:45:30 riastradh Exp $ */ 2 3 /* 4 * Copyright 2014 Intel Corporation 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 10 * and/or sell copies of the Software, and to permit persons to whom the 11 * Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 22 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 23 * IN THE SOFTWARE. 24 * 25 * Authors: 26 * Daniel Vetter <daniel.vetter (at) ffwll.ch> 27 * 28 */ 29 30 #include <sys/cdefs.h> 31 __KERNEL_RCSID(0, "$NetBSD: intel_fifo_underrun.c,v 1.2 2021/12/18 23:45:30 riastradh Exp $"); 32 33 #include "i915_drv.h" 34 #include "i915_trace.h" 35 #include "intel_display_types.h" 36 #include "intel_fbc.h" 37 #include "intel_fifo_underrun.h" 38 39 /** 40 * DOC: fifo underrun handling 41 * 42 * The i915 driver checks for display fifo underruns using the interrupt signals 43 * provided by the hardware. This is enabled by default and fairly useful to 44 * debug display issues, especially watermark settings. 45 * 46 * If an underrun is detected this is logged into dmesg. To avoid flooding logs 47 * and occupying the cpu underrun interrupts are disabled after the first 48 * occurrence until the next modeset on a given pipe. 49 * 50 * Note that underrun detection on gmch platforms is a bit more ugly since there 51 * is no interrupt (despite that the signalling bit is in the PIPESTAT pipe 52 * interrupt register). Also on some other platforms underrun interrupts are 53 * shared, which means that if we detect an underrun we need to disable underrun 54 * reporting on all pipes. 55 * 56 * The code also supports underrun detection on the PCH transcoder. 57 */ 58 59 static bool ivb_can_enable_err_int(struct drm_device *dev) 60 { 61 struct drm_i915_private *dev_priv = to_i915(dev); 62 struct intel_crtc *crtc; 63 enum pipe pipe; 64 65 lockdep_assert_held(&dev_priv->irq_lock); 66 67 for_each_pipe(dev_priv, pipe) { 68 crtc = intel_get_crtc_for_pipe(dev_priv, pipe); 69 70 if (crtc->cpu_fifo_underrun_disabled) 71 return false; 72 } 73 74 return true; 75 } 76 77 static bool cpt_can_enable_serr_int(struct drm_device *dev) 78 { 79 struct drm_i915_private *dev_priv = to_i915(dev); 80 enum pipe pipe; 81 struct intel_crtc *crtc; 82 83 lockdep_assert_held(&dev_priv->irq_lock); 84 85 for_each_pipe(dev_priv, pipe) { 86 crtc = intel_get_crtc_for_pipe(dev_priv, pipe); 87 88 if (crtc->pch_fifo_underrun_disabled) 89 return false; 90 } 91 92 return true; 93 } 94 95 static void i9xx_check_fifo_underruns(struct intel_crtc *crtc) 96 { 97 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 98 i915_reg_t reg = PIPESTAT(crtc->pipe); 99 u32 enable_mask; 100 101 lockdep_assert_held(&dev_priv->irq_lock); 102 103 if ((I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS) == 0) 104 return; 105 106 enable_mask = i915_pipestat_enable_mask(dev_priv, crtc->pipe); 107 I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS); 108 POSTING_READ(reg); 109 110 trace_intel_cpu_fifo_underrun(dev_priv, crtc->pipe); 111 DRM_ERROR("pipe %c underrun\n", pipe_name(crtc->pipe)); 112 } 113 114 static void i9xx_set_fifo_underrun_reporting(struct drm_device *dev, 115 enum pipe pipe, 116 bool enable, bool old) 117 { 118 struct drm_i915_private *dev_priv = to_i915(dev); 119 i915_reg_t reg = PIPESTAT(pipe); 120 121 lockdep_assert_held(&dev_priv->irq_lock); 122 123 if (enable) { 124 u32 enable_mask = i915_pipestat_enable_mask(dev_priv, pipe); 125 126 I915_WRITE(reg, enable_mask | PIPE_FIFO_UNDERRUN_STATUS); 127 POSTING_READ(reg); 128 } else { 129 if (old && I915_READ(reg) & PIPE_FIFO_UNDERRUN_STATUS) 130 DRM_ERROR("pipe %c underrun\n", pipe_name(pipe)); 131 } 132 } 133 134 static void ilk_set_fifo_underrun_reporting(struct drm_device *dev, 135 enum pipe pipe, bool enable) 136 { 137 struct drm_i915_private *dev_priv = to_i915(dev); 138 u32 bit = (pipe == PIPE_A) ? 139 DE_PIPEA_FIFO_UNDERRUN : DE_PIPEB_FIFO_UNDERRUN; 140 141 if (enable) 142 ilk_enable_display_irq(dev_priv, bit); 143 else 144 ilk_disable_display_irq(dev_priv, bit); 145 } 146 147 static void ivb_check_fifo_underruns(struct intel_crtc *crtc) 148 { 149 struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); 150 enum pipe pipe = crtc->pipe; 151 u32 err_int = I915_READ(GEN7_ERR_INT); 152 153 lockdep_assert_held(&dev_priv->irq_lock); 154 155 if ((err_int & ERR_INT_FIFO_UNDERRUN(pipe)) == 0) 156 return; 157 158 I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); 159 POSTING_READ(GEN7_ERR_INT); 160 161 trace_intel_cpu_fifo_underrun(dev_priv, pipe); 162 DRM_ERROR("fifo underrun on pipe %c\n", pipe_name(pipe)); 163 } 164 165 static void ivb_set_fifo_underrun_reporting(struct drm_device *dev, 166 enum pipe pipe, bool enable, 167 bool old) 168 { 169 struct drm_i915_private *dev_priv = to_i915(dev); 170 if (enable) { 171 I915_WRITE(GEN7_ERR_INT, ERR_INT_FIFO_UNDERRUN(pipe)); 172 173 if (!ivb_can_enable_err_int(dev)) 174 return; 175 176 ilk_enable_display_irq(dev_priv, DE_ERR_INT_IVB); 177 } else { 178 ilk_disable_display_irq(dev_priv, DE_ERR_INT_IVB); 179 180 if (old && 181 I915_READ(GEN7_ERR_INT) & ERR_INT_FIFO_UNDERRUN(pipe)) { 182 DRM_ERROR("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 = I915_READ(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 I915_WRITE(SERR_INT, SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)); 225 POSTING_READ(SERR_INT); 226 227 trace_intel_pch_fifo_underrun(dev_priv, pch_transcoder); 228 DRM_ERROR("pch fifo underrun on pch transcoder %c\n", 229 pipe_name(pch_transcoder)); 230 } 231 232 static void cpt_set_fifo_underrun_reporting(struct drm_device *dev, 233 enum pipe pch_transcoder, 234 bool enable, bool old) 235 { 236 struct drm_i915_private *dev_priv = to_i915(dev); 237 238 if (enable) { 239 I915_WRITE(SERR_INT, 240 SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)); 241 242 if (!cpt_can_enable_serr_int(dev)) 243 return; 244 245 ibx_enable_display_interrupt(dev_priv, SDE_ERROR_CPT); 246 } else { 247 ibx_disable_display_interrupt(dev_priv, SDE_ERROR_CPT); 248 249 if (old && I915_READ(SERR_INT) & 250 SERR_INT_TRANS_FIFO_UNDERRUN(pch_transcoder)) { 251 DRM_ERROR("uncleared pch fifo underrun on pch transcoder %c\n", 252 pipe_name(pch_transcoder)); 253 } 254 } 255 } 256 257 static bool __intel_set_cpu_fifo_underrun_reporting(struct drm_device *dev, 258 enum pipe pipe, bool enable) 259 { 260 struct drm_i915_private *dev_priv = to_i915(dev); 261 struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); 262 bool old; 263 264 lockdep_assert_held(&dev_priv->irq_lock); 265 266 old = !crtc->cpu_fifo_underrun_disabled; 267 crtc->cpu_fifo_underrun_disabled = !enable; 268 269 if (HAS_GMCH(dev_priv)) 270 i9xx_set_fifo_underrun_reporting(dev, pipe, enable, old); 271 else if (IS_GEN_RANGE(dev_priv, 5, 6)) 272 ilk_set_fifo_underrun_reporting(dev, pipe, enable); 273 else if (IS_GEN(dev_priv, 7)) 274 ivb_set_fifo_underrun_reporting(dev, pipe, enable, old); 275 else if (INTEL_GEN(dev_priv) >= 8) 276 bdw_set_fifo_underrun_reporting(dev, pipe, enable); 277 278 return old; 279 } 280 281 /** 282 * intel_set_cpu_fifo_underrun_reporting - set cpu fifo underrrun reporting state 283 * @dev_priv: i915 device instance 284 * @pipe: (CPU) pipe to set state for 285 * @enable: whether underruns should be reported or not 286 * 287 * This function sets the fifo underrun state for @pipe. It is used in the 288 * modeset code to avoid false positives since on many platforms underruns are 289 * expected when disabling or enabling the pipe. 290 * 291 * Notice that on some platforms disabling underrun reports for one pipe 292 * disables for all due to shared interrupts. Actual reporting is still per-pipe 293 * though. 294 * 295 * Returns the previous state of underrun reporting. 296 */ 297 bool intel_set_cpu_fifo_underrun_reporting(struct drm_i915_private *dev_priv, 298 enum pipe pipe, bool enable) 299 { 300 unsigned long flags; 301 bool ret; 302 303 spin_lock_irqsave(&dev_priv->irq_lock, flags); 304 ret = __intel_set_cpu_fifo_underrun_reporting(&dev_priv->drm, pipe, 305 enable); 306 spin_unlock_irqrestore(&dev_priv->irq_lock, flags); 307 308 return ret; 309 } 310 311 /** 312 * intel_set_pch_fifo_underrun_reporting - set PCH fifo underrun reporting state 313 * @dev_priv: i915 device instance 314 * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older) 315 * @enable: whether underruns should be reported or not 316 * 317 * This function makes us disable or enable PCH fifo underruns for a specific 318 * PCH transcoder. Notice that on some PCHs (e.g. CPT/PPT), disabling FIFO 319 * underrun reporting for one transcoder may also disable all the other PCH 320 * error interruts for the other transcoders, due to the fact that there's just 321 * one interrupt mask/enable bit for all the transcoders. 322 * 323 * Returns the previous state of underrun reporting. 324 */ 325 bool intel_set_pch_fifo_underrun_reporting(struct drm_i915_private *dev_priv, 326 enum pipe pch_transcoder, 327 bool enable) 328 { 329 struct intel_crtc *crtc = 330 intel_get_crtc_for_pipe(dev_priv, pch_transcoder); 331 unsigned long flags; 332 bool old; 333 334 /* 335 * NOTE: Pre-LPT has a fixed cpu pipe -> pch transcoder mapping, but LPT 336 * has only one pch transcoder A that all pipes can use. To avoid racy 337 * pch transcoder -> pipe lookups from interrupt code simply store the 338 * underrun statistics in crtc A. Since we never expose this anywhere 339 * nor use it outside of the fifo underrun code here using the "wrong" 340 * crtc on LPT won't cause issues. 341 */ 342 343 spin_lock_irqsave(&dev_priv->irq_lock, flags); 344 345 old = !crtc->pch_fifo_underrun_disabled; 346 crtc->pch_fifo_underrun_disabled = !enable; 347 348 if (HAS_PCH_IBX(dev_priv)) 349 ibx_set_fifo_underrun_reporting(&dev_priv->drm, 350 pch_transcoder, 351 enable); 352 else 353 cpt_set_fifo_underrun_reporting(&dev_priv->drm, 354 pch_transcoder, 355 enable, old); 356 357 spin_unlock_irqrestore(&dev_priv->irq_lock, flags); 358 return old; 359 } 360 361 /** 362 * intel_cpu_fifo_underrun_irq_handler - handle CPU fifo underrun interrupt 363 * @dev_priv: i915 device instance 364 * @pipe: (CPU) pipe to set state for 365 * 366 * This handles a CPU fifo underrun interrupt, generating an underrun warning 367 * into dmesg if underrun reporting is enabled and then disables the underrun 368 * interrupt to avoid an irq storm. 369 */ 370 void intel_cpu_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, 371 enum pipe pipe) 372 { 373 struct intel_crtc *crtc = intel_get_crtc_for_pipe(dev_priv, pipe); 374 375 /* We may be called too early in init, thanks BIOS! */ 376 if (crtc == NULL) 377 return; 378 379 /* GMCH can't disable fifo underruns, filter them. */ 380 if (HAS_GMCH(dev_priv) && 381 crtc->cpu_fifo_underrun_disabled) 382 return; 383 384 if (intel_set_cpu_fifo_underrun_reporting(dev_priv, pipe, false)) { 385 trace_intel_cpu_fifo_underrun(dev_priv, pipe); 386 DRM_ERROR("CPU pipe %c FIFO underrun\n", 387 pipe_name(pipe)); 388 } 389 390 intel_fbc_handle_fifo_underrun_irq(dev_priv); 391 } 392 393 /** 394 * intel_pch_fifo_underrun_irq_handler - handle PCH fifo underrun interrupt 395 * @dev_priv: i915 device instance 396 * @pch_transcoder: the PCH transcoder (same as pipe on IVB and older) 397 * 398 * This handles a PCH fifo underrun interrupt, generating an underrun warning 399 * into dmesg if underrun reporting is enabled and then disables the underrun 400 * interrupt to avoid an irq storm. 401 */ 402 void intel_pch_fifo_underrun_irq_handler(struct drm_i915_private *dev_priv, 403 enum pipe pch_transcoder) 404 { 405 if (intel_set_pch_fifo_underrun_reporting(dev_priv, pch_transcoder, 406 false)) { 407 trace_intel_pch_fifo_underrun(dev_priv, pch_transcoder); 408 DRM_ERROR("PCH transcoder %c FIFO underrun\n", 409 pipe_name(pch_transcoder)); 410 } 411 } 412 413 /** 414 * intel_check_cpu_fifo_underruns - check for CPU fifo underruns immediately 415 * @dev_priv: i915 device instance 416 * 417 * Check for CPU fifo underruns immediately. Useful on IVB/HSW where the shared 418 * error interrupt may have been disabled, and so CPU fifo underruns won't 419 * necessarily raise an interrupt, and on GMCH platforms where underruns never 420 * raise an interrupt. 421 */ 422 void intel_check_cpu_fifo_underruns(struct drm_i915_private *dev_priv) 423 { 424 struct intel_crtc *crtc; 425 426 spin_lock_irq(&dev_priv->irq_lock); 427 428 for_each_intel_crtc(&dev_priv->drm, crtc) { 429 if (crtc->cpu_fifo_underrun_disabled) 430 continue; 431 432 if (HAS_GMCH(dev_priv)) 433 i9xx_check_fifo_underruns(crtc); 434 else if (IS_GEN(dev_priv, 7)) 435 ivb_check_fifo_underruns(crtc); 436 } 437 438 spin_unlock_irq(&dev_priv->irq_lock); 439 } 440 441 /** 442 * intel_check_pch_fifo_underruns - check for PCH fifo underruns immediately 443 * @dev_priv: i915 device instance 444 * 445 * Check for PCH fifo underruns immediately. Useful on CPT/PPT where the shared 446 * error interrupt may have been disabled, and so PCH fifo underruns won't 447 * necessarily raise an interrupt. 448 */ 449 void intel_check_pch_fifo_underruns(struct drm_i915_private *dev_priv) 450 { 451 struct intel_crtc *crtc; 452 453 spin_lock_irq(&dev_priv->irq_lock); 454 455 for_each_intel_crtc(&dev_priv->drm, crtc) { 456 if (crtc->pch_fifo_underrun_disabled) 457 continue; 458 459 if (HAS_PCH_CPT(dev_priv)) 460 cpt_check_pch_fifo_underruns(crtc); 461 } 462 463 spin_unlock_irq(&dev_priv->irq_lock); 464 } 465