unknown changes from android-tegra-nv-3.4
[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/cpu.h>
26 #include <linux/cpuidle.h>
27 #include <linux/debugfs.h>
28 #include <linux/delay.h>
29 #include <linux/init.h>
30 #include <linux/interrupt.h>
31 #include <linux/irq.h>
32 #include <linux/io.h>
33 #include <linux/sched.h>
34 #include <linux/seq_file.h>
35 #include <linux/slab.h>
36 #include <linux/smp.h>
37 #include <linux/suspend.h>
38 #include <linux/tick.h>
39 #include <linux/cpu_pm.h>
40 #include <linux/module.h>
41 #include <linux/hrtimer.h>
42
43 #include <asm/proc-fns.h>
44
45 #include <mach/irqs.h>
46
47 #include <trace/events/power.h>
48
49 #include "cpuidle.h"
50 #include "pm.h"
51 #include "sleep.h"
52
53 int tegra_lp2_exit_latency;
54 static int tegra_lp2_power_off_time;
55 static unsigned int tegra_lp2_min_residency;
56
57 static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
58                                 int index);
59
60 struct cpuidle_driver tegra_idle_driver = {
61         .name = "tegra_idle",
62         .owner = THIS_MODULE,
63 };
64
65 static DEFINE_PER_CPU(struct cpuidle_device *, tegra_idle_device);
66
67 static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
68         int index)
69 {
70         ktime_t enter, exit;
71         s64 us;
72
73         trace_power_start(POWER_CSTATE, 1, dev->cpu);
74
75         local_irq_disable();
76         local_fiq_disable();
77
78         enter = ktime_get();
79
80         cpu_do_idle();
81
82         exit = ktime_sub(ktime_get(), enter);
83         us = ktime_to_us(exit);
84
85         local_fiq_enable();
86         local_irq_enable();
87
88         dev->last_residency = us;
89         return index;
90 }
91
92 static bool lp2_in_idle __read_mostly = false;
93
94 #ifdef CONFIG_PM_SLEEP
95 static bool lp2_in_idle_modifiable __read_mostly = true;
96 static bool lp2_disabled_by_suspend;
97
98 void tegra_lp2_in_idle(bool enable)
99 {
100         /* If LP2 in idle is permanently disabled it can't be re-enabled. */
101         if (lp2_in_idle_modifiable) {
102                 lp2_in_idle = enable;
103                 lp2_in_idle_modifiable = enable;
104                 if (!enable)
105                         pr_warn("LP2 in idle disabled\n");
106         }
107 }
108
109 void tegra_lp2_update_target_residency(struct cpuidle_state *state)
110 {
111         state->target_residency = state->exit_latency +
112                 tegra_lp2_power_off_time;
113         if (state->target_residency < tegra_lp2_min_residency)
114                 state->target_residency = tegra_lp2_min_residency;
115 }
116
117 static int tegra_idle_enter_lp2(struct cpuidle_device *dev,
118         int index)
119 {
120         ktime_t enter, exit;
121         s64 us;
122         struct cpuidle_state *state = &dev->states[index];
123         bool entered_lp2;
124
125         if (!lp2_in_idle || lp2_disabled_by_suspend ||
126             !tegra_lp2_is_allowed(dev, state)) {
127                 return dev->states[dev->safe_state_index].enter(dev,
128                                         dev->safe_state_index);
129         }
130
131         local_irq_disable();
132         enter = ktime_get();
133
134         tegra_cpu_idle_stats_lp2_ready(dev->cpu);
135         entered_lp2 = tegra_idle_lp2(dev, state);
136
137         exit = ktime_sub(ktime_get(), enter);
138         us = ktime_to_us(exit);
139
140         local_irq_enable();
141
142         /* cpu clockevents may have been reset by powerdown */
143         hrtimer_peek_ahead_timers();
144
145         smp_rmb();
146
147         /* Update LP2 latency provided no fall back to LP3 */
148         if (entered_lp2) {
149                 tegra_lp2_set_global_latency(state);
150                 tegra_lp2_update_target_residency(state);
151         }
152         tegra_cpu_idle_stats_lp2_time(dev->cpu, us);
153
154         dev->last_residency = (int)us;
155         return (entered_lp2) ? index : 0;
156 }
157 #endif
158
159 static int tegra_cpuidle_register_device(unsigned int cpu)
160 {
161         struct cpuidle_device *dev;
162         struct cpuidle_state *state;
163
164         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
165         if (!dev)
166                 return -ENOMEM;
167
168         dev->state_count = 0;
169         dev->cpu = cpu;
170
171         state = &dev->states[0];
172         snprintf(state->name, CPUIDLE_NAME_LEN, "LP3");
173         snprintf(state->desc, CPUIDLE_DESC_LEN, "CPU flow-controlled");
174         state->exit_latency = 10;
175         state->target_residency = 10;
176         state->power_usage = 600;
177         state->flags = CPUIDLE_FLAG_TIME_VALID;
178         state->enter = tegra_idle_enter_lp3;
179         dev->safe_state_index = 0;
180         dev->state_count++;
181
182 #ifdef CONFIG_PM_SLEEP
183         state = &dev->states[1];
184         snprintf(state->name, CPUIDLE_NAME_LEN, "LP2");
185         snprintf(state->desc, CPUIDLE_DESC_LEN, "CPU power-gate");
186         state->exit_latency = tegra_cpu_power_good_time();
187         state->target_residency = tegra_cpu_power_off_time() +
188                 tegra_cpu_power_good_time();
189         if (state->target_residency < tegra_lp2_min_residency)
190                 state->target_residency = tegra_lp2_min_residency;
191         state->power_usage = 0;
192         state->flags = CPUIDLE_FLAG_TIME_VALID;
193         state->enter = tegra_idle_enter_lp2;
194         dev->power_specified = 1;
195         dev->state_count++;
196 #endif
197
198         if (cpuidle_register_device(dev)) {
199                 pr_err("CPU%u: failed to register idle device\n", cpu);
200                 kfree(dev);
201                 return -EIO;
202         }
203         per_cpu(tegra_idle_device, cpu) = dev;
204         return 0;
205 }
206
207 static int tegra_cpuidle_pm_notify(struct notifier_block *nb,
208         unsigned long event, void *dummy)
209 {
210 #ifdef CONFIG_PM_SLEEP
211         if (event == PM_SUSPEND_PREPARE)
212                 lp2_disabled_by_suspend = true;
213         else if (event == PM_POST_SUSPEND)
214                 lp2_disabled_by_suspend = false;
215 #endif
216
217         return NOTIFY_OK;
218 }
219
220 static struct notifier_block tegra_cpuidle_pm_notifier = {
221         .notifier_call = tegra_cpuidle_pm_notify,
222 };
223
224 static int __init tegra_cpuidle_init(void)
225 {
226         unsigned int cpu;
227         int ret;
228
229         ret = cpuidle_register_driver(&tegra_idle_driver);
230         if (ret) {
231                 pr_err("CPUidle driver registration failed\n");
232                 return ret;
233         }
234
235 #ifdef CONFIG_PM_SLEEP
236         tegra_lp2_min_residency = tegra_cpu_lp2_min_residency();
237         tegra_lp2_exit_latency = tegra_cpu_power_good_time();
238         tegra_lp2_power_off_time = tegra_cpu_power_off_time();
239
240         ret = tegra_cpudile_init_soc();
241         if (ret)
242                 return ret;
243 #endif
244
245         for_each_possible_cpu(cpu) {
246                 ret = tegra_cpuidle_register_device(cpu);
247                 if (ret) {
248                         pr_err("CPU%u: CPUidle device registration failed\n",
249                                 cpu);
250                         return ret;
251                 }
252         }
253
254         register_pm_notifier(&tegra_cpuidle_pm_notifier);
255         return 0;
256 }
257 device_initcall(tegra_cpuidle_init);
258
259 static void __exit tegra_cpuidle_exit(void)
260 {
261         unregister_pm_notifier(&tegra_cpuidle_pm_notifier);
262         cpuidle_unregister_driver(&tegra_idle_driver);
263 }
264 module_exit(tegra_cpuidle_exit);
265
266 static int lp2_in_idle_set(const char *arg, const struct kernel_param *kp)
267 {
268 #ifdef CONFIG_PM_SLEEP
269         int ret;
270
271         /* If LP2 in idle is permanently disabled it can't be re-enabled. */
272         if (lp2_in_idle_modifiable) {
273                 ret = param_set_bool(arg, kp);
274                 return ret;
275         }
276 #endif
277         return -ENODEV;
278 }
279
280 static int lp2_in_idle_get(char *buffer, const struct kernel_param *kp)
281 {
282         return param_get_bool(buffer, kp);
283 }
284
285 static struct kernel_param_ops lp2_in_idle_ops = {
286         .set = lp2_in_idle_set,
287         .get = lp2_in_idle_get,
288 };
289 module_param_cb(lp2_in_idle, &lp2_in_idle_ops, &lp2_in_idle, 0644);
290
291 #if defined(CONFIG_DEBUG_FS) && defined(CONFIG_PM_SLEEP)
292 static int tegra_lp2_debug_open(struct inode *inode, struct file *file)
293 {
294         return single_open(file, tegra_lp2_debug_show, inode->i_private);
295 }
296
297 static const struct file_operations tegra_lp2_debug_ops = {
298         .open           = tegra_lp2_debug_open,
299         .read           = seq_read,
300         .llseek         = seq_lseek,
301         .release        = single_release,
302 };
303
304 static int __init tegra_cpuidle_debug_init(void)
305 {
306         struct dentry *dir;
307         struct dentry *d;
308
309         dir = debugfs_create_dir("cpuidle", NULL);
310         if (!dir)
311                 return -ENOMEM;
312
313         d = debugfs_create_file("lp2", S_IRUGO, dir, NULL,
314                 &tegra_lp2_debug_ops);
315         if (!d)
316                 return -ENOMEM;
317
318         return 0;
319 }
320
321 late_initcall(tegra_cpuidle_debug_init);
322 #endif