blob: 8c5b581dfe7f2c7ea51c7f0b03d982ffccc718d5 [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>
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080029
30static unsigned long arch_timer_rate;
31static int arch_timer_ppi;
32static int arch_timer_ppi2;
Marc Zyngier165a4742011-11-11 14:30:44 -080033static DEFINE_CLOCK_DATA(cd);
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080034
Marc Zyngierdf590cc2012-01-11 17:25:17 +000035static struct clock_event_device __percpu **arch_timer_evt;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080036
37/*
38 * Architected system timer support.
39 */
40
41#define ARCH_TIMER_CTRL_ENABLE (1 << 0)
42#define ARCH_TIMER_CTRL_IT_MASK (1 << 1)
Marc Zyngierdf590cc2012-01-11 17:25:17 +000043#define ARCH_TIMER_CTRL_IT_STAT (1 << 2)
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080044
45#define ARCH_TIMER_REG_CTRL 0
46#define ARCH_TIMER_REG_FREQ 1
47#define ARCH_TIMER_REG_TVAL 2
48
49static void arch_timer_reg_write(int reg, u32 val)
50{
51 switch (reg) {
52 case ARCH_TIMER_REG_CTRL:
53 asm volatile("mcr p15, 0, %0, c14, c2, 1" : : "r" (val));
54 break;
55 case ARCH_TIMER_REG_TVAL:
56 asm volatile("mcr p15, 0, %0, c14, c2, 0" : : "r" (val));
57 break;
58 }
59
60 isb();
61}
62
63static u32 arch_timer_reg_read(int reg)
64{
65 u32 val;
66
67 switch (reg) {
68 case ARCH_TIMER_REG_CTRL:
69 asm volatile("mrc p15, 0, %0, c14, c2, 1" : "=r" (val));
70 break;
71 case ARCH_TIMER_REG_FREQ:
72 asm volatile("mrc p15, 0, %0, c14, c0, 0" : "=r" (val));
73 break;
74 case ARCH_TIMER_REG_TVAL:
75 asm volatile("mrc p15, 0, %0, c14, c2, 0" : "=r" (val));
76 break;
77 default:
78 BUG();
79 }
80
81 return val;
82}
83
84static irqreturn_t arch_timer_handler(int irq, void *dev_id)
85{
Sathish Ambley8a309822011-11-07 14:49:08 -080086 struct clock_event_device *evt;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080087 unsigned long ctrl;
88
89 ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
Marc Zyngierdf590cc2012-01-11 17:25:17 +000090 if (ctrl & ARCH_TIMER_CTRL_IT_STAT) {
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080091 ctrl |= ARCH_TIMER_CTRL_IT_MASK;
92 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
Marc Zyngierdf590cc2012-01-11 17:25:17 +000093 evt = *__this_cpu_ptr(arch_timer_evt);
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -080094 evt->event_handler(evt);
95 return IRQ_HANDLED;
96 }
97
98 return IRQ_NONE;
99}
100
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000101static void arch_timer_disable(void)
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800102{
103 unsigned long ctrl;
104
105 ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
106 ctrl &= ~ARCH_TIMER_CTRL_ENABLE;
107 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
108}
109
110static void arch_timer_set_mode(enum clock_event_mode mode,
111 struct clock_event_device *clk)
112{
113 switch (mode) {
114 case CLOCK_EVT_MODE_UNUSED:
115 case CLOCK_EVT_MODE_SHUTDOWN:
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000116 arch_timer_disable();
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800117 break;
118 default:
119 break;
120 }
121}
122
123static int arch_timer_set_next_event(unsigned long evt,
124 struct clock_event_device *unused)
125{
126 unsigned long ctrl;
127
128 ctrl = arch_timer_reg_read(ARCH_TIMER_REG_CTRL);
129 ctrl |= ARCH_TIMER_CTRL_ENABLE;
130 ctrl &= ~ARCH_TIMER_CTRL_IT_MASK;
131
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800132 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, ctrl);
Sathish Ambley9c642ec2011-12-02 10:50:58 -0800133 arch_timer_reg_write(ARCH_TIMER_REG_TVAL, evt);
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800134
135 return 0;
136}
137
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000138static int __cpuinit arch_timer_setup(struct clock_event_device *clk)
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800139{
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000140 /* setup clock event only once for CPU 0 */
141 if (!smp_processor_id() && clk->irq == arch_timer_ppi)
142 return 0;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800143
144 /* Be safe... */
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000145 arch_timer_disable();
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800146
147 clk->features = CLOCK_EVT_FEAT_ONESHOT;
148 clk->name = "arch_sys_timer";
149 clk->rating = 450;
150 clk->set_mode = arch_timer_set_mode;
151 clk->set_next_event = arch_timer_set_next_event;
152 clk->irq = arch_timer_ppi;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800153
154 clockevents_config_and_register(clk, arch_timer_rate,
155 0xf, 0x7fffffff);
156
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000157 *__this_cpu_ptr(arch_timer_evt) = clk;
158
159 enable_percpu_irq(clk->irq, 0);
160 if (arch_timer_ppi2)
Trilok Sonieecb28c2011-07-20 16:24:14 +0100161 enable_percpu_irq(arch_timer_ppi2, 0);
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000162
163 return 0;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800164}
165
166/* Is the optional system timer available? */
167static int local_timer_is_architected(void)
168{
169 return (cpu_architecture() >= CPU_ARCH_ARMv7) &&
170 ((read_cpuid_ext(CPUID_EXT_PFR1) >> 16) & 0xf) == 1;
171}
172
173static int arch_timer_available(void)
174{
175 unsigned long freq;
176
177 if (!local_timer_is_architected())
178 return -ENXIO;
179
180 if (arch_timer_rate == 0) {
181 arch_timer_reg_write(ARCH_TIMER_REG_CTRL, 0);
182 freq = arch_timer_reg_read(ARCH_TIMER_REG_FREQ);
183
184 /* Check the timer frequency. */
185 if (freq == 0) {
186 pr_warn("Architected timer frequency not available\n");
187 return -EINVAL;
188 }
189
190 arch_timer_rate = freq;
191 pr_info("Architected local timer running at %lu.%02luMHz.\n",
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000192 freq / 1000000, (freq / 10000) % 100);
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800193 }
194
195 return 0;
196}
197
198static inline cycle_t arch_counter_get_cntpct(void)
199{
200 u32 cvall, cvalh;
201
202 asm volatile("mrrc p15, 0, %0, %1, c14" : "=r" (cvall), "=r" (cvalh));
203
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000204 return ((cycle_t) cvalh << 32) | cvall;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800205}
206
207static inline cycle_t arch_counter_get_cntvct(void)
208{
209 u32 cvall, cvalh;
210
211 asm volatile("mrrc p15, 1, %0, %1, c14" : "=r" (cvall), "=r" (cvalh));
212
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000213 return ((cycle_t) cvalh << 32) | cvall;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800214}
215
216static cycle_t arch_counter_read(struct clocksource *cs)
217{
218 return arch_counter_get_cntpct();
219}
220
Sathish Ambley8a309822011-11-07 14:49:08 -0800221#ifdef ARCH_HAS_READ_CURRENT_TIMER
222int read_current_timer(unsigned long *timer_val)
223{
224 *timer_val = (unsigned long)arch_counter_get_cntpct();
225 return 0;
226}
227#endif
228
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800229static struct clocksource clocksource_counter = {
230 .name = "arch_sys_counter",
231 .rating = 400,
232 .read = arch_counter_read,
233 .mask = CLOCKSOURCE_MASK(56),
234 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
235};
236
Marc Zyngier165a4742011-11-11 14:30:44 -0800237static u32 arch_counter_get_cntvct32(void)
238{
239 cycle_t cntvct;
240
241 cntvct = arch_counter_get_cntvct();
242
243 /*
244 * The sched_clock infrastructure only knows about counters
245 * with at most 32bits. Forget about the upper 24 bits for the
246 * time being...
247 */
248 return (u32)(cntvct & (u32)~0);
249}
250
Sathish Ambley8a309822011-11-07 14:49:08 -0800251unsigned long long notrace sched_clock(void)
Marc Zyngier165a4742011-11-11 14:30:44 -0800252{
253 return cyc_to_sched_clock(&cd, arch_counter_get_cntvct32(), (u32)~0);
254}
255
256static void notrace arch_timer_update_sched_clock(void)
257{
258 update_sched_clock(&cd, arch_counter_get_cntvct32(), (u32)~0);
259}
260
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000261static void __cpuinit arch_timer_stop(struct clock_event_device *clk)
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800262{
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800263 pr_debug("arch_timer_teardown disable IRQ%d cpu #%d\n",
264 clk->irq, smp_processor_id());
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000265 disable_percpu_irq(clk->irq);
266 if (arch_timer_ppi2)
Trilok Sonieecb28c2011-07-20 16:24:14 +0100267 disable_percpu_irq(arch_timer_ppi2);
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800268 arch_timer_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
269}
270
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000271static struct local_timer_ops arch_timer_ops __cpuinitdata = {
272 .setup = arch_timer_setup,
273 .stop = arch_timer_stop,
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800274};
275
Marc Zyngierf2caa512012-01-19 13:53:50 +0000276static int __init arch_timer_common_register(void)
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800277{
278 int err;
279
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800280 err = arch_timer_available();
281 if (err)
282 return err;
283
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000284 arch_timer_evt = alloc_percpu(struct clock_event_device *);
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800285 if (!arch_timer_evt)
286 return -ENOMEM;
287
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800288 clocksource_register_hz(&clocksource_counter, arch_timer_rate);
289
Sathish Ambley8a309822011-11-07 14:49:08 -0800290 init_sched_clock(&cd, arch_timer_update_sched_clock, 32,
291 arch_timer_rate);
292
293#ifdef ARCH_HAS_READ_CURRENT_TIMER
294 set_delay_fn(read_current_timer_delay_loop);
295#endif
296
Trilok Sonieecb28c2011-07-20 16:24:14 +0100297 err = request_percpu_irq(arch_timer_ppi, arch_timer_handler,
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000298 "arch_timer", arch_timer_evt);
Sathish Ambley8a309822011-11-07 14:49:08 -0800299 if (err) {
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000300 pr_err("arch_timer: can't register interrupt %d (%d)\n",
301 arch_timer_ppi, err);
302 goto out_free;
Sathish Ambley8a309822011-11-07 14:49:08 -0800303 }
304
Marc Zyngierf2caa512012-01-19 13:53:50 +0000305 if (arch_timer_ppi2) {
Trilok Sonieecb28c2011-07-20 16:24:14 +0100306 err = request_percpu_irq(arch_timer_ppi2, arch_timer_handler,
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000307 "arch_timer", arch_timer_evt);
308 if (err) {
309 pr_err("arch_timer: can't register interrupt %d (%d)\n",
310 arch_timer_ppi2, err);
311 arch_timer_ppi2 = 0;
312 goto out_free_irq;
313 }
Sathish Ambley8a309822011-11-07 14:49:08 -0800314 }
Marc Zyngier165a4742011-11-11 14:30:44 -0800315
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000316 err = local_timer_register(&arch_timer_ops);
317 if (err)
318 goto out_free_irq;
319 percpu_timer_setup();
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800320
321 return 0;
Marc Zyngierdf590cc2012-01-11 17:25:17 +0000322
323out_free_irq:
324 free_percpu_irq(arch_timer_ppi, arch_timer_evt);
325 if (arch_timer_ppi2)
326 free_percpu_irq(arch_timer_ppi2, arch_timer_evt);
327
328out_free:
329 free_percpu(arch_timer_evt);
330
331 return err;
Marc Zyngierf5b3b2b2011-11-07 14:28:33 -0800332}
Marc Zyngierf2caa512012-01-19 13:53:50 +0000333
334int __init arch_timer_register(struct arch_timer *at)
335{
336 if (at->res[0].start <= 0 || !(at->res[0].flags & IORESOURCE_IRQ))
337 return -EINVAL;
338
339 arch_timer_ppi = at->res[0].start;
340
341 if (at->res[1].start > 0 && (at->res[1].flags & IORESOURCE_IRQ))
342 arch_timer_ppi2 = at->res[1].start;
343
344 return arch_timer_common_register();
345}
346
347#ifdef CONFIG_OF
348static const struct of_device_id arch_timer_of_match[] __initconst = {
349 { .compatible = "arm,armv7-timer", },
350 {},
351};
352
353int __init arch_timer_of_register(void)
354{
355 struct device_node *np;
356 u32 freq;
357 int ret;
358
359 np = of_find_matching_node(NULL, arch_timer_of_match);
360 if (!np) {
361 pr_err("arch_timer: can't find DT node\n");
362 return -ENODEV;
363 }
364
365 /* Try to determine the frequency from the device tree or CNTFRQ */
366 if (!of_property_read_u32(np, "clock-frequency", &freq))
367 arch_timer_rate = freq;
368
369 ret = irq_of_parse_and_map(np, 0);
370 if (ret <= 0) {
371 pr_err("arch_timer: interrupt not specified in timer node\n");
372 return -ENODEV;
373 }
374 arch_timer_ppi = ret;
375 ret = irq_of_parse_and_map(np, 1);
376 if (ret > 0)
377 arch_timer_ppi2 = ret;
378 pr_info("arch_timer: found %s irqs %d %d\n",
379 np->name, arch_timer_ppi, arch_timer_ppi2);
380
381 return arch_timer_common_register();
382}
383#endif