From ab3a31fc1c2fdea90c0be47f40b603675103bc96 Mon Sep 17 00:00:00 2001 From: Alex Frid Date: Tue, 19 Apr 2011 23:38:46 -0700 Subject: 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 Tested-by: Varun Colbert Original-Change-Id: I5a19be79dd8f8fe788637870a22cd34dcfea150e Rebase-Id: Re264ec676c5c2103f7738c9eab5f4e11a4344975 --- arch/arm/mach-tegra/cpu-tegra.c | 45 +++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) (limited to 'arch/arm/mach-tegra/cpu-tegra.c') 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: -- cgit v1.2.3