summaryrefslogtreecommitdiffstats
path: root/drivers/video/tegra/dc/dp.c
diff options
context:
space:
mode:
authorAnimesh Kishore <ankishore@nvidia.com>2014-03-11 06:43:01 -0400
committerDan Willemsen <dwillemsen@nvidia.com>2015-03-18 15:08:34 -0400
commitedfaa712d9da49673379a24e8f412d1460dafa7f (patch)
tree21fce61095db3db7485b5e47f8f6aac85f7c8282 /drivers/video/tegra/dc/dp.c
parentfaca38984a2a97cd2f6cf61adfe929425d7c370c (diff)
video: tegra: dp: Remove early enable
Move edid read from panel to display enable operation. Bug 1472436 Change-Id: I8f44283620b110af2bf13dd6370da3dff0b14138 Signed-off-by: Animesh Kishore <ankishore@nvidia.com> Reviewed-on: http://git-master/r/379874 Reviewed-by: Venkat Moganty <vmoganty@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.c99
1 files changed, 39 insertions, 60 deletions
diff --git a/drivers/video/tegra/dc/dp.c b/drivers/video/tegra/dc/dp.c
index 800f091bf..a1fe98a89 100644
--- a/drivers/video/tegra/dc/dp.c
+++ b/drivers/video/tegra/dc/dp.c
@@ -1968,6 +1968,42 @@ static void tegra_dp_link_config(struct tegra_dc_dp_data *dp)
1968 tegra_sor_port_enable(sor, true); 1968 tegra_sor_port_enable(sor, true);
1969} 1969}
1970 1970
1971static int tegra_dp_edid(struct tegra_dc_dp_data *dp)
1972{
1973 struct tegra_dc *dc = dp->dc;
1974 struct fb_monspecs specs;
1975 int err;
1976
1977 err = tegra_edid_get_monspecs(dp->dp_edid, &specs);
1978 if (err < 0) {
1979 dev_err(&dc->ndev->dev, "dp: Failed to get EDID data\n");
1980 goto fail;
1981 }
1982
1983 dc->out->h_size = specs.max_x * 10; /* in mm */
1984 dc->out->v_size = specs.max_y * 10;
1985
1986 tegra_dc_set_fb_mode(dc, specs.modedb, false);
1987
1988 if (!dc->out->width && !dc->out->height) {
1989 /*
1990 * EDID specifies either the acutal screen sizes or
1991 * the aspect ratios. The panel file can choose to
1992 * trust the value as the actual sizes by leaving
1993 * width/height to 0s
1994 */
1995 dc->out->width = dc->out->h_size;
1996 dc->out->height = dc->out->v_size;
1997 }
1998
1999 /* adjust clk for new mode */
2000 tegra_dc_setup_clk(dc, dc->clk);
2001
2002 return 0;
2003fail:
2004 return err;
2005}
2006
1971static void tegra_dc_dp_enable(struct tegra_dc *dc) 2007static void tegra_dc_dp_enable(struct tegra_dc *dc)
1972{ 2008{
1973 struct tegra_dc_dp_data *dp = tegra_dc_get_outdata(dc); 2009 struct tegra_dc_dp_data *dp = tegra_dc_get_outdata(dc);
@@ -1997,6 +2033,9 @@ static void tegra_dc_dp_enable(struct tegra_dc *dc)
1997 goto error_enable; 2033 goto error_enable;
1998 } 2034 }
1999 2035
2036 if (dp->dp_edid && !dp->dp_edid->data)
2037 tegra_dp_edid(dp);
2038
2000 tegra_dp_dpcd_init(dp); 2039 tegra_dp_dpcd_init(dp);
2001 2040
2002 tegra_dc_sor_enable_dp(dp->sor); 2041 tegra_dc_sor_enable_dp(dp->sor);
@@ -2068,65 +2107,6 @@ static long tegra_dc_dp_setup_clk(struct tegra_dc *dc, struct clk *clk)
2068 return tegra_dc_pclk_round_rate(dc, dp->sor->dc->mode.pclk); 2107 return tegra_dc_pclk_round_rate(dc, dp->sor->dc->mode.pclk);
2069} 2108}
2070 2109
2071
2072static bool tegra_dc_dp_early_enable(struct tegra_dc *dc)
2073{
2074 struct tegra_dc_dp_data *dp = tegra_dc_get_outdata(dc);
2075 struct fb_monspecs specs;
2076 u32 reg_val;
2077
2078 /* Power on panel */
2079 if (dc->out->enable)
2080 dc->out->enable(&dc->ndev->dev);
2081
2082 tegra_dc_get(dp->dc);
2083
2084 if (!tegra_is_clk_enabled(dp->clk))
2085 clk_prepare_enable(dp->clk);
2086 tegra_dpaux_enable(dp);
2087 tegra_dp_enable_irq(dp->irq);
2088 tegra_dp_hpd_config(dp);
2089
2090 tegra_dc_unpowergate_locked(dc);
2091 msleep(80);
2092
2093 if (tegra_dp_hpd_plug(dp) < 0) {
2094 dev_err(&dc->ndev->dev, "dp: hpd plug failed\n");
2095 return false;
2096 }
2097
2098 reg_val = tegra_dpaux_readl(dp, DPAUX_DP_AUXSTAT);
2099 if (!(reg_val & DPAUX_DP_AUXSTAT_HPD_STATUS_PLUGGED)) {
2100 dev_err(&dc->ndev->dev, "dp: Failed to detect HPD\n");
2101 return false;
2102 }
2103
2104 if (tegra_edid_get_monspecs(dp->dp_edid, &specs)) {
2105 dev_err(&dc->ndev->dev, "dp: Failed to get EDID data\n");
2106 return false;
2107 }
2108
2109 tegra_dc_set_fb_mode(dc, specs.modedb, false);
2110
2111 dc->out->h_size = specs.max_x * 10; /* in mm */
2112 dc->out->v_size = specs.max_y * 10;
2113
2114 if (!dc->out->width && !dc->out->height) {
2115 /* EDID specifies either the acutal screen sizes or
2116 the aspect ratios. The panel file can choose to
2117 trust the value as the actual sizes by leaving
2118 width/height to 0s */
2119 dc->out->width = dc->out->h_size;
2120 dc->out->height = dc->out->v_size;
2121 }
2122
2123 tegra_dc_powergate_locked(dc);
2124 msleep(50);
2125 tegra_dp_disable_irq(dp->irq);
2126 tegra_dc_put(dp->dc);
2127 return true;
2128}
2129
2130static void tegra_dc_dp_modeset_notifier(struct tegra_dc *dc) 2110static void tegra_dc_dp_modeset_notifier(struct tegra_dc *dc)
2131{ 2111{
2132 struct tegra_dc_dp_data *dp = tegra_dc_get_outdata(dc); 2112 struct tegra_dc_dp_data *dp = tegra_dc_get_outdata(dc);
@@ -2140,7 +2120,6 @@ struct tegra_dc_out_ops tegra_dc_dp_ops = {
2140 .disable = tegra_dc_dp_disable, 2120 .disable = tegra_dc_dp_disable,
2141 .setup_clk = tegra_dc_dp_setup_clk, 2121 .setup_clk = tegra_dc_dp_setup_clk,
2142 .modeset_notifier = tegra_dc_dp_modeset_notifier, 2122 .modeset_notifier = tegra_dc_dp_modeset_notifier,
2143 .early_enable = tegra_dc_dp_early_enable,
2144}; 2123};
2145 2124
2146 2125