ARM: tegra: power: Set minimum LP2 target residency
Alex Frid [Tue, 19 Apr 2011 04:35:58 +0000 (21:35 -0700)]
Added board level tuning parameter to specify minimum LP2 residency
time (previous policy allows down to zero residency targets limited
only by LP2 exit latency).

Original-Change-Id: I4ae7d458fba78f35a40f138cf9489bf938715b22
Reviewed-on: http://git-master/r/28162
Reviewed-by: Varun Colbert <vcolbert@nvidia.com>
Tested-by: Varun Colbert <vcolbert@nvidia.com>
Original-Change-Id: I38e798ca6d242d136ea2353d90cc961de14f25b6

Rebase-Id: Rcf9efce3dd037b0a7ca13a9c342f884fac38d654

arch/arm/mach-tegra/cpuidle.c
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/pm.h

index 1ae19f9..5eaf807 100644 (file)
@@ -65,6 +65,8 @@ static struct {
        unsigned int last_lp2_int_count[NR_IRQS];
 } idle_stats;
 
+static unsigned int tegra_lp2_min_residency;
+
 struct cpuidle_driver tegra_idle_driver = {
        .name = "tegra_idle",
        .owner = THIS_MODULE,
@@ -143,6 +145,8 @@ static int tegra_idle_enter_lp2(struct cpuidle_device *dev,
        local_irq_enable();
 
        smp_rmb();
+       if (state->target_residency < tegra_lp2_min_residency)
+               state->target_residency = tegra_lp2_min_residency;
 
        idle_stats.cpu_wants_lp2_time[dev->cpu] += us;
 
@@ -158,9 +162,13 @@ static int __init tegra_cpuidle_init(void)
        struct cpuidle_device *dev;
        struct cpuidle_driver *drv = &tegra_idle_driver;
 
+       tegra_lp2_min_residency = tegra_cpu_lp2_min_residency();
+
        tegra_idle_driver.states[1].exit_latency = tegra_cpu_power_good_time();
        tegra_idle_driver.states[1].target_residency = tegra_cpu_power_off_time() +
                tegra_cpu_power_good_time();
+       if (tegra_idle_driver.states[1].target_residency < tegra_lp2_min_residency)
+               tegra_idle_driver.states[1].target_residency = tegra_lp2_min_residency;
 
        ret = cpuidle_register_driver(&tegra_idle_driver);
        if (ret) {
index 52fb6f9..0c0e300 100644 (file)
@@ -222,6 +222,14 @@ unsigned long tegra_cpu_power_off_time(void)
        return pdata->cpu_off_timer;
 }
 
+unsigned long tegra_cpu_lp2_min_residency(void)
+{
+       if (WARN_ON_ONCE(!pdata))
+               return 2000;
+
+       return pdata->cpu_lp2_min_residency;
+}
+
 /* ensures that sufficient time is passed for a register write to
  * serialize into the 32KHz domain */
 static void pmc_32kwritel(u32 val, unsigned long offs)
index 5350c1a..6cf0219 100644 (file)
@@ -2,6 +2,7 @@
  * arch/arm/mach-tegra/include/mach/suspend.h
  *
  * Copyright (C) 2010 Google, Inc.
+ * Copyright (C) 2011 NVIDIA Corporation
  *
  * Author:
  *     Colin Cross <ccross@google.com>
@@ -39,10 +40,12 @@ struct tegra_suspend_platform_data {
        bool corereq_high;         /* Core power request active-high */
        bool sysclkreq_high;       /* System clock request is active-high */
        enum tegra_suspend_mode suspend_mode;
+       unsigned long cpu_lp2_min_residency; /* Min LP2 state residency in us */
 };
 
 unsigned long tegra_cpu_power_good_time(void);
 unsigned long tegra_cpu_power_off_time(void);
+unsigned long tegra_cpu_lp2_min_residency(void);
 
 #define TEGRA_POWER_SDRAM_SELFREFRESH  0x400   /* SDRAM is in self-refresh */