diff options
| author | Ville Syrjälä <ville.syrjala@linux.intel.com> | 2016-07-12 08:59:30 -0400 |
|---|---|---|
| committer | Jani Nikula <jani.nikula@intel.com> | 2016-08-10 17:51:57 -0400 |
| commit | 7ff9a55614712adf13ce7990565be0263e620f5e (patch) | |
| tree | 2f7672e8269806f311dde73c0e9f0a29d38ff5d5 | |
| parent | 5728e0de741a3581e9900c5cbee3a51425daf211 (diff) | |
drm/i915: Program iboost settings for HDMI/DVI on SKL
Currently we fail to program the iboost stuff for HDMI/DVI. Let's remedy
that.
Cc: stable@vger.kernel.org
Fixes: f8896f5d58e6 ("drm/i915/skl: Buffer translation improvements")
Cc: David Weinehall <david.weinehall@linux.intel.com>
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1468328376-6380-4-git-send-email-ville.syrjala@linux.intel.com
Reviewed-by: David Weinehall <david.weinehall@linux.intel.com>
(cherry picked from commit 8d8bb85eb7d859aa9bbe36e588690a1d22af7608)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
| -rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 51 |
1 files changed, 40 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 75354cd9bbab..415c061e2969 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c | |||
| @@ -388,6 +388,40 @@ skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries) | |||
| 388 | } | 388 | } |
| 389 | } | 389 | } |
| 390 | 390 | ||
| 391 | static int intel_ddi_hdmi_level(struct drm_i915_private *dev_priv, enum port port) | ||
| 392 | { | ||
| 393 | int n_hdmi_entries; | ||
| 394 | int hdmi_level; | ||
| 395 | int hdmi_default_entry; | ||
| 396 | |||
| 397 | hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; | ||
| 398 | |||
| 399 | if (IS_BROXTON(dev_priv)) | ||
| 400 | return hdmi_level; | ||
| 401 | |||
| 402 | if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) { | ||
| 403 | skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); | ||
| 404 | hdmi_default_entry = 8; | ||
| 405 | } else if (IS_BROADWELL(dev_priv)) { | ||
| 406 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | ||
| 407 | hdmi_default_entry = 7; | ||
| 408 | } else if (IS_HASWELL(dev_priv)) { | ||
| 409 | n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); | ||
| 410 | hdmi_default_entry = 6; | ||
| 411 | } else { | ||
| 412 | WARN(1, "ddi translation table missing\n"); | ||
| 413 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | ||
| 414 | hdmi_default_entry = 7; | ||
| 415 | } | ||
| 416 | |||
| 417 | /* Choose a good default if VBT is badly populated */ | ||
| 418 | if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN || | ||
| 419 | hdmi_level >= n_hdmi_entries) | ||
| 420 | hdmi_level = hdmi_default_entry; | ||
| 421 | |||
| 422 | return hdmi_level; | ||
| 423 | } | ||
| 424 | |||
| 391 | /* | 425 | /* |
| 392 | * Starting with Haswell, DDI port buffers must be programmed with correct | 426 | * Starting with Haswell, DDI port buffers must be programmed with correct |
| 393 | * values in advance. The buffer values are different for FDI and DP modes, | 427 | * values in advance. The buffer values are different for FDI and DP modes, |
| @@ -399,7 +433,7 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) | |||
| 399 | { | 433 | { |
| 400 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); | 434 | struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); |
| 401 | u32 iboost_bit = 0; | 435 | u32 iboost_bit = 0; |
| 402 | int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry, | 436 | int i, n_hdmi_entries, n_dp_entries, n_edp_entries, |
| 403 | size; | 437 | size; |
| 404 | int hdmi_level; | 438 | int hdmi_level; |
| 405 | enum port port; | 439 | enum port port; |
| @@ -410,7 +444,7 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) | |||
| 410 | const struct ddi_buf_trans *ddi_translations; | 444 | const struct ddi_buf_trans *ddi_translations; |
| 411 | 445 | ||
| 412 | port = intel_ddi_get_encoder_port(encoder); | 446 | port = intel_ddi_get_encoder_port(encoder); |
| 413 | hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift; | 447 | hdmi_level = intel_ddi_hdmi_level(dev_priv, port); |
| 414 | 448 | ||
| 415 | if (IS_BROXTON(dev_priv)) { | 449 | if (IS_BROXTON(dev_priv)) { |
| 416 | if (encoder->type != INTEL_OUTPUT_HDMI) | 450 | if (encoder->type != INTEL_OUTPUT_HDMI) |
| @@ -430,7 +464,6 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) | |||
| 430 | skl_get_buf_trans_edp(dev_priv, &n_edp_entries); | 464 | skl_get_buf_trans_edp(dev_priv, &n_edp_entries); |
| 431 | ddi_translations_hdmi = | 465 | ddi_translations_hdmi = |
| 432 | skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); | 466 | skl_get_buf_trans_hdmi(dev_priv, &n_hdmi_entries); |
| 433 | hdmi_default_entry = 8; | ||
| 434 | /* If we're boosting the current, set bit 31 of trans1 */ | 467 | /* If we're boosting the current, set bit 31 of trans1 */ |
| 435 | if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level || | 468 | if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level || |
| 436 | dev_priv->vbt.ddi_port_info[port].dp_boost_level) | 469 | dev_priv->vbt.ddi_port_info[port].dp_boost_level) |
| @@ -456,7 +489,6 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) | |||
| 456 | 489 | ||
| 457 | n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); | 490 | n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); |
| 458 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | 491 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); |
| 459 | hdmi_default_entry = 7; | ||
| 460 | } else if (IS_HASWELL(dev_priv)) { | 492 | } else if (IS_HASWELL(dev_priv)) { |
| 461 | ddi_translations_fdi = hsw_ddi_translations_fdi; | 493 | ddi_translations_fdi = hsw_ddi_translations_fdi; |
| 462 | ddi_translations_dp = hsw_ddi_translations_dp; | 494 | ddi_translations_dp = hsw_ddi_translations_dp; |
| @@ -464,7 +496,6 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) | |||
| 464 | ddi_translations_hdmi = hsw_ddi_translations_hdmi; | 496 | ddi_translations_hdmi = hsw_ddi_translations_hdmi; |
| 465 | n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp); | 497 | n_dp_entries = n_edp_entries = ARRAY_SIZE(hsw_ddi_translations_dp); |
| 466 | n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); | 498 | n_hdmi_entries = ARRAY_SIZE(hsw_ddi_translations_hdmi); |
| 467 | hdmi_default_entry = 6; | ||
| 468 | } else { | 499 | } else { |
| 469 | WARN(1, "ddi translation table missing\n"); | 500 | WARN(1, "ddi translation table missing\n"); |
| 470 | ddi_translations_edp = bdw_ddi_translations_dp; | 501 | ddi_translations_edp = bdw_ddi_translations_dp; |
| @@ -474,7 +505,6 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) | |||
| 474 | n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); | 505 | n_edp_entries = ARRAY_SIZE(bdw_ddi_translations_edp); |
| 475 | n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); | 506 | n_dp_entries = ARRAY_SIZE(bdw_ddi_translations_dp); |
| 476 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); | 507 | n_hdmi_entries = ARRAY_SIZE(bdw_ddi_translations_hdmi); |
| 477 | hdmi_default_entry = 7; | ||
| 478 | } | 508 | } |
| 479 | 509 | ||
| 480 | switch (encoder->type) { | 510 | switch (encoder->type) { |
| @@ -505,11 +535,6 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) | |||
| 505 | if (encoder->type != INTEL_OUTPUT_HDMI) | 535 | if (encoder->type != INTEL_OUTPUT_HDMI) |
| 506 | return; | 536 | return; |
| 507 | 537 | ||
| 508 | /* Choose a good default if VBT is badly populated */ | ||
| 509 | if (hdmi_level == HDMI_LEVEL_SHIFT_UNKNOWN || | ||
| 510 | hdmi_level >= n_hdmi_entries) | ||
| 511 | hdmi_level = hdmi_default_entry; | ||
| 512 | |||
| 513 | /* Entry 9 is for HDMI: */ | 538 | /* Entry 9 is for HDMI: */ |
| 514 | I915_WRITE(DDI_BUF_TRANS_LO(port, i), | 539 | I915_WRITE(DDI_BUF_TRANS_LO(port, i), |
| 515 | ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit); | 540 | ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit); |
| @@ -1647,6 +1672,10 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) | |||
| 1647 | intel_dp_stop_link_train(intel_dp); | 1672 | intel_dp_stop_link_train(intel_dp); |
| 1648 | } else if (type == INTEL_OUTPUT_HDMI) { | 1673 | } else if (type == INTEL_OUTPUT_HDMI) { |
| 1649 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); | 1674 | struct intel_hdmi *intel_hdmi = enc_to_intel_hdmi(encoder); |
| 1675 | int level = intel_ddi_hdmi_level(dev_priv, port); | ||
| 1676 | |||
| 1677 | if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) | ||
| 1678 | skl_ddi_set_iboost(intel_encoder, level); | ||
| 1650 | 1679 | ||
| 1651 | intel_hdmi->set_infoframes(encoder, | 1680 | intel_hdmi->set_infoframes(encoder, |
| 1652 | crtc->config->has_hdmi_sink, | 1681 | crtc->config->has_hdmi_sink, |
