c59e6c9d05cb9b50d10e1a700e8faa9aa401a6f4
[linux-3.10.git] / arch / arm / mach-tegra / cpuidle.c
1 /*
2  * arch/arm/mach-tegra/cpuidle.c
3  *
4  * CPU idle driver for Tegra CPUs
5  *
6  * Copyright (c) 2010-2012, NVIDIA Corporation.
7  * Copyright (c) 2011 Google, Inc.
8  * Author: Colin Cross <ccross@android.com>
9  *         Gary King <gking@nvidia.com>
10  *
11  * Rework for 3.3 by Peter De Schrijver <pdeschrijver@nvidia.com>
12  *
13  * This program is free software; you can redistribute it and/or modify
14  * it under the terms of the GNU General Public License as published by
15  * the Free Software Foundation; either version 2 of the License, or
16  * (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful, but WITHOUT
19  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
21  * more details.
22  */
23
24 #include <linux/kernel.h>
25 #include <linux/module.h>
26 #include <linux/cpu.h>
27 #include <linux/cpuidle.h>
28 #include <linux/debugfs.h>
29 #include <linux/delay.h>
30 #include <linux/init.h>
31 #include <linux/interrupt.h>
32 #include <linux/irq.h>
33 #include <linux/io.h>
34 #include <linux/sched.h>
35 #include <linux/seq_file.h>
36 #include <linux/slab.h>
37 #include <linux/smp.h>
38 #include <linux/suspend.h>
39 #include <linux/tick.h>
40
41 #include <asm/proc-fns.h>
42
43 #include <mach/irqs.h>
44
45 #include <trace/events/power.h>
46
47 #include "cpuidle.h"
48 #include "pm.h"
49 #include "sleep.h"
50
51 static int tegra_idle_enter_lp3(struct cpuidle_device *dev, int index);
52 #ifdef CONFIG_PM_SLEEP
53 static int tegra_idle_enter_lp2(struct cpuidle_device *dev, int index);
54 #endif
55
56 int tegra_lp2_exit_latency;
57 static int tegra_lp2_power_off_time;
58 static unsigned int tegra_lp2_min_residency;
59
60 struct cpuidle_driver tegra_idle_driver = {
61         .name = "tegra_idle",
62         .owner = THIS_MODULE,
63 };
64
65 static struct cpuidle_state tegra_cpuidle_states[] = {
66         [0] = {
67                 .enter                  = tegra_idle_enter_lp3,
68                 .exit_latency           = 10,
69                 .target_residency       = 10,
70                 .power_usage            = 600,
71                 .flags                  = CPUIDLE_FLAG_TIME_VALID,
72                 .name                   = "LP3",
73                 .desc                   = "CPU flow-controlled",
74         },
75 #ifdef CONFIG_PM_SLEEP
76         [1] = {
77                 .enter                  = tegra_idle_enter_lp2,
78                 .power_usage            = 0,
79                 .flags                  = CPUIDLE_FLAG_TIME_VALID,
80                 .name                   = "LP2",
81                 .desc                   = "CPU power-gate",
82         },
83 #endif
84 };
85
86 static DEFINE_PER_CPU(struct cpuidle_device, tegra_idle_device);
87
88 static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
89         int index)
90 {
91         ktime_t enter, exit;
92         s64 us;
93
94         trace_power_start(POWER_CSTATE, 1, dev->cpu);
95
96         local_irq_disable();
97         local_fiq_disable();
98
99         enter = ktime_get();
100
101         cpu_do_idle();
102
103         exit = ktime_sub(ktime_get(), enter);
104         us = ktime_to_us(exit);
105
106         local_fiq_enable();
107         local_irq_enable();
108
109         dev->last_residency = us;
110
111         return index;
112 }
113
114 static bool lp2_in_idle __read_mostly = false;
115
116 #ifdef CONFIG_PM_SLEEP
117 static bool lp2_in_idle_modifiable __read_mostly = true;
118 static bool lp2_disabled_by_suspend;
119
120 void tegra_lp2_in_idle(bool enable)
121 {
122         /* If LP2 in idle is permanently disabled it can't be re-enabled. */
123         if (lp2_in_idle_modifiable) {
124                 lp2_in_idle = enable;
125                 lp2_in_idle_modifiable = enable;
126                 if (!enable)
127                         pr_warn("LP2 in idle disabled\n");
128         }
129 }
130
131 void tegra_lp2_update_target_residency(struct cpuidle_state *state)
132 {
133         state->target_residency = state->exit_latency +
134                 tegra_lp2_power_off_time;
135         if (state->target_residency < tegra_lp2_min_residency)
136                 state->target_residency = tegra_lp2_min_residency;
137 }
138
139 static int tegra_idle_enter_lp2(struct cpuidle_device *dev,
140         int index)
141 {
142         ktime_t enter, exit;
143         s64 us;
144         struct cpuidle_state *state = &dev->states[index];
145         bool entered_lp2;
146
147         if (!lp2_in_idle || lp2_disabled_by_suspend ||
148             !tegra_lp2_is_allowed(dev, state)) {
149                 return dev->states[dev->safe_state_index].enter(dev,
150                                         dev->safe_state_index);
151         }
152
153         local_irq_disable();
154         enter = ktime_get();
155
156         tegra_cpu_idle_stats_lp2_ready(dev->cpu);
157         entered_lp2 = tegra_idle_lp2(dev, state);
158
159         exit = ktime_sub(ktime_get(), enter);
160         us = ktime_to_us(exit);
161
162         local_irq_enable();
163
164         /* cpu clockevents may have been reset by powerdown */
165         hrtimer_peek_ahead_timers();
166
167         smp_rmb();
168
169         /* Update LP2 latency provided no fall back to LP3 */
170         if (entered_lp2) {
171                 tegra_lp2_set_global_latency(state);
172                 tegra_lp2_update_target_residency(state);
173         }
174         tegra_cpu_idle_stats_lp2_time(dev->cpu, us);
175
176         dev->last_residency = us;
177
178         return index;
179 }
180 #endif
181
182 static int tegra_cpuidle_pm_notify(struct notifier_block *nb,
183         unsigned long event, void *dummy)
184 {
185 #ifdef CONFIG_PM_SLEEP
186         if (event == PM_SUSPEND_PREPARE)
187                 lp2_disabled_by_suspend = true;
188         else if (event == PM_POST_SUSPEND)
189                 lp2_disabled_by_suspend = false;
190 #endif
191
192         return NOTIFY_OK;
193 }
194
195 static struct notifier_block tegra_cpuidle_pm_notifier = {
196         .notifier_call = tegra_cpuidle_pm_notify,
197 };
198
199 static int __init tegra_cpuidle_init(void)
200 {
201         int ret;
202         unsigned int cpu;
203         struct cpuidle_device *dev;
204         struct cpuidle_driver *drv = &tegra_idle_driver;
205
206 #ifdef CONFIG_PM_SLEEP
207         tegra_lp2_min_residency = tegra_cpu_lp2_min_residency();
208         tegra_lp2_exit_latency = tegra_cpu_power_good_time();
209         tegra_lp2_power_off_time = tegra_cpu_power_off_time();
210
211         ret = tegra_cpudile_init_soc();
212         if (ret)
213                 return ret;
214
215         tegra_cpuidle_states[1].exit_latency = tegra_cpu_power_good_time();
216         tegra_cpuidle_states[1].target_residency = tegra_cpu_power_off_time() +
217                 tegra_cpu_power_good_time();
218         if (tegra_cpuidle_states[1].target_residency < tegra_lp2_min_residency)
219                 tegra_cpuidle_states[1].target_residency = tegra_lp2_min_residency;
220 #endif
221         
222         ret = cpuidle_register_driver(&tegra_idle_driver);
223         if (ret) {
224                 pr_err("CPUidle driver registration failed\n");
225                 return ret;
226         }
227
228         for_each_possible_cpu(cpu) {
229                 dev = &per_cpu(tegra_idle_device, cpu);
230                 dev->cpu = cpu;
231
232                 memcpy(&dev->states, tegra_cpuidle_states,
233                         ARRAY_SIZE(tegra_cpuidle_states) *
234                            sizeof(*tegra_cpuidle_states));
235
236                 dev->state_count = ARRAY_SIZE(tegra_cpuidle_states);
237                 dev->safe_state_index = 0;
238                 dev->power_specified = 1;
239                 ret = cpuidle_register_device(dev);
240                 if (ret) {
241                         pr_err("CPU%u: CPUidle device registration failed\n",
242                                 cpu);
243                         return ret;
244                 }
245         }
246         register_pm_notifier(&tegra_cpuidle_pm_notifier);
247
248         return 0;
249 }
250 device_initcall(tegra_cpuidle_init);
251
252 static int lp2_in_idle_set(const char *arg, const struct kernel_param *kp)
253 {
254 #ifdef CONFIG_PM_SLEEP
255         int ret;
256
257         /* If LP2 in idle is permanently disabled it can't be re-enabled. */
258         if (lp2_in_idle_modifiable) {
259                 ret = param_set_bool(arg, kp);
260                 return ret;
261         }
262 #endif
263         return -ENODEV;
264 }
265
266 static int lp2_in_idle_get(char *buffer, const struct kernel_param *kp)
267 {
268         return param_get_bool(buffer, kp);
269 }
270
271 static struct kernel_param_ops lp2_in_idle_ops = {
272         .set = lp2_in_idle_set,
273         .get = lp2_in_idle_get,
274 };
275 module_param_cb(lp2_in_idle, &lp2_in_idle_ops, &lp2_in_idle, 0644);
276
277 #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_PM_SLEEP)
278 static int tegra_lp2_debug_open(struct inode *inode, struct file *file)
279 {
280         return single_open(file, tegra_lp2_debug_show, inode->i_private);
281 }
282
283 static const struct file_operations tegra_lp2_debug_ops = {
284         .open           = tegra_lp2_debug_open,
285         .read           = seq_read,
286         .llseek         = seq_lseek,
287         .release        = single_release,
288 };
289
290 static int __init tegra_cpuidle_debug_init(void)
291 {
292         struct dentry *dir;
293         struct dentry *d;
294
295         dir = debugfs_create_dir("cpuidle", NULL);
296         if (!dir)
297                 return -ENOMEM;
298
299         d = debugfs_create_file("lp2", S_IRUGO, dir, NULL,
300                 &tegra_lp2_debug_ops);
301         if (!d)
302                 return -ENOMEM;
303
304         return 0;
305 }
306
307 late_initcall(tegra_cpuidle_debug_init);
308 #endif