Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: MIT
0002 /*
0003  * Copyright © 2020 Intel Corporation
0004  */
0005 
0006 #include <linux/string_helpers.h>
0007 
0008 #include "intel_atomic.h"
0009 #include "intel_crtc.h"
0010 #include "intel_ddi.h"
0011 #include "intel_de.h"
0012 #include "intel_display_types.h"
0013 #include "intel_fdi.h"
0014 
0015 struct intel_fdi_funcs {
0016     void (*fdi_link_train)(struct intel_crtc *crtc,
0017                    const struct intel_crtc_state *crtc_state);
0018 };
0019 
0020 static void assert_fdi_tx(struct drm_i915_private *dev_priv,
0021               enum pipe pipe, bool state)
0022 {
0023     bool cur_state;
0024 
0025     if (HAS_DDI(dev_priv)) {
0026         /*
0027          * DDI does not have a specific FDI_TX register.
0028          *
0029          * FDI is never fed from EDP transcoder
0030          * so pipe->transcoder cast is fine here.
0031          */
0032         enum transcoder cpu_transcoder = (enum transcoder)pipe;
0033         cur_state = intel_de_read(dev_priv, TRANS_DDI_FUNC_CTL(cpu_transcoder)) & TRANS_DDI_FUNC_ENABLE;
0034     } else {
0035         cur_state = intel_de_read(dev_priv, FDI_TX_CTL(pipe)) & FDI_TX_ENABLE;
0036     }
0037     I915_STATE_WARN(cur_state != state,
0038             "FDI TX state assertion failure (expected %s, current %s)\n",
0039             str_on_off(state), str_on_off(cur_state));
0040 }
0041 
0042 void assert_fdi_tx_enabled(struct drm_i915_private *i915, enum pipe pipe)
0043 {
0044     assert_fdi_tx(i915, pipe, true);
0045 }
0046 
0047 void assert_fdi_tx_disabled(struct drm_i915_private *i915, enum pipe pipe)
0048 {
0049     assert_fdi_tx(i915, pipe, false);
0050 }
0051 
0052 static void assert_fdi_rx(struct drm_i915_private *dev_priv,
0053               enum pipe pipe, bool state)
0054 {
0055     bool cur_state;
0056 
0057     cur_state = intel_de_read(dev_priv, FDI_RX_CTL(pipe)) & FDI_RX_ENABLE;
0058     I915_STATE_WARN(cur_state != state,
0059             "FDI RX state assertion failure (expected %s, current %s)\n",
0060             str_on_off(state), str_on_off(cur_state));
0061 }
0062 
0063 void assert_fdi_rx_enabled(struct drm_i915_private *i915, enum pipe pipe)
0064 {
0065     assert_fdi_rx(i915, pipe, true);
0066 }
0067 
0068 void assert_fdi_rx_disabled(struct drm_i915_private *i915, enum pipe pipe)
0069 {
0070     assert_fdi_rx(i915, pipe, false);
0071 }
0072 
0073 void assert_fdi_tx_pll_enabled(struct drm_i915_private *i915,
0074                    enum pipe pipe)
0075 {
0076     bool cur_state;
0077 
0078     /* ILK FDI PLL is always enabled */
0079     if (IS_IRONLAKE(i915))
0080         return;
0081 
0082     /* On Haswell, DDI ports are responsible for the FDI PLL setup */
0083     if (HAS_DDI(i915))
0084         return;
0085 
0086     cur_state = intel_de_read(i915, FDI_TX_CTL(pipe)) & FDI_TX_PLL_ENABLE;
0087     I915_STATE_WARN(!cur_state, "FDI TX PLL assertion failure, should be active but is disabled\n");
0088 }
0089 
0090 static void assert_fdi_rx_pll(struct drm_i915_private *i915,
0091                   enum pipe pipe, bool state)
0092 {
0093     bool cur_state;
0094 
0095     cur_state = intel_de_read(i915, FDI_RX_CTL(pipe)) & FDI_RX_PLL_ENABLE;
0096     I915_STATE_WARN(cur_state != state,
0097             "FDI RX PLL assertion failure (expected %s, current %s)\n",
0098             str_on_off(state), str_on_off(cur_state));
0099 }
0100 
0101 void assert_fdi_rx_pll_enabled(struct drm_i915_private *i915, enum pipe pipe)
0102 {
0103     assert_fdi_rx_pll(i915, pipe, true);
0104 }
0105 
0106 void assert_fdi_rx_pll_disabled(struct drm_i915_private *i915, enum pipe pipe)
0107 {
0108     assert_fdi_rx_pll(i915, pipe, false);
0109 }
0110 
0111 void intel_fdi_link_train(struct intel_crtc *crtc,
0112               const struct intel_crtc_state *crtc_state)
0113 {
0114     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
0115 
0116     dev_priv->fdi_funcs->fdi_link_train(crtc, crtc_state);
0117 }
0118 
0119 /* units of 100MHz */
0120 static int pipe_required_fdi_lanes(struct intel_crtc_state *crtc_state)
0121 {
0122     if (crtc_state->hw.enable && crtc_state->has_pch_encoder)
0123         return crtc_state->fdi_lanes;
0124 
0125     return 0;
0126 }
0127 
0128 static int ilk_check_fdi_lanes(struct drm_device *dev, enum pipe pipe,
0129                    struct intel_crtc_state *pipe_config)
0130 {
0131     struct drm_i915_private *dev_priv = to_i915(dev);
0132     struct drm_atomic_state *state = pipe_config->uapi.state;
0133     struct intel_crtc *other_crtc;
0134     struct intel_crtc_state *other_crtc_state;
0135 
0136     drm_dbg_kms(&dev_priv->drm,
0137             "checking fdi config on pipe %c, lanes %i\n",
0138             pipe_name(pipe), pipe_config->fdi_lanes);
0139     if (pipe_config->fdi_lanes > 4) {
0140         drm_dbg_kms(&dev_priv->drm,
0141                 "invalid fdi lane config on pipe %c: %i lanes\n",
0142                 pipe_name(pipe), pipe_config->fdi_lanes);
0143         return -EINVAL;
0144     }
0145 
0146     if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
0147         if (pipe_config->fdi_lanes > 2) {
0148             drm_dbg_kms(&dev_priv->drm,
0149                     "only 2 lanes on haswell, required: %i lanes\n",
0150                     pipe_config->fdi_lanes);
0151             return -EINVAL;
0152         } else {
0153             return 0;
0154         }
0155     }
0156 
0157     if (INTEL_NUM_PIPES(dev_priv) == 2)
0158         return 0;
0159 
0160     /* Ivybridge 3 pipe is really complicated */
0161     switch (pipe) {
0162     case PIPE_A:
0163         return 0;
0164     case PIPE_B:
0165         if (pipe_config->fdi_lanes <= 2)
0166             return 0;
0167 
0168         other_crtc = intel_crtc_for_pipe(dev_priv, PIPE_C);
0169         other_crtc_state =
0170             intel_atomic_get_crtc_state(state, other_crtc);
0171         if (IS_ERR(other_crtc_state))
0172             return PTR_ERR(other_crtc_state);
0173 
0174         if (pipe_required_fdi_lanes(other_crtc_state) > 0) {
0175             drm_dbg_kms(&dev_priv->drm,
0176                     "invalid shared fdi lane config on pipe %c: %i lanes\n",
0177                     pipe_name(pipe), pipe_config->fdi_lanes);
0178             return -EINVAL;
0179         }
0180         return 0;
0181     case PIPE_C:
0182         if (pipe_config->fdi_lanes > 2) {
0183             drm_dbg_kms(&dev_priv->drm,
0184                     "only 2 lanes on pipe %c: required %i lanes\n",
0185                     pipe_name(pipe), pipe_config->fdi_lanes);
0186             return -EINVAL;
0187         }
0188 
0189         other_crtc = intel_crtc_for_pipe(dev_priv, PIPE_B);
0190         other_crtc_state =
0191             intel_atomic_get_crtc_state(state, other_crtc);
0192         if (IS_ERR(other_crtc_state))
0193             return PTR_ERR(other_crtc_state);
0194 
0195         if (pipe_required_fdi_lanes(other_crtc_state) > 2) {
0196             drm_dbg_kms(&dev_priv->drm,
0197                     "fdi link B uses too many lanes to enable link C\n");
0198             return -EINVAL;
0199         }
0200         return 0;
0201     default:
0202         MISSING_CASE(pipe);
0203         return 0;
0204     }
0205 }
0206 
0207 void intel_fdi_pll_freq_update(struct drm_i915_private *i915)
0208 {
0209     if (IS_IRONLAKE(i915)) {
0210         u32 fdi_pll_clk =
0211             intel_de_read(i915, FDI_PLL_BIOS_0) & FDI_PLL_FB_CLOCK_MASK;
0212 
0213         i915->fdi_pll_freq = (fdi_pll_clk + 2) * 10000;
0214     } else if (IS_SANDYBRIDGE(i915) || IS_IVYBRIDGE(i915)) {
0215         i915->fdi_pll_freq = 270000;
0216     } else {
0217         return;
0218     }
0219 
0220     drm_dbg(&i915->drm, "FDI PLL freq=%d\n", i915->fdi_pll_freq);
0221 }
0222 
0223 int intel_fdi_link_freq(struct drm_i915_private *i915,
0224             const struct intel_crtc_state *pipe_config)
0225 {
0226     if (HAS_DDI(i915))
0227         return pipe_config->port_clock; /* SPLL */
0228     else
0229         return i915->fdi_pll_freq;
0230 }
0231 
0232 int ilk_fdi_compute_config(struct intel_crtc *crtc,
0233                struct intel_crtc_state *pipe_config)
0234 {
0235     struct drm_device *dev = crtc->base.dev;
0236     struct drm_i915_private *i915 = to_i915(dev);
0237     const struct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode;
0238     int lane, link_bw, fdi_dotclock, ret;
0239     bool needs_recompute = false;
0240 
0241 retry:
0242     /* FDI is a binary signal running at ~2.7GHz, encoding
0243      * each output octet as 10 bits. The actual frequency
0244      * is stored as a divider into a 100MHz clock, and the
0245      * mode pixel clock is stored in units of 1KHz.
0246      * Hence the bw of each lane in terms of the mode signal
0247      * is:
0248      */
0249     link_bw = intel_fdi_link_freq(i915, pipe_config);
0250 
0251     fdi_dotclock = adjusted_mode->crtc_clock;
0252 
0253     lane = ilk_get_lanes_required(fdi_dotclock, link_bw,
0254                       pipe_config->pipe_bpp);
0255 
0256     pipe_config->fdi_lanes = lane;
0257 
0258     intel_link_compute_m_n(pipe_config->pipe_bpp, lane, fdi_dotclock,
0259                    link_bw, &pipe_config->fdi_m_n, false, false);
0260 
0261     ret = ilk_check_fdi_lanes(dev, crtc->pipe, pipe_config);
0262     if (ret == -EDEADLK)
0263         return ret;
0264 
0265     if (ret == -EINVAL && pipe_config->pipe_bpp > 6*3) {
0266         pipe_config->pipe_bpp -= 2*3;
0267         drm_dbg_kms(&i915->drm,
0268                 "fdi link bw constraint, reducing pipe bpp to %i\n",
0269                 pipe_config->pipe_bpp);
0270         needs_recompute = true;
0271         pipe_config->bw_constrained = true;
0272 
0273         goto retry;
0274     }
0275 
0276     if (needs_recompute)
0277         return -EAGAIN;
0278 
0279     return ret;
0280 }
0281 
0282 static void cpt_set_fdi_bc_bifurcation(struct drm_i915_private *dev_priv, bool enable)
0283 {
0284     u32 temp;
0285 
0286     temp = intel_de_read(dev_priv, SOUTH_CHICKEN1);
0287     if (!!(temp & FDI_BC_BIFURCATION_SELECT) == enable)
0288         return;
0289 
0290     drm_WARN_ON(&dev_priv->drm,
0291             intel_de_read(dev_priv, FDI_RX_CTL(PIPE_B)) &
0292             FDI_RX_ENABLE);
0293     drm_WARN_ON(&dev_priv->drm,
0294             intel_de_read(dev_priv, FDI_RX_CTL(PIPE_C)) &
0295             FDI_RX_ENABLE);
0296 
0297     temp &= ~FDI_BC_BIFURCATION_SELECT;
0298     if (enable)
0299         temp |= FDI_BC_BIFURCATION_SELECT;
0300 
0301     drm_dbg_kms(&dev_priv->drm, "%sabling fdi C rx\n",
0302             enable ? "en" : "dis");
0303     intel_de_write(dev_priv, SOUTH_CHICKEN1, temp);
0304     intel_de_posting_read(dev_priv, SOUTH_CHICKEN1);
0305 }
0306 
0307 static void ivb_update_fdi_bc_bifurcation(const struct intel_crtc_state *crtc_state)
0308 {
0309     struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
0310     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
0311 
0312     switch (crtc->pipe) {
0313     case PIPE_A:
0314         break;
0315     case PIPE_B:
0316         if (crtc_state->fdi_lanes > 2)
0317             cpt_set_fdi_bc_bifurcation(dev_priv, false);
0318         else
0319             cpt_set_fdi_bc_bifurcation(dev_priv, true);
0320 
0321         break;
0322     case PIPE_C:
0323         cpt_set_fdi_bc_bifurcation(dev_priv, true);
0324 
0325         break;
0326     default:
0327         MISSING_CASE(crtc->pipe);
0328     }
0329 }
0330 
0331 void intel_fdi_normal_train(struct intel_crtc *crtc)
0332 {
0333     struct drm_device *dev = crtc->base.dev;
0334     struct drm_i915_private *dev_priv = to_i915(dev);
0335     enum pipe pipe = crtc->pipe;
0336     i915_reg_t reg;
0337     u32 temp;
0338 
0339     /* enable normal train */
0340     reg = FDI_TX_CTL(pipe);
0341     temp = intel_de_read(dev_priv, reg);
0342     if (IS_IVYBRIDGE(dev_priv)) {
0343         temp &= ~FDI_LINK_TRAIN_NONE_IVB;
0344         temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE;
0345     } else {
0346         temp &= ~FDI_LINK_TRAIN_NONE;
0347         temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
0348     }
0349     intel_de_write(dev_priv, reg, temp);
0350 
0351     reg = FDI_RX_CTL(pipe);
0352     temp = intel_de_read(dev_priv, reg);
0353     if (HAS_PCH_CPT(dev_priv)) {
0354         temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
0355         temp |= FDI_LINK_TRAIN_NORMAL_CPT;
0356     } else {
0357         temp &= ~FDI_LINK_TRAIN_NONE;
0358         temp |= FDI_LINK_TRAIN_NONE;
0359     }
0360     intel_de_write(dev_priv, reg, temp | FDI_RX_ENHANCE_FRAME_ENABLE);
0361 
0362     /* wait one idle pattern time */
0363     intel_de_posting_read(dev_priv, reg);
0364     udelay(1000);
0365 
0366     /* IVB wants error correction enabled */
0367     if (IS_IVYBRIDGE(dev_priv))
0368         intel_de_write(dev_priv, reg,
0369                    intel_de_read(dev_priv, reg) | FDI_FS_ERRC_ENABLE | FDI_FE_ERRC_ENABLE);
0370 }
0371 
0372 /* The FDI link training functions for ILK/Ibexpeak. */
0373 static void ilk_fdi_link_train(struct intel_crtc *crtc,
0374                    const struct intel_crtc_state *crtc_state)
0375 {
0376     struct drm_device *dev = crtc->base.dev;
0377     struct drm_i915_private *dev_priv = to_i915(dev);
0378     enum pipe pipe = crtc->pipe;
0379     i915_reg_t reg;
0380     u32 temp, tries;
0381 
0382     /*
0383      * Write the TU size bits before fdi link training, so that error
0384      * detection works.
0385      */
0386     intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe),
0387                intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
0388 
0389     /* FDI needs bits from pipe first */
0390     assert_transcoder_enabled(dev_priv, crtc_state->cpu_transcoder);
0391 
0392     /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
0393        for train result */
0394     reg = FDI_RX_IMR(pipe);
0395     temp = intel_de_read(dev_priv, reg);
0396     temp &= ~FDI_RX_SYMBOL_LOCK;
0397     temp &= ~FDI_RX_BIT_LOCK;
0398     intel_de_write(dev_priv, reg, temp);
0399     intel_de_read(dev_priv, reg);
0400     udelay(150);
0401 
0402     /* enable CPU FDI TX and PCH FDI RX */
0403     reg = FDI_TX_CTL(pipe);
0404     temp = intel_de_read(dev_priv, reg);
0405     temp &= ~FDI_DP_PORT_WIDTH_MASK;
0406     temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
0407     temp &= ~FDI_LINK_TRAIN_NONE;
0408     temp |= FDI_LINK_TRAIN_PATTERN_1;
0409     intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE);
0410 
0411     reg = FDI_RX_CTL(pipe);
0412     temp = intel_de_read(dev_priv, reg);
0413     temp &= ~FDI_LINK_TRAIN_NONE;
0414     temp |= FDI_LINK_TRAIN_PATTERN_1;
0415     intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE);
0416 
0417     intel_de_posting_read(dev_priv, reg);
0418     udelay(150);
0419 
0420     /* Ironlake workaround, enable clock pointer after FDI enable*/
0421     intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe),
0422                FDI_RX_PHASE_SYNC_POINTER_OVR);
0423     intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe),
0424                FDI_RX_PHASE_SYNC_POINTER_OVR | FDI_RX_PHASE_SYNC_POINTER_EN);
0425 
0426     reg = FDI_RX_IIR(pipe);
0427     for (tries = 0; tries < 5; tries++) {
0428         temp = intel_de_read(dev_priv, reg);
0429         drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
0430 
0431         if ((temp & FDI_RX_BIT_LOCK)) {
0432             drm_dbg_kms(&dev_priv->drm, "FDI train 1 done.\n");
0433             intel_de_write(dev_priv, reg, temp | FDI_RX_BIT_LOCK);
0434             break;
0435         }
0436     }
0437     if (tries == 5)
0438         drm_err(&dev_priv->drm, "FDI train 1 fail!\n");
0439 
0440     /* Train 2 */
0441     reg = FDI_TX_CTL(pipe);
0442     temp = intel_de_read(dev_priv, reg);
0443     temp &= ~FDI_LINK_TRAIN_NONE;
0444     temp |= FDI_LINK_TRAIN_PATTERN_2;
0445     intel_de_write(dev_priv, reg, temp);
0446 
0447     reg = FDI_RX_CTL(pipe);
0448     temp = intel_de_read(dev_priv, reg);
0449     temp &= ~FDI_LINK_TRAIN_NONE;
0450     temp |= FDI_LINK_TRAIN_PATTERN_2;
0451     intel_de_write(dev_priv, reg, temp);
0452 
0453     intel_de_posting_read(dev_priv, reg);
0454     udelay(150);
0455 
0456     reg = FDI_RX_IIR(pipe);
0457     for (tries = 0; tries < 5; tries++) {
0458         temp = intel_de_read(dev_priv, reg);
0459         drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
0460 
0461         if (temp & FDI_RX_SYMBOL_LOCK) {
0462             intel_de_write(dev_priv, reg,
0463                        temp | FDI_RX_SYMBOL_LOCK);
0464             drm_dbg_kms(&dev_priv->drm, "FDI train 2 done.\n");
0465             break;
0466         }
0467     }
0468     if (tries == 5)
0469         drm_err(&dev_priv->drm, "FDI train 2 fail!\n");
0470 
0471     drm_dbg_kms(&dev_priv->drm, "FDI train done\n");
0472 
0473 }
0474 
0475 static const int snb_b_fdi_train_param[] = {
0476     FDI_LINK_TRAIN_400MV_0DB_SNB_B,
0477     FDI_LINK_TRAIN_400MV_6DB_SNB_B,
0478     FDI_LINK_TRAIN_600MV_3_5DB_SNB_B,
0479     FDI_LINK_TRAIN_800MV_0DB_SNB_B,
0480 };
0481 
0482 /* The FDI link training functions for SNB/Cougarpoint. */
0483 static void gen6_fdi_link_train(struct intel_crtc *crtc,
0484                 const struct intel_crtc_state *crtc_state)
0485 {
0486     struct drm_device *dev = crtc->base.dev;
0487     struct drm_i915_private *dev_priv = to_i915(dev);
0488     enum pipe pipe = crtc->pipe;
0489     i915_reg_t reg;
0490     u32 temp, i, retry;
0491 
0492     /*
0493      * Write the TU size bits before fdi link training, so that error
0494      * detection works.
0495      */
0496     intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe),
0497                intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
0498 
0499     /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
0500        for train result */
0501     reg = FDI_RX_IMR(pipe);
0502     temp = intel_de_read(dev_priv, reg);
0503     temp &= ~FDI_RX_SYMBOL_LOCK;
0504     temp &= ~FDI_RX_BIT_LOCK;
0505     intel_de_write(dev_priv, reg, temp);
0506 
0507     intel_de_posting_read(dev_priv, reg);
0508     udelay(150);
0509 
0510     /* enable CPU FDI TX and PCH FDI RX */
0511     reg = FDI_TX_CTL(pipe);
0512     temp = intel_de_read(dev_priv, reg);
0513     temp &= ~FDI_DP_PORT_WIDTH_MASK;
0514     temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
0515     temp &= ~FDI_LINK_TRAIN_NONE;
0516     temp |= FDI_LINK_TRAIN_PATTERN_1;
0517     temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
0518     /* SNB-B */
0519     temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
0520     intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE);
0521 
0522     intel_de_write(dev_priv, FDI_RX_MISC(pipe),
0523                FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
0524 
0525     reg = FDI_RX_CTL(pipe);
0526     temp = intel_de_read(dev_priv, reg);
0527     if (HAS_PCH_CPT(dev_priv)) {
0528         temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
0529         temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
0530     } else {
0531         temp &= ~FDI_LINK_TRAIN_NONE;
0532         temp |= FDI_LINK_TRAIN_PATTERN_1;
0533     }
0534     intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE);
0535 
0536     intel_de_posting_read(dev_priv, reg);
0537     udelay(150);
0538 
0539     for (i = 0; i < 4; i++) {
0540         reg = FDI_TX_CTL(pipe);
0541         temp = intel_de_read(dev_priv, reg);
0542         temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
0543         temp |= snb_b_fdi_train_param[i];
0544         intel_de_write(dev_priv, reg, temp);
0545 
0546         intel_de_posting_read(dev_priv, reg);
0547         udelay(500);
0548 
0549         for (retry = 0; retry < 5; retry++) {
0550             reg = FDI_RX_IIR(pipe);
0551             temp = intel_de_read(dev_priv, reg);
0552             drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
0553             if (temp & FDI_RX_BIT_LOCK) {
0554                 intel_de_write(dev_priv, reg,
0555                            temp | FDI_RX_BIT_LOCK);
0556                 drm_dbg_kms(&dev_priv->drm,
0557                         "FDI train 1 done.\n");
0558                 break;
0559             }
0560             udelay(50);
0561         }
0562         if (retry < 5)
0563             break;
0564     }
0565     if (i == 4)
0566         drm_err(&dev_priv->drm, "FDI train 1 fail!\n");
0567 
0568     /* Train 2 */
0569     reg = FDI_TX_CTL(pipe);
0570     temp = intel_de_read(dev_priv, reg);
0571     temp &= ~FDI_LINK_TRAIN_NONE;
0572     temp |= FDI_LINK_TRAIN_PATTERN_2;
0573     if (IS_SANDYBRIDGE(dev_priv)) {
0574         temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
0575         /* SNB-B */
0576         temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
0577     }
0578     intel_de_write(dev_priv, reg, temp);
0579 
0580     reg = FDI_RX_CTL(pipe);
0581     temp = intel_de_read(dev_priv, reg);
0582     if (HAS_PCH_CPT(dev_priv)) {
0583         temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
0584         temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
0585     } else {
0586         temp &= ~FDI_LINK_TRAIN_NONE;
0587         temp |= FDI_LINK_TRAIN_PATTERN_2;
0588     }
0589     intel_de_write(dev_priv, reg, temp);
0590 
0591     intel_de_posting_read(dev_priv, reg);
0592     udelay(150);
0593 
0594     for (i = 0; i < 4; i++) {
0595         reg = FDI_TX_CTL(pipe);
0596         temp = intel_de_read(dev_priv, reg);
0597         temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
0598         temp |= snb_b_fdi_train_param[i];
0599         intel_de_write(dev_priv, reg, temp);
0600 
0601         intel_de_posting_read(dev_priv, reg);
0602         udelay(500);
0603 
0604         for (retry = 0; retry < 5; retry++) {
0605             reg = FDI_RX_IIR(pipe);
0606             temp = intel_de_read(dev_priv, reg);
0607             drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
0608             if (temp & FDI_RX_SYMBOL_LOCK) {
0609                 intel_de_write(dev_priv, reg,
0610                            temp | FDI_RX_SYMBOL_LOCK);
0611                 drm_dbg_kms(&dev_priv->drm,
0612                         "FDI train 2 done.\n");
0613                 break;
0614             }
0615             udelay(50);
0616         }
0617         if (retry < 5)
0618             break;
0619     }
0620     if (i == 4)
0621         drm_err(&dev_priv->drm, "FDI train 2 fail!\n");
0622 
0623     drm_dbg_kms(&dev_priv->drm, "FDI train done.\n");
0624 }
0625 
0626 /* Manual link training for Ivy Bridge A0 parts */
0627 static void ivb_manual_fdi_link_train(struct intel_crtc *crtc,
0628                       const struct intel_crtc_state *crtc_state)
0629 {
0630     struct drm_device *dev = crtc->base.dev;
0631     struct drm_i915_private *dev_priv = to_i915(dev);
0632     enum pipe pipe = crtc->pipe;
0633     i915_reg_t reg;
0634     u32 temp, i, j;
0635 
0636     ivb_update_fdi_bc_bifurcation(crtc_state);
0637 
0638     /*
0639      * Write the TU size bits before fdi link training, so that error
0640      * detection works.
0641      */
0642     intel_de_write(dev_priv, FDI_RX_TUSIZE1(pipe),
0643                intel_de_read(dev_priv, PIPE_DATA_M1(pipe)) & TU_SIZE_MASK);
0644 
0645     /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
0646        for train result */
0647     reg = FDI_RX_IMR(pipe);
0648     temp = intel_de_read(dev_priv, reg);
0649     temp &= ~FDI_RX_SYMBOL_LOCK;
0650     temp &= ~FDI_RX_BIT_LOCK;
0651     intel_de_write(dev_priv, reg, temp);
0652 
0653     intel_de_posting_read(dev_priv, reg);
0654     udelay(150);
0655 
0656     drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR before link train 0x%x\n",
0657             intel_de_read(dev_priv, FDI_RX_IIR(pipe)));
0658 
0659     /* Try each vswing and preemphasis setting twice before moving on */
0660     for (j = 0; j < ARRAY_SIZE(snb_b_fdi_train_param) * 2; j++) {
0661         /* disable first in case we need to retry */
0662         reg = FDI_TX_CTL(pipe);
0663         temp = intel_de_read(dev_priv, reg);
0664         temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB);
0665         temp &= ~FDI_TX_ENABLE;
0666         intel_de_write(dev_priv, reg, temp);
0667 
0668         reg = FDI_RX_CTL(pipe);
0669         temp = intel_de_read(dev_priv, reg);
0670         temp &= ~FDI_LINK_TRAIN_AUTO;
0671         temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
0672         temp &= ~FDI_RX_ENABLE;
0673         intel_de_write(dev_priv, reg, temp);
0674 
0675         /* enable CPU FDI TX and PCH FDI RX */
0676         reg = FDI_TX_CTL(pipe);
0677         temp = intel_de_read(dev_priv, reg);
0678         temp &= ~FDI_DP_PORT_WIDTH_MASK;
0679         temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
0680         temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
0681         temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
0682         temp |= snb_b_fdi_train_param[j/2];
0683         temp |= FDI_COMPOSITE_SYNC;
0684         intel_de_write(dev_priv, reg, temp | FDI_TX_ENABLE);
0685 
0686         intel_de_write(dev_priv, FDI_RX_MISC(pipe),
0687                    FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
0688 
0689         reg = FDI_RX_CTL(pipe);
0690         temp = intel_de_read(dev_priv, reg);
0691         temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
0692         temp |= FDI_COMPOSITE_SYNC;
0693         intel_de_write(dev_priv, reg, temp | FDI_RX_ENABLE);
0694 
0695         intel_de_posting_read(dev_priv, reg);
0696         udelay(1); /* should be 0.5us */
0697 
0698         for (i = 0; i < 4; i++) {
0699             reg = FDI_RX_IIR(pipe);
0700             temp = intel_de_read(dev_priv, reg);
0701             drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
0702 
0703             if (temp & FDI_RX_BIT_LOCK ||
0704                 (intel_de_read(dev_priv, reg) & FDI_RX_BIT_LOCK)) {
0705                 intel_de_write(dev_priv, reg,
0706                            temp | FDI_RX_BIT_LOCK);
0707                 drm_dbg_kms(&dev_priv->drm,
0708                         "FDI train 1 done, level %i.\n",
0709                         i);
0710                 break;
0711             }
0712             udelay(1); /* should be 0.5us */
0713         }
0714         if (i == 4) {
0715             drm_dbg_kms(&dev_priv->drm,
0716                     "FDI train 1 fail on vswing %d\n", j / 2);
0717             continue;
0718         }
0719 
0720         /* Train 2 */
0721         reg = FDI_TX_CTL(pipe);
0722         temp = intel_de_read(dev_priv, reg);
0723         temp &= ~FDI_LINK_TRAIN_NONE_IVB;
0724         temp |= FDI_LINK_TRAIN_PATTERN_2_IVB;
0725         intel_de_write(dev_priv, reg, temp);
0726 
0727         reg = FDI_RX_CTL(pipe);
0728         temp = intel_de_read(dev_priv, reg);
0729         temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
0730         temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
0731         intel_de_write(dev_priv, reg, temp);
0732 
0733         intel_de_posting_read(dev_priv, reg);
0734         udelay(2); /* should be 1.5us */
0735 
0736         for (i = 0; i < 4; i++) {
0737             reg = FDI_RX_IIR(pipe);
0738             temp = intel_de_read(dev_priv, reg);
0739             drm_dbg_kms(&dev_priv->drm, "FDI_RX_IIR 0x%x\n", temp);
0740 
0741             if (temp & FDI_RX_SYMBOL_LOCK ||
0742                 (intel_de_read(dev_priv, reg) & FDI_RX_SYMBOL_LOCK)) {
0743                 intel_de_write(dev_priv, reg,
0744                            temp | FDI_RX_SYMBOL_LOCK);
0745                 drm_dbg_kms(&dev_priv->drm,
0746                         "FDI train 2 done, level %i.\n",
0747                         i);
0748                 goto train_done;
0749             }
0750             udelay(2); /* should be 1.5us */
0751         }
0752         if (i == 4)
0753             drm_dbg_kms(&dev_priv->drm,
0754                     "FDI train 2 fail on vswing %d\n", j / 2);
0755     }
0756 
0757 train_done:
0758     drm_dbg_kms(&dev_priv->drm, "FDI train done.\n");
0759 }
0760 
0761 /* Starting with Haswell, different DDI ports can work in FDI mode for
0762  * connection to the PCH-located connectors. For this, it is necessary to train
0763  * both the DDI port and PCH receiver for the desired DDI buffer settings.
0764  *
0765  * The recommended port to work in FDI mode is DDI E, which we use here. Also,
0766  * please note that when FDI mode is active on DDI E, it shares 2 lines with
0767  * DDI A (which is used for eDP)
0768  */
0769 void hsw_fdi_link_train(struct intel_encoder *encoder,
0770             const struct intel_crtc_state *crtc_state)
0771 {
0772     struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
0773     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
0774     u32 temp, i, rx_ctl_val;
0775     int n_entries;
0776 
0777     encoder->get_buf_trans(encoder, crtc_state, &n_entries);
0778 
0779     hsw_prepare_dp_ddi_buffers(encoder, crtc_state);
0780 
0781     /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the
0782      * mode set "sequence for CRT port" document:
0783      * - TP1 to TP2 time with the default value
0784      * - FDI delay to 90h
0785      *
0786      * WaFDIAutoLinkSetTimingOverrride:hsw
0787      */
0788     intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A),
0789                FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2) | FDI_RX_TP1_TO_TP2_48 | FDI_RX_FDI_DELAY_90);
0790 
0791     /* Enable the PCH Receiver FDI PLL */
0792     rx_ctl_val = dev_priv->fdi_rx_config | FDI_RX_ENHANCE_FRAME_ENABLE |
0793              FDI_RX_PLL_ENABLE |
0794              FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
0795     intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
0796     intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A));
0797     udelay(220);
0798 
0799     /* Switch from Rawclk to PCDclk */
0800     rx_ctl_val |= FDI_PCDCLK;
0801     intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
0802 
0803     /* Configure Port Clock Select */
0804     drm_WARN_ON(&dev_priv->drm, crtc_state->shared_dpll->info->id != DPLL_ID_SPLL);
0805     intel_ddi_enable_clock(encoder, crtc_state);
0806 
0807     /* Start the training iterating through available voltages and emphasis,
0808      * testing each value twice. */
0809     for (i = 0; i < n_entries * 2; i++) {
0810         /* Configure DP_TP_CTL with auto-training */
0811         intel_de_write(dev_priv, DP_TP_CTL(PORT_E),
0812                    DP_TP_CTL_FDI_AUTOTRAIN |
0813                    DP_TP_CTL_ENHANCED_FRAME_ENABLE |
0814                    DP_TP_CTL_LINK_TRAIN_PAT1 |
0815                    DP_TP_CTL_ENABLE);
0816 
0817         /* Configure and enable DDI_BUF_CTL for DDI E with next voltage.
0818          * DDI E does not support port reversal, the functionality is
0819          * achieved on the PCH side in FDI_RX_CTL, so no need to set the
0820          * port reversal bit */
0821         intel_de_write(dev_priv, DDI_BUF_CTL(PORT_E),
0822                    DDI_BUF_CTL_ENABLE | ((crtc_state->fdi_lanes - 1) << 1) | DDI_BUF_TRANS_SELECT(i / 2));
0823         intel_de_posting_read(dev_priv, DDI_BUF_CTL(PORT_E));
0824 
0825         udelay(600);
0826 
0827         /* Program PCH FDI Receiver TU */
0828         intel_de_write(dev_priv, FDI_RX_TUSIZE1(PIPE_A), TU_SIZE(64));
0829 
0830         /* Enable PCH FDI Receiver with auto-training */
0831         rx_ctl_val |= FDI_RX_ENABLE | FDI_LINK_TRAIN_AUTO;
0832         intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
0833         intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A));
0834 
0835         /* Wait for FDI receiver lane calibration */
0836         udelay(30);
0837 
0838         /* Unset FDI_RX_MISC pwrdn lanes */
0839         temp = intel_de_read(dev_priv, FDI_RX_MISC(PIPE_A));
0840         temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
0841         intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A), temp);
0842         intel_de_posting_read(dev_priv, FDI_RX_MISC(PIPE_A));
0843 
0844         /* Wait for FDI auto training time */
0845         udelay(5);
0846 
0847         temp = intel_de_read(dev_priv, DP_TP_STATUS(PORT_E));
0848         if (temp & DP_TP_STATUS_AUTOTRAIN_DONE) {
0849             drm_dbg_kms(&dev_priv->drm,
0850                     "FDI link training done on step %d\n", i);
0851             break;
0852         }
0853 
0854         /*
0855          * Leave things enabled even if we failed to train FDI.
0856          * Results in less fireworks from the state checker.
0857          */
0858         if (i == n_entries * 2 - 1) {
0859             drm_err(&dev_priv->drm, "FDI link training failed!\n");
0860             break;
0861         }
0862 
0863         rx_ctl_val &= ~FDI_RX_ENABLE;
0864         intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), rx_ctl_val);
0865         intel_de_posting_read(dev_priv, FDI_RX_CTL(PIPE_A));
0866 
0867         temp = intel_de_read(dev_priv, DDI_BUF_CTL(PORT_E));
0868         temp &= ~DDI_BUF_CTL_ENABLE;
0869         intel_de_write(dev_priv, DDI_BUF_CTL(PORT_E), temp);
0870         intel_de_posting_read(dev_priv, DDI_BUF_CTL(PORT_E));
0871 
0872         /* Disable DP_TP_CTL and FDI_RX_CTL and retry */
0873         temp = intel_de_read(dev_priv, DP_TP_CTL(PORT_E));
0874         temp &= ~(DP_TP_CTL_ENABLE | DP_TP_CTL_LINK_TRAIN_MASK);
0875         temp |= DP_TP_CTL_LINK_TRAIN_PAT1;
0876         intel_de_write(dev_priv, DP_TP_CTL(PORT_E), temp);
0877         intel_de_posting_read(dev_priv, DP_TP_CTL(PORT_E));
0878 
0879         intel_wait_ddi_buf_idle(dev_priv, PORT_E);
0880 
0881         /* Reset FDI_RX_MISC pwrdn lanes */
0882         temp = intel_de_read(dev_priv, FDI_RX_MISC(PIPE_A));
0883         temp &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
0884         temp |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
0885         intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A), temp);
0886         intel_de_posting_read(dev_priv, FDI_RX_MISC(PIPE_A));
0887     }
0888 
0889     /* Enable normal pixel sending for FDI */
0890     intel_de_write(dev_priv, DP_TP_CTL(PORT_E),
0891                DP_TP_CTL_FDI_AUTOTRAIN |
0892                DP_TP_CTL_LINK_TRAIN_NORMAL |
0893                DP_TP_CTL_ENHANCED_FRAME_ENABLE |
0894                DP_TP_CTL_ENABLE);
0895 }
0896 
0897 void hsw_fdi_disable(struct intel_encoder *encoder)
0898 {
0899     struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
0900     u32 val;
0901 
0902     /*
0903      * Bspec lists this as both step 13 (before DDI_BUF_CTL disable)
0904      * and step 18 (after clearing PORT_CLK_SEL). Based on a BUN,
0905      * step 13 is the correct place for it. Step 18 is where it was
0906      * originally before the BUN.
0907      */
0908     val = intel_de_read(dev_priv, FDI_RX_CTL(PIPE_A));
0909     val &= ~FDI_RX_ENABLE;
0910     intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), val);
0911 
0912     val = intel_de_read(dev_priv, DDI_BUF_CTL(PORT_E));
0913     val &= ~DDI_BUF_CTL_ENABLE;
0914     intel_de_write(dev_priv, DDI_BUF_CTL(PORT_E), val);
0915 
0916     intel_wait_ddi_buf_idle(dev_priv, PORT_E);
0917 
0918     intel_ddi_disable_clock(encoder);
0919 
0920     val = intel_de_read(dev_priv, FDI_RX_MISC(PIPE_A));
0921     val &= ~(FDI_RX_PWRDN_LANE1_MASK | FDI_RX_PWRDN_LANE0_MASK);
0922     val |= FDI_RX_PWRDN_LANE1_VAL(2) | FDI_RX_PWRDN_LANE0_VAL(2);
0923     intel_de_write(dev_priv, FDI_RX_MISC(PIPE_A), val);
0924 
0925     val = intel_de_read(dev_priv, FDI_RX_CTL(PIPE_A));
0926     val &= ~FDI_PCDCLK;
0927     intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), val);
0928 
0929     val = intel_de_read(dev_priv, FDI_RX_CTL(PIPE_A));
0930     val &= ~FDI_RX_PLL_ENABLE;
0931     intel_de_write(dev_priv, FDI_RX_CTL(PIPE_A), val);
0932 }
0933 
0934 void ilk_fdi_pll_enable(const struct intel_crtc_state *crtc_state)
0935 {
0936     struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
0937     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
0938     enum pipe pipe = crtc->pipe;
0939     i915_reg_t reg;
0940     u32 temp;
0941 
0942     /* enable PCH FDI RX PLL, wait warmup plus DMI latency */
0943     reg = FDI_RX_CTL(pipe);
0944     temp = intel_de_read(dev_priv, reg);
0945     temp &= ~(FDI_DP_PORT_WIDTH_MASK | (0x7 << 16));
0946     temp |= FDI_DP_PORT_WIDTH(crtc_state->fdi_lanes);
0947     temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
0948     intel_de_write(dev_priv, reg, temp | FDI_RX_PLL_ENABLE);
0949 
0950     intel_de_posting_read(dev_priv, reg);
0951     udelay(200);
0952 
0953     /* Switch from Rawclk to PCDclk */
0954     temp = intel_de_read(dev_priv, reg);
0955     intel_de_write(dev_priv, reg, temp | FDI_PCDCLK);
0956 
0957     intel_de_posting_read(dev_priv, reg);
0958     udelay(200);
0959 
0960     /* Enable CPU FDI TX PLL, always on for Ironlake */
0961     reg = FDI_TX_CTL(pipe);
0962     temp = intel_de_read(dev_priv, reg);
0963     if ((temp & FDI_TX_PLL_ENABLE) == 0) {
0964         intel_de_write(dev_priv, reg, temp | FDI_TX_PLL_ENABLE);
0965 
0966         intel_de_posting_read(dev_priv, reg);
0967         udelay(100);
0968     }
0969 }
0970 
0971 void ilk_fdi_pll_disable(struct intel_crtc *crtc)
0972 {
0973     struct drm_device *dev = crtc->base.dev;
0974     struct drm_i915_private *dev_priv = to_i915(dev);
0975     enum pipe pipe = crtc->pipe;
0976     i915_reg_t reg;
0977     u32 temp;
0978 
0979     /* Switch from PCDclk to Rawclk */
0980     reg = FDI_RX_CTL(pipe);
0981     temp = intel_de_read(dev_priv, reg);
0982     intel_de_write(dev_priv, reg, temp & ~FDI_PCDCLK);
0983 
0984     /* Disable CPU FDI TX PLL */
0985     reg = FDI_TX_CTL(pipe);
0986     temp = intel_de_read(dev_priv, reg);
0987     intel_de_write(dev_priv, reg, temp & ~FDI_TX_PLL_ENABLE);
0988 
0989     intel_de_posting_read(dev_priv, reg);
0990     udelay(100);
0991 
0992     reg = FDI_RX_CTL(pipe);
0993     temp = intel_de_read(dev_priv, reg);
0994     intel_de_write(dev_priv, reg, temp & ~FDI_RX_PLL_ENABLE);
0995 
0996     /* Wait for the clocks to turn off. */
0997     intel_de_posting_read(dev_priv, reg);
0998     udelay(100);
0999 }
1000 
1001 void ilk_fdi_disable(struct intel_crtc *crtc)
1002 {
1003     struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
1004     enum pipe pipe = crtc->pipe;
1005     i915_reg_t reg;
1006     u32 temp;
1007 
1008     /* disable CPU FDI tx and PCH FDI rx */
1009     reg = FDI_TX_CTL(pipe);
1010     temp = intel_de_read(dev_priv, reg);
1011     intel_de_write(dev_priv, reg, temp & ~FDI_TX_ENABLE);
1012     intel_de_posting_read(dev_priv, reg);
1013 
1014     reg = FDI_RX_CTL(pipe);
1015     temp = intel_de_read(dev_priv, reg);
1016     temp &= ~(0x7 << 16);
1017     temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
1018     intel_de_write(dev_priv, reg, temp & ~FDI_RX_ENABLE);
1019 
1020     intel_de_posting_read(dev_priv, reg);
1021     udelay(100);
1022 
1023     /* Ironlake workaround, disable clock pointer after downing FDI */
1024     if (HAS_PCH_IBX(dev_priv))
1025         intel_de_write(dev_priv, FDI_RX_CHICKEN(pipe),
1026                    FDI_RX_PHASE_SYNC_POINTER_OVR);
1027 
1028     /* still set train pattern 1 */
1029     reg = FDI_TX_CTL(pipe);
1030     temp = intel_de_read(dev_priv, reg);
1031     temp &= ~FDI_LINK_TRAIN_NONE;
1032     temp |= FDI_LINK_TRAIN_PATTERN_1;
1033     intel_de_write(dev_priv, reg, temp);
1034 
1035     reg = FDI_RX_CTL(pipe);
1036     temp = intel_de_read(dev_priv, reg);
1037     if (HAS_PCH_CPT(dev_priv)) {
1038         temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
1039         temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
1040     } else {
1041         temp &= ~FDI_LINK_TRAIN_NONE;
1042         temp |= FDI_LINK_TRAIN_PATTERN_1;
1043     }
1044     /* BPC in FDI rx is consistent with that in PIPECONF */
1045     temp &= ~(0x07 << 16);
1046     temp |= (intel_de_read(dev_priv, PIPECONF(pipe)) & PIPECONF_BPC_MASK) << 11;
1047     intel_de_write(dev_priv, reg, temp);
1048 
1049     intel_de_posting_read(dev_priv, reg);
1050     udelay(100);
1051 }
1052 
1053 static const struct intel_fdi_funcs ilk_funcs = {
1054     .fdi_link_train = ilk_fdi_link_train,
1055 };
1056 
1057 static const struct intel_fdi_funcs gen6_funcs = {
1058     .fdi_link_train = gen6_fdi_link_train,
1059 };
1060 
1061 static const struct intel_fdi_funcs ivb_funcs = {
1062     .fdi_link_train = ivb_manual_fdi_link_train,
1063 };
1064 
1065 void
1066 intel_fdi_init_hook(struct drm_i915_private *dev_priv)
1067 {
1068     if (IS_IRONLAKE(dev_priv)) {
1069         dev_priv->fdi_funcs = &ilk_funcs;
1070     } else if (IS_SANDYBRIDGE(dev_priv)) {
1071         dev_priv->fdi_funcs = &gen6_funcs;
1072     } else if (IS_IVYBRIDGE(dev_priv)) {
1073         /* FIXME: detect B0+ stepping and use auto training */
1074         dev_priv->fdi_funcs = &ivb_funcs;
1075     }
1076 }