aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2014-08-18 15:16:08 -0400
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-09-04 09:01:00 -0400
commit7b13b58a802bbea6d94aac4e3cc6b33e481eb900 (patch)
treed8ce782c78776c6c364109285089ac20dc5ad95f
parent43072a454646d22f81808bdc8fb1b269ee1717a6 (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.c172
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
2366static 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
2449static 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
2366static void intel_enable_dp(struct intel_encoder *encoder) 2464static 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);