ARM: tegra: kernel fix QT platform detection
[linux-3.10.git] / arch / arm / mach-tegra / timer-t3.c
1 /*
2  * arch/arch/mach-tegra/timer-t3.c
3  *
4  * Copyright (c) 2011-2013, NVIDIA CORPORATION.  All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along
17  * with this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
19  */
20
21 #include <linux/init.h>
22 #include <linux/err.h>
23 #include <linux/sched.h>
24 #include <linux/time.h>
25 #include <linux/interrupt.h>
26 #include <linux/irq.h>
27 #include <linux/clockchips.h>
28 #include <linux/clocksource.h>
29 #include <linux/clk.h>
30 #include <linux/io.h>
31 #include <linux/smp.h>
32 #include <linux/syscore_ops.h>
33 #include <linux/cpu.h>
34 #include <linux/export.h>
35
36 #include <asm/mach/time.h>
37 #include <asm/localtimer.h>
38 #include <asm/sched_clock.h>
39 #include <asm/smp_plat.h>
40
41 #include <mach/irqs.h>
42 #include <mach/hardware.h>
43
44 #include "board.h"
45 #include "clock.h"
46 #include "cpuidle.h"
47 #include "iomap.h"
48 #include "timer.h"
49 #include "fuse.h"
50 enum tegra_revision tegra_get_revision(void); /* !!!FIXME!!! eliminate */
51
52 #if defined(CONFIG_ARM_ARCH_TIMER) || defined(CONFIG_HAVE_ARM_TWD)
53
54 #define TEST_LP2_WAKE_TIMERS    0
55
56 /*
57  * Timers usage:
58  * TMR1 - used as general CPU timer.
59  * TMR2 - used by AVP.
60  * TMR3 - used by CPU0 for LP2 wakeup.
61  * TMR4 - used by CPU1 for LP2 wakeup.
62  * TMR5 - used by CPU2 for LP2 wakeup.
63  * TMR6 - used by CPU3 for LP2 wakeup.
64  * TMR7 - watchdog, for generic purpose.
65  * TMR8 - Free.
66  * TMR9 - Free.
67  * TMR10 - watchdog, suspend/resume recovery
68 */
69
70 #define TIMER1_OFFSET (TEGRA_TMR1_BASE-TEGRA_TMR1_BASE)
71 #define TIMER2_OFFSET (TEGRA_TMR2_BASE-TEGRA_TMR1_BASE)
72 #define TIMER3_OFFSET (TEGRA_TMR3_BASE-TEGRA_TMR1_BASE)
73 #define TIMER4_OFFSET (TEGRA_TMR4_BASE-TEGRA_TMR1_BASE)
74 #define TIMER5_OFFSET (TEGRA_TMR5_BASE-TEGRA_TMR1_BASE)
75 #define TIMER6_OFFSET (TEGRA_TMR6_BASE-TEGRA_TMR1_BASE)
76
77 static void __iomem *timer_reg_base = IO_ADDRESS(TEGRA_TMR1_BASE);
78
79 #if defined(CONFIG_PM_SLEEP)
80 static cpumask_t wake_timer_canceled;
81 static cpumask_t wake_timer_ready;
82 #endif
83
84 static inline void timer_writel(u32 value, unsigned long reg)
85 {
86         __raw_writel(value, timer_reg_base + (reg));
87 }
88
89 static inline unsigned int timer_readl(unsigned long reg)
90 {
91         return __raw_readl(timer_reg_base + (reg));
92 }
93
94 #ifdef CONFIG_PM_SLEEP
95 static u32 lp2_wake_timers[] = {
96         TIMER3_OFFSET,
97 #ifdef CONFIG_SMP
98         TIMER4_OFFSET,
99         TIMER5_OFFSET,
100         TIMER6_OFFSET,
101 #endif
102 };
103
104 static irqreturn_t tegra_lp2wake_interrupt(int irq, void *dev_id)
105 {
106         int cpu = (int)dev_id;
107         int base;
108
109         base = lp2_wake_timers[cpu];
110         timer_writel(1<<30, base + TIMER_PCR);
111         return IRQ_HANDLED;
112 }
113
114 #define LP2_TIMER_IRQ_ACTION(cpu, irqnum) {                     \
115         .name           = "tmr_lp2wake_cpu" __stringify(cpu),   \
116         .flags          = IRQF_DISABLED,                        \
117         .handler        = tegra_lp2wake_interrupt,              \
118         .dev_id         = (void*)cpu,                           \
119         .irq            = irqnum }
120
121 static struct irqaction tegra_lp2wake_irq[] = {
122         LP2_TIMER_IRQ_ACTION(0, INT_TMR3),
123 #ifdef CONFIG_SMP
124         LP2_TIMER_IRQ_ACTION(1, INT_TMR4),
125         LP2_TIMER_IRQ_ACTION(2, INT_TMR5),
126         LP2_TIMER_IRQ_ACTION(3, INT_TMR6),
127 #endif
128 };
129
130 /*
131  * To sanity test LP2 timer interrupts for CPU 0-3, enable this flag and check
132  * /proc/interrupts for timer interrupts. CPUs 0-3 should have one interrupt
133  * counted against them for tmr_lp2wake_cpu<n>, where <n> is the CPU number.
134  */
135 #if TEST_LP2_WAKE_TIMERS
136 static void test_lp2_wake_timer(unsigned int cpu)
137 {
138         unsigned long cycles = 50000;
139         unsigned int base = lp2_wake_timers[cpu];
140         static bool tested[4] = {false, false, false, false};
141
142         /* Don't repeat the test process on hotplug restart. */
143         if (!tested[cpu]) {
144                 timer_writel(0, base + TIMER_PTV);
145                 if (cycles) {
146                         u32 reg = 0x80000000ul | min(0x1ffffffful, cycles);
147                         timer_writel(reg, base + TIMER_PTV);
148                         tested[cpu] = true;
149                 }
150         }
151 }
152 #else
153 static inline void test_lp2_wake_timer(unsigned int cpu) {}
154 #endif
155
156 static int tegra3_resume_wake_timer(unsigned int cpu)
157 {
158 #ifdef CONFIG_SMP
159         int ret = irq_set_affinity(tegra_lp2wake_irq[cpu].irq, cpumask_of(cpu));
160         if (ret) {
161                 pr_err("Failed to set affinity for LP2 timer IRQ to "
162                         "CPU %d: irq=%d, ret=%d\n", cpu,
163                         tegra_lp2wake_irq[cpu].irq, ret);
164                 return ret;
165         }
166 #endif
167         cpumask_set_cpu(cpu, &wake_timer_ready);
168         return 0;
169 }
170
171 static void tegra3_register_wake_timer(unsigned int cpu)
172 {
173         int ret;
174
175         ret = setup_irq(tegra_lp2wake_irq[cpu].irq, &tegra_lp2wake_irq[cpu]);
176         if (ret) {
177                 pr_err("Failed to register LP2 timer IRQ for CPU %d: "
178                         "irq=%d, ret=%d\n", cpu,
179                         tegra_lp2wake_irq[cpu].irq, ret);
180                 goto fail;
181         }
182
183         ret = tegra3_resume_wake_timer(cpu);
184         if (ret)
185                 goto fail;
186
187         test_lp2_wake_timer(cpu);
188         return;
189 fail:
190         tegra_pd_in_idle(false);
191 }
192
193 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_HOTPLUG_CPU)
194 static void tegra3_suspend_wake_timer(unsigned int cpu)
195 {
196         cpumask_clear_cpu(cpu, &wake_timer_ready);
197 #ifdef CONFIG_SMP
198         /* Reassign the affinity of the wake IRQ to any ready CPU. */
199         for_each_cpu_not(cpu, &wake_timer_ready)
200         {
201                 (void)irq_set_affinity(tegra_lp2wake_irq[cpu].irq,
202                         cpumask_of(cpumask_any(&wake_timer_ready)));
203         }
204 #endif
205 }
206
207 static void tegra3_unregister_wake_timer(unsigned int cpu)
208 {
209         tegra3_suspend_wake_timer(cpu);
210
211         /* Dispose of this IRQ. */
212         remove_irq(tegra_lp2wake_irq[cpu].irq, &tegra_lp2wake_irq[cpu]);
213 }
214 #endif
215
216 void tegra3_lp2_set_trigger(unsigned long cycles)
217 {
218         int cpu = cpu_logical_map(smp_processor_id());
219         int base;
220
221         base = lp2_wake_timers[cpu];
222         timer_writel(0, base + TIMER_PTV);
223         if (cycles) {
224                 u32 reg = 0x80000000ul | min(0x1ffffffful, cycles);
225                 timer_writel(reg, base + TIMER_PTV);
226         }
227 }
228 EXPORT_SYMBOL(tegra3_lp2_set_trigger);
229
230 unsigned long tegra3_lp2_timer_remain(void)
231 {
232         int cpu = cpu_logical_map(smp_processor_id());
233
234         if (cpumask_test_and_clear_cpu(cpu, &wake_timer_canceled))
235                 return -ETIME;
236
237         return timer_readl(lp2_wake_timers[cpu] + TIMER_PCR) & 0x1ffffffful;
238 }
239
240 int tegra3_is_cpu_wake_timer_ready(unsigned int cpu)
241 {
242         return cpumask_test_cpu(cpu, &wake_timer_ready);
243 }
244
245 void tegra3_lp2_timer_cancel_secondary(void)
246 {
247         int cpu;
248         int base;
249
250         for (cpu = 1; cpu < ARRAY_SIZE(lp2_wake_timers); cpu++) {
251                 base = lp2_wake_timers[cpu];
252                 cpumask_set_cpu(cpu, &wake_timer_canceled);
253                 timer_writel(0, base + TIMER_PTV);
254                 timer_writel(1<<30, base + TIMER_PCR);
255         }
256 }
257 #endif
258
259 void __init tegra30_init_timer(void)
260 {
261         unsigned long rate = tegra_clk_measure_input_freq();
262
263         switch (rate) {
264         case 12000000:
265                 timer_writel(0x000b, TIMERUS_USEC_CFG);
266                 break;
267         case 13000000:
268                 timer_writel(0x000c, TIMERUS_USEC_CFG);
269                 break;
270         case 19200000:
271                 timer_writel(0x045f, TIMERUS_USEC_CFG);
272                 break;
273         case 26000000:
274                 timer_writel(0x0019, TIMERUS_USEC_CFG);
275                 break;
276         case 16800000:
277                 timer_writel(0x0453, TIMERUS_USEC_CFG);
278                 break;
279         case 38400000:
280                 timer_writel(0x04BF, TIMERUS_USEC_CFG);
281                 break;
282         case 48000000:
283                 timer_writel(0x002F, TIMERUS_USEC_CFG);
284                 break;
285         default:
286                 if (tegra_platform_is_qt()) {
287                         timer_writel(0x000c, TIMERUS_USEC_CFG);
288                         break;
289                 }
290                 WARN(1, "Unknown clock rate");
291         }
292
293 #ifdef CONFIG_PM_SLEEP
294         tegra3_register_wake_timer(0);
295 #endif
296 }
297
298 #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_HOTPLUG_CPU)
299 static int hotplug_notify(struct notifier_block *self,
300                                       unsigned long action, void *cpu)
301 {
302         switch (action) {
303         case CPU_ONLINE:
304                 tegra3_register_wake_timer((unsigned int)cpu);
305                 break;
306         case CPU_ONLINE_FROZEN:
307                 tegra3_resume_wake_timer((unsigned int)cpu);
308                 break;
309         case CPU_DOWN_PREPARE:
310                 tegra3_unregister_wake_timer((unsigned int)cpu);
311                 break;
312         case CPU_DOWN_PREPARE_FROZEN:
313                 tegra3_suspend_wake_timer((unsigned int)cpu);
314                 break;
315         default:
316                 break;
317         }
318
319         return NOTIFY_OK;
320 }
321
322 static struct notifier_block __cpuinitdata hotplug_notifier_block = {
323         .notifier_call = hotplug_notify,
324 };
325
326 static int __init hotplug_cpu_register(void)
327 {
328         return register_cpu_notifier(&hotplug_notifier_block);
329 }
330 early_initcall(hotplug_cpu_register);
331 #endif
332 #endif