ARM: tegra11x: residency time for different LP2 mode
Bo Yan [Wed, 17 Oct 2012 02:10:03 +0000 (19:10 -0700)]
Select CPU partition power gating only, non-CPU power gating, or
rail gating based on the required minimum residency and requested
sleep length.

The minimum residency for non-cpu power gating and rail-gating are
arbitrarily set in this change, they have to be characterized.

The minimum residency for non-cpu power gating shall always be
less than the minimu residency for rail gating.

Also fix a bug that prevents rail-gating

Change-Id: Icc646061f0fb47662fa74e77c6ae6b5d5da1444a
Signed-off-by: Bo Yan <byan@nvidia.com>
Reviewed-on: http://git-master/r/146640
Reviewed-by: Simone Willett <swillett@nvidia.com>
Tested-by: Simone Willett <swillett@nvidia.com>

Rebase-Id: Rd2f8f5583057310c04bf0ea1d1bd8cdbbd15a9a6

arch/arm/mach-tegra/board-dalmore-power.c
arch/arm/mach-tegra/board-pluto-power.c
arch/arm/mach-tegra/cpuidle-t11x.c
arch/arm/mach-tegra/pm.c
arch/arm/mach-tegra/pm.h
arch/arm/mach-tegra/sleep.h

index b267b88..19ea860 100644 (file)
@@ -951,6 +951,8 @@ static struct tegra_suspend_platform_data dalmore_suspend_data = {
        .core_off_timer = 2000,
        .corereq_high   = true,
        .sysclkreq_high = true,
+       .min_residency_noncpu = 600,
+       .min_residency_crail = 1000,
 };
 #ifdef CONFIG_ARCH_TEGRA_HAS_CL_DVFS
 /* board parameters for cpu dfll */
index 8852b4c..52e045e 100644 (file)
@@ -664,6 +664,8 @@ static struct tegra_suspend_platform_data pluto_suspend_data = {
        .core_off_timer = 2000,
        .corereq_high   = false,
        .sysclkreq_high = true,
+       .min_residency_noncpu = 600,
+       .min_residency_crail = 1000,
 };
 
 int __init pluto_suspend_init(void)
index f841cbc..a9c91d1 100644 (file)
@@ -272,7 +272,10 @@ static bool tegra_cpu_cluster_power_down(struct cpuidle_device *dev,
                tegra_dvfs_rail_off(tegra_cpu_rail, entry_time);
                flag = (fast_cluster_power_down_mode
                        << TEGRA_POWER_CLUSTER_PART_SHIFT)
-                       && TEGRA_POWER_CLUSTER_PART_MASK;
+                       & TEGRA_POWER_CLUSTER_PART_MASK;
+               if ((request < tegra_min_residency_crail()) &&
+                       (flag != TEGRA_POWER_CLUSTER_PART_MASK))
+                       flag = TEGRA_POWER_CLUSTER_PART_NONCPU;
        }
 
        if (tegra_idle_lp2_last(sleep_time, flag) == 0)
@@ -423,18 +426,19 @@ bool tegra11x_idle_lp2(struct cpuidle_device *dev,
        tegra_set_cpu_in_lp2(dev->cpu);
        cpu_gating_only = (((fast_cluster_power_down_mode
                        << TEGRA_POWER_CLUSTER_PART_SHIFT)
-                       && TEGRA_POWER_CLUSTER_PART_MASK) == 0);
+                       & TEGRA_POWER_CLUSTER_PART_MASK) == 0);
 
        if (is_lp_cluster()) {
-               if (slow_cluster_power_gating_noncpu)
-                       power_gating_cpu_only = false;
+               if (slow_cluster_power_gating_noncpu &&
+                       (request > tegra_min_residency_noncpu()))
+                               power_gating_cpu_only = false;
                else
                        power_gating_cpu_only = true;
        } else if (!cpu_gating_only &&
-               (dev->cpu == 0) &&
                (num_online_cpus() == 1) &&
-               tegra_rail_off_is_allowed())
-               power_gating_cpu_only = false;
+               tegra_rail_off_is_allowed() &&
+               (request > tegra_min_residency_noncpu()))
+                       power_gating_cpu_only = false;
        else
                power_gating_cpu_only = true;
 
index 7683cdb..62e7ce9 100644 (file)
@@ -251,6 +251,18 @@ unsigned long tegra_cpu_lp2_min_residency(void)
        return pdata->cpu_lp2_min_residency;
 }
 
+#ifdef CONFIG_ARCH_TEGRA_HAS_SYMMETRIC_CPU_PWR_GATE
+unsigned long tegra_min_residency_noncpu(void)
+{
+       return pdata->min_residency_noncpu;
+}
+
+unsigned long tegra_min_residency_crail(void)
+{
+       return pdata->min_residency_crail;
+}
+#endif
+
 static void suspend_cpu_dfll_mode(void)
 {
 #ifdef CONFIG_ARCH_TEGRA_HAS_CL_DVFS
index e1e9666..0f962c6 100644 (file)
@@ -73,6 +73,10 @@ struct tegra_suspend_platform_data {
        unsigned int lp1_core_volt_low;
        unsigned int lp1_core_volt_high;
 #endif
+#ifdef CONFIG_ARCH_TEGRA_HAS_SYMMETRIC_CPU_PWR_GATE
+       unsigned long min_residency_noncpu;
+       unsigned long min_residency_crail;
+#endif
 };
 
 /* clears io dpd settings before kernel code */
@@ -81,6 +85,10 @@ void tegra_bl_io_dpd_cleanup(void);
 unsigned long tegra_cpu_power_good_time(void);
 unsigned long tegra_cpu_power_off_time(void);
 unsigned long tegra_cpu_lp2_min_residency(void);
+#ifdef CONFIG_ARCH_TEGRA_HAS_SYMMETRIC_CPU_PWR_GATE
+unsigned long tegra_min_residency_noncpu(void);
+unsigned long tegra_min_residency_crail(void);
+#endif
 void tegra_clear_cpu_in_lp2(int cpu);
 bool tegra_set_cpu_in_lp2(int cpu);
 
index 09b7077..c9b6455 100644 (file)
 #define TEGRA_POWER_LP1_AUDIO          (1 << 25) /* do not turn off pll-p in LP1 */
 
 #ifdef CONFIG_ARCH_TEGRA_HAS_SYMMETRIC_CPU_PWR_GATE
-#define TEGRA_POWER_CLUSTER_PART_CRAIL (1 << 24) /* Power gate CRAIL partition */
-#define TEGRA_POWER_CLUSTER_PART_NONCPU        (1 << 25) /* Power gate CxNC partition */
+
+/* Power gate CRAIL partition */
+#define TEGRA_POWER_CLUSTER_PART_CRAIL (1 << 25)
+
+/* Power gate CxNC partition */
+#define TEGRA_POWER_CLUSTER_PART_NONCPU        (1 << 24)
+
 #define TEGRA_POWER_CLUSTER_PART_MASK  (TEGRA_POWER_CLUSTER_PART_CRAIL | \
                                                TEGRA_POWER_CLUSTER_PART_NONCPU)
 #define TEGRA_POWER_CLUSTER_PART_DEFAULT TEGRA_POWER_CLUSTER_PART_CRAIL