aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_ddi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ddi.c')
-rw-r--r--drivers/gpu/drm/i915/intel_ddi.c91
1 files changed, 65 insertions, 26 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c
index dd1d6fe12297..1a7efac65fd5 100644
--- a/drivers/gpu/drm/i915/intel_ddi.c
+++ b/drivers/gpu/drm/i915/intel_ddi.c
@@ -145,7 +145,7 @@ static const struct ddi_buf_trans skl_ddi_translations_dp[] = {
145static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = { 145static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = {
146 { 0x0000201B, 0x000000A2, 0x0 }, 146 { 0x0000201B, 0x000000A2, 0x0 },
147 { 0x00005012, 0x00000088, 0x0 }, 147 { 0x00005012, 0x00000088, 0x0 },
148 { 0x80007011, 0x000000CD, 0x0 }, 148 { 0x80007011, 0x000000CD, 0x1 },
149 { 0x80009010, 0x000000C0, 0x1 }, 149 { 0x80009010, 0x000000C0, 0x1 },
150 { 0x0000201B, 0x0000009D, 0x0 }, 150 { 0x0000201B, 0x0000009D, 0x0 },
151 { 0x80005012, 0x000000C0, 0x1 }, 151 { 0x80005012, 0x000000C0, 0x1 },
@@ -158,7 +158,7 @@ static const struct ddi_buf_trans skl_u_ddi_translations_dp[] = {
158static const struct ddi_buf_trans skl_y_ddi_translations_dp[] = { 158static const struct ddi_buf_trans skl_y_ddi_translations_dp[] = {
159 { 0x00000018, 0x000000A2, 0x0 }, 159 { 0x00000018, 0x000000A2, 0x0 },
160 { 0x00005012, 0x00000088, 0x0 }, 160 { 0x00005012, 0x00000088, 0x0 },
161 { 0x80007011, 0x000000CD, 0x0 }, 161 { 0x80007011, 0x000000CD, 0x3 },
162 { 0x80009010, 0x000000C0, 0x3 }, 162 { 0x80009010, 0x000000C0, 0x3 },
163 { 0x00000018, 0x0000009D, 0x0 }, 163 { 0x00000018, 0x0000009D, 0x0 },
164 { 0x80005012, 0x000000C0, 0x3 }, 164 { 0x80005012, 0x000000C0, 0x3 },
@@ -388,6 +388,40 @@ skl_get_buf_trans_hdmi(struct drm_i915_private *dev_priv, int *n_entries)
388 } 388 }
389} 389}
390 390
391static 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);
@@ -1379,14 +1404,30 @@ void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc)
1379 TRANS_CLK_SEL_DISABLED); 1404 TRANS_CLK_SEL_DISABLED);
1380} 1405}
1381 1406
1382static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv, 1407static void _skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
1383 u32 level, enum port port, int type) 1408 enum port port, uint8_t iboost)
1384{ 1409{
1410 u32 tmp;
1411
1412 tmp = I915_READ(DISPIO_CR_TX_BMU_CR0);
1413 tmp &= ~(BALANCE_LEG_MASK(port) | BALANCE_LEG_DISABLE(port));
1414 if (iboost)
1415 tmp |= iboost << BALANCE_LEG_SHIFT(port);
1416 else
1417 tmp |= BALANCE_LEG_DISABLE(port);
1418 I915_WRITE(DISPIO_CR_TX_BMU_CR0, tmp);
1419}
1420
1421static void skl_ddi_set_iboost(struct intel_encoder *encoder, u32 level)
1422{
1423 struct intel_digital_port *intel_dig_port = enc_to_dig_port(&encoder->base);
1424 struct drm_i915_private *dev_priv = to_i915(intel_dig_port->base.base.dev);
1425 enum port port = intel_dig_port->port;
1426 int type = encoder->type;
1385 const struct ddi_buf_trans *ddi_translations; 1427 const struct ddi_buf_trans *ddi_translations;
1386 uint8_t iboost; 1428 uint8_t iboost;
1387 uint8_t dp_iboost, hdmi_iboost; 1429 uint8_t dp_iboost, hdmi_iboost;
1388 int n_entries; 1430 int n_entries;
1389 u32 reg;
1390 1431
1391 /* VBT may override standard boost values */ 1432 /* VBT may override standard boost values */
1392 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level; 1433 dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
@@ -1428,16 +1469,10 @@ static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv,
1428 return; 1469 return;
1429 } 1470 }
1430 1471
1431 reg = I915_READ(DISPIO_CR_TX_BMU_CR0); 1472 _skl_ddi_set_iboost(dev_priv, port, iboost);
1432 reg &= ~BALANCE_LEG_MASK(port);
1433 reg &= ~(1 << (BALANCE_LEG_DISABLE_SHIFT + port));
1434
1435 if (iboost)
1436 reg |= iboost << BALANCE_LEG_SHIFT(port);
1437 else
1438 reg |= 1 << (BALANCE_LEG_DISABLE_SHIFT + port);
1439 1473
1440 I915_WRITE(DISPIO_CR_TX_BMU_CR0, reg); 1474 if (port == PORT_A && intel_dig_port->max_lanes == 4)
1475 _skl_ddi_set_iboost(dev_priv, PORT_E, iboost);
1441} 1476}
1442 1477
1443static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv, 1478static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv,
@@ -1568,7 +1603,7 @@ uint32_t ddi_signal_levels(struct intel_dp *intel_dp)
1568 level = translate_signal_level(signal_levels); 1603 level = translate_signal_level(signal_levels);
1569 1604
1570 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv)) 1605 if (IS_SKYLAKE(dev_priv) || IS_KABYLAKE(dev_priv))
1571 skl_ddi_set_iboost(dev_priv, level, port, encoder->type); 1606 skl_ddi_set_iboost(encoder, level);
1572 else if (IS_BROXTON(dev_priv)) 1607 else if (IS_BROXTON(dev_priv))
1573 bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type); 1608 bxt_ddi_vswing_sequence(dev_priv, level, port, encoder->type);
1574 1609
@@ -1637,6 +1672,10 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder)
1637 intel_dp_stop_link_train(intel_dp); 1672 intel_dp_stop_link_train(intel_dp);
1638 } else if (type == INTEL_OUTPUT_HDMI) { 1673 } else if (type == INTEL_OUTPUT_HDMI) {
1639 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);
1640 1679
1641 intel_hdmi->set_infoframes(encoder, 1680 intel_hdmi->set_infoframes(encoder,
1642 crtc->config->has_hdmi_sink, 1681 crtc->config->has_hdmi_sink,