summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/cpu-tegra3.c
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-02-12 17:20:43 -0800
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:42:22 -0800
commit3a7d79d26a47e82546ac2d6e053276fbc87d8f31 (patch)
tree072ecc5e1576aeda897c16c5ce24f212f5fbd908 /arch/arm/mach-tegra/cpu-tegra3.c
parent2cb26eeefc5f4ce61046451a62eaf2ef68bf99b0 (diff)
ARM: tegra: cpu: Update auto-hotplug policy
Do not switch to G cluster if cpufreq spikes above LP frequency limit for a short time - currently set threshold to 100ms. Fixed timing update for LP cluster statistic. Original-Change-Id: Id4f00fd5c39d7fe2aa931da30cf607a5144dc3ab Reviewed-on: http://git-master/r/19381 Tested-by: Aleksandr Frid <afrid@nvidia.com> Reviewed-by: Yu-Huan Hsu <yhsu@nvidia.com> Original-Change-Id: Ief6d391a5806d6cba20b6b5b407acb9846725260 Rebase-Id: Ref560d34203900e32b63d5b6104cb0fb105e4c63
Diffstat (limited to 'arch/arm/mach-tegra/cpu-tegra3.c')
-rw-r--r--arch/arm/mach-tegra/cpu-tegra3.c56
1 files changed, 29 insertions, 27 deletions
diff --git a/arch/arm/mach-tegra/cpu-tegra3.c b/arch/arm/mach-tegra/cpu-tegra3.c
index 895f286daa4c..e9d17416cc44 100644
--- a/arch/arm/mach-tegra/cpu-tegra3.c
+++ b/arch/arm/mach-tegra/cpu-tegra3.c
@@ -36,7 +36,8 @@
#define INITIAL_STATE TEGRA_HP_DISABLED
#define IDLE_HYSTERESIS 100000
-#define UP_DELAY_MS 1000
+#define UP2G0_DELAY_MS 100
+#define UP2Gn_DELAY_MS 1000
#define DOWN_DELAY_MS 2000
static DEFINE_MUTEX(tegra_hp_lock);
@@ -44,9 +45,11 @@ static DEFINE_MUTEX(tegra_hp_lock);
static struct workqueue_struct *hotplug_wq;
static struct delayed_work hotplug_work;
-static unsigned long up_delay;
+static unsigned long up2gn_delay;
+static unsigned long up2g0_delay;
static unsigned long down_delay;
-module_param(up_delay, ulong, 0644);
+module_param(up2gn_delay, ulong, 0644);
+module_param(up2g0_delay, ulong, 0644);
module_param(down_delay, ulong, 0644);
static unsigned int idle_top_freq;
@@ -91,7 +94,7 @@ static int hp_state_set(const char *arg, const struct kernel_param *kp)
case TEGRA_HP_UP:
if (old_state == TEGRA_HP_DISABLED) {
queue_delayed_work(
- hotplug_wq, &hotplug_work, up_delay);
+ hotplug_wq, &hotplug_work, down_delay);
pr_info("Tegra auto-hotplug enabled\n");
}
break;
@@ -147,11 +150,6 @@ static void tegra_auto_hotplug_work_func(struct work_struct *work)
mutex_lock(&tegra_hp_lock);
- if (is_lp_cluster()) {
- mutex_unlock(&tegra_hp_lock);
- return;
- }
-
switch (hp_state) {
case TEGRA_HP_DISABLED:
case TEGRA_HP_IDLE:
@@ -163,7 +161,7 @@ static void tegra_auto_hotplug_work_func(struct work_struct *work)
queue_delayed_work(
hotplug_wq, &hotplug_work, down_delay);
hp_stats_update(cpu, false);
- } else {
+ } else if (!is_lp_cluster()) {
tegra_cluster_control(0, TEGRA_POWER_CLUSTER_LP |
TEGRA_POWER_CLUSTER_IMMEDIATE);
hp_stats_update(CONFIG_NR_CPUS, true);
@@ -171,12 +169,21 @@ static void tegra_auto_hotplug_work_func(struct work_struct *work)
}
break;
case TEGRA_HP_UP:
- cpu = cpumask_next_zero(0, cpu_online_mask);
- if (cpu < nr_cpu_ids) {
- up = true;
+ if (is_lp_cluster()) {
+ tegra_cluster_control(0, TEGRA_POWER_CLUSTER_G |
+ TEGRA_POWER_CLUSTER_IMMEDIATE);
+ hp_stats_update(CONFIG_NR_CPUS, false);
+ hp_stats_update(0, true);
queue_delayed_work(
- hotplug_wq, &hotplug_work, up_delay);
- hp_stats_update(cpu, true);
+ hotplug_wq, &hotplug_work, up2gn_delay);
+ } else {
+ cpu = cpumask_next_zero(0, cpu_online_mask);
+ if (cpu < nr_cpu_ids) {
+ up = true;
+ queue_delayed_work(
+ hotplug_wq, &hotplug_work, up2gn_delay);
+ hp_stats_update(cpu, true);
+ }
}
break;
default:
@@ -195,18 +202,13 @@ static void tegra_auto_hotplug_work_func(struct work_struct *work)
void tegra_auto_hotplug_governor(unsigned int cpu_freq)
{
+ unsigned long up_delay;
+
if (!is_g_cluster_present())
return;
mutex_lock(&tegra_hp_lock);
-
- if (is_lp_cluster() && (cpu_freq > lpcpu_max_freq)) {
- if (tegra_cluster_control(0, TEGRA_POWER_CLUSTER_G |
- TEGRA_POWER_CLUSTER_IMMEDIATE))
- goto fail;
- hp_stats_update(CONFIG_NR_CPUS, false);
- hp_stats_update(0, true);
- }
+ up_delay = is_lp_cluster() ? up2g0_delay : up2gn_delay;
switch (hp_state) {
case TEGRA_HP_DISABLED:
@@ -245,7 +247,6 @@ void tegra_auto_hotplug_governor(unsigned int cpu_freq)
__func__, hp_state);
BUG();
}
-fail:
mutex_unlock(&tegra_hp_lock);
}
@@ -268,14 +269,15 @@ int tegra_auto_hotplug_init(void)
idle_top_freq = lpcpu_max_freq;
idle_bottom_freq = idle_top_freq - IDLE_HYSTERESIS;
- up_delay = msecs_to_jiffies(UP_DELAY_MS);
+ up2g0_delay = msecs_to_jiffies(UP2G0_DELAY_MS);
+ up2gn_delay = msecs_to_jiffies(UP2Gn_DELAY_MS);
down_delay = msecs_to_jiffies(DOWN_DELAY_MS);
hp_state = INITIAL_STATE;
pr_info("Tegra auto-hotplug initialized: %s\n",
(hp_state == TEGRA_HP_DISABLED) ? "disabled" : "enabled");
- for (i = 0; i < CONFIG_NR_CPUS; i++) {
+ for (i = 0; i <= CONFIG_NR_CPUS; i++) {
hp_stats[i].time_up_total = 0;
hp_stats[i].last_update = cur_jiffies;
@@ -302,7 +304,7 @@ static int hp_stats_show(struct seq_file *s, void *data)
u64 cur_jiffies = get_jiffies_64();
mutex_lock(&tegra_hp_lock);
- for (i = 0; i < CONFIG_NR_CPUS; i++) {
+ for (i = 0; i <= CONFIG_NR_CPUS; i++) {
bool was_up = (hp_stats[i].up_down_count & 0x1);
hp_stats_update(i, was_up);
}