diff options
author | Shashank Sharma <shashanks@nvidia.com> | 2012-02-27 15:06:54 +0530 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-03-23 13:57:17 -0700 |
commit | 11f2194618140f7a6628554f732e3a7f82a20dfb (patch) | |
tree | 09be16925058adc4a70b31fcd86a4ac97116338d /drivers/video/tegra/dc | |
parent | 23bd23f414d1b3e677ac42b3ef1dfd8e09553d88 (diff) |
video: tegra3: dc: remove hard coded HDMI rates
Set dc clock rate dynamically to requested pixel rate.
Using modes specified in monitor's EDID data.
Return mode set errors on unsupported clock tolerances.
Bug 931908
Change-Id: I60990ecbc2fbeab542987036b8ccc30b8dababe8
Signed-off-by: Shashank Sharma <shashanks@nvidia.com>
Reviewed-on: http://git-master/r/86073
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'drivers/video/tegra/dc')
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 45 |
1 files changed, 32 insertions, 13 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index ac024f68b371..3d09a13eaa64 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -66,6 +66,8 @@ static int no_vsync; +static void _tegra_dc_controller_disable(struct tegra_dc *dc); + module_param_named(no_vsync, no_vsync, int, S_IRUGO | S_IWUSR); static int use_dynamic_emc = 1; @@ -1445,15 +1447,13 @@ void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk) clk_get_sys(NULL, dc->out->parent_clk ? : "pll_d_out0"); struct clk *base_clk = clk_get_parent(parent_clk); - /* needs to match tegra_dc_hdmi_supported_modes[] - and tegra_pll_d_freq_table[] */ - if (dc->mode.pclk > 70000000) - rate = 594000000; - else if (dc->mode.pclk > 25200000) - rate = 216000000; - else - rate = 504000000; + /* + * Providing dynamic frequency rate setting for T20/T30 HDMI. + * The required rate needs to be setup at 4x multiplier, + * as out0 is 1/2 of the actual PLL output. + */ + rate = dc->mode.pclk * 4; if (rate != clk_get_rate(base_clk)) clk_set_rate(base_clk, rate); @@ -2374,7 +2374,7 @@ static u32 get_syncpt(struct tegra_dc *dc, int idx) return syncpt_id; } -static void tegra_dc_init(struct tegra_dc *dc) +static int tegra_dc_init(struct tegra_dc *dc) { int i; @@ -2440,15 +2440,20 @@ static void tegra_dc_init(struct tegra_dc *dc) print_mode(dc, &dc->mode, __func__); if (dc->mode.pclk) - tegra_dc_program_mode(dc, &dc->mode); + if (tegra_dc_program_mode(dc, &dc->mode)) + return -EINVAL; /* Initialize SD AFTER the modeset. nvsd_init handles the sd_settings = NULL case. */ nvsd_init(dc, dc->out->sd_settings); + + return 0; } static bool _tegra_dc_controller_enable(struct tegra_dc *dc) { + int failed_init = 0; + if (dc->out->enable) dc->out->enable(); @@ -2461,7 +2466,11 @@ static bool _tegra_dc_controller_enable(struct tegra_dc *dc) enable_dc_irq(dc->irq); - tegra_dc_init(dc); + failed_init = tegra_dc_init(dc); + if (failed_init) { + _tegra_dc_controller_disable(dc); + return false; + } if (dc->out_ops && dc->out_ops->enable) dc->out_ops->enable(dc); @@ -2480,6 +2489,8 @@ static bool _tegra_dc_controller_enable(struct tegra_dc *dc) #ifdef CONFIG_ARCH_TEGRA_2x_SOC static bool _tegra_dc_controller_reset_enable(struct tegra_dc *dc) { + bool ret = true; + if (dc->out->enable) dc->out->enable(); @@ -2512,7 +2523,10 @@ static bool _tegra_dc_controller_reset_enable(struct tegra_dc *dc) enable_dc_irq(dc->irq); - tegra_dc_init(dc); + if (tegra_dc_init(dc)) { + dev_err(&dc->ndev->dev, "cannot initialize\n"); + ret = false; + } if (dc->out_ops && dc->out_ops->enable) dc->out_ops->enable(dc); @@ -2525,7 +2539,12 @@ static bool _tegra_dc_controller_reset_enable(struct tegra_dc *dc) tegra_dc_ext_enable(dc->ext); - return true; + if (!ret) { + dev_err(&dc->ndev->dev, "initialization failed,disabling"); + _tegra_dc_controller_disable(dc); + } + + return ret; } #endif |