[ARM/tegra] Add Tegra3 support
[linux-2.6.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, NVIDIA Corporation.
7  * Copyright (c) 2011 Google, Inc.
8  * Author: Colin Cross <ccross@android.com>
9  *         Gary King <gking@nvidia.com>
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful, but WITHOUT
17  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
19  * more details.
20  */
21
22 #include <linux/kernel.h>
23 #include <linux/cpu.h>
24 #include <linux/cpuidle.h>
25 #include <linux/debugfs.h>
26 #include <linux/delay.h>
27 #include <linux/init.h>
28 #include <linux/interrupt.h>
29 #include <linux/irq.h>
30 #include <linux/io.h>
31 #include <linux/sched.h>
32 #include <linux/seq_file.h>
33 #include <linux/slab.h>
34 #include <linux/smp.h>
35 #include <linux/suspend.h>
36 #include <linux/tick.h>
37
38 #include <asm/cpu_pm.h>
39
40 #include <mach/iomap.h>
41 #include <mach/irqs.h>
42
43 #include "pm.h"
44 #include "sleep.h"
45
46 #if defined(CONFIG_ARCH_TEGRA_2x_SOC)
47 #define TEGRA_CPUIDLE_BOTH_IDLE         INT_QUAD_RES_24
48 #define TEGRA_CPUIDLE_TEAR_DOWN         INT_QUAD_RES_25
49 #else
50 /* !!!FIXME!!! THIS MODEL IS BROKEN ON T30 -- 4 CPUS BREAKS THE "BOTH" IDLE CONCEPT .....*/
51 #define TEGRA_CPUIDLE_BOTH_IDLE         INT_QUINT_RES_24
52 #define TEGRA_CPUIDLE_TEAR_DOWN         INT_QUINT_RES_25
53 #endif
54
55 static bool lp2_in_idle __read_mostly = true;
56 module_param(lp2_in_idle, bool, 0644);
57
58 static struct {
59         unsigned int cpu_ready_count[2];
60         unsigned long long cpu_wants_lp2_time[2];
61         unsigned long long in_lp2_time;
62         unsigned int both_idle_count;
63         unsigned int tear_down_count;
64         unsigned int lp2_count;
65         unsigned int lp2_count_bin[32];
66         unsigned int lp2_int_count[NR_IRQS];
67         unsigned int last_lp2_int_count[NR_IRQS];
68 } idle_stats;
69
70 struct cpuidle_driver tegra_idle = {
71         .name = "tegra_idle",
72         .owner = THIS_MODULE,
73 };
74
75 static DEFINE_PER_CPU(struct cpuidle_device *, idle_devices);
76
77 #define CLK_RESET_CLK_MASK_ARM 0x44
78
79 static inline unsigned int time_to_bin(unsigned int time)
80 {
81         return fls(time);
82 }
83
84 static int tegra_idle_enter_lp3(struct cpuidle_device *dev,
85         struct cpuidle_state *state)
86 {
87         ktime_t enter, exit;
88         s64 us;
89
90         local_irq_disable();
91         local_fiq_disable();
92
93         enter = ktime_get();
94
95         tegra_cpu_wfi();
96
97         exit = ktime_sub(ktime_get(), enter);
98         us = ktime_to_us(exit);
99
100         local_fiq_enable();
101         local_irq_enable();
102         return (int)us;
103 }
104
105 static int tegra_idle_enter_lp2(struct cpuidle_device *dev,
106         struct cpuidle_state *state)
107 {
108         ktime_t enter, exit;
109         s64 us;
110
111         local_irq_disable();
112         clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
113         enter = ktime_get();
114
115         idle_stats.cpu_ready_count[dev->cpu]++;
116
117         clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &dev->cpu);
118         tegra_idle_lp2();
119         clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
120
121         exit = ktime_sub(ktime_get(), enter);
122         us = ktime_to_us(exit);
123
124         clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &dev->cpu);
125         local_irq_enable();
126
127         smp_rmb();
128
129         idle_stats.cpu_wants_lp2_time[dev->cpu] += us;
130
131         return (int)us;
132 }
133
134 static int tegra_idle_prepare(struct cpuidle_device *dev)
135 {
136         if (lp2_in_idle)
137                 dev->states[1].flags &= ~CPUIDLE_FLAG_IGNORE;
138         else
139                 dev->states[1].flags |= CPUIDLE_FLAG_IGNORE;
140
141         return 0;
142 }
143
144 static int tegra_idle_enter(unsigned int cpu)
145 {
146         struct cpuidle_device *dev;
147         struct cpuidle_state *state;
148
149         dev = kzalloc(sizeof(*dev), GFP_KERNEL);
150         if (!dev)
151                 return -ENOMEM;
152
153         dev->state_count = 0;
154         dev->cpu = cpu;
155
156         state = &dev->states[0];
157         snprintf(state->name, CPUIDLE_NAME_LEN, "LP3");
158         snprintf(state->desc, CPUIDLE_DESC_LEN, "CPU flow-controlled");
159         state->exit_latency = 10;
160         state->target_residency = 10;
161         state->power_usage = 600;
162         state->flags = CPUIDLE_FLAG_TIME_VALID;
163         state->enter = tegra_idle_enter_lp3;
164         dev->safe_state = state;
165         dev->state_count++;
166
167         state = &dev->states[1];
168         snprintf(state->name, CPUIDLE_NAME_LEN, "LP2");
169         snprintf(state->desc, CPUIDLE_DESC_LEN, "CPU power-gate");
170         state->exit_latency = tegra_cpu_power_good_time();
171
172         state->target_residency = tegra_cpu_power_off_time() +
173                 tegra_cpu_power_good_time();
174         state->power_usage = 0;
175         state->flags = CPUIDLE_FLAG_TIME_VALID;
176         state->enter = tegra_idle_enter_lp2;
177
178         dev->power_specified = 1;
179         dev->safe_state = state;
180         dev->state_count++;
181         dev->prepare = tegra_idle_prepare;
182
183         if (cpuidle_register_device(dev)) {
184                 pr_err("CPU%u: failed to register idle device\n", cpu);
185                 kfree(dev);
186                 return -EIO;
187         }
188         per_cpu(idle_devices, cpu) = dev;
189         return 0;
190 }
191
192 static int __init tegra_cpuidle_init(void)
193 {
194         unsigned int cpu;
195         void __iomem *mask_arm;
196         unsigned int reg;
197         int ret;
198
199         mask_arm = IO_ADDRESS(TEGRA_CLK_RESET_BASE) + CLK_RESET_CLK_MASK_ARM;
200
201         reg = readl(mask_arm);
202         writel(reg | (1<<31), mask_arm);
203
204         ret = cpuidle_register_driver(&tegra_idle);
205
206         if (ret)
207                 return ret;
208
209         for_each_possible_cpu(cpu) {
210                 if (tegra_idle_enter(cpu))
211                         pr_err("CPU%u: error initializing idle loop\n", cpu);
212         }
213
214         return 0;
215 }
216
217 static void __exit tegra_cpuidle_exit(void)
218 {
219         cpuidle_unregister_driver(&tegra_idle);
220 }
221
222 module_init(tegra_cpuidle_init);
223 module_exit(tegra_cpuidle_exit);
224
225 #ifdef CONFIG_DEBUG_FS
226 static int tegra_lp2_debug_show(struct seq_file *s, void *data)
227 {
228         int bin;
229         int i;
230         seq_printf(s, "                                    cpu0     cpu1\n");
231         seq_printf(s, "-------------------------------------------------\n");
232         seq_printf(s, "cpu ready:                      %8u %8u\n",
233                 idle_stats.cpu_ready_count[0],
234                 idle_stats.cpu_ready_count[1]);
235         seq_printf(s, "both idle:      %8u        %7u%% %7u%%\n",
236                 idle_stats.both_idle_count,
237                 idle_stats.both_idle_count * 100 /
238                         (idle_stats.cpu_ready_count[0] ?: 1),
239                 idle_stats.both_idle_count * 100 /
240                         (idle_stats.cpu_ready_count[1] ?: 1));
241         seq_printf(s, "tear down:      %8u %7u%%\n", idle_stats.tear_down_count,
242                 idle_stats.tear_down_count * 100 /
243                         (idle_stats.both_idle_count ?: 1));
244         seq_printf(s, "lp2:            %8u %7u%%\n", idle_stats.lp2_count,
245                 idle_stats.lp2_count * 100 /
246                         (idle_stats.both_idle_count ?: 1));
247
248         seq_printf(s, "\n");
249         seq_printf(s, "cpu ready time:                 %8llu %8llu ms\n",
250                 div64_u64(idle_stats.cpu_wants_lp2_time[0], 1000),
251                 div64_u64(idle_stats.cpu_wants_lp2_time[1], 1000));
252         seq_printf(s, "lp2 time:       %8llu ms     %7d%% %7d%%\n",
253                 div64_u64(idle_stats.in_lp2_time, 1000),
254                 (int)div64_u64(idle_stats.in_lp2_time * 100,
255                         idle_stats.cpu_wants_lp2_time[0] ?: 1),
256                 (int)div64_u64(idle_stats.in_lp2_time * 100,
257                         idle_stats.cpu_wants_lp2_time[1] ?: 1));
258
259         seq_printf(s, "\n");
260         seq_printf(s, "%19s %8s\n", "", "lp2");
261         seq_printf(s, "-------------------------------------------------\n");
262         for (bin = 0; bin < 32; bin++) {
263                 if (idle_stats.lp2_count_bin[bin] == 0)
264                         continue;
265                 seq_printf(s, "%6u - %6u ms: %8u\n",
266                         1 << (bin - 1), 1 << bin,
267                         idle_stats.lp2_count_bin[bin]);
268         }
269
270         seq_printf(s, "\n");
271         seq_printf(s, "%3s %20s %6s %10s\n",
272                 "int", "name", "count", "last count");
273         seq_printf(s, "--------------------------------------------\n");
274         for (i = 0; i < NR_IRQS; i++) {
275                 if (idle_stats.lp2_int_count[i] == 0)
276                         continue;
277                 seq_printf(s, "%3d %20s %6d %10d\n",
278                         i, irq_to_desc(i)->action ?
279                                 irq_to_desc(i)->action->name ?: "???" : "???",
280                         idle_stats.lp2_int_count[i],
281                         idle_stats.lp2_int_count[i] -
282                                 idle_stats.last_lp2_int_count[i]);
283                 idle_stats.last_lp2_int_count[i] = idle_stats.lp2_int_count[i];
284         };
285         return 0;
286 }
287
288 static int tegra_lp2_debug_open(struct inode *inode, struct file *file)
289 {
290         return single_open(file, tegra_lp2_debug_show, inode->i_private);
291 }
292
293 static const struct file_operations tegra_lp2_debug_ops = {
294         .open           = tegra_lp2_debug_open,
295         .read           = seq_read,
296         .llseek         = seq_lseek,
297         .release        = single_release,
298 };
299
300 static int __init tegra_cpuidle_debug_init(void)
301 {
302         struct dentry *dir;
303         struct dentry *d;
304
305         dir = debugfs_create_dir("cpuidle", NULL);
306         if (!dir)
307                 return -ENOMEM;
308
309         d = debugfs_create_file("lp2", S_IRUGO, dir, NULL,
310                 &tegra_lp2_debug_ops);
311         if (!d)
312                 return -ENOMEM;
313
314         return 0;
315 }
316
317 late_initcall(tegra_cpuidle_debug_init);
318 #endif