summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2012-01-12 22:57:29 -0800
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-01-24 10:58:25 -0800
commitef9b0e60d0afc5a3a6e5f2a560464cf92222b304 (patch)
tree2a3251b0d2c5a792ee78c03b2f71a120416bdf4e
parent584000839fcb301882687a814b5b9652c358a040 (diff)
video: tegra: dc: Add dc backup clock source support
Add backup clock source option in dc platform configuration. Use backup source if fixed frequency pllp is specified as main source, but its rate can not be divided into pixel clock within required tolerance. 928260 Change-Id: I19bd9173276c6ea087f86361956809787875e979 Reviewed-on: http://git-master/r/76033 Signed-off-by: Alex Frid <afrid@nvidia.com> Signed-off-by: Varun Wadekar <vwadekar@nvidia.com> Reviewed-on: http://git-master/r/76818 Reviewed-by: Automatic_Commit_Validation_User
-rw-r--r--arch/arm/mach-tegra/include/mach/dc.h1
-rw-r--r--drivers/video/tegra/dc/dc.c26
2 files changed, 27 insertions, 0 deletions
diff --git a/arch/arm/mach-tegra/include/mach/dc.h b/arch/arm/mach-tegra/include/mach/dc.h
index caca9d84c1be..4137a8f11017 100644
--- a/arch/arm/mach-tegra/include/mach/dc.h
+++ b/arch/arm/mach-tegra/include/mach/dc.h
@@ -324,6 +324,7 @@ struct tegra_dc_out {
int dcc_bus;
int hotplug_gpio;
const char *parent_clk;
+ const char *parent_clk_backup;
unsigned max_pixclock;
unsigned order;
diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c
index 951e8caaff2e..45962baa9fce 100644
--- a/drivers/video/tegra/dc/dc.c
+++ b/drivers/video/tegra/dc/dc.c
@@ -1362,6 +1362,21 @@ static unsigned long tegra_dc_pclk_round_rate(struct tegra_dc *dc, int pclk)
return rate * 2 / div;
}
+static unsigned long tegra_dc_pclk_predict_rate(struct clk *parent, int pclk)
+{
+ unsigned long rate;
+ unsigned long div;
+
+ rate = clk_get_rate(parent);
+
+ div = DIV_ROUND_CLOSEST(rate * 2, pclk);
+
+ if (div < 2)
+ return 0;
+
+ return rate * 2 / div;
+}
+
void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk)
{
int pclk;
@@ -1371,6 +1386,17 @@ void tegra_dc_setup_clk(struct tegra_dc *dc, struct clk *clk)
struct clk *parent_clk =
clk_get_sys(NULL, dc->out->parent_clk ? : "pll_p");
+ if (dc->out->parent_clk_backup &&
+ (parent_clk == clk_get_sys(NULL, "pll_p"))) {
+ rate = tegra_dc_pclk_predict_rate(
+ parent_clk, dc->mode.pclk);
+ /* use pll_d as last resort */
+ if (rate < (dc->mode.pclk / 100 * 99) ||
+ rate > (dc->mode.pclk / 100 * 109))
+ parent_clk = clk_get_sys(
+ NULL, dc->out->parent_clk_backup);
+ }
+
if (clk_get_parent(clk) != parent_clk)
clk_set_parent(clk, parent_clk);