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