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