diff options
author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2014-08-18 15:16:08 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2014-09-04 09:01:00 -0400 |
commit | 7b13b58a802bbea6d94aac4e3cc6b33e481eb900 (patch) | |
tree | d8ce782c78776c6c364109285089ac20dc5ad95f | |
parent | 43072a454646d22f81808bdc8fb1b269ee1717a6 (diff) |
drm/i915: Enable DP port earlier
Bspec says we should enable the DP port before enabling panel power,
and that the port must be enabled with training pattern 1. Do so.
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 172 |
1 files changed, 100 insertions, 72 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 8935c5113ea7..522400db7ba6 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -2363,6 +2363,104 @@ static void chv_post_disable_dp(struct intel_encoder *encoder) | |||
2363 | mutex_unlock(&dev_priv->dpio_lock); | 2363 | mutex_unlock(&dev_priv->dpio_lock); |
2364 | } | 2364 | } |
2365 | 2365 | ||
2366 | static void | ||
2367 | _intel_dp_set_link_train(struct intel_dp *intel_dp, | ||
2368 | uint32_t *DP, | ||
2369 | uint8_t dp_train_pat) | ||
2370 | { | ||
2371 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | ||
2372 | struct drm_device *dev = intel_dig_port->base.base.dev; | ||
2373 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2374 | enum port port = intel_dig_port->port; | ||
2375 | |||
2376 | if (HAS_DDI(dev)) { | ||
2377 | uint32_t temp = I915_READ(DP_TP_CTL(port)); | ||
2378 | |||
2379 | if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE) | ||
2380 | temp |= DP_TP_CTL_SCRAMBLE_DISABLE; | ||
2381 | else | ||
2382 | temp &= ~DP_TP_CTL_SCRAMBLE_DISABLE; | ||
2383 | |||
2384 | temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; | ||
2385 | switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { | ||
2386 | case DP_TRAINING_PATTERN_DISABLE: | ||
2387 | temp |= DP_TP_CTL_LINK_TRAIN_NORMAL; | ||
2388 | |||
2389 | break; | ||
2390 | case DP_TRAINING_PATTERN_1: | ||
2391 | temp |= DP_TP_CTL_LINK_TRAIN_PAT1; | ||
2392 | break; | ||
2393 | case DP_TRAINING_PATTERN_2: | ||
2394 | temp |= DP_TP_CTL_LINK_TRAIN_PAT2; | ||
2395 | break; | ||
2396 | case DP_TRAINING_PATTERN_3: | ||
2397 | temp |= DP_TP_CTL_LINK_TRAIN_PAT3; | ||
2398 | break; | ||
2399 | } | ||
2400 | I915_WRITE(DP_TP_CTL(port), temp); | ||
2401 | |||
2402 | } else if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || port != PORT_A)) { | ||
2403 | *DP &= ~DP_LINK_TRAIN_MASK_CPT; | ||
2404 | |||
2405 | switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { | ||
2406 | case DP_TRAINING_PATTERN_DISABLE: | ||
2407 | *DP |= DP_LINK_TRAIN_OFF_CPT; | ||
2408 | break; | ||
2409 | case DP_TRAINING_PATTERN_1: | ||
2410 | *DP |= DP_LINK_TRAIN_PAT_1_CPT; | ||
2411 | break; | ||
2412 | case DP_TRAINING_PATTERN_2: | ||
2413 | *DP |= DP_LINK_TRAIN_PAT_2_CPT; | ||
2414 | break; | ||
2415 | case DP_TRAINING_PATTERN_3: | ||
2416 | DRM_ERROR("DP training pattern 3 not supported\n"); | ||
2417 | *DP |= DP_LINK_TRAIN_PAT_2_CPT; | ||
2418 | break; | ||
2419 | } | ||
2420 | |||
2421 | } else { | ||
2422 | if (IS_CHERRYVIEW(dev)) | ||
2423 | *DP &= ~DP_LINK_TRAIN_MASK_CHV; | ||
2424 | else | ||
2425 | *DP &= ~DP_LINK_TRAIN_MASK; | ||
2426 | |||
2427 | switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { | ||
2428 | case DP_TRAINING_PATTERN_DISABLE: | ||
2429 | *DP |= DP_LINK_TRAIN_OFF; | ||
2430 | break; | ||
2431 | case DP_TRAINING_PATTERN_1: | ||
2432 | *DP |= DP_LINK_TRAIN_PAT_1; | ||
2433 | break; | ||
2434 | case DP_TRAINING_PATTERN_2: | ||
2435 | *DP |= DP_LINK_TRAIN_PAT_2; | ||
2436 | break; | ||
2437 | case DP_TRAINING_PATTERN_3: | ||
2438 | if (IS_CHERRYVIEW(dev)) { | ||
2439 | *DP |= DP_LINK_TRAIN_PAT_3_CHV; | ||
2440 | } else { | ||
2441 | DRM_ERROR("DP training pattern 3 not supported\n"); | ||
2442 | *DP |= DP_LINK_TRAIN_PAT_2; | ||
2443 | } | ||
2444 | break; | ||
2445 | } | ||
2446 | } | ||
2447 | } | ||
2448 | |||
2449 | static void intel_dp_enable_port(struct intel_dp *intel_dp) | ||
2450 | { | ||
2451 | struct drm_device *dev = intel_dp_to_dev(intel_dp); | ||
2452 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2453 | |||
2454 | intel_dp->DP |= DP_PORT_EN; | ||
2455 | |||
2456 | /* enable with pattern 1 (as per spec) */ | ||
2457 | _intel_dp_set_link_train(intel_dp, &intel_dp->DP, | ||
2458 | DP_TRAINING_PATTERN_1); | ||
2459 | |||
2460 | I915_WRITE(intel_dp->output_reg, intel_dp->DP); | ||
2461 | POSTING_READ(intel_dp->output_reg); | ||
2462 | } | ||
2463 | |||
2366 | static void intel_enable_dp(struct intel_encoder *encoder) | 2464 | static void intel_enable_dp(struct intel_encoder *encoder) |
2367 | { | 2465 | { |
2368 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); | 2466 | struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); |
@@ -2373,6 +2471,7 @@ static void intel_enable_dp(struct intel_encoder *encoder) | |||
2373 | if (WARN_ON(dp_reg & DP_PORT_EN)) | 2471 | if (WARN_ON(dp_reg & DP_PORT_EN)) |
2374 | return; | 2472 | return; |
2375 | 2473 | ||
2474 | intel_dp_enable_port(intel_dp); | ||
2376 | intel_edp_panel_vdd_on(intel_dp); | 2475 | intel_edp_panel_vdd_on(intel_dp); |
2377 | intel_edp_panel_on(intel_dp); | 2476 | intel_edp_panel_on(intel_dp); |
2378 | intel_edp_panel_vdd_off(intel_dp, true); | 2477 | intel_edp_panel_vdd_off(intel_dp, true); |
@@ -3252,81 +3351,10 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, | |||
3252 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); | 3351 | struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); |
3253 | struct drm_device *dev = intel_dig_port->base.base.dev; | 3352 | struct drm_device *dev = intel_dig_port->base.base.dev; |
3254 | struct drm_i915_private *dev_priv = dev->dev_private; | 3353 | struct drm_i915_private *dev_priv = dev->dev_private; |
3255 | enum port port = intel_dig_port->port; | ||
3256 | uint8_t buf[sizeof(intel_dp->train_set) + 1]; | 3354 | uint8_t buf[sizeof(intel_dp->train_set) + 1]; |
3257 | int ret, len; | 3355 | int ret, len; |
3258 | 3356 | ||
3259 | if (HAS_DDI(dev)) { | 3357 | _intel_dp_set_link_train(intel_dp, DP, dp_train_pat); |
3260 | uint32_t temp = I915_READ(DP_TP_CTL(port)); | ||
3261 | |||
3262 | if (dp_train_pat & DP_LINK_SCRAMBLING_DISABLE) | ||
3263 | temp |= DP_TP_CTL_SCRAMBLE_DISABLE; | ||
3264 | else | ||
3265 | temp &= ~DP_TP_CTL_SCRAMBLE_DISABLE; | ||
3266 | |||
3267 | temp &= ~DP_TP_CTL_LINK_TRAIN_MASK; | ||
3268 | switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { | ||
3269 | case DP_TRAINING_PATTERN_DISABLE: | ||
3270 | temp |= DP_TP_CTL_LINK_TRAIN_NORMAL; | ||
3271 | |||
3272 | break; | ||
3273 | case DP_TRAINING_PATTERN_1: | ||
3274 | temp |= DP_TP_CTL_LINK_TRAIN_PAT1; | ||
3275 | break; | ||
3276 | case DP_TRAINING_PATTERN_2: | ||
3277 | temp |= DP_TP_CTL_LINK_TRAIN_PAT2; | ||
3278 | break; | ||
3279 | case DP_TRAINING_PATTERN_3: | ||
3280 | temp |= DP_TP_CTL_LINK_TRAIN_PAT3; | ||
3281 | break; | ||
3282 | } | ||
3283 | I915_WRITE(DP_TP_CTL(port), temp); | ||
3284 | |||
3285 | } else if (HAS_PCH_CPT(dev) && (IS_GEN7(dev) || port != PORT_A)) { | ||
3286 | *DP &= ~DP_LINK_TRAIN_MASK_CPT; | ||
3287 | |||
3288 | switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { | ||
3289 | case DP_TRAINING_PATTERN_DISABLE: | ||
3290 | *DP |= DP_LINK_TRAIN_OFF_CPT; | ||
3291 | break; | ||
3292 | case DP_TRAINING_PATTERN_1: | ||
3293 | *DP |= DP_LINK_TRAIN_PAT_1_CPT; | ||
3294 | break; | ||
3295 | case DP_TRAINING_PATTERN_2: | ||
3296 | *DP |= DP_LINK_TRAIN_PAT_2_CPT; | ||
3297 | break; | ||
3298 | case DP_TRAINING_PATTERN_3: | ||
3299 | DRM_ERROR("DP training pattern 3 not supported\n"); | ||
3300 | *DP |= DP_LINK_TRAIN_PAT_2_CPT; | ||
3301 | break; | ||
3302 | } | ||
3303 | |||
3304 | } else { | ||
3305 | if (IS_CHERRYVIEW(dev)) | ||
3306 | *DP &= ~DP_LINK_TRAIN_MASK_CHV; | ||
3307 | else | ||
3308 | *DP &= ~DP_LINK_TRAIN_MASK; | ||
3309 | |||
3310 | switch (dp_train_pat & DP_TRAINING_PATTERN_MASK) { | ||
3311 | case DP_TRAINING_PATTERN_DISABLE: | ||
3312 | *DP |= DP_LINK_TRAIN_OFF; | ||
3313 | break; | ||
3314 | case DP_TRAINING_PATTERN_1: | ||
3315 | *DP |= DP_LINK_TRAIN_PAT_1; | ||
3316 | break; | ||
3317 | case DP_TRAINING_PATTERN_2: | ||
3318 | *DP |= DP_LINK_TRAIN_PAT_2; | ||
3319 | break; | ||
3320 | case DP_TRAINING_PATTERN_3: | ||
3321 | if (IS_CHERRYVIEW(dev)) { | ||
3322 | *DP |= DP_LINK_TRAIN_PAT_3_CHV; | ||
3323 | } else { | ||
3324 | DRM_ERROR("DP training pattern 3 not supported\n"); | ||
3325 | *DP |= DP_LINK_TRAIN_PAT_2; | ||
3326 | } | ||
3327 | break; | ||
3328 | } | ||
3329 | } | ||
3330 | 3358 | ||
3331 | I915_WRITE(intel_dp->output_reg, *DP); | 3359 | I915_WRITE(intel_dp->output_reg, *DP); |
3332 | POSTING_READ(intel_dp->output_reg); | 3360 | POSTING_READ(intel_dp->output_reg); |