summaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra/dc/dp.c
diff options
context:
space:
mode:
authorChao Xu <cxu@nvidia.com>2013-07-09 00:55:52 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:05:26 -0400
commit7b45f842ff16b4c29b5848ae9c9029c2a79e96ab (patch)
tree3236b64d65b063821886dc62e818b4c85226d79b /drivers/video/tegra/dc/dp.c
parentc845e1b1458d008756f0a310e02b57ee17e8311b (diff)
video: tegra: dc: Update eDP support
Change-Id: I6ee39c20d4e120926837f84ab3107d6f4bc5a144 Signed-off-by: Chao Xu <cxu@nvidia.com> Reviewed-on: http://git-master/r/246468 Reviewed-by: Jon Mayo <jmayo@nvidia.com> Reviewed-by: Automatic_Commit_Validation_User
Diffstat (limited to 'drivers/video/tegra/dc/dp.c')
-rw-r--r--drivers/video/tegra/dc/dp.c102
1 files changed, 66 insertions, 36 deletions
diff --git a/drivers/video/tegra/dc/dp.c b/drivers/video/tegra/dc/dp.c
index fb32b1d1a..c7baed83d 100644
--- a/drivers/video/tegra/dc/dp.c
+++ b/drivers/video/tegra/dc/dp.c
@@ -490,18 +490,10 @@ static void tegra_dc_dpaux_enable(struct tegra_dc_dp_data *dp)
490 DPAUX_HYBRID_PADCTL_AUX_INPUT_RCV_ENABLE); 490 DPAUX_HYBRID_PADCTL_AUX_INPUT_RCV_ENABLE);
491} 491}
492 492
493static void tegra_dc_dpaux_disable(struct tegra_dc_dp_data *dp)
494{
495 tegra_dpaux_writel(dp, NV_DPCD_SET_POWER,
496 NV_DPCD_SET_POWER_VAL_D3_PWRDWN);
497
498 /* TODO: power down DPAUX_HYBRID_SPARE too? */
499}
500
501static void tegra_dc_dp_dump_link_cfg(struct tegra_dc_dp_data *dp, 493static void tegra_dc_dp_dump_link_cfg(struct tegra_dc_dp_data *dp,
502 const struct tegra_dc_dp_link_config *cfg) 494 const struct tegra_dc_dp_link_config *cfg)
503{ 495{
504 BUG_ON(!cfg || !cfg->is_valid); 496 BUG_ON(!cfg);
505 497
506 dev_info(&dp->dc->ndev->dev, "DP config: cfg_name cfg_value\n"); 498 dev_info(&dp->dc->ndev->dev, "DP config: cfg_name cfg_value\n");
507 dev_info(&dp->dc->ndev->dev, " Lane Count %d\n", 499 dev_info(&dp->dc->ndev->dev, " Lane Count %d\n",
@@ -595,8 +587,8 @@ static bool tegra_dc_dp_calc_config(struct tegra_dc_dp_data *dp,
595 !cfg->bits_per_pixel) 587 !cfg->bits_per_pixel)
596 return false; 588 return false;
597 589
598 if (mode->pclk * cfg->bits_per_pixel >= 590 if ((u64)mode->pclk * cfg->bits_per_pixel >=
599 8 * link_rate * cfg->lane_count) 591 (u64)link_rate * 8 * cfg->lane_count)
600 return false; 592 return false;
601 593
602 num_linkclk_line = (u32)tegra_div64( 594 num_linkclk_line = (u32)tegra_div64(
@@ -759,6 +751,12 @@ static int tegra_dc_dp_init_max_link_cfg(struct tegra_dc_dp_data *dp,
759 751
760 cfg->bits_per_pixel = dp->dc->pdata->default_out->depth; 752 cfg->bits_per_pixel = dp->dc->pdata->default_out->depth;
761 753
754 /* TODO: need to come from the board file */
755 cfg->drive_current = 0x40404040;
756 cfg->preemphasis = 0x0f0f0f0f;
757 cfg->postcursor = 0;
758 cfg->max_link_bw = SOR_LINK_SPEED_G1_62;
759
762 CHECK_RET(tegra_dc_dp_dpcd_read(dp, NV_DPCD_EDP_CONFIG_CAP, 760 CHECK_RET(tegra_dc_dp_dpcd_read(dp, NV_DPCD_EDP_CONFIG_CAP,
763 &dpcd_data)); 761 &dpcd_data));
764 cfg->alt_scramber_reset_cap = 762 cfg->alt_scramber_reset_cap =
@@ -768,15 +766,11 @@ static int tegra_dc_dp_init_max_link_cfg(struct tegra_dc_dp_data *dp,
768 (dpcd_data & NV_DPCD_EDP_CONFIG_CAP_FRAMING_CHANGE_YES) ? 766 (dpcd_data & NV_DPCD_EDP_CONFIG_CAP_FRAMING_CHANGE_YES) ?
769 true : false; 767 true : false;
770 768
771 if (tegra_platform_is_fpga()) /* hardcoded to 1.62G on fpga */
772 cfg->max_link_bw = SOR_LINK_SPEED_G1_62;
773 cfg->lane_count = cfg->max_lane_count; 769 cfg->lane_count = cfg->max_lane_count;
774 cfg->link_bw = cfg->max_link_bw; 770 cfg->link_bw = cfg->max_link_bw;
775 cfg->enhanced_framing = cfg->support_enhanced_framing; 771 cfg->enhanced_framing = cfg->support_enhanced_framing;
776 772
777 tegra_dc_dp_calc_config(dp, dp->mode, cfg); 773 tegra_dc_dp_calc_config(dp, dp->mode, cfg);
778 tegra_dc_dp_dump_link_cfg(dp, cfg);
779
780 return 0; 774 return 0;
781} 775}
782 776
@@ -821,6 +815,7 @@ static int tegra_dp_set_lane_count(struct tegra_dc_dp_data *dp,
821 tegra_dc_sor_set_lane_count(dp->sor, cfg->lane_count); 815 tegra_dc_sor_set_lane_count(dp->sor, cfg->lane_count);
822 816
823 /* Also power down lanes that will not be used */ 817 /* Also power down lanes that will not be used */
818 return 0;
824} 819}
825 820
826static int tegra_dc_dp_set_lane_config(struct tegra_dc_dp_data *dp, 821static int tegra_dc_dp_set_lane_config(struct tegra_dc_dp_data *dp,
@@ -896,6 +891,7 @@ static int tegra_dc_dp_set_lane_config(struct tegra_dc_dp_data *dp,
896 temp_edc[0] &= NV_DPCD_TRAINING_PATTERN_SET_TPS_MASK; 891 temp_edc[0] &= NV_DPCD_TRAINING_PATTERN_SET_TPS_MASK;
897 temp_edc[0] |= (training_pattern & 892 temp_edc[0] |= (training_pattern &
898 NV_DPCD_TRAINING_PATTERN_SET_TPS_MASK); 893 NV_DPCD_TRAINING_PATTERN_SET_TPS_MASK);
894 temp_edc[0] |= NV_DPCD_TRAINING_PATTERN_SET_SC_DISABLED_T;
899 895
900 size = 4; 896 size = 4;
901 ret = tegra_dc_dpaux_write(dp, DPAUX_DP_AUXCTL_CMD_AUXRD, 897 ret = tegra_dc_dpaux_write(dp, DPAUX_DP_AUXCTL_CMD_AUXRD,
@@ -1197,28 +1193,72 @@ static int tegra_dc_dp_fast_link_training(struct tegra_dc_dp_data *dp,
1197 const struct tegra_dc_dp_link_config *cfg) 1193 const struct tegra_dc_dp_link_config *cfg)
1198{ 1194{
1199 struct tegra_dc_sor_data *sor = dp->sor; 1195 struct tegra_dc_sor_data *sor = dp->sor;
1200 u8 link_bw; 1196 u8 link_bw;
1201 u8 lane_count; 1197 u8 lane_count;
1198 u32 data;
1199 u32 size;
1200 u32 status;
1201 int j;
1202 u32 mask = 0xffff >> ((4 - cfg->lane_count) * 4);
1202 1203
1203 BUG_ON(!cfg || !cfg->is_valid); 1204 BUG_ON(!cfg || !cfg->is_valid);
1204 tegra_dc_sor_set_link_bandwidth(sor, cfg->link_bw); 1205
1205 tegra_dc_sor_set_lane_count(sor, cfg->lane_count); 1206 tegra_dc_sor_set_lane_parm(sor, cfg);
1207 tegra_dc_dp_dpcd_write(dp, NV_DPCD_MAIN_LINK_CHANNEL_CODING_SET,
1208 NV_DPCD_MAIN_LINK_CHANNEL_CODING_SET_ANSI_8B10B);
1206 1209
1207 /* Send TP1 */ 1210 /* Send TP1 */
1208 tegra_dc_sor_set_dp_linkctl(sor, true, trainingPattern_1, cfg); 1211 tegra_dc_sor_set_dp_linkctl(sor, true, trainingPattern_1, cfg);
1212 tegra_dc_dp_dpcd_write(dp, NV_DPCD_TRAINING_PATTERN_SET,
1213 NV_DPCD_TRAINING_PATTERN_SET_TPS_TP1);
1209 1214
1215 for (j = 0; j < cfg->lane_count; ++j)
1216 tegra_dc_dp_dpcd_write(dp, NV_DPCD_TRAINING_LANE0_SET + j,
1217 0x24);
1210 usleep_range(500, 1000); 1218 usleep_range(500, 1000);
1219 size = 2;
1220 tegra_dc_dpaux_read(dp, DPAUX_DP_AUXCTL_CMD_AUXRD,
1221 NV_DPCD_LANE0_1_STATUS, (u8 *)&data, &size, &status);
1222 status = mask & 0x1111;
1223 if ((data & status) != status) {
1224 dev_err(&dp->dc->ndev->dev,
1225 "dp: Link training error for TP1 (0x%x)\n", data);
1226 return -EFAULT;
1227 }
1228
1229 if ((data & status) != status) {
1230 dev_err(&dp->dc->ndev->dev,
1231 "dp: Link training error for TP1 (0x%x)\n", data);
1232 return -EFAULT;
1233 }
1234
1211 /* enable ASSR */ 1235 /* enable ASSR */
1212 tegra_dc_dp_set_assr(dp, true); 1236 tegra_dc_dp_set_assr(dp, true);
1213 tegra_dc_sor_set_dp_linkctl(sor, true, trainingPattern_2, cfg); 1237 tegra_dc_sor_set_dp_linkctl(sor, true, trainingPattern_3, cfg);
1214 1238
1239 tegra_dc_dp_dpcd_write(dp, NV_DPCD_TRAINING_PATTERN_SET,
1240 cfg->link_bw == 20 ? 0x23 : 0x22);
1241 for (j = 0; j < cfg->lane_count; ++j)
1242 tegra_dc_dp_dpcd_write(dp, NV_DPCD_TRAINING_LANE0_SET + j,
1243 0x24);
1215 usleep_range(500, 1000); 1244 usleep_range(500, 1000);
1245
1246 size = 4;
1247 tegra_dc_dpaux_read(dp, DPAUX_DP_AUXCTL_CMD_AUXRD,
1248 NV_DPCD_LANE0_1_STATUS, (u8 *)&data, &size, &status);
1249 if ((data & mask) != (0x7777 & mask)) {
1250 dev_info(&dp->dc->ndev->dev,
1251 "dp: Link training error for TP2/3 (0x%x)\n", data);
1252 return -EFAULT;
1253 }
1254
1216 tegra_dc_sor_set_dp_linkctl(sor, true, trainingPattern_Disabled, cfg); 1255 tegra_dc_sor_set_dp_linkctl(sor, true, trainingPattern_Disabled, cfg);
1256 tegra_dc_dp_dpcd_write(dp, NV_DPCD_TRAINING_PATTERN_SET, 0);
1217 1257
1218 if (!tegra_dc_dp_link_trained(dp, cfg)) { 1258 if (!tegra_dc_dp_link_trained(dp, cfg)) {
1219 tegra_dc_sor_read_link_config(dp->sor, &link_bw, 1259 tegra_dc_sor_read_link_config(dp->sor, &link_bw,
1220 &lane_count); 1260 &lane_count);
1221 dev_info(&dp->dc->ndev->dev, 1261 dev_err(&dp->dc->ndev->dev,
1222 "Fast link trainging failed, link bw %d, lane # %d\n", 1262 "Fast link trainging failed, link bw %d, lane # %d\n",
1223 link_bw, lane_count); 1263 link_bw, lane_count);
1224 return -EFAULT; 1264 return -EFAULT;
@@ -1274,7 +1314,6 @@ static int tegra_dp_link_config(struct tegra_dc_dp_data *dp,
1274 dev_err(&dp->dc->ndev->dev, "dp: Failed to set lane count\n"); 1314 dev_err(&dp->dc->ndev->dev, "dp: Failed to set lane count\n");
1275 return ret; 1315 return ret;
1276 } 1316 }
1277 tegra_dc_dp_dump_link_cfg(dp, cfg);
1278 tegra_dc_sor_set_dp_linkctl(dp->sor, true, trainingPattern_None, cfg); 1317 tegra_dc_sor_set_dp_linkctl(dp->sor, true, trainingPattern_None, cfg);
1279 1318
1280 /* Now do the fast link training for eDP */ 1319 /* Now do the fast link training for eDP */
@@ -1432,6 +1471,7 @@ static int tegra_dc_dp_init(struct tegra_dc *dc)
1432 /* TODO: confirm interrupt num is acquired from gpio_to_irq, 1471 /* TODO: confirm interrupt num is acquired from gpio_to_irq,
1433 Also how to differentiate them from HDMI HPD. 1472 Also how to differentiate them from HDMI HPD.
1434 */ 1473 */
1474#if 0
1435 if (request_irq(gpio_to_irq(dc->out->hotplug_gpio), tegra_dc_dp_hpd_irq, 1475 if (request_irq(gpio_to_irq(dc->out->hotplug_gpio), tegra_dc_dp_hpd_irq,
1436 IRQF_DISABLED | IRQF_TRIGGER_RISING | 1476 IRQF_DISABLED | IRQF_TRIGGER_RISING |
1437 IRQF_TRIGGER_FALLING, dev_name(&dc->ndev->dev), dc)) { 1477 IRQF_TRIGGER_FALLING, dev_name(&dc->ndev->dev), dc)) {
@@ -1440,6 +1480,7 @@ static int tegra_dc_dp_init(struct tegra_dc *dc)
1440 err = -EBUSY; 1480 err = -EBUSY;
1441 goto err_get_clk; 1481 goto err_get_clk;
1442 } 1482 }
1483#endif
1443 1484
1444 1485
1445 dp->dc = dc; 1486 dp->dc = dc;
@@ -1487,8 +1528,6 @@ static void tegra_dc_dp_enable(struct tegra_dc *dc)
1487 tegra_dc_dpaux_enable(dp); 1528 tegra_dc_dpaux_enable(dp);
1488 1529
1489 /* Power on panel */ 1530 /* Power on panel */
1490 tegra_dc_sor_set_panel_power(dp->sor, true);
1491
1492 if (tegra_dc_dp_init_max_link_cfg(dp, &dp->link_cfg)) { 1531 if (tegra_dc_dp_init_max_link_cfg(dp, &dp->link_cfg)) {
1493 dev_err(&dc->ndev->dev, 1532 dev_err(&dc->ndev->dev,
1494 "dp: failed to init link configuration\n"); 1533 "dp: failed to init link configuration\n");
@@ -1497,9 +1536,10 @@ static void tegra_dc_dp_enable(struct tegra_dc *dc)
1497 1536
1498 tegra_dc_sor_enable_dp(dp->sor); 1537 tegra_dc_sor_enable_dp(dp->sor);
1499 1538
1500 /* Enable backlight -- TODO: need to go through I2C */
1501 msleep(DP_LCDVCC_TO_HPD_DELAY_MS); 1539 msleep(DP_LCDVCC_TO_HPD_DELAY_MS);
1502 1540
1541 tegra_dc_sor_set_panel_power(dp->sor, true);
1542
1503 /* Write power on to DPCD */ 1543 /* Write power on to DPCD */
1504 data = NV_DPCD_SET_POWER_VAL_D0_NORMAL; 1544 data = NV_DPCD_SET_POWER_VAL_D0_NORMAL;
1505 retry = 0; 1545 retry = 0;
@@ -1527,14 +1567,9 @@ static void tegra_dc_dp_enable(struct tegra_dc *dc)
1527 dev_err(&dp->dc->ndev->dev, 1567 dev_err(&dp->dc->ndev->dev,
1528 "dp: failed to read the revision number from sink\n"); 1568 "dp: failed to read the revision number from sink\n");
1529 1569
1530 if (tegra_dp_link_config(dp, &dp->link_cfg)) {
1531 dev_err(&dp->dc->ndev->dev, "dp: Could not setup link\n");
1532 return;
1533 }
1534
1535 tegra_dc_dp_explore_link_cfg(dp, &dp->link_cfg, dp->mode); 1570 tegra_dc_dp_explore_link_cfg(dp, &dp->link_cfg, dp->mode);
1536 1571
1537 mdelay(100); 1572 tegra_dc_sor_set_power_state(dp->sor, 1);
1538 tegra_dc_sor_attach(dp->sor); 1573 tegra_dc_sor_attach(dp->sor);
1539 1574
1540error_enable: 1575error_enable:
@@ -1558,15 +1593,10 @@ static void tegra_dc_dp_disable(struct tegra_dc *dc)
1558{ 1593{
1559 struct tegra_dc_dp_data *dp = tegra_dc_get_outdata(dc); 1594 struct tegra_dc_dp_data *dp = tegra_dc_get_outdata(dc);
1560 1595
1561 /* TODO: confirm that dpaux_disable is not needed for eDP */
1562 tegra_dc_dpaux_disable(dp);
1563
1564 /* Power down SOR */ 1596 /* Power down SOR */
1565 tegra_dc_sor_disable(dp->sor, false); 1597 tegra_dc_sor_disable(dp->sor, false);
1566 1598
1567 clk_disable(dp->clk); 1599 clk_disable(dp->clk);
1568 /* TODO: Now power down the panel -- through GPIO */
1569 /* Make sure the timing meet the eDP specs */
1570} 1600}
1571 1601
1572extern struct clk *tegra_get_clock_by_name(const char *name); 1602extern struct clk *tegra_get_clock_by_name(const char *name);