summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-12-16 19:57:04 -0800
committerVarun Wadekar <vwadekar@nvidia.com>2011-12-30 10:50:24 +0530
commitec68b0ceec876ea62394707f886d97caaf8174cf (patch)
treeeeb72a6cf4586d988e3a5d933c538d7363ac9d21 /arch
parent2078cb5cd2e382c1419217231bbce22dbf92c127 (diff)
ARM: tegra: power: Update Tegra3 auto-hotplug states
Updated Tegra3 auto-hotplug state machine: - no longer enter down state on LP CPU (there is no down path on LP) - no longer enter idle state on G CPU (since load distribution between G cores may change without CPU frequency change, continue polling) - allow only disabled or idle state to be set via auto-hotplug sysfs node, and synchronize with cpufreq governor in the latter case Change-Id: Ibb93ddca852bbe1341fc5c52b0c83c16e9963e9d Signed-off-by: Alex Frid <afrid@nvidia.com> Reviewed-on: http://git-master/r/71584 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Wen Yi <wyi@nvidia.com> Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com> Reviewed-by: Krishna Reddy <vdumpa@nvidia.com>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/mach-tegra/cpu-tegra3.c54
1 files changed, 28 insertions, 26 deletions
diff --git a/arch/arm/mach-tegra/cpu-tegra3.c b/arch/arm/mach-tegra/cpu-tegra3.c
index 6aaa87e36918..78425f4f7643 100644
--- a/arch/arm/mach-tegra/cpu-tegra3.c
+++ b/arch/arm/mach-tegra/cpu-tegra3.c
@@ -143,30 +143,24 @@ static int hp_state_set(const char *arg, const struct kernel_param *kp)
mutex_lock(tegra3_cpu_lock);
old_state = hp_state;
- ret = param_set_int(arg, kp);
+ ret = param_set_bool(arg, kp); /* set idle or disabled only */
if (ret == 0) {
- switch (hp_state) {
- case TEGRA_HP_DISABLED:
- if (old_state != TEGRA_HP_DISABLED)
- pr_info("Tegra auto-hotplug disabled\n");
- break;
- case TEGRA_HP_IDLE:
- case TEGRA_HP_DOWN:
- case TEGRA_HP_UP:
+ if ((hp_state == TEGRA_HP_DISABLED) &&
+ (old_state != TEGRA_HP_DISABLED))
+ pr_info("Tegra auto-hotplug disabled\n");
+ else if (hp_state != TEGRA_HP_DISABLED) {
if (old_state == TEGRA_HP_DISABLED) {
- hp_init_stats();
- queue_delayed_work(
- hotplug_wq, &hotplug_work, down_delay);
pr_info("Tegra auto-hotplug enabled\n");
+ hp_init_stats();
}
- break;
- default:
- pr_warn("%s: unable to set tegra hotplug state %d\n",
- __func__, hp_state);
- hp_state = old_state;
+ /* catch-up with governor target speed */
+ tegra_cpu_set_speed_cap(NULL);
}
- }
+ } else
+ pr_warn("%s: unable to set tegra hotplug state %s\n",
+ __func__, arg);
+
mutex_unlock(tegra3_cpu_lock);
return ret;
}
@@ -293,7 +287,7 @@ static void tegra_auto_hotplug_work_func(struct work_struct *work)
void tegra_auto_hotplug_governor(unsigned int cpu_freq, bool suspend)
{
- unsigned long up_delay;
+ unsigned long up_delay, top_freq, bottom_freq;
if (!is_g_cluster_present())
return;
@@ -303,37 +297,45 @@ void tegra_auto_hotplug_governor(unsigned int cpu_freq, bool suspend)
return;
}
- up_delay = is_lp_cluster() ? up2g0_delay : up2gn_delay;
+ if (is_lp_cluster()) {
+ up_delay = up2g0_delay;
+ top_freq = idle_top_freq;
+ bottom_freq = 0;
+ } else {
+ up_delay = up2gn_delay;
+ top_freq = idle_bottom_freq;
+ bottom_freq = idle_bottom_freq;
+ }
switch (hp_state) {
case TEGRA_HP_DISABLED:
break;
case TEGRA_HP_IDLE:
- if (cpu_freq > idle_top_freq) {
+ if (cpu_freq > top_freq) {
hp_state = TEGRA_HP_UP;
queue_delayed_work(
hotplug_wq, &hotplug_work, up_delay);
- } else if (cpu_freq <= idle_bottom_freq) {
+ } else if (cpu_freq <= bottom_freq) {
hp_state = TEGRA_HP_DOWN;
queue_delayed_work(
hotplug_wq, &hotplug_work, down_delay);
}
break;
case TEGRA_HP_DOWN:
- if (cpu_freq > idle_top_freq) {
+ if (cpu_freq > top_freq) {
hp_state = TEGRA_HP_UP;
queue_delayed_work(
hotplug_wq, &hotplug_work, up_delay);
- } else if (cpu_freq > idle_bottom_freq) {
+ } else if (cpu_freq > bottom_freq) {
hp_state = TEGRA_HP_IDLE;
}
break;
case TEGRA_HP_UP:
- if (cpu_freq <= idle_bottom_freq) {
+ if (cpu_freq <= bottom_freq) {
hp_state = TEGRA_HP_DOWN;
queue_delayed_work(
hotplug_wq, &hotplug_work, down_delay);
- } else if (cpu_freq <= idle_top_freq) {
+ } else if (cpu_freq <= top_freq) {
hp_state = TEGRA_HP_IDLE;
}
break;