aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h10
-rw-r--r--drivers/gpu/drm/i915/intel_display.c130
2 files changed, 136 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 289adaa9c928..ea12ca01ef63 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -3104,7 +3104,15 @@
3104#define FDI_TX_ENHANCE_FRAME_ENABLE (1<<18) 3104#define FDI_TX_ENHANCE_FRAME_ENABLE (1<<18)
3105/* Ironlake: hardwired to 1 */ 3105/* Ironlake: hardwired to 1 */
3106#define FDI_TX_PLL_ENABLE (1<<14) 3106#define FDI_TX_PLL_ENABLE (1<<14)
3107
3108/* Ivybridge has different bits for lolz */
3109#define FDI_LINK_TRAIN_PATTERN_1_IVB (0<<8)
3110#define FDI_LINK_TRAIN_PATTERN_2_IVB (1<<8)
3111#define FDI_LINK_TRAIN_PATTERN_IDLE_IVB (2<<8)
3112#define FDI_LINK_TRAIN_NONE_IVB (3<<8)
3113
3107/* both Tx and Rx */ 3114/* both Tx and Rx */
3115#define FDI_LINK_TRAIN_AUTO (1<<10)
3108#define FDI_SCRAMBLING_ENABLE (0<<7) 3116#define FDI_SCRAMBLING_ENABLE (0<<7)
3109#define FDI_SCRAMBLING_DISABLE (1<<7) 3117#define FDI_SCRAMBLING_DISABLE (1<<7)
3110 3118
@@ -3114,6 +3122,8 @@
3114#define FDI_RX_CTL(pipe) _PIPE(pipe, _FDI_RXA_CTL, _FDI_RXB_CTL) 3122#define FDI_RX_CTL(pipe) _PIPE(pipe, _FDI_RXA_CTL, _FDI_RXB_CTL)
3115#define FDI_RX_ENABLE (1<<31) 3123#define FDI_RX_ENABLE (1<<31)
3116/* train, dp width same as FDI_TX */ 3124/* train, dp width same as FDI_TX */
3125#define FDI_FS_ERRC_ENABLE (1<<27)
3126#define FDI_FE_ERRC_ENABLE (1<<26)
3117#define FDI_DP_PORT_WIDTH_X8 (7<<19) 3127#define FDI_DP_PORT_WIDTH_X8 (7<<19)
3118#define FDI_8BPC (0<<16) 3128#define FDI_8BPC (0<<16)
3119#define FDI_10BPC (1<<16) 3129#define FDI_10BPC (1<<16)
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index ba618d509dee..5ccd18f62e43 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2051,8 +2051,13 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc)
2051 /* enable normal train */ 2051 /* enable normal train */
2052 reg = FDI_TX_CTL(pipe); 2052 reg = FDI_TX_CTL(pipe);
2053 temp = I915_READ(reg); 2053 temp = I915_READ(reg);
2054 temp &= ~FDI_LINK_TRAIN_NONE; 2054 if (IS_GEN6(dev)) {
2055 temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE; 2055 temp &= ~FDI_LINK_TRAIN_NONE;
2056 temp |= FDI_LINK_TRAIN_NONE | FDI_TX_ENHANCE_FRAME_ENABLE;
2057 } else if (IS_IVYBRIDGE(dev)) {
2058 temp &= ~FDI_LINK_TRAIN_NONE_IVB;
2059 temp |= FDI_LINK_TRAIN_NONE_IVB | FDI_TX_ENHANCE_FRAME_ENABLE;
2060 }
2056 I915_WRITE(reg, temp); 2061 I915_WRITE(reg, temp);
2057 2062
2058 reg = FDI_RX_CTL(pipe); 2063 reg = FDI_RX_CTL(pipe);
@@ -2069,6 +2074,11 @@ static void intel_fdi_normal_train(struct drm_crtc *crtc)
2069 /* wait one idle pattern time */ 2074 /* wait one idle pattern time */
2070 POSTING_READ(reg); 2075 POSTING_READ(reg);
2071 udelay(1000); 2076 udelay(1000);
2077
2078 /* IVB wants error correction enabled */
2079 if (IS_IVYBRIDGE(dev))
2080 I915_WRITE(reg, I915_READ(reg) | FDI_FS_ERRC_ENABLE |
2081 FDI_FE_ERRC_ENABLE);
2072} 2082}
2073 2083
2074/* The FDI link training functions for ILK/Ibexpeak. */ 2084/* The FDI link training functions for ILK/Ibexpeak. */
@@ -2296,7 +2306,116 @@ static void gen6_fdi_link_train(struct drm_crtc *crtc)
2296 DRM_DEBUG_KMS("FDI train done.\n"); 2306 DRM_DEBUG_KMS("FDI train done.\n");
2297} 2307}
2298 2308
2299static void ironlake_fdi_enable(struct drm_crtc *crtc) 2309/* Manual link training for Ivy Bridge A0 parts */
2310static void ivb_manual_fdi_link_train(struct drm_crtc *crtc)
2311{
2312 struct drm_device *dev = crtc->dev;
2313 struct drm_i915_private *dev_priv = dev->dev_private;
2314 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
2315 int pipe = intel_crtc->pipe;
2316 u32 reg, temp, i;
2317
2318 /* Train 1: umask FDI RX Interrupt symbol_lock and bit_lock bit
2319 for train result */
2320 reg = FDI_RX_IMR(pipe);
2321 temp = I915_READ(reg);
2322 temp &= ~FDI_RX_SYMBOL_LOCK;
2323 temp &= ~FDI_RX_BIT_LOCK;
2324 I915_WRITE(reg, temp);
2325
2326 POSTING_READ(reg);
2327 udelay(150);
2328
2329 /* enable CPU FDI TX and PCH FDI RX */
2330 reg = FDI_TX_CTL(pipe);
2331 temp = I915_READ(reg);
2332 temp &= ~(7 << 19);
2333 temp |= (intel_crtc->fdi_lanes - 1) << 19;
2334 temp &= ~(FDI_LINK_TRAIN_AUTO | FDI_LINK_TRAIN_NONE_IVB);
2335 temp |= FDI_LINK_TRAIN_PATTERN_1_IVB;
2336 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
2337 temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
2338 I915_WRITE(reg, temp | FDI_TX_ENABLE);
2339
2340 reg = FDI_RX_CTL(pipe);
2341 temp = I915_READ(reg);
2342 temp &= ~FDI_LINK_TRAIN_AUTO;
2343 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
2344 temp |= FDI_LINK_TRAIN_PATTERN_1_CPT;
2345 I915_WRITE(reg, temp | FDI_RX_ENABLE);
2346
2347 POSTING_READ(reg);
2348 udelay(150);
2349
2350 for (i = 0; i < 4; i++ ) {
2351 reg = FDI_TX_CTL(pipe);
2352 temp = I915_READ(reg);
2353 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
2354 temp |= snb_b_fdi_train_param[i];
2355 I915_WRITE(reg, temp);
2356
2357 POSTING_READ(reg);
2358 udelay(500);
2359
2360 reg = FDI_RX_IIR(pipe);
2361 temp = I915_READ(reg);
2362 DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
2363
2364 if (temp & FDI_RX_BIT_LOCK ||
2365 (I915_READ(reg) & FDI_RX_BIT_LOCK)) {
2366 I915_WRITE(reg, temp | FDI_RX_BIT_LOCK);
2367 DRM_DEBUG_KMS("FDI train 1 done.\n");
2368 break;
2369 }
2370 }
2371 if (i == 4)
2372 DRM_ERROR("FDI train 1 fail!\n");
2373
2374 /* Train 2 */
2375 reg = FDI_TX_CTL(pipe);
2376 temp = I915_READ(reg);
2377 temp &= ~FDI_LINK_TRAIN_NONE_IVB;
2378 temp |= FDI_LINK_TRAIN_PATTERN_2_IVB;
2379 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
2380 temp |= FDI_LINK_TRAIN_400MV_0DB_SNB_B;
2381 I915_WRITE(reg, temp);
2382
2383 reg = FDI_RX_CTL(pipe);
2384 temp = I915_READ(reg);
2385 temp &= ~FDI_LINK_TRAIN_PATTERN_MASK_CPT;
2386 temp |= FDI_LINK_TRAIN_PATTERN_2_CPT;
2387 I915_WRITE(reg, temp);
2388
2389 POSTING_READ(reg);
2390 udelay(150);
2391
2392 for (i = 0; i < 4; i++ ) {
2393 reg = FDI_TX_CTL(pipe);
2394 temp = I915_READ(reg);
2395 temp &= ~FDI_LINK_TRAIN_VOL_EMP_MASK;
2396 temp |= snb_b_fdi_train_param[i];
2397 I915_WRITE(reg, temp);
2398
2399 POSTING_READ(reg);
2400 udelay(500);
2401
2402 reg = FDI_RX_IIR(pipe);
2403 temp = I915_READ(reg);
2404 DRM_DEBUG_KMS("FDI_RX_IIR 0x%x\n", temp);
2405
2406 if (temp & FDI_RX_SYMBOL_LOCK) {
2407 I915_WRITE(reg, temp | FDI_RX_SYMBOL_LOCK);
2408 DRM_DEBUG_KMS("FDI train 2 done.\n");
2409 break;
2410 }
2411 }
2412 if (i == 4)
2413 DRM_ERROR("FDI train 2 fail!\n");
2414
2415 DRM_DEBUG_KMS("FDI train done.\n");
2416}
2417
2418static void ironlake_fdi_pll_enable(struct drm_crtc *crtc)
2300{ 2419{
2301 struct drm_device *dev = crtc->dev; 2420 struct drm_device *dev = crtc->dev;
2302 struct drm_i915_private *dev_priv = dev->dev_private; 2421 struct drm_i915_private *dev_priv = dev->dev_private;
@@ -2559,7 +2678,7 @@ static void ironlake_crtc_enable(struct drm_crtc *crtc)
2559 is_pch_port = intel_crtc_driving_pch(crtc); 2678 is_pch_port = intel_crtc_driving_pch(crtc);
2560 2679
2561 if (is_pch_port) 2680 if (is_pch_port)
2562 ironlake_fdi_enable(crtc); 2681 ironlake_fdi_pll_enable(crtc);
2563 else 2682 else
2564 ironlake_fdi_disable(crtc); 2683 ironlake_fdi_disable(crtc);
2565 2684
@@ -7438,6 +7557,9 @@ static void intel_init_display(struct drm_device *dev)
7438 dev_priv->display.update_wm = NULL; 7557 dev_priv->display.update_wm = NULL;
7439 } 7558 }
7440 dev_priv->display.fdi_link_train = gen6_fdi_link_train; 7559 dev_priv->display.fdi_link_train = gen6_fdi_link_train;
7560 } else if (IS_IVYBRIDGE(dev)) {
7561 /* FIXME: detect B0+ stepping and use auto training */
7562 dev_priv->display.fdi_link_train = ivb_manual_fdi_link_train;
7441 } else 7563 } else
7442 dev_priv->display.update_wm = NULL; 7564 dev_priv->display.update_wm = NULL;
7443 } else if (IS_PINEVIEW(dev)) { 7565 } else if (IS_PINEVIEW(dev)) {