summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra3_dvfs.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-11-11 18:19:16 -0800
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:50:19 -0800
commite6fa3337de9a8d0ee7236f424905d7ccdcc2401e (patch)
tree57f2818152896472b26a40dd636d05ceb1c4d711 /arch/arm/mach-tegra/tegra3_dvfs.c
parent7f650285a37030a14bf9036a95a1d8d66e4cb666 (diff)
ARM: tegra: clock: Support restricted PLLM usage
Added configuration option TEGRA_PLLM_RESTRICTED - when enabled, PLLM - memory PLL - usage may be restricted to modules with dividers capable of dividing maximum PLLM frequency at minimum voltage. When disabled, PLLM is available as a clock source with no restrictions (current configuration), which may effectively increase lower limit for core voltage if high grade SDRAM is used. Implemented PLLM restrictions in Tegra3 clock framework and DVFS, but keep them disabled by default. Bug 884419 Signed-off-by: Alex Frid <afrid@nvidia.com> (cherry picked from commit 5313ebcae92839146870d5865bc0f4cd08b35c61) (cherry picked from commit 634647a9d2a8c1e03c8d98d0b2199950c947acc3) Change-Id: I012452d92830ad6b63ec407350568b8c316b3caa Reviewed-on: http://git-master/r/66512 Reviewed-by: Lokesh Pathak <lpathak@nvidia.com> Tested-by: Lokesh Pathak <lpathak@nvidia.com> Rebase-Id: R22de0f09e7af2640499ec8cd96e974328d78bace
Diffstat (limited to 'arch/arm/mach-tegra/tegra3_dvfs.c')
-rw-r--r--arch/arm/mach-tegra/tegra3_dvfs.c49
1 files changed, 37 insertions, 12 deletions
diff --git a/arch/arm/mach-tegra/tegra3_dvfs.c b/arch/arm/mach-tegra/tegra3_dvfs.c
index 98b68c97bfcd..2ad2c90629f9 100644
--- a/arch/arm/mach-tegra/tegra3_dvfs.c
+++ b/arch/arm/mach-tegra/tegra3_dvfs.c
@@ -329,6 +329,23 @@ module_param_cb(disable_core, &tegra_dvfs_disable_core_ops,
module_param_cb(disable_cpu, &tegra_dvfs_disable_cpu_ops,
&tegra_dvfs_cpu_disabled, 0644);
+static bool __init is_pllm_dvfs(struct clk *c, struct dvfs *d)
+{
+#ifdef CONFIG_TEGRA_PLLM_RESTRICTED
+ /* Restricting PLLM usage on T30 and T33, rev A02+, allows to apply
+ maximum PLLM frequency to clock tree at minimum core voltage;
+ no need to enable dvfs on PLLM in this case */
+ if ((tegra_cpu_speedo_id() == 2) || (tegra_cpu_speedo_id() == 5))
+ return false;
+#endif
+ /* Check if PLLM boot frequency can be applied to clock tree at
+ minimum voltage. If yes, no need to enable dvfs on PLLM */
+ if (clk_get_rate_all_locked(c) <= d->freqs[0] * d->freqs_mult)
+ return false;
+
+ return true;
+}
+
static void __init init_dvfs_one(struct dvfs *d, int nominal_mv_index)
{
int ret;
@@ -340,25 +357,33 @@ static void __init init_dvfs_one(struct dvfs *d, int nominal_mv_index)
return;
}
+ /*
+ * Update max rate for auto-dvfs clocks, except EMC.
+ * EMC is a special case, since EMC dvfs is board dependent: max rate
+ * and EMC scaling frequencies are determined by tegra BCT (flashed
+ * together with the image) and board specific EMC DFS table; we will
+ * check the scaling ladder against nominal core voltage when the table
+ * is loaded (and if on particular board the table is not loaded, EMC
+ * scaling is disabled).
+ */
if (!(c->flags & PERIPH_EMC_ENB) && d->auto_dvfs) {
- /* Update max rate for auto-dvfs clocks, except EMC.
- * EMC is a special case, since EMC dvfs is board dependent:
- * max rate and EMC scaling frequencies are determined by tegra
- * BCT (flashed together with the image) and board specific EMC
- * DFS table; we will check the scaling ladder against nominal
- * core voltage when the table is loaded (and if on particular
- * board the table is not loaded, EMC scaling is disabled).
- */
BUG_ON(!d->freqs[nominal_mv_index]);
tegra_init_max_rate(
c, d->freqs[nominal_mv_index] * d->freqs_mult);
}
d->max_millivolts = d->dvfs_rail->nominal_millivolts;
- ret = tegra_enable_dvfs_on_clk(c, d);
- if (ret)
- pr_err("tegra3_dvfs: failed to enable dvfs on %s\n",
- c->name);
+ /*
+ * Check if we may skip enabling dvfs on PLLM. PLLM is a special case,
+ * since its frequency never exceeds boot rate, and configuration with
+ * restricted PLLM usage is possible.
+ */
+ if (!(c->flags & PLLM) || is_pllm_dvfs(c, d)) {
+ ret = tegra_enable_dvfs_on_clk(c, d);
+ if (ret)
+ pr_err("tegra3_dvfs: failed to enable dvfs on %s\n",
+ c->name);
+ }
}
static bool __init match_dvfs_one(struct dvfs *d, int speedo_id, int process_id)