summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/cpu-tegra.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-04-19 23:38:46 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:42:32 -0800
commitab3a31fc1c2fdea90c0be47f40b603675103bc96 (patch)
tree5e5b052a67866a460dd303f14e5b27ede7649b29 /arch/arm/mach-tegra/cpu-tegra.c
parentdf2009abf96414d23278f5342296d645b43a9fde (diff)
ARM: tegra: power: Update Tegra3 CPU auto-hotplug
- taking CPU core off-line: selected CPU with minimum load - switching from ULP to G CPU mode: set CPU clock to cpufreq target rate after the mode switch is completed Original-Change-Id: I9bf4d0f4b48c262cf678c603aac02043dd602674 Reviewed-on: http://git-master/r/28420 Reviewed-by: Varun Colbert <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com> Original-Change-Id: I5a19be79dd8f8fe788637870a22cd34dcfea150e Rebase-Id: Re264ec676c5c2103f7738c9eab5f4e11a4344975
Diffstat (limited to 'arch/arm/mach-tegra/cpu-tegra.c')
-rw-r--r--arch/arm/mach-tegra/cpu-tegra.c45
1 files changed, 37 insertions, 8 deletions
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c
index dae7042c350f..baf543674c3d 100644
--- a/arch/arm/mach-tegra/cpu-tegra.c
+++ b/arch/arm/mach-tegra/cpu-tegra.c
@@ -55,7 +55,6 @@ static bool is_suspended;
unsigned int tegra_getspeed(unsigned int cpu);
static int tegra_update_cpu_speed(unsigned long rate);
-static unsigned long tegra_cpu_highest_speed(void);
#ifdef CONFIG_TEGRA_THERMAL_THROTTLE
/* CPU frequency is gradually lowered when throttling is enabled */
@@ -117,7 +116,7 @@ void tegra_throttling_enable(bool enable)
cancel_delayed_work_sync(&throttle_work);
is_throttling = false;
/* restore speed requested by governor */
- tegra_update_cpu_speed(tegra_cpu_highest_speed());
+ tegra_cpu_cap_highest_speed(NULL);
}
mutex_unlock(&tegra_cpu_lock);
@@ -241,7 +240,7 @@ static int tegra_cpu_edp_notify(
cpu_speed = tegra_getspeed(0);
new_speed = edp_governor_speed(cpu_speed);
- if (cpu_speed != new_speed) {
+ if (new_speed < cpu_speed) {
ret = tegra_update_cpu_speed(new_speed);
if (ret) {
cpu_clear(cpu, edp_cpumask);
@@ -363,8 +362,29 @@ static int tegra_update_cpu_speed(unsigned long rate)
return 0;
}
-static unsigned long tegra_cpu_highest_speed(void)
-{
+unsigned int tegra_get_slowest_cpu_n(void) {
+ unsigned int cpu = nr_cpu_ids;
+ unsigned long rate = ULONG_MAX;
+ int i;
+
+ for_each_online_cpu(i)
+ if ((i > 0) && (rate > target_cpu_speed[i])) {
+ cpu = i;
+ rate = target_cpu_speed[i];
+ }
+ return cpu;
+}
+
+unsigned long tegra_cpu_lowest_speed(void) {
+ unsigned long rate = ULONG_MAX;
+ int i;
+
+ for_each_online_cpu(i)
+ rate = min(rate, target_cpu_speed[i]);
+ return rate;
+}
+
+unsigned long tegra_cpu_highest_speed(void) {
unsigned long rate = 0;
int i;
@@ -373,6 +393,17 @@ static unsigned long tegra_cpu_highest_speed(void)
return rate;
}
+int tegra_cpu_cap_highest_speed(unsigned int *speed_cap)
+{
+ unsigned int new_speed = tegra_cpu_highest_speed();
+
+ new_speed = throttle_governor_speed(new_speed);
+ new_speed = edp_governor_speed(new_speed);
+ if (speed_cap)
+ *speed_cap = new_speed;
+ return tegra_update_cpu_speed(new_speed);
+}
+
static int tegra_target(struct cpufreq_policy *policy,
unsigned int target_freq,
unsigned int relation)
@@ -395,9 +426,7 @@ static int tegra_target(struct cpufreq_policy *policy,
freq = freq_table[idx].frequency;
target_cpu_speed[policy->cpu] = freq;
- new_speed = throttle_governor_speed(tegra_cpu_highest_speed());
- new_speed = edp_governor_speed(new_speed);
- ret = tegra_update_cpu_speed(new_speed);
+ ret = tegra_cpu_cap_highest_speed(&new_speed);
if (ret == 0)
tegra_auto_hotplug_governor(new_speed);
out: