intel_fifo_underrun.c 14 KB

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