diff options
author | Alex Frid <afrid@nvidia.com> | 2012-05-29 13:16:05 -0700 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-06-07 13:06:54 -0700 |
commit | 009db50dd4fd10c47d7b0ceb738bafa32b41f041 (patch) | |
tree | 8f265b881e43d2cdca73f6b15e982926f1317524 /arch | |
parent | d47cd91dfd01671681caa2ad1b8afc761e78d927 (diff) |
ARM: tegra: dvfs: Separate Tegra3 single core dvfs table
On Tegra3 added mechanism to alter dvfs table between single and
multiple CPU cores. This mechanism is dormant since no single-core
table is available yet.
Change-Id: I63bd513bd5fd7347f64c88f46974cf7fac55c419
Signed-off-by: Alex Frid <afrid@nvidia.com>
Reviewed-on: http://git-master/r/105508
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/arm/mach-tegra/tegra3_dvfs.c | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/arch/arm/mach-tegra/tegra3_dvfs.c b/arch/arm/mach-tegra/tegra3_dvfs.c index e71e52dea1f7..e34eb946e4f1 100644 --- a/arch/arm/mach-tegra/tegra3_dvfs.c +++ b/arch/arm/mach-tegra/tegra3_dvfs.c @@ -202,6 +202,10 @@ static struct dvfs cpu_dvfs_table[] = { CPU_DVFS("cpu_g", -1, -1, MHZ, 1, 1, 216, 216, 300), }; +static struct dvfs cpu_0_dvfs_table[] = { + /* Cpu voltages (mV): 800, 825, 850, 875, 900, 916, 950, 975, 1000, 1007, 1025, 1050, 1075, 1100, 1125, 1150, 1175, 1200, 1212, 1237 */ +}; + #define CORE_DVFS(_clk_name, _speedo_id, _auto, _mult, _freqs...) \ { \ .clk_name = _clk_name, \ @@ -355,6 +359,9 @@ static struct dvfs core_dvfs_table[] = { /* CPU alternative DVFS table for cold zone */ static unsigned long cpu_cold_freqs[MAX_DVFS_FREQS]; +/* CPU alternative DVFS table for single G CPU core 0 */ +static unsigned long *cpu_0_freqs; + int tegra_dvfs_disable_core_set(const char *arg, const struct kernel_param *kp) { int ret; @@ -501,6 +508,35 @@ static bool __init match_dvfs_one(struct dvfs *d, int speedo_id, int process_id) return true; } +static void __init init_cpu_0_dvfs(struct dvfs *cpud) +{ + int i; + struct dvfs *d = NULL; + + /* Init single G CPU core 0 dvfs if this particular SKU/bin has it. + Max rates in multi-core and single-core tables must be the same */ + for (i = 0; i < ARRAY_SIZE(cpu_0_dvfs_table); i++) { + if (match_dvfs_one(&cpu_0_dvfs_table[i], + cpud->speedo_id, cpud->process_id)) { + d = &cpu_0_dvfs_table[i]; + break; + } + } + + if (d) { + for (i = 0; i < cpud->num_freqs; i++) { + d->freqs[i] *= d->freqs_mult; + if (d->freqs[i] == 0) { + BUG_ON(i == 0); + d->freqs[i] = d->freqs[i - 1]; + } + } + BUG_ON(cpud->freqs[cpud->num_freqs - 1] != + d->freqs[cpud->num_freqs - 1]); + cpu_0_freqs = d->freqs; + } +} + static int __init get_cpu_nominal_mv_index( int speedo_id, int process_id, struct dvfs **cpu_dvfs) { @@ -647,7 +683,10 @@ 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); + + /* Initialize alternative cold zone and single core tables */ init_dvfs_cold(cpu_dvfs, cpu_nominal_mv_index); + init_cpu_0_dvfs(cpu_dvfs); /* Finally disable dvfs on rails if necessary */ if (tegra_dvfs_core_disabled) @@ -667,12 +706,14 @@ void tegra_cpu_dvfs_alter(int edp_thermal_index, const cpumask_t *cpus, bool before_clk_update) { bool cpu_warm = !!edp_thermal_index; - unsigned long *alt_freqs = cpu_warm ? NULL : cpu_cold_freqs; + unsigned int n = cpumask_weight(cpus); + unsigned long *alt_freqs = cpu_warm ? + (n > 1 ? NULL : cpu_0_freqs) : cpu_cold_freqs; if (cpu_warm == before_clk_update) { int ret = tegra_dvfs_alt_freqs_set(cpu_dvfs, alt_freqs); - WARN_ONCE(ret, "tegra dvfs: failed to set CPU alternative" - " frequency limits for cold temeperature\n"); + WARN_ONCE(ret, "tegra dvfs: failed to update CPU alternative" + " frequency limits\n"); } } |