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
committerRohan Somvanshi <rsomvanshi@nvidia.com>2012-01-19 10:29:49 -0800
commit4f5892b1c1aa1ffb085333bb2412464a66910a99 (patch)
treec89dc27e341342176a60a8531385526c133de2b1 /arch/arm/mach-tegra/tegra3_dvfs.c
parent732dd0ebfa107da83c18bedc42f1d606271bb89c (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>
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 8bd8bf7b775f..8f560ca6f7b9 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 tegra_soc_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 tegra_soc_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 tegra_soc_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;