summaryrefslogtreecommitdiff
path: root/drivers/video/tegra/dc/dc.c
diff options
context:
space:
mode:
authorShashank Sharma <shashanks@nvidia.com>2012-02-27 15:06:54 +0530
committerSimone Willett <swillett@nvidia.com>2012-03-23 13:57:17 -0700
commit11f2194618140f7a6628554f732e3a7f82a20dfb (patch)
tree09be16925058adc4a70b31fcd86a4ac97116338d /drivers/video/tegra/dc/dc.c
parent23bd23f414d1b3e677ac42b3ef1dfd8e09553d88 (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/dc.c')
-rw-r--r--drivers/video/tegra/dc/dc.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index ac024f6..3d09a13 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