aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoseph Lo <josephl@nvidia.com>2013-07-19 05:25:26 -0400
committerStephen Warren <swarren@nvidia.com>2013-07-19 12:07:14 -0400
commit3045cb33eb6081a937d9a2873f5fb88d9fcb7900 (patch)
tree046853597195752cda428c21c6609d44605e8848
parent1b9e6b2745621984b4aad49b0386814815fb15e7 (diff)
ARM: tegra114: cpuidle: add powered-down state
This supports CPU core power down on each CPU when CPU idle. When CPU go into this state, it saves it's context and needs a proper configuration in flow controller to power gate the CPU when CPU runs into WFI instruction. And the CPU also needs to set the IRQ as CPU power down idle wake up event in flow controller. Cc: Daniel Lezcano <daniel.lezcano@linaro.org> Signed-off-by: Joseph Lo <josephl@nvidia.com> Signed-off-by: Stephen Warren <swarren@nvidia.com>
-rw-r--r--arch/arm/mach-tegra/cpuidle-tegra114.c51
1 files changed, 50 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/cpuidle-tegra114.c b/arch/arm/mach-tegra/cpuidle-tegra114.c
index 1d1c6023f4a2..e0b87300243d 100644
--- a/arch/arm/mach-tegra/cpuidle-tegra114.c
+++ b/arch/arm/mach-tegra/cpuidle-tegra114.c
@@ -17,15 +17,64 @@
17#include <linux/kernel.h> 17#include <linux/kernel.h>
18#include <linux/module.h> 18#include <linux/module.h>
19#include <linux/cpuidle.h> 19#include <linux/cpuidle.h>
20#include <linux/cpu_pm.h>
21#include <linux/clockchips.h>
20 22
21#include <asm/cpuidle.h> 23#include <asm/cpuidle.h>
24#include <asm/suspend.h>
25#include <asm/smp_plat.h>
26
27#include "pm.h"
28#include "sleep.h"
29
30#ifdef CONFIG_PM_SLEEP
31#define TEGRA114_MAX_STATES 2
32#else
33#define TEGRA114_MAX_STATES 1
34#endif
35
36#ifdef CONFIG_PM_SLEEP
37static int tegra114_idle_power_down(struct cpuidle_device *dev,
38 struct cpuidle_driver *drv,
39 int index)
40{
41 local_fiq_disable();
42
43 tegra_set_cpu_in_lp2();
44 cpu_pm_enter();
45
46 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
47
48 cpu_suspend(0, tegra30_sleep_cpu_secondary_finish);
49
50 clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
51
52 cpu_pm_exit();
53 tegra_clear_cpu_in_lp2();
54
55 local_fiq_enable();
56
57 return index;
58}
59#endif
22 60
23static struct cpuidle_driver tegra_idle_driver = { 61static struct cpuidle_driver tegra_idle_driver = {
24 .name = "tegra_idle", 62 .name = "tegra_idle",
25 .owner = THIS_MODULE, 63 .owner = THIS_MODULE,
26 .state_count = 1, 64 .state_count = TEGRA114_MAX_STATES,
27 .states = { 65 .states = {
28 [0] = ARM_CPUIDLE_WFI_STATE_PWR(600), 66 [0] = ARM_CPUIDLE_WFI_STATE_PWR(600),
67#ifdef CONFIG_PM_SLEEP
68 [1] = {
69 .enter = tegra114_idle_power_down,
70 .exit_latency = 500,
71 .target_residency = 1000,
72 .power_usage = 0,
73 .flags = CPUIDLE_FLAG_TIME_VALID,
74 .name = "powered-down",
75 .desc = "CPU power gated",
76 },
77#endif
29 }, 78 },
30}; 79};
31 80