diff options
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 75 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp_mst.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 2 |
3 files changed, 49 insertions, 32 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 35b979956d6d..5cae63aa3905 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
@@ -421,28 +421,20 @@ static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port por | |||
421 | 421 | ||
422 | /* | 422 | /* |
423 | * Starting with Haswell, DDI port buffers must be programmed with correct | 423 | * Starting with Haswell, DDI port buffers must be programmed with correct |
424 | * values in advance. The buffer values are different for FDI and DP modes, | 424 | * values in advance. This function programs the correct values for |
425 | * but the HDMI/DVI fields are shared among those. So we program the DDI | 425 | * DP/eDP/FDI use cases. |
426 | * in either FDI or DP modes only, as HDMI connections will work with both | ||
427 | * of those | ||
428 | */ | 426 | */ |
429 | void intel_prepare_ddi_buffer(struct intel_encoder *encoder) | 427 | void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder) |
430 | { | 428 | { |
431 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 429 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
432 | u32 iboost_bit = 0; | 430 | u32 iboost_bit = 0; |
433 | int i, n_hdmi_entries, n_dp_entries, n_edp_entries, | 431 | int i, n_dp_entries, n_edp_entries, size; |
434 | size; | 432 | enum port port = intel_ddi_get_encoder_port(encoder); |
435 | int hdmi_level; | ||
436 | enum port port; | ||
437 | const struct ddi_buf_trans *ddi_translations_fdi; | 433 | const struct ddi_buf_trans *ddi_translations_fdi; |
438 | const struct ddi_buf_trans *ddi_translations_dp; | 434 | const struct ddi_buf_trans *ddi_translations_dp; |
439 | const struct ddi_buf_trans *ddi_translations_edp; | 435 | const struct ddi_buf_trans *ddi_translations_edp; |
440 | const struct ddi_buf_trans *ddi_translations_hdmi; | ||
441 | const struct ddi_buf_trans *ddi_translations; | 436 | const struct ddi_buf_trans *ddi_translations; |
442 | 437 | ||
443 | port = intel_ddi_get_encoder_port(encoder); | ||
444 | hdmi_level = intel_ddi_hdmi_level(dev_priv, port); | ||
445 | |||
446 | if (IS_BROXTON(dev_priv)) | 438 | if (IS_BROXTON(dev_priv)) |
447 | return; | 439 | return; |
448 | 440 | ||
@@ -452,8 +444,7 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) | |||
452 | skl_get_buf_trans_dp(dev_priv, &n_dp_entries); | 444 | skl_get_buf_trans_dp(dev_priv, &n_dp_entries); |
453 | ddi_translations_edp = | 445 | ddi_translations_edp = |
454 | skl_get_buf_trans_edp(dev_priv, &n_edp_entries); | 446 | skl_get_buf_trans_edp(dev_priv, &n_edp_entries); |
455 | ddi_translations_hdmi = | 447 | |
456 | skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); | ||
457 | /* If we're boosting the current, set bit 31 of trans1 */ | 448 | /* If we're boosting the current, set bit 31 of trans1 */ |
458 | if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level || | 449 | if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level || |
459 | dev_priv->vbt.ddi_port_info[port].dp_boost_level) | 450 | dev_priv->vbt.ddi_port_info[port].dp_boost_level) |
@@ -466,7 +457,6 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) | |||
466 | } else if (IS_BROADWELL(dev_priv)) { | 457 | } else if (IS_BROADWELL(dev_priv)) { |
467 | ddi_translations_fdi = bdw_ddi_translations_fdi; | 458 | ddi_translations_fdi = bdw_ddi_translations_fdi; |
468 | ddi_translations_dp = bdw_ddi_translations_dp; | 459 | ddi_translations_dp = bdw_ddi_translations_dp; |
469 | |||
470 | if (dev_priv->vbt.edp.low_vswing) { | 460 | if (dev_priv->vbt.edp.low_vswing) { |
471 | ddi_translations_edp = bdw_ddi_translations_edp; | 461 | ddi_translations_edp = bdw_ddi_translations_edp; |
472 | n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); | 462 | n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); |
@@ -474,27 +464,19 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) | |||
474 | ddi_translations_edp = bdw_ddi_translations_dp; | 464 | ddi_translations_edp = bdw_ddi_translations_dp; |
475 | n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); | 465 | n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); |
476 | } | 466 | } |
477 | |||
478 | ddi_translations_hdmi = bdw_ddi_translations_hdmi; | ||
479 | |||
480 | n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); | 467 | n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); |
481 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | ||
482 | } else if (IS_HASWELL(dev_priv)) { | 468 | } else if (IS_HASWELL(dev_priv)) { |
483 | ddi_translations_fdi = hsw_ddi_translations_fdi; | 469 | ddi_translations_fdi = hsw_ddi_translations_fdi; |
484 | ddi_translations_dp = hsw_ddi_translations_dp; | 470 | ddi_translations_dp = hsw_ddi_translations_dp; |
485 | ddi_translations_edp = hsw_ddi_translations_dp; | 471 | ddi_translations_edp = hsw_ddi_translations_dp; |
486 | ddi_translations_hdmi = hsw_ddi_translations_hdmi; | ||
487 | n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp); | 472 | n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp); |
488 | n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); | ||
489 | } else { | 473 | } else { |
490 | WARN(1, "ddi translation table missing\n"); | 474 | WARN(1, "ddi translation table missing\n"); |
491 | ddi_translations_edp = bdw_ddi_translations_dp; | 475 | ddi_translations_edp = bdw_ddi_translations_dp; |
492 | ddi_translations_fdi = bdw_ddi_translations_fdi; | 476 | ddi_translations_fdi = bdw_ddi_translations_fdi; |
493 | ddi_translations_dp = bdw_ddi_translations_dp; | 477 | ddi_translations_dp = bdw_ddi_translations_dp; |
494 | ddi_translations_hdmi = bdw_ddi_translations_hdmi; | ||
495 | n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); | 478 | n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); |
496 | n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); | 479 | n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); |
497 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | ||
498 | } | 480 | } |
499 | 481 | ||
500 | switch (encoder->type) { | 482 | switch (encoder->type) { |
@@ -503,7 +485,6 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) | |||
503 | size = n_edp_entries; | 485 | size = n_edp_entries; |
504 | break; | 486 | break; |
505 | case INTEL_OUTPUT_DP: | 487 | case INTEL_OUTPUT_DP: |
506 | case INTEL_OUTPUT_HDMI: | ||
507 | ddi_translations = ddi_translations_dp; | 488 | ddi_translations = ddi_translations_dp; |
508 | size = n_dp_entries; | 489 | size = n_dp_entries; |
509 | break; | 490 | break; |
@@ -521,10 +502,44 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) | |||
521 | I915_WRITE(DDI_BUF_TRANS_HI(port, i), | 502 | I915_WRITE(DDI_BUF_TRANS_HI(port, i), |
522 | ddi_translations[i].trans2); | 503 | ddi_translations[i].trans2); |
523 | } | 504 | } |
505 | } | ||
506 | |||
507 | /* | ||
508 | * Starting with Haswell, DDI port buffers must be programmed with correct | ||
509 | * values in advance. This function programs the correct values for | ||
510 | * HDMI/DVI use cases. | ||
511 | */ | ||
512 | static void intel_prepare_hdmi_ddi_buffers(struct intel_encoder *encoder) | ||
513 | { | ||
514 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | ||
515 | u32 iboost_bit = 0; | ||
516 | int n_hdmi_entries, hdmi_level; | ||
517 | enum port port = intel_ddi_get_encoder_port(encoder); | ||
518 | const struct ddi_buf_trans *ddi_translations_hdmi; | ||
524 | 519 | ||
525 | if (encoder->type != INTEL_OUTPUT_HDMI) | 520 | if (IS_BROXTON(dev_priv)) |
526 | return; | 521 | return; |
527 | 522 | ||
523 | hdmi_level = intel_ddi_hdmi_level(dev_priv, port); | ||
524 | |||
525 | if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { | ||
526 | ddi_translations_hdmi = skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); | ||
527 | /* If we're boosting the current, set bit 31 of trans1 */ | ||
528 | if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level || | ||
529 | dev_priv->vbt.ddi_port_info[port].dp_boost_level) | ||
530 | iboost_bit = DDI_BUF_BALANCE_LEG_ENABLE; | ||
531 | } else if (IS_BROADWELL(dev_priv)) { | ||
532 | ddi_translations_hdmi = bdw_ddi_translations_hdmi; | ||
533 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | ||
534 | } else if (IS_HASWELL(dev_priv)) { | ||
535 | ddi_translations_hdmi = hsw_ddi_translations_hdmi; | ||
536 | n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); | ||
537 | } else { | ||
538 | WARN(1, "ddi translation table missing\n"); | ||
539 | ddi_translations_hdmi = bdw_ddi_translations_hdmi; | ||
540 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | ||
541 | } | ||
542 | |||
528 | /* Entry 9 is for HDMI: */ | 543 | /* Entry 9 is for HDMI: */ |
529 | I915_WRITE(DDI_BUF_TRANS_LO(port, 9), | 544 | I915_WRITE(DDI_BUF_TRANS_LO(port, 9), |
530 | ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit); | 545 | ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit); |
@@ -565,7 +580,7 @@ void hsw_fdi_link_train(struct drm_crtc *crtc) | |||
565 | 580 | ||
566 | for_each_encoder_on_crtc(dev, crtc, encoder) { | 581 | for_each_encoder_on_crtc(dev, crtc, encoder) { |
567 | WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG); | 582 | WARN_ON(encoder->type != INTEL_OUTPUT_ANALOG); |
568 | intel_prepare_ddi_buffer(encoder); | 583 | intel_prepare_dp_ddi_buffers(encoder); |
569 | } | 584 | } |
570 | 585 | ||
571 | /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the | 586 | /* Set the FDI_RX_MISC pwrdn lanes and the 2 workarounds listed at the |
@@ -1640,8 +1655,6 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) | |||
1640 | intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); | 1655 | intel_dp_dual_mode_set_tmds_output(intel_hdmi, true); |
1641 | } | 1656 | } |
1642 | 1657 | ||
1643 | intel_prepare_ddi_buffer(intel_encoder); | ||
1644 | |||
1645 | if (type == INTEL_OUTPUT_EDP) { | 1658 | if (type == INTEL_OUTPUT_EDP) { |
1646 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1659 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1647 | intel_edp_panel_on(intel_dp); | 1660 | intel_edp_panel_on(intel_dp); |
@@ -1652,6 +1665,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) | |||
1652 | if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { | 1665 | if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { |
1653 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 1666 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
1654 | 1667 | ||
1668 | intel_prepare_dp_ddi_buffers(intel_encoder); | ||
1669 | |||
1655 | intel_dp_set_link_params(intel_dp, crtc->config); | 1670 | intel_dp_set_link_params(intel_dp, crtc->config); |
1656 | 1671 | ||
1657 | intel_ddi_init_dp_buf_reg(intel_encoder); | 1672 | intel_ddi_init_dp_buf_reg(intel_encoder); |
@@ -1664,6 +1679,8 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) | |||
1664 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 1679 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
1665 | int level = intel_ddi_hdmi_level(dev_priv, port); | 1680 | int level = intel_ddi_hdmi_level(dev_priv, port); |
1666 | 1681 | ||
1682 | intel_prepare_hdmi_ddi_buffers(intel_encoder); | ||
1683 | |||
1667 | if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) | 1684 | if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) |
1668 | skl_ddi_set_iboost(intel_encoder, level); | 1685 | skl_ddi_set_iboost(intel_encoder, level); |
1669 | else if (IS_BROXTON(dev_priv)) | 1686 | else if (IS_BROXTON(dev_priv)) |
diff --git a/drivers/gpu/drm/i915/intel_dp_mst.c b/drivers/gpu/drm/i915/intel_dp_mst.c index 68a005d729e9..629337dbca3d 100644 --- a/drivers/gpu/drm/i915/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/intel_dp_mst.c | |||
@@ -170,10 +170,10 @@ static void intel_mst_pre_enable_dp(struct intel_encoder *encoder) | |||
170 | intel_mst->connector = found; | 170 | intel_mst->connector = found; |
171 | 171 | ||
172 | if (intel_dp->active_mst_links == 0) { | 172 | if (intel_dp->active_mst_links == 0) { |
173 | intel_prepare_ddi_buffer(&intel_dig_port->base); | ||
174 | |||
175 | intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config); | 173 | intel_ddi_clk_select(&intel_dig_port->base, intel_crtc->config); |
176 | 174 | ||
175 | intel_prepare_dp_ddi_buffers(&intel_dig_port->base); | ||
176 | |||
177 | intel_dp_set_link_params(intel_dp, intel_crtc->config); | 177 | intel_dp_set_link_params(intel_dp, intel_crtc->config); |
178 | 178 | ||
179 | intel_ddi_init_dp_buf_reg(&intel_dig_port->base); | 179 | intel_ddi_init_dp_buf_reg(&intel_dig_port->base); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index e74d851868c5..50cdc890d956 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -1107,7 +1107,7 @@ void intel_crt_reset(struct drm_encoder *encoder); | |||
1107 | /* intel_ddi.c */ | 1107 | /* intel_ddi.c */ |
1108 | void intel_ddi_clk_select(struct intel_encoder *encoder, | 1108 | void intel_ddi_clk_select(struct intel_encoder *encoder, |
1109 | const struct intel_crtc_state *pipe_config); | 1109 | const struct intel_crtc_state *pipe_config); |
1110 | void intel_prepare_ddi_buffer(struct intel_encoder *encoder); | 1110 | void intel_prepare_dp_ddi_buffers(struct intel_encoder *encoder); |
1111 | void hsw_fdi_link_train(struct drm_crtc *crtc); | 1111 | void hsw_fdi_link_train(struct drm_crtc *crtc); |
1112 | void intel_ddi_init(struct drm_device *dev, enum port port); | 1112 | void intel_ddi_init(struct drm_device *dev, enum port port); |
1113 | enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder); | 1113 | enum port intel_ddi_get_encoder_port(struct intel_encoder *intel_encoder); |