linux/drivers/gpu/drm/i915/display/intel_fdi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: MIT
   2/*
   3 * Copyright © 2020 Intel Corporation
   4 */
   5#include "intel_atomic.h"
   6#include "intel_ddi.h"
   7#include "intel_de.h"
   8#include "intel_display_types.h"
   9#include "intel_fdi.h"
  10
  11/* units of 100MHz */
  12static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state)
  13{
  14        if (crtc_state->hw.enable && crtc_state->has_pch_encoder)
  15                return crtc_state->fdi_lanes;
  16
  17        return 0;
  18}
  19
  20static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
  21                               struct intel_crtc_state *pipe_config)
  22{
  23        struct drm_i915_private *dev_priv = to_i915(dev);
  24        struct drm_atomic_state *state = pipe_config->uapi.state;
  25        struct intel_crtc *other_crtc;
  26        struct intel_crtc_state *other_crtc_state;
  27
  28        drm_dbg_kms(&dev_priv->drm,
  29                    "checking fdi config on pipe %c, lanes %i\n",
  30                    pipe_name(pipe), pipe_config->fdi_lanes);
  31        if (pipe_config->fdi_lanes > 4) {
  32                drm_dbg_kms(&dev_priv->drm,
  33                            "invalid fdi lane config on pipe %c: %i lanes\n",
  34                            pipe_name(pipe), pipe_config->fdi_lanes);
  35                return -EINVAL;
  36        }
  37
  38        if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
  39                if (pipe_config->fdi_lanes > 2) {
  40                        drm_dbg_kms(&dev_priv->drm,
  41                                    "only 2 lanes on haswell, required: %i lanes\n",
  42                                    pipe_config->fdi_lanes);
  43                        return -EINVAL;
  44                } else {
  45                        return 0;
  46                }
  47        }
  48
  49        if (INTEL_NUM_PIPES(dev_priv) == 2)
  50                return 0;
  51
  52        /* Ivybridge 3 pipe is really complicated */
  53        switch (pipe) {
  54        case PIPE_A:
  55                return 0;
  56        case PIPE_B:
  57                if (pipe_config->fdi_lanes <= 2)
  58                        return 0;
  59
  60                other_crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_C);
  61                other_crtc_state =
  62                        intel_atomic_get_crtc_state(state, other_crtc);
  63                if (IS_ERR(other_crtc_state))
  64                        return PTR_ERR(other_crtc_state);
  65
  66                if (pipe_required_fdi_lanes(other_crtc_state) > 0) {
  67                        drm_dbg_kms(&dev_priv->drm,
  68                                    "invalid shared fdi lane config on pipe %c: %i lanes\n",
  69                                    pipe_name(pipe), pipe_config->fdi_lanes);
  70                        return -EINVAL;
  71                }
  72                return 0;
  73        case PIPE_C:
  74                if (pipe_config->fdi_lanes > 2) {
  75                        drm_dbg_kms(&dev_priv->drm,
  76                                    "only 2 lanes on pipe %c: required %i lanes\n",
  77                                    pipe_name(pipe), pipe_config->fdi_lanes);
  78                        return -EINVAL;
  79                }
  80
  81                other_crtc = intel_get_crtc_for_pipe(dev_priv, PIPE_B);
  82                other_crtc_state =
  83                        intel_atomic_get_crtc_state(state, other_crtc);
  84                if (IS_ERR(other_crtc_state))
  85                        return PTR_ERR(other_crtc_state);
  86
  87                if (pipe_required_fdi_lanes(other_crtc_state) > 2) {
  88                        drm_dbg_kms(&dev_priv->drm,
  89                                    "fdi link B uses too many lanes to enable link C\n");
  90                        return -EINVAL;
  91                }
  92                return 0;
  93        default:
  94                BUG();
  95        }
  96}
  97
  98int ilk_fdi_compute_config(struct intel_crtc *crtc,
  99                           struct intel_crtc_state *pipe_config)
 100{
 101        struct drm_device *dev = crtc->base.dev;
 102        struct drm_i915_private *i915 = to_i915(dev);
 103        const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
 104        int lane, link_bw, fdi_dotclock, ret;
 105        bool needs_recompute = false;
 106
 107retry:
 108        /* FDI is a binary signal running at ~2.7GHz, encoding
 109         * each output octet as 10 bits. The actual frequency
 110         * is stored as a divider into a 100MHz clock, and the
 111         * mode pixel clock is stored in units of 1KHz.
 112         * Hence the bw of each lane in terms of the mode signal
 113         * is:
 114         */
 115        link_bw = intel_fdi_link_freq(i915, pipe_config);
 116
 117        fdi_dotclock = adjusted_mode->crtc_clock;
 118
 119        lane = ilk_get_lanes_required(fdi_dotclock, link_bw,
 120                                      pipe_config->pipe_bpp);
 121
 122        pipe_config->fdi_lanes = lane;
 123
 124        intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
 125                               link_bw, &pipe_config->fdi_m_n, false, false);
 126
 127        ret = ilk_check_fdi_lanes(dev, crtc->pipe, pipe_config);
 128        if (ret == -EDEADLK)
 129                return ret;
 130
 131        if (ret == -EINVAL && pipe_config->pipe_bpp > 6*3) {
 132                pipe_config->pipe_bpp -= 2*3;
 133                drm_dbg_kms(&i915->drm,
 134                            "fdi link bw constraint, reducing pipe bpp to %i\n",
 135                            pipe_config->pipe_bpp);
 136                needs_recompute = true;
 137                pipe_config->bw_constrained = true;
 138
 139                goto retry;
 140        }
 141
 142        if (needs_recompute)
 143                return I915_DISPLAY_CONFIG_RETRY;
 144
 145        return ret;
 146}
 147
 148void intel_fdi_normal_train(struct intel_crtc *crtc)
 149{
 150        struct drm_device *dev = crtc->base.dev;
 151        struct drm_i915_private *dev_priv = to_i915(dev);
 152        enum pipe pipe = crtc->pipe;
 153        i915_reg_t reg;
 154        u32 temp;
 155
 156        /* enable normal train */
 157        reg = FDI_TX_CTL(pipe);
 158        temp = intel_de_read(dev_priv, reg);
 159        if (IS_IVYBRIDGE(dev_priv)) {
 160                temp &= ~FDI_LINK_TRAIN_NONE_IVB;
 161                temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE;
 162        } else {
 163                temp &= ~FDI_LINK_TRAIN_NONE;
 164                temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
 165        }
 166        intel_de_write(dev_priv, reg, temp);
 167
 168        reg = FDI_RX_CTL(pipe);
 169        temp = intel_de_read(dev_priv, reg);
 170        if (HAS_PCH_CPT(dev_priv)) {
 171                temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
 172                temp |= FDI_LINK_TRAIN_NORMAL_CPT;
 173        } else {
 174                temp &= ~FDI_LINK_TRAIN_NONE;
 175                temp |= FDI_LINK_TRAIN_NONE;
 176        }
 177        intel_de_write(dev_priv, reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);
 178
 179        /* wait one idle pattern time */
 180        intel_de_posting_read(dev_priv, reg);
 181        udelay(1000);
 182
 183        /* IVB wants error correction enabled */
 184        if (IS_IVYBRIDGE(dev_priv))
 185                intel_de_write(dev_priv, reg,
 186                               intel_de_read(dev_priv, reg) | FDI_FS_ERRC_ENABLE | FDI_FE_ERRC_ENABLE);
 187}
 188
 189/* The FDI link training functions for ILK/Ibexpeak. */
 190static void ilk_fdi_link_train(struct intel_crtc *crtc,
 191                               const struct intel_crtc_state *crtc_state)
 192{
 193        struct drm_device *dev = crtc->base.dev;
 194        struct drm_i915_private *dev_priv = to_i915(dev);
 195        enum pipe pipe = crtc->pipe;
 196        i915_reg_t reg;
 197        u32 temp, tries;
 198
 199        /* FDI needs bits from pipe first */
 200        assert_pipe_enabled(dev_priv, crtc_state->cpu_transcoder);
 201
 202        /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
 203           for train result */
 204        reg = FDI_RX_IMR(pipe);
 205        temp = intel_de_read(dev_priv, reg);
 206        temp &= ~FDI_RX_SYMBOL_LOCK;
 207        temp &= ~FDI_RX_BIT_LOCK;
 208        intel_de_write(dev_priv, reg, temp);
 209        intel_de_read(dev_priv, reg);
 210        udelay(150);
 211
 212        /* enable CPU FDI TX and PCH FDI RX */
 213        reg = FDI_TX_CTL(pipe);
 214        temp = intel_de_read(dev_priv, reg);
 215        temp &= ~FDI_DP_PORT_WIDTH_MASK;
 216        temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
 217        temp &= ~FDI_LINK_TRAIN_NONE;
 218        temp |= FDI_LINK_TRAIN_PATTERN_1;
 219        intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE);
 220
 221        reg = FDI_RX_CTL(pipe);
 222        temp = intel_de_read(dev_priv, reg);
 223        temp &= ~FDI_LINK_TRAIN_NONE;
 224        temp |= FDI_LINK_TRAIN_PATTERN_1;
 225        intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE);
 226
 227        intel_de_posting_read(dev_priv, reg);
 228        udelay(150);
 229
 230        /* Ironlake workaround, enable clock pointer after FDI enable*/
 231        intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe),
 232                       FDI_RX_PHASE_SYNC_POINTER_OVR);
 233        intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe),
 234                       FDI_RX_PHASE_SYNC_POINTER_OVR | FDI_RX_PHASE_SYNC_POINTER_EN);
 235
 236        reg = FDI_RX_IIR(pipe);
 237        for (tries = 0; tries < 5; tries++) {
 238                temp = intel_de_read(dev_priv, reg);
 239                drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
 240
 241                if ((temp & FDI_RX_BIT_LOCK)) {
 242                        drm_dbg_kms(&dev_priv->drm, "FDI train 1 done.\n");
 243                        intel_de_write(dev_priv, reg, temp | FDI_RX_BIT_LOCK);
 244                        break;
 245                }
 246        }
 247        if (tries == 5)
 248                drm_err(&dev_priv->drm, "FDI train 1 fail!\n");
 249
 250        /* Train 2 */
 251        reg = FDI_TX_CTL(pipe);
 252        temp = intel_de_read(dev_priv, reg);
 253        temp &= ~FDI_LINK_TRAIN_NONE;
 254        temp |= FDI_LINK_TRAIN_PATTERN_2;
 255        intel_de_write(dev_priv, reg, temp);
 256
 257        reg = FDI_RX_CTL(pipe);
 258        temp = intel_de_read(dev_priv, reg);
 259        temp &= ~FDI_LINK_TRAIN_NONE;
 260        temp |= FDI_LINK_TRAIN_PATTERN_2;
 261        intel_de_write(dev_priv, reg, temp);
 262
 263        intel_de_posting_read(dev_priv, reg);
 264        udelay(150);
 265
 266        reg = FDI_RX_IIR(pipe);
 267        for (tries = 0; tries < 5; tries++) {
 268                temp = intel_de_read(dev_priv, reg);
 269                drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
 270
 271                if (temp & FDI_RX_SYMBOL_LOCK) {
 272                        intel_de_write(dev_priv, reg,
 273                                       temp | FDI_RX_SYMBOL_LOCK);
 274                        drm_dbg_kms(&dev_priv->drm, "FDI train 2 done.\n");
 275                        break;
 276                }
 277        }
 278        if (tries == 5)
 279                drm_err(&dev_priv->drm, "FDI train 2 fail!\n");
 280
 281        drm_dbg_kms(&dev_priv->drm, "FDI train done\n");
 282
 283}
 284
 285static const int snb_b_fdi_train_param[] = {
 286        FDI_LINK_TRAIN_400MV_0DB_SNB_B,
 287        FDI_LINK_TRAIN_400MV_6DB_SNB_B,
 288        FDI_LINK_TRAIN_600MV_3_5DB_SNB_B,
 289        FDI_LINK_TRAIN_800MV_0DB_SNB_B,
 290};
 291
 292/* The FDI link training functions for SNB/Cougarpoint. */
 293static void gen6_fdi_link_train(struct intel_crtc *crtc,
 294                                const struct intel_crtc_state *crtc_state)
 295{
 296        struct drm_device *dev = crtc->base.dev;
 297        struct drm_i915_private *dev_priv = to_i915(dev);
 298        enum pipe pipe = crtc->pipe;
 299        i915_reg_t reg;
 300        u32 temp, i, retry;
 301
 302        /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
 303           for train result */
 304        reg = FDI_RX_IMR(pipe);
 305        temp = intel_de_read(dev_priv, reg);
 306        temp &= ~FDI_RX_SYMBOL_LOCK;
 307        temp &= ~FDI_RX_BIT_LOCK;
 308        intel_de_write(dev_priv, reg, temp);
 309
 310        intel_de_posting_read(dev_priv, reg);
 311        udelay(150);
 312
 313        /* enable CPU FDI TX and PCH FDI RX */
 314        reg = FDI_TX_CTL(pipe);
 315        temp = intel_de_read(dev_priv, reg);
 316        temp &= ~FDI_DP_PORT_WIDTH_MASK;
 317        temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
 318        temp &= ~FDI_LINK_TRAIN_NONE;
 319        temp |= FDI_LINK_TRAIN_PATTERN_1;
 320        temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
 321        /* SNB-B */
 322        temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
 323        intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE);
 324
 325        intel_de_write(dev_priv, FDI_RX_MISC(pipe),
 326                       FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
 327
 328        reg = FDI_RX_CTL(pipe);
 329        temp = intel_de_read(dev_priv, reg);
 330        if (HAS_PCH_CPT(dev_priv)) {
 331                temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
 332                temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
 333        } else {
 334                temp &= ~FDI_LINK_TRAIN_NONE;
 335                temp |= FDI_LINK_TRAIN_PATTERN_1;
 336        }
 337        intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE);
 338
 339        intel_de_posting_read(dev_priv, reg);
 340        udelay(150);
 341
 342        for (i = 0; i < 4; i++) {
 343                reg = FDI_TX_CTL(pipe);
 344                temp = intel_de_read(dev_priv, reg);
 345                temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
 346                temp |= snb_b_fdi_train_param[i];
 347                intel_de_write(dev_priv, reg, temp);
 348
 349                intel_de_posting_read(dev_priv, reg);
 350                udelay(500);
 351
 352                for (retry = 0; retry < 5; retry++) {
 353                        reg = FDI_RX_IIR(pipe);
 354                        temp = intel_de_read(dev_priv, reg);
 355                        drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
 356                        if (temp & FDI_RX_BIT_LOCK) {
 357                                intel_de_write(dev_priv, reg,
 358                                               temp | FDI_RX_BIT_LOCK);
 359                                drm_dbg_kms(&dev_priv->drm,
 360                                            "FDI train 1 done.\n");
 361                                break;
 362                        }
 363                        udelay(50);
 364                }
 365                if (retry < 5)
 366                        break;
 367        }
 368        if (i == 4)
 369                drm_err(&dev_priv->drm, "FDI train 1 fail!\n");
 370
 371        /* Train 2 */
 372        reg = FDI_TX_CTL(pipe);
 373        temp = intel_de_read(dev_priv, reg);
 374        temp &= ~FDI_LINK_TRAIN_NONE;
 375        temp |= FDI_LINK_TRAIN_PATTERN_2;
 376        if (IS_SANDYBRIDGE(dev_priv)) {
 377                temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
 378                /* SNB-B */
 379                temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
 380        }
 381        intel_de_write(dev_priv, reg, temp);
 382
 383        reg = FDI_RX_CTL(pipe);
 384        temp = intel_de_read(dev_priv, reg);
 385        if (HAS_PCH_CPT(dev_priv)) {
 386                temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
 387                temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
 388        } else {
 389                temp &= ~FDI_LINK_TRAIN_NONE;
 390                temp |= FDI_LINK_TRAIN_PATTERN_2;
 391        }
 392        intel_de_write(dev_priv, reg, temp);
 393
 394        intel_de_posting_read(dev_priv, reg);
 395        udelay(150);
 396
 397        for (i = 0; i < 4; i++) {
 398                reg = FDI_TX_CTL(pipe);
 399                temp = intel_de_read(dev_priv, reg);
 400                temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
 401                temp |= snb_b_fdi_train_param[i];
 402                intel_de_write(dev_priv, reg, temp);
 403
 404                intel_de_posting_read(dev_priv, reg);
 405                udelay(500);
 406
 407                for (retry = 0; retry < 5; retry++) {
 408                        reg = FDI_RX_IIR(pipe);
 409                        temp = intel_de_read(dev_priv, reg);
 410                        drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
 411                        if (temp & FDI_RX_SYMBOL_LOCK) {
 412                                intel_de_write(dev_priv, reg,
 413                                               temp | FDI_RX_SYMBOL_LOCK);
 414                                drm_dbg_kms(&dev_priv->drm,
 415                                            "FDI train 2 done.\n");
 416                                break;
 417                        }
 418                        udelay(50);
 419                }
 420                if (retry < 5)
 421                        break;
 422        }
 423        if (i == 4)
 424                drm_err(&dev_priv->drm, "FDI train 2 fail!\n");
 425
 426        drm_dbg_kms(&dev_priv->drm, "FDI train done.\n");
 427}
 428
 429/* Manual link training for Ivy Bridge A0 parts */
 430static void ivb_manual_fdi_link_train(struct intel_crtc *crtc,
 431                                      const struct intel_crtc_state *crtc_state)
 432{
 433        struct drm_device *dev = crtc->base.dev;
 434        struct drm_i915_private *dev_priv = to_i915(dev);
 435        enum pipe pipe = crtc->pipe;
 436        i915_reg_t reg;
 437        u32 temp, i, j;
 438
 439        /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
 440           for train result */
 441        reg = FDI_RX_IMR(pipe);
 442        temp = intel_de_read(dev_priv, reg);
 443        temp &= ~FDI_RX_SYMBOL_LOCK;
 444        temp &= ~FDI_RX_BIT_LOCK;
 445        intel_de_write(dev_priv, reg, temp);
 446
 447        intel_de_posting_read(dev_priv, reg);
 448        udelay(150);
 449
 450        drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR before link train 0x%x\n",
 451                    intel_de_read(dev_priv, FDI_RX_IIR(pipe)));
 452
 453        /* Try each vswing and preemphasis setting twice before moving on */
 454        for (j = 0; j < ARRAY_SIZE(snb_b_fdi_train_param) * 2; j++) {
 455                /* disable first in case we need to retry */
 456                reg = FDI_TX_CTL(pipe);
 457                temp = intel_de_read(dev_priv, reg);
 458                temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB);
 459                temp &= ~FDI_TX_ENABLE;
 460                intel_de_write(dev_priv, reg, temp);
 461
 462                reg = FDI_RX_CTL(pipe);
 463                temp = intel_de_read(dev_priv, reg);
 464                temp &= ~FDI_LINK_TRAIN_AUTO;
 465                temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
 466                temp &= ~FDI_RX_ENABLE;
 467                intel_de_write(dev_priv, reg, temp);
 468
 469                /* enable CPU FDI TX and PCH FDI RX */
 470                reg = FDI_TX_CTL(pipe);
 471                temp = intel_de_read(dev_priv, reg);
 472                temp &= ~FDI_DP_PORT_WIDTH_MASK;
 473                temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
 474                temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
 475                temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
 476                temp |= snb_b_fdi_train_param[j/2];
 477                temp |= FDI_COMPOSITE_SYNC;
 478                intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE);
 479
 480                intel_de_write(dev_priv, FDI_RX_MISC(pipe),
 481                               FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
 482
 483                reg = FDI_RX_CTL(pipe);
 484                temp = intel_de_read(dev_priv, reg);
 485                temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
 486                temp |= FDI_COMPOSITE_SYNC;
 487                intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE);
 488
 489                intel_de_posting_read(dev_priv, reg);
 490                udelay(1); /* should be 0.5us */
 491
 492                for (i = 0; i < 4; i++) {
 493                        reg = FDI_RX_IIR(pipe);
 494                        temp = intel_de_read(dev_priv, reg);
 495                        drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
 496
 497                        if (temp & FDI_RX_BIT_LOCK ||
 498                            (intel_de_read(dev_priv, reg) & FDI_RX_BIT_LOCK)) {
 499                                intel_de_write(dev_priv, reg,
 500                                               temp | FDI_RX_BIT_LOCK);
 501                                drm_dbg_kms(&dev_priv->drm,
 502                                            "FDI train 1 done, level %i.\n",
 503                                            i);
 504                                break;
 505                        }
 506                        udelay(1); /* should be 0.5us */
 507                }
 508                if (i == 4) {
 509                        drm_dbg_kms(&dev_priv->drm,
 510                                    "FDI train 1 fail on vswing %d\n", j / 2);
 511                        continue;
 512                }
 513
 514                /* Train 2 */
 515                reg = FDI_TX_CTL(pipe);
 516                temp = intel_de_read(dev_priv, reg);
 517                temp &= ~FDI_LINK_TRAIN_NONE_IVB;
 518                temp |= FDI_LINK_TRAIN_PATTERN_2_IVB;
 519                intel_de_write(dev_priv, reg, temp);
 520
 521                reg = FDI_RX_CTL(pipe);
 522                temp = intel_de_read(dev_priv, reg);
 523                temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
 524                temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
 525                intel_de_write(dev_priv, reg, temp);
 526
 527                intel_de_posting_read(dev_priv, reg);
 528                udelay(2); /* should be 1.5us */
 529
 530                for (i = 0; i < 4; i++) {
 531                        reg = FDI_RX_IIR(pipe);
 532                        temp = intel_de_read(dev_priv, reg);
 533                        drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
 534
 535                        if (temp & FDI_RX_SYMBOL_LOCK ||
 536                            (intel_de_read(dev_priv, reg) & FDI_RX_SYMBOL_LOCK)) {
 537                                intel_de_write(dev_priv, reg,
 538                                               temp | FDI_RX_SYMBOL_LOCK);
 539                                drm_dbg_kms(&dev_priv->drm,
 540                                            "FDI train 2 done, level %i.\n",
 541                                            i);
 542                                goto train_done;
 543                        }
 544                        udelay(2); /* should be 1.5us */
 545                }
 546                if (i == 4)
 547                        drm_dbg_kms(&dev_priv->drm,
 548                                    "FDI train 2 fail on vswing %d\n", j / 2);
 549        }
 550
 551train_done:
 552        drm_dbg_kms(&dev_priv->drm, "FDI train done.\n");
 553}
 554
 555/* Starting with Haswell, different DDI ports can work in FDI mode for
 556 * connection to the PCH-located connectors. For this, it is necessary to train
 557 * both the DDI port and PCH receiver for the desired DDI buffer settings.
 558 *
 559 * The recommended port to work in FDI mode is DDI E, which we use here. Also,
 560 * please note that when FDI mode is active on DDI E, it shares 2 lines with
 561 * DDI A (which is used for eDP)
 562 */
 563void hsw_fdi_link_train(struct intel_encoder *encoder,
 564                        const struct intel_crtc_state *crtc_state)
 565{
 566        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 567        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 568        u32 temp, i, rx_ctl_val;
 569        int n_entries;
 570
 571        encoder->get_buf_trans(encoder, crtc_state, &n_entries);
 572
 573        hsw_prepare_dp_ddi_buffers(encoder, crtc_state);
 574
 575        /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
 576         * mode set "sequence for CRT port" document:
 577         * - TP1 to TP2 time with the default value
 578         * - FDI delay to 90h
 579         *
 580         * WaFDIAutoLinkSetTimingOverrride:hsw
 581         */
 582        intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A),
 583                       FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2) | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
 584
 585        /* Enable the PCH Receiver FDI PLL */
 586        rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
 587                     FDI_RX_PLL_ENABLE |
 588                     FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
 589        intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
 590        intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A));
 591        udelay(220);
 592
 593        /* Switch from Rawclk to PCDclk */
 594        rx_ctl_val |= FDI_PCDCLK;
 595        intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
 596
 597        /* Configure Port Clock Select */
 598        drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll->info->id != DPLL_ID_SPLL);
 599        intel_ddi_enable_clock(encoder, crtc_state);
 600
 601        /* Start the training iterating through available voltages and emphasis,
 602         * testing each value twice. */
 603        for (i = 0; i < n_entries * 2; i++) {
 604                /* Configure DP_TP_CTL with auto-training */
 605                intel_de_write(dev_priv, DP_TP_CTL(PORT_E),
 606                               DP_TP_CTL_FDI_AUTOTRAIN |
 607                               DP_TP_CTL_ENHANCED_FRAME_ENABLE |
 608                               DP_TP_CTL_LINK_TRAIN_PAT1 |
 609                               DP_TP_CTL_ENABLE);
 610
 611                /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
 612                 * DDI E does not support port reversal, the functionality is
 613                 * achieved on the PCH side in FDI_RX_CTL, so no need to set the
 614                 * port reversal bit */
 615                intel_de_write(dev_priv, DDI_BUF_CTL(PORT_E),
 616                               DDI_BUF_CTL_ENABLE | ((crtc_state->fdi_lanes - 1) << 1) | DDI_BUF_TRANS_SELECT(i / 2));
 617                intel_de_posting_read(dev_priv, DDI_BUF_CTL(PORT_E));
 618
 619                udelay(600);
 620
 621                /* Program PCH FDI Receiver TU */
 622                intel_de_write(dev_priv, FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
 623
 624                /* Enable PCH FDI Receiver with auto-training */
 625                rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
 626                intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
 627                intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A));
 628
 629                /* Wait for FDI receiver lane calibration */
 630                udelay(30);
 631
 632                /* Unset FDI_RX_MISC pwrdn lanes */
 633                temp = intel_de_read(dev_priv, FDI_RX_MISC(PIPE_A));
 634                temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
 635                intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A), temp);
 636                intel_de_posting_read(dev_priv, FDI_RX_MISC(PIPE_A));
 637
 638                /* Wait for FDI auto training time */
 639                udelay(5);
 640
 641                temp = intel_de_read(dev_priv, DP_TP_STATUS(PORT_E));
 642                if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
 643                        drm_dbg_kms(&dev_priv->drm,
 644                                    "FDI link training done on step %d\n", i);
 645                        break;
 646                }
 647
 648                /*
 649                 * Leave things enabled even if we failed to train FDI.
 650                 * Results in less fireworks from the state checker.
 651                 */
 652                if (i == n_entries * 2 - 1) {
 653                        drm_err(&dev_priv->drm, "FDI link training failed!\n");
 654                        break;
 655                }
 656
 657                rx_ctl_val &= ~FDI_RX_ENABLE;
 658                intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
 659                intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A));
 660
 661                temp = intel_de_read(dev_priv, DDI_BUF_CTL(PORT_E));
 662                temp &= ~DDI_BUF_CTL_ENABLE;
 663                intel_de_write(dev_priv, DDI_BUF_CTL(PORT_E), temp);
 664                intel_de_posting_read(dev_priv, DDI_BUF_CTL(PORT_E));
 665
 666                /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
 667                temp = intel_de_read(dev_priv, DP_TP_CTL(PORT_E));
 668                temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
 669                temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
 670                intel_de_write(dev_priv, DP_TP_CTL(PORT_E), temp);
 671                intel_de_posting_read(dev_priv, DP_TP_CTL(PORT_E));
 672
 673                intel_wait_ddi_buf_idle(dev_priv, PORT_E);
 674
 675                /* Reset FDI_RX_MISC pwrdn lanes */
 676                temp = intel_de_read(dev_priv, FDI_RX_MISC(PIPE_A));
 677                temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
 678                temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
 679                intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A), temp);
 680                intel_de_posting_read(dev_priv, FDI_RX_MISC(PIPE_A));
 681        }
 682
 683        /* Enable normal pixel sending for FDI */
 684        intel_de_write(dev_priv, DP_TP_CTL(PORT_E),
 685                       DP_TP_CTL_FDI_AUTOTRAIN |
 686                       DP_TP_CTL_LINK_TRAIN_NORMAL |
 687                       DP_TP_CTL_ENHANCED_FRAME_ENABLE |
 688                       DP_TP_CTL_ENABLE);
 689}
 690
 691void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state)
 692{
 693        struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
 694        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 695        enum pipe pipe = crtc->pipe;
 696        i915_reg_t reg;
 697        u32 temp;
 698
 699        /* enable PCH FDI RX PLL, wait warmup plus DMI latency */
 700        reg = FDI_RX_CTL(pipe);
 701        temp = intel_de_read(dev_priv, reg);
 702        temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16));
 703        temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
 704        temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
 705        intel_de_write(dev_priv, reg, temp | FDI_RX_PLL_ENABLE);
 706
 707        intel_de_posting_read(dev_priv, reg);
 708        udelay(200);
 709
 710        /* Switch from Rawclk to PCDclk */
 711        temp = intel_de_read(dev_priv, reg);
 712        intel_de_write(dev_priv, reg, temp | FDI_PCDCLK);
 713
 714        intel_de_posting_read(dev_priv, reg);
 715        udelay(200);
 716
 717        /* Enable CPU FDI TX PLL, always on for Ironlake */
 718        reg = FDI_TX_CTL(pipe);
 719        temp = intel_de_read(dev_priv, reg);
 720        if ((temp & FDI_TX_PLL_ENABLE) == 0) {
 721                intel_de_write(dev_priv, reg, temp | FDI_TX_PLL_ENABLE);
 722
 723                intel_de_posting_read(dev_priv, reg);
 724                udelay(100);
 725        }
 726}
 727
 728void ilk_fdi_pll_disable(struct intel_crtc *crtc)
 729{
 730        struct drm_device *dev = crtc->base.dev;
 731        struct drm_i915_private *dev_priv = to_i915(dev);
 732        enum pipe pipe = crtc->pipe;
 733        i915_reg_t reg;
 734        u32 temp;
 735
 736        /* Switch from PCDclk to Rawclk */
 737        reg = FDI_RX_CTL(pipe);
 738        temp = intel_de_read(dev_priv, reg);
 739        intel_de_write(dev_priv, reg, temp & ~FDI_PCDCLK);
 740
 741        /* Disable CPU FDI TX PLL */
 742        reg = FDI_TX_CTL(pipe);
 743        temp = intel_de_read(dev_priv, reg);
 744        intel_de_write(dev_priv, reg, temp & ~FDI_TX_PLL_ENABLE);
 745
 746        intel_de_posting_read(dev_priv, reg);
 747        udelay(100);
 748
 749        reg = FDI_RX_CTL(pipe);
 750        temp = intel_de_read(dev_priv, reg);
 751        intel_de_write(dev_priv, reg, temp & ~FDI_RX_PLL_ENABLE);
 752
 753        /* Wait for the clocks to turn off. */
 754        intel_de_posting_read(dev_priv, reg);
 755        udelay(100);
 756}
 757
 758void ilk_fdi_disable(struct intel_crtc *crtc)
 759{
 760        struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
 761        enum pipe pipe = crtc->pipe;
 762        i915_reg_t reg;
 763        u32 temp;
 764
 765        /* disable CPU FDI tx and PCH FDI rx */
 766        reg = FDI_TX_CTL(pipe);
 767        temp = intel_de_read(dev_priv, reg);
 768        intel_de_write(dev_priv, reg, temp & ~FDI_TX_ENABLE);
 769        intel_de_posting_read(dev_priv, reg);
 770
 771        reg = FDI_RX_CTL(pipe);
 772        temp = intel_de_read(dev_priv, reg);
 773        temp &= ~(0x7 << 16);
 774        temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
 775        intel_de_write(dev_priv, reg, temp & ~FDI_RX_ENABLE);
 776
 777        intel_de_posting_read(dev_priv, reg);
 778        udelay(100);
 779
 780        /* Ironlake workaround, disable clock pointer after downing FDI */
 781        if (HAS_PCH_IBX(dev_priv))
 782                intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe),
 783                               FDI_RX_PHASE_SYNC_POINTER_OVR);
 784
 785        /* still set train pattern 1 */
 786        reg = FDI_TX_CTL(pipe);
 787        temp = intel_de_read(dev_priv, reg);
 788        temp &= ~FDI_LINK_TRAIN_NONE;
 789        temp |= FDI_LINK_TRAIN_PATTERN_1;
 790        intel_de_write(dev_priv, reg, temp);
 791
 792        reg = FDI_RX_CTL(pipe);
 793        temp = intel_de_read(dev_priv, reg);
 794        if (HAS_PCH_CPT(dev_priv)) {
 795                temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
 796                temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
 797        } else {
 798                temp &= ~FDI_LINK_TRAIN_NONE;
 799                temp |= FDI_LINK_TRAIN_PATTERN_1;
 800        }
 801        /* BPC in FDI rx is consistent with that in PIPECONF */
 802        temp &= ~(0x07 << 16);
 803        temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
 804        intel_de_write(dev_priv, reg, temp);
 805
 806        intel_de_posting_read(dev_priv, reg);
 807        udelay(100);
 808}
 809
 810void
 811intel_fdi_init_hook(struct drm_i915_private *dev_priv)
 812{
 813        if (IS_IRONLAKE(dev_priv)) {
 814                dev_priv->display.fdi_link_train = ilk_fdi_link_train;
 815        } else if (IS_SANDYBRIDGE(dev_priv)) {
 816                dev_priv->display.fdi_link_train = gen6_fdi_link_train;
 817        } else if (IS_IVYBRIDGE(dev_priv)) {
 818                /* FIXME: detect B0+ stepping and use auto training */
 819                dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train;
 820        }
 821}
 822