diff options
author | Alex Frid <afrid@nvidia.com> | 2011-12-16 19:57:04 -0800 |
---|---|---|
committer | Varun Wadekar <vwadekar@nvidia.com> | 2011-12-30 10:50:24 +0530 |
commit | ec68b0ceec876ea62394707f886d97caaf8174cf (patch) | |
tree | eeb72a6cf4586d988e3a5d933c538d7363ac9d21 /arch/arm/mach-tegra | |
parent | 2078cb5cd2e382c1419217231bbce22dbf92c127 (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/arm/mach-tegra')
-rw-r--r-- | arch/arm/mach-tegra/cpu-tegra3.c | 54 |
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; |