summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra11_emc.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2012-12-18 19:12:34 -0800
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-12-20 06:09:28 -0800
commit5c396f85c7e3c5a8bb336c60497527e1277b5adf (patch)
tree8da1f46504394b8b5add23fa34ef5ddf81dfa9d2 /arch/arm/mach-tegra/tegra11_emc.c
parentdedec22ea854a61611dafb80522a05fe5611c08f (diff)
ARM: tegra11: clock: Handle unreachable EMC maximum rate
Handled the case when reaching maximum EMC rate in the EMC scaling table requires PLLM re-scaling, but backup rate is not included into the table. Set PLLM boot rate as maximum limit in this case. Bug 1193281 Change-Id: I77daa9ec7c136ba5737c1024891e332277706a39 Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/172597 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com>
Diffstat (limited to 'arch/arm/mach-tegra/tegra11_emc.c')
-rw-r--r--arch/arm/mach-tegra/tegra11_emc.c23
1 files changed, 17 insertions, 6 deletions
diff --git a/arch/arm/mach-tegra/tegra11_emc.c b/arch/arm/mach-tegra/tegra11_emc.c
index cea487951e29..41f93a2a6cde 100644
--- a/arch/arm/mach-tegra/tegra11_emc.c
+++ b/arch/arm/mach-tegra/tegra11_emc.c
@@ -993,12 +993,13 @@ static void adjust_emc_dvfs_table(const struct tegra11_emc_table *table,
#ifdef CONFIG_TEGRA_PLLM_SCALED
/* When pll_m is scaled, pll_c must provide backup rate;
if not - remove rates that require pll_m scaling */
-static void purge_emc_table(void)
+static int purge_emc_table(unsigned long max_rate)
{
int i;
+ int ret = 0;
if (emc->shared_bus_backup.input)
- return;
+ return ret;
pr_warn("tegra: selected pll_m scaling option but no backup source:\n");
pr_warn(" removed not supported entries from the table:\n");
@@ -1013,13 +1014,16 @@ static void purge_emc_table(void)
sel->input = NULL;
sel->input_rate = 0;
sel->value = 0;
+ if (max_rate == tegra_emc_table[i].rate)
+ ret = -EINVAL;
}
}
}
+ return ret;
}
#else
/* When pll_m is fixed @ max EMC rate, it always provides backup for pll_c */
-#define purge_emc_table()
+#define purge_emc_table(max_rate) (0)
#endif
static int init_emc_table(const struct tegra11_emc_table *table, int table_size)
@@ -1105,10 +1109,19 @@ static int init_emc_table(const struct tegra11_emc_table *table, int table_size)
" %lu kHz is not found\n", max_rate);
return -ENODATA;
}
- tegra_init_max_rate(emc, max_rate * 1000);
tegra_emc_table = table;
+ /*
+ * Purge rates that cannot be reached because table does not specify
+ * proper backup source. If maximum rate was purged, fall back on boot
+ * pll_m rate as maximum limit. In any case propagate new maximum limit
+ * down stream to shared users, and check it against nominal voltage.
+ */
+ if (purge_emc_table(max_rate))
+ max_rate = clk_get_rate(emc->parent) / 1000;
+ tegra_init_max_rate(emc, max_rate * 1000);
+
if (emc->dvfs) {
adjust_emc_dvfs_table(tegra_emc_table, tegra_emc_table_size);
mv = tegra_dvfs_predict_millivolts(emc, max_rate * 1000);
@@ -1121,8 +1134,6 @@ static int init_emc_table(const struct tegra11_emc_table *table, int table_size)
}
}
- purge_emc_table();
-
pr_info("tegra: validated EMC DFS table\n");
/* Configure clock change mode according to dram type */