blob: 81a9a7101fffb15e7bc348aeede05989156ba2af [file] [log] [blame]
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -08001/*
2 * linux/arch/arm/kernel/arch_timer.c
3 *
4 * Copyright (C) 2011 ARM Ltd.
5 * All Rights Reserved
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
10 */
11#include <linux/init.h>
12#include <linux/kernel.h>
13#include <linux/delay.h>
Sathish Ambley8a309822011-11-07 14:49:08 -080014#include <linux/timex.h>
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080015#include <linux/device.h>
16#include <linux/smp.h>
17#include <linux/cpu.h>
18#include <linux/jiffies.h>
19#include <linux/clockchips.h>
20#include <linux/interrupt.h>
Marc Zyngierf2caa512012-01-19 13:53:50 +000021#include <linux/of_irq.h>
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080022#include <linux/io.h>
Sathish Ambley8a309822011-11-07 14:49:08 -080023#include <linux/irq.h>
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080024
25#include <asm/cputype.h>
Marc Zyngierdf590cc2012-01-11 17:25:17 +000026#include <asm/localtimer.h>
27#include <asm/arch_timer.h>
Sathish Ambley8a309822011-11-07 14:49:08 -080028#include <asm/sched_clock.h>
Steve Mucklef132c6c2012-06-06 18:30:57 -070029#include <asm/hardware/gic.h>
30#include <asm/system_info.h>
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080031
32static unsigned long arch_timer_rate;
33static int arch_timer_ppi;
34static int arch_timer_ppi2;
35
Marc Zyngierdf590cc2012-01-11 17:25:17 +000036static struct clock_event_device __percpu **arch_timer_evt;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080037
38/*
39 * Architected system timer support.
40 */
41
42#define ARCH_TIMER_CTRL_ENABLE (1 << 0)
43#define ARCH_TIMER_CTRL_IT_MASK (1 << 1)
Marc Zyngierdf590cc2012-01-11 17:25:17 +000044#define ARCH_TIMER_CTRL_IT_STAT (1 << 2)
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080045
46#define ARCH_TIMER_REG_CTRL 0
47#define ARCH_TIMER_REG_FREQ 1
48#define ARCH_TIMER_REG_TVAL 2
49
50static void arch_timer_reg_write(int reg, u32 val)
51{
52 switch (reg) {
53 case ARCH_TIMER_REG_CTRL:
54 asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
55 break;
56 case ARCH_TIMER_REG_TVAL:
57 asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
58 break;
59 }
60
61 isb();
62}
63
64static u32 arch_timer_reg_read(int reg)
65{
66 u32 val;
67
68 switch (reg) {
69 case ARCH_TIMER_REG_CTRL:
70 asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
71 break;
72 case ARCH_TIMER_REG_FREQ:
73 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
74 break;
75 case ARCH_TIMER_REG_TVAL:
76 asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
77 break;
78 default:
79 BUG();
80 }
81
82 return val;
83}
84
85static irqreturn_t arch_timer_handler(int irq, void *dev_id)
86{
Sathish Ambley8a309822011-11-07 14:49:08 -080087 struct clock_event_device *evt;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080088 unsigned long ctrl;
89
90 ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
Marc Zyngierdf590cc2012-01-11 17:25:17 +000091 if (ctrl & ARCH_TIMER_CTRL_IT_STAT) {
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080092 ctrl |= ARCH_TIMER_CTRL_IT_MASK;
93 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
Marc Zyngierdf590cc2012-01-11 17:25:17 +000094 evt = *__this_cpu_ptr(arch_timer_evt);
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080095 evt->event_handler(evt);
96 return IRQ_HANDLED;
97 }
98
99 return IRQ_NONE;
100}
101
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000102static void arch_timer_disable(void)
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800103{
104 unsigned long ctrl;
105
106 ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
107 ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
108 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
109}
110
111static void arch_timer_set_mode(enum clock_event_mode mode,
112 struct clock_event_device *clk)
113{
114 switch (mode) {
115 case CLOCK_EVT_MODE_UNUSED:
116 case CLOCK_EVT_MODE_SHUTDOWN:
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000117 arch_timer_disable();
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800118 break;
119 default:
120 break;
121 }
122}
123
124static int arch_timer_set_next_event(unsigned long evt,
125 struct clock_event_device *unused)
126{
127 unsigned long ctrl;
128
129 ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
130 ctrl |= ARCH_TIMER_CTRL_ENABLE;
131 ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
132
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800133 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
Sathish Ambley9c642ec2011-12-02 10:50:58 -0800134 arch_timer_reg_write(ARCH_TIMER_REG_TVAL, evt);
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800135
136 return 0;
137}
138
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000139static int __cpuinit arch_timer_setup(struct clock_event_device *clk)
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800140{
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000141 /* setup clock event only once for CPU 0 */
142 if (!smp_processor_id() && clk->irq == arch_timer_ppi)
143 return 0;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800144
145 /* Be safe... */
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000146 arch_timer_disable();
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800147
148 clk->features = CLOCK_EVT_FEAT_ONESHOT;
149 clk->name = "arch_sys_timer";
150 clk->rating = 450;
151 clk->set_mode = arch_timer_set_mode;
152 clk->set_next_event = arch_timer_set_next_event;
153 clk->irq = arch_timer_ppi;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800154
155 clockevents_config_and_register(clk, arch_timer_rate,
156 0xf, 0x7fffffff);
157
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000158 *__this_cpu_ptr(arch_timer_evt) = clk;
159
160 enable_percpu_irq(clk->irq, 0);
161 if (arch_timer_ppi2)
Trilok Sonieecb28c2011-07-20 16:24:14 +0100162 enable_percpu_irq(arch_timer_ppi2, 0);
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000163
164 return 0;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800165}
166
167/* Is the optional system timer available? */
168static int local_timer_is_architected(void)
169{
170 return (cpu_architecture() >= CPU_ARCH_ARMv7) &&
171 ((read_cpuid_ext(CPUID_EXT_PFR1) >> 16) & 0xf) == 1;
172}
173
174static int arch_timer_available(void)
175{
176 unsigned long freq;
177
178 if (!local_timer_is_architected())
179 return -ENXIO;
180
181 if (arch_timer_rate == 0) {
182 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, 0);
183 freq = arch_timer_reg_read(ARCH_TIMER_REG_FREQ);
184
185 /* Check the timer frequency. */
186 if (freq == 0) {
187 pr_warn("Architected timer frequency not available\n");
188 return -EINVAL;
189 }
190
191 arch_timer_rate = freq;
192 pr_info("Architected local timer running at %lu.%02luMHz.\n",
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000193 freq / 1000000, (freq / 10000) % 100);
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800194 }
195
196 return 0;
197}
198
199static inline cycle_t arch_counter_get_cntpct(void)
200{
201 u32 cvall, cvalh;
202
203 asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (cvall), "=r" (cvalh));
204
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000205 return ((cycle_t) cvalh << 32) | cvall;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800206}
207
208static inline cycle_t arch_counter_get_cntvct(void)
209{
210 u32 cvall, cvalh;
211
212 asm volatile("mrrc p15, 1, %0, %1, c14" : "=r" (cvall), "=r" (cvalh));
213
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000214 return ((cycle_t) cvalh << 32) | cvall;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800215}
216
217static cycle_t arch_counter_read(struct clocksource *cs)
218{
219 return arch_counter_get_cntpct();
220}
221
Sathish Ambley8a309822011-11-07 14:49:08 -0800222#ifdef ARCH_HAS_READ_CURRENT_TIMER
223int read_current_timer(unsigned long *timer_val)
224{
225 *timer_val = (unsigned long)arch_counter_get_cntpct();
226 return 0;
227}
228#endif
229
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800230static struct clocksource clocksource_counter = {
231 .name = "arch_sys_counter",
232 .rating = 400,
233 .read = arch_counter_read,
234 .mask = CLOCKSOURCE_MASK(56),
235 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
236};
237
Marc Zyngier165a4742011-11-11 14:30:44 -0800238static u32 arch_counter_get_cntvct32(void)
239{
240 cycle_t cntvct;
241
242 cntvct = arch_counter_get_cntvct();
243
244 /*
245 * The sched_clock infrastructure only knows about counters
246 * with at most 32bits. Forget about the upper 24 bits for the
247 * time being...
248 */
249 return (u32)(cntvct & (u32)~0);
250}
251
Steve Mucklef132c6c2012-06-06 18:30:57 -0700252static u32 notrace arch_timer_update_sched_clock(void)
Marc Zyngier165a4742011-11-11 14:30:44 -0800253{
Steve Mucklef132c6c2012-06-06 18:30:57 -0700254 return arch_counter_get_cntvct32();
Marc Zyngier165a4742011-11-11 14:30:44 -0800255}
256
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000257static void __cpuinit arch_timer_stop(struct clock_event_device *clk)
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800258{
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800259 pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n",
260 clk->irq, smp_processor_id());
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000261 disable_percpu_irq(clk->irq);
262 if (arch_timer_ppi2)
Trilok Sonieecb28c2011-07-20 16:24:14 +0100263 disable_percpu_irq(arch_timer_ppi2);
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800264 arch_timer_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
265}
266
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000267static struct local_timer_ops arch_timer_ops __cpuinitdata = {
268 .setup = arch_timer_setup,
269 .stop = arch_timer_stop,
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800270};
271
Marc Zyngierf2caa512012-01-19 13:53:50 +0000272static int __init arch_timer_common_register(void)
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800273{
274 int err;
275
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800276 err = arch_timer_available();
277 if (err)
278 return err;
279
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000280 arch_timer_evt = alloc_percpu(struct clock_event_device *);
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800281 if (!arch_timer_evt)
282 return -ENOMEM;
283
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800284 clocksource_register_hz(&clocksource_counter, arch_timer_rate);
285
Steve Mucklef132c6c2012-06-06 18:30:57 -0700286 setup_sched_clock(arch_timer_update_sched_clock, 32, arch_timer_rate);
Sathish Ambley8a309822011-11-07 14:49:08 -0800287
288#ifdef ARCH_HAS_READ_CURRENT_TIMER
289 set_delay_fn(read_current_timer_delay_loop);
290#endif
291
Trilok Sonieecb28c2011-07-20 16:24:14 +0100292 err = request_percpu_irq(arch_timer_ppi, arch_timer_handler,
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000293 "arch_timer", arch_timer_evt);
Sathish Ambley8a309822011-11-07 14:49:08 -0800294 if (err) {
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000295 pr_err("arch_timer: can't register interrupt %d (%d)\n",
296 arch_timer_ppi, err);
297 goto out_free;
Sathish Ambley8a309822011-11-07 14:49:08 -0800298 }
299
Marc Zyngierf2caa512012-01-19 13:53:50 +0000300 if (arch_timer_ppi2) {
Trilok Sonieecb28c2011-07-20 16:24:14 +0100301 err = request_percpu_irq(arch_timer_ppi2, arch_timer_handler,
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000302 "arch_timer", arch_timer_evt);
303 if (err) {
304 pr_err("arch_timer: can't register interrupt %d (%d)\n",
305 arch_timer_ppi2, err);
306 arch_timer_ppi2 = 0;
307 goto out_free_irq;
308 }
Sathish Ambley8a309822011-11-07 14:49:08 -0800309 }
Marc Zyngier165a4742011-11-11 14:30:44 -0800310
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000311 err = local_timer_register(&arch_timer_ops);
312 if (err)
313 goto out_free_irq;
314 percpu_timer_setup();
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800315
316 return 0;
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000317
318out_free_irq:
319 free_percpu_irq(arch_timer_ppi, arch_timer_evt);
320 if (arch_timer_ppi2)
321 free_percpu_irq(arch_timer_ppi2, arch_timer_evt);
322
323out_free:
324 free_percpu(arch_timer_evt);
325
326 return err;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800327}
Marc Zyngierf2caa512012-01-19 13:53:50 +0000328
329int __init arch_timer_register(struct arch_timer *at)
330{
331 if (at->res[0].start <= 0 || !(at->res[0].flags & IORESOURCE_IRQ))
332 return -EINVAL;
333
334 arch_timer_ppi = at->res[0].start;
335
336 if (at->res[1].start > 0 && (at->res[1].flags & IORESOURCE_IRQ))
337 arch_timer_ppi2 = at->res[1].start;
338
339 return arch_timer_common_register();
340}
341
342#ifdef CONFIG_OF
343static const struct of_device_id arch_timer_of_match[] __initconst = {
344 { .compatible = "arm,armv7-timer", },
345 {},
346};
347
348int __init arch_timer_of_register(void)
349{
350 struct device_node *np;
351 u32 freq;
352 int ret;
353
354 np = of_find_matching_node(NULL, arch_timer_of_match);
355 if (!np) {
356 pr_err("arch_timer: can't find DT node\n");
357 return -ENODEV;
358 }
359
360 /* Try to determine the frequency from the device tree or CNTFRQ */
361 if (!of_property_read_u32(np, "clock-frequency", &freq))
362 arch_timer_rate = freq;
363
364 ret = irq_of_parse_and_map(np, 0);
365 if (ret <= 0) {
366 pr_err("arch_timer: interrupt not specified in timer node\n");
367 return -ENODEV;
368 }
369 arch_timer_ppi = ret;
370 ret = irq_of_parse_and_map(np, 1);
371 if (ret > 0)
372 arch_timer_ppi2 = ret;
373 pr_info("arch_timer: found %s irqs %d %d\n",
374 np->name, arch_timer_ppi, arch_timer_ppi2);
375
376 return arch_timer_common_register();
377}
378#endif