diff options
author | Sungwook Kim <sungwookk@nvidia.com> | 2014-03-25 04:26:16 -0700 |
---|---|---|
committer | Mandar Padmawar <mpadmawar@nvidia.com> | 2014-06-20 02:47:34 -0700 |
commit | 118596094bdcfa0935a0a40a23b6860a04614c49 (patch) | |
tree | eb921abef153d079ad794c4252bbd381f8581614 /drivers/video/tegra | |
parent | 1c17dcad971192c67a9a7c3a687a58906c40e428 (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.c | 8 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dp.c | 32 |
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, }; |