intel_fifo_underrun.c 14 KB

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