summaryrefslogtreecommitdiff
path: root/drivers/video/tegra
diff options
context:
space:
mode:
authorSungwook Kim <sungwookk@nvidia.com>2014-03-25 04:26:16 -0700
committerMandar Padmawar <mpadmawar@nvidia.com>2014-06-20 02:47:34 -0700
commit118596094bdcfa0935a0a40a23b6860a04614c49 (patch)
treeeb921abef153d079ad794c4252bbd381f8581614 /drivers/video/tegra
parent1c17dcad971192c67a9a7c3a687a58906c40e428 (diff)
video: tegra: dp: eDP/miniDP support
To add a support for an internal eDP panel or an external DP monitor - reduce the HPD waiting time to reasonable - fix Alternate Scrambler Reset To 0xFFFE setting to support an external DP monitor - fix unplugged eDP/miniDP display at boot time blocking detection of the HDMI display - disable dpaux clock and pad power when no eDP panel or external monitor connected at boot time Note: It works with the eDP panel or the monitor connected only at boot time. No run-time hot plug support yet. Note2: Reposting due the Gerrit bug. bug 1409738 Change-Id: I81b8bab8881a6d849d97562deabd16fe794ff812 Signed-off-by: Sungwook Kim <sungwookk@nvidia.com> Reviewed-on: http://git-master/r/405512 (cherry picked from commit 199b1034b39f2a133623e5645e378c5a9abd1c81) Reviewed-on: http://git-master/r/420122 Reviewed-by: Mandar Padmawar <mpadmawar@nvidia.com> Tested-by: Mandar Padmawar <mpadmawar@nvidia.com>
Diffstat (limited to 'drivers/video/tegra')
-rw-r--r--drivers/video/tegra/dc/dc.c8
-rw-r--r--drivers/video/tegra/dc/dp.c32
2 files changed, 38 insertions, 2 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index fe106d1c61b5..3b8d807e9c03 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -1450,6 +1450,9 @@ static int tegra_dc_set_out(struct tegra_dc *dc, struct tegra_dc_out *out)
if (err < 0) {
dc->out = NULL;
dc->out_ops = NULL;
+ dev_err(&dc->ndev->dev,
+ "Error: out->type:%d out_ops->init() failed\n",
+ out->type);
return err;
}
}
@@ -2255,6 +2258,9 @@ static int tegra_dc_init(struct tegra_dc *dc)
if (!dc->initialized) {
if (tegra_dc_program_mode(dc, &dc->mode)) {
tegra_dc_io_end(dc);
+ dev_warn(&dc->ndev->dev,
+ "%s: tegra_dc_program_mode failed\n",
+ __func__);
return -EINVAL;
}
} else {
@@ -2314,6 +2320,8 @@ static bool _tegra_dc_controller_enable(struct tegra_dc *dc)
tegra_dc_clk_disable(dc);
else
tegra_dvfs_set_rate(dc->clk, 0);
+ dev_warn(&dc->ndev->dev,
+ "%s: tegra_dc_init failed\n", __func__);
return false;
}
diff --git a/drivers/video/tegra/dc/dp.c b/drivers/video/tegra/dc/dp.c
index ebb7b46ad4fa..2e47617d3006 100644
--- a/drivers/video/tegra/dc/dp.c
+++ b/drivers/video/tegra/dc/dp.c
@@ -778,6 +778,8 @@ static void tegra_dc_dp_dump_link_cfg(struct tegra_dc_dp_data *dp,
cfg->max_lane_count);
dev_info(&dp->dc->ndev->dev, " SupportEnhancedFraming %s\n",
cfg->support_enhanced_framing ? "Y" : "N");
+ dev_info(&dp->dc->ndev->dev, " SupportAltScrmbRstFffe %s\n",
+ cfg->alt_scramber_reset_cap ? "Y" : "N");
dev_info(&dp->dc->ndev->dev, " Bandwidth %d\n",
cfg->max_link_bw);
dev_info(&dp->dc->ndev->dev, " bpp %d\n",
@@ -1528,7 +1530,7 @@ static void tegra_dp_hpd_config(struct tegra_dc_dp_data *dp)
static int tegra_dp_hpd_plug(struct tegra_dc_dp_data *dp)
{
-#define TEGRA_DP_HPD_PLUG_TIMEOUT_MS 10000
+#define TEGRA_DP_HPD_PLUG_TIMEOUT_MS 500
u32 val;
int err = 0;
@@ -2002,6 +2004,8 @@ static void tegra_dp_link_config(struct tegra_dc_dp_data *dp)
if (cfg->alt_scramber_reset_cap)
tegra_dc_dp_set_assr(dp, true);
+ else
+ tegra_dc_sor_set_internal_panel(dp->sor, false);
tegra_dc_dp_dpcd_write(dp, NV_DPCD_MAIN_LINK_CHANNEL_CODING_SET,
NV_DPCD_MAIN_LINK_CHANNEL_CODING_SET_ANSI_8B10B);
@@ -2085,7 +2089,7 @@ static void tegra_dc_dp_enable(struct tegra_dc *dc)
tegra_dp_hpd_config(dp);
if (tegra_dp_hpd_plug(dp) < 0) {
- dev_err(&dc->ndev->dev, "dp: hpd plug failed\n");
+ dev_info(&dc->ndev->dev, "dp: no panel/monitor plugged\n");
goto error_enable;
}
@@ -2109,9 +2113,14 @@ static void tegra_dc_dp_enable(struct tegra_dc *dc)
tegra_dc_sor_attach(dp->sor);
dp->enabled = true;
+ tegra_dp_default_int(dp, false);
+ tegra_dc_io_end(dc);
+ return;
error_enable:
tegra_dp_default_int(dp, false);
+ tegra_dpaux_pad_power(dp->dc, false);
+ tegra_dpaux_clk_disable(dp);
tegra_dc_io_end(dc);
return;
}
@@ -2178,6 +2187,24 @@ static long tegra_dc_dp_setup_clk(struct tegra_dc *dc, struct clk *clk)
return tegra_dc_pclk_round_rate(dc, dc->mode.pclk);
}
+/* used by tegra_dc_probe() to detect connection(HPD) status at boot */
+static bool tegra_dc_dp_detect(struct tegra_dc *dc)
+{
+ struct tegra_dc_dp_data *dp = tegra_dc_get_outdata(dc);
+ u32 rd;
+
+ tegra_dc_io_start(dc);
+ tegra_dpaux_clk_enable(dp);
+ rd = tegra_dpaux_readl(dp, DPAUX_DP_AUXSTAT);
+ tegra_dpaux_clk_disable(dp);
+ tegra_dc_io_end(dc);
+ dev_info(&dc->ndev->dev,
+ "dp: DPAUX_DP_AUXSTAT:0x%08x HPD:%splugged\n",
+ rd, (DPAUX_DP_AUXSTAT_HPD_STATUS_PLUGGED & rd) ? "" : "un");
+ return (DPAUX_DP_AUXSTAT_HPD_STATUS_PLUGGED & rd) ? true : false;
+}
+
+
static void tegra_dc_dp_modeset_notifier(struct tegra_dc *dc)
{
struct tegra_dc_dp_data *dp = tegra_dc_get_outdata(dc);
@@ -2196,6 +2223,7 @@ struct tegra_dc_out_ops tegra_dc_dp_ops = {
.destroy = tegra_dc_dp_destroy,
.enable = tegra_dc_dp_enable,
.disable = tegra_dc_dp_disable,
+ .detect = tegra_dc_dp_detect,
.setup_clk = tegra_dc_dp_setup_clk,
.modeset_notifier = tegra_dc_dp_modeset_notifier,
};