summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/tegra3_dvfs.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-12-14 15:28:44 -0800
committerDan Willemsen <dwillemsen@nvidia.com>2012-03-22 23:50:14 -0700
commitc3fbb9a226141d1eeb21fc9cad1c5e4d0ca2343b (patch)
treeb68f439d54a2d6cb9e82f39692ffa695133e7aa9 /arch/arm/mach-tegra/tegra3_dvfs.c
parentccbaca219ddb971c4362e6b2fa63791e25947164 (diff)
ARM: tegra: dvfs: Add cold zone Tegra3 CPU dvfs limits
Added alternative frequency limits for Tegra3 CPU. These limits are applied only in the lowest CPU EDP temperature zone, and the offset from regular Tegra3 dvfs frequencies is set at -50MHz at all scaling voltage steps. Offset values as well as temperature threshold are to be updated per characterization. Bug 913884 Change-Id: Ia420f54b4c9fdc966e44d0269d45d9164d751b5f Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/70189 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com> Tested-by: Diwakar Tundlam <dtundlam@nvidia.com> Reviewed-by: Krishna Reddy <vdumpa@nvidia.com> Reviewed-on: http://git-master/r/75615 Reviewed-by: Varun Wadekar <vwadekar@nvidia.com> Tested-by: Varun Wadekar <vwadekar@nvidia.com> Rebase-Id: R407cbe270b2e10bc398c7f84840682f94c65c672
Diffstat (limited to 'arch/arm/mach-tegra/tegra3_dvfs.c')
-rw-r--r--arch/arm/mach-tegra/tegra3_dvfs.c42
1 files changed, 41 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/tegra3_dvfs.c b/arch/arm/mach-tegra/tegra3_dvfs.c
index f4f72620dfcb..2e1c0c5aa8fc 100644
--- a/arch/arm/mach-tegra/tegra3_dvfs.c
+++ b/arch/arm/mach-tegra/tegra3_dvfs.c
@@ -30,10 +30,14 @@
static bool tegra_dvfs_cpu_disabled;
static bool tegra_dvfs_core_disabled;
+static struct dvfs *cpu_dvfs;
static const int cpu_millivolts[MAX_DVFS_FREQS] = {
800, 825, 850, 875, 900, 912, 975, 1000, 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, 1212, 1237};
+static const unsigned int cpu_cold_offs_mhz[MAX_DVFS_FREQS] = {
+ 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50};
+
static const int core_millivolts[MAX_DVFS_FREQS] =
{1000, 1050, 1100, 1150, 1200, 1250, 1300};
@@ -422,6 +426,31 @@ static void __init init_dvfs_one(struct dvfs *d, int nominal_mv_index)
}
}
+static void __init init_dvfs_cold(struct dvfs *d, int nominal_mv_index)
+{
+ int i;
+ unsigned long offs;
+
+ BUG_ON((nominal_mv_index == 0) || (nominal_mv_index > d->num_freqs));
+
+ for (i = 0; i < d->num_freqs; i++) {
+ offs = cpu_cold_offs_mhz[i] * MHZ;
+ if (i > nominal_mv_index)
+ d->alt_freqs[i] = d->alt_freqs[i - 1];
+ else if (d->freqs[i] > offs)
+ d->alt_freqs[i] = d->freqs[i] - offs;
+ else {
+ d->alt_freqs[i] = d->freqs[i];
+ pr_warn("tegra3_dvfs: cold offset %lu is too high for"
+ " regular dvfs limit %lu\n", offs, d->freqs[i]);
+ }
+
+ if (i)
+ BUG_ON(d->alt_freqs[i] < d->alt_freqs[i - 1]);
+ }
+ d->alt_freqs_state = ALT_FREQS_DISABLED;
+}
+
static bool __init match_dvfs_one(struct dvfs *d, int speedo_id, int process_id)
{
if ((d->process_id != -1 && d->process_id != process_id) ||
@@ -535,7 +564,6 @@ void __init tegra3_init_dvfs(void)
int i;
int core_nominal_mv_index;
int cpu_nominal_mv_index;
- struct dvfs *cpu_dvfs = NULL;
#ifndef CONFIG_TEGRA_CORE_DVFS
tegra_dvfs_core_disabled = true;
@@ -581,6 +609,7 @@ void __init tegra3_init_dvfs(void)
/* Initialize matching cpu dvfs entry already found when nominal
voltage was determined */
init_dvfs_one(cpu_dvfs, cpu_nominal_mv_index);
+ init_dvfs_cold(cpu_dvfs, cpu_nominal_mv_index);
/* Finally disable dvfs on rails if necessary */
if (tegra_dvfs_core_disabled)
@@ -596,6 +625,17 @@ void __init tegra3_init_dvfs(void)
tegra_dvfs_core_disabled ? "disabled" : "enabled");
}
+void tegra_cpu_dvfs_alter(int edp_thermal_index, bool before_clk_update)
+{
+ bool enable = !edp_thermal_index;
+
+ if (enable != before_clk_update) {
+ int ret = tegra_dvfs_alt_freqs_set(cpu_dvfs, enable);
+ WARN_ONCE(ret, "tegra dvfs: failed to set CPU alternative"
+ " frequency limits for cold temeperature\n");
+ }
+}
+
int tegra_dvfs_rail_disable_prepare(struct dvfs_rail *rail)
{
int ret = 0;