diff options
author | Alex Frid <afrid@nvidia.com> | 2011-12-14 15:28:44 -0800 |
---|---|---|
committer | Rohan Somvanshi <rsomvanshi@nvidia.com> | 2012-01-19 10:29:49 -0800 |
commit | 4f5892b1c1aa1ffb085333bb2412464a66910a99 (patch) | |
tree | c89dc27e341342176a60a8531385526c133de2b1 /arch/arm/mach-tegra/tegra3_dvfs.c | |
parent | 732dd0ebfa107da83c18bedc42f1d606271bb89c (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.c | 42 |
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; |