2 * System timer for CSR SiRFprimaII
4 * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company.
6 * Licensed under GPLv2 or later.
9 #include <linux/kernel.h>
10 #include <linux/interrupt.h>
11 #include <linux/clockchips.h>
12 #include <linux/clocksource.h>
13 #include <linux/bitops.h>
14 #include <linux/irq.h>
15 #include <linux/clk.h>
16 #include <linux/slab.h>
18 #include <linux/of_irq.h>
19 #include <linux/of_address.h>
20 #include <asm/sched_clock.h>
21 #include <asm/localtimer.h>
22 #include <asm/mach/time.h>
26 #define SIRFSOC_TIMER_32COUNTER_0_CTRL 0x0000
27 #define SIRFSOC_TIMER_32COUNTER_1_CTRL 0x0004
28 #define SIRFSOC_TIMER_MATCH_0 0x0018
29 #define SIRFSOC_TIMER_MATCH_1 0x001c
30 #define SIRFSOC_TIMER_COUNTER_0 0x0048
31 #define SIRFSOC_TIMER_COUNTER_1 0x004c
32 #define SIRFSOC_TIMER_INTR_STATUS 0x0060
33 #define SIRFSOC_TIMER_WATCHDOG_EN 0x0064
34 #define SIRFSOC_TIMER_64COUNTER_CTRL 0x0068
35 #define SIRFSOC_TIMER_64COUNTER_LO 0x006c
36 #define SIRFSOC_TIMER_64COUNTER_HI 0x0070
37 #define SIRFSOC_TIMER_64COUNTER_LOAD_LO 0x0074
38 #define SIRFSOC_TIMER_64COUNTER_LOAD_HI 0x0078
39 #define SIRFSOC_TIMER_64COUNTER_RLATCHED_LO 0x007c
40 #define SIRFSOC_TIMER_64COUNTER_RLATCHED_HI 0x0080
42 #define SIRFSOC_TIMER_REG_CNT 6
44 static const u32 sirfsoc_timer_reg_list[SIRFSOC_TIMER_REG_CNT] = {
45 SIRFSOC_TIMER_WATCHDOG_EN,
46 SIRFSOC_TIMER_32COUNTER_0_CTRL,
47 SIRFSOC_TIMER_32COUNTER_1_CTRL,
48 SIRFSOC_TIMER_64COUNTER_CTRL,
49 SIRFSOC_TIMER_64COUNTER_RLATCHED_LO,
50 SIRFSOC_TIMER_64COUNTER_RLATCHED_HI,
53 static u32 sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT];
55 static void __iomem *sirfsoc_timer_base;
56 static void __init sirfsoc_of_timer_map(void);
58 /* disable count and interrupt */
59 static inline void sirfsoc_timer_count_disable(int idx)
61 writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx) & ~0x7,
62 sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx);
65 /* enable count and interrupt */
66 static inline void sirfsoc_timer_count_enable(int idx)
68 writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx) | 0x7,
69 sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL + 4 * idx);
72 /* timer interrupt handler */
73 static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id)
75 struct clock_event_device *ce = dev_id;
76 int cpu = smp_processor_id();
78 /* clear timer interrupt */
79 writel_relaxed(BIT(cpu), sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS);
81 if (ce->mode == CLOCK_EVT_MODE_ONESHOT)
82 sirfsoc_timer_count_disable(cpu);
84 ce->event_handler(ce);
89 /* read 64-bit timer counter */
90 static cycle_t sirfsoc_timer_read(struct clocksource *cs)
94 writel_relaxed((readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL) |
95 BIT(0)) & ~BIT(1), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
97 cycles = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_RLATCHED_HI);
98 cycles = (cycles << 32) | readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_RLATCHED_LO);
103 static int sirfsoc_timer_set_next_event(unsigned long delta,
104 struct clock_event_device *ce)
106 int cpu = smp_processor_id();
108 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_0 +
110 writel_relaxed(delta, sirfsoc_timer_base + SIRFSOC_TIMER_MATCH_0 +
113 /* enable the tick */
114 sirfsoc_timer_count_enable(cpu);
119 static void sirfsoc_timer_set_mode(enum clock_event_mode mode,
120 struct clock_event_device *ce)
123 case CLOCK_EVT_MODE_ONESHOT:
124 /* enable in set_next_event */
130 sirfsoc_timer_count_disable(smp_processor_id());
133 static void sirfsoc_clocksource_suspend(struct clocksource *cs)
137 for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++)
138 sirfsoc_timer_reg_val[i] = readl_relaxed(sirfsoc_timer_base + sirfsoc_timer_reg_list[i]);
141 static void sirfsoc_clocksource_resume(struct clocksource *cs)
145 for (i = 0; i < SIRFSOC_TIMER_REG_CNT - 2; i++)
146 writel_relaxed(sirfsoc_timer_reg_val[i], sirfsoc_timer_base + sirfsoc_timer_reg_list[i]);
148 writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 2],
149 sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO);
150 writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 1],
151 sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_HI);
153 writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL) |
154 BIT(1) | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
157 static struct clock_event_device sirfsoc_clockevent = {
158 .name = "sirfsoc_clockevent",
160 .features = CLOCK_EVT_FEAT_ONESHOT,
161 .set_mode = sirfsoc_timer_set_mode,
162 .set_next_event = sirfsoc_timer_set_next_event,
165 static struct clocksource sirfsoc_clocksource = {
166 .name = "sirfsoc_clocksource",
168 .mask = CLOCKSOURCE_MASK(64),
169 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
170 .read = sirfsoc_timer_read,
171 .suspend = sirfsoc_clocksource_suspend,
172 .resume = sirfsoc_clocksource_resume,
175 static struct irqaction sirfsoc_timer_irq = {
176 .name = "sirfsoc_timer0",
177 .flags = IRQF_TIMER | IRQF_NOBALANCING,
178 .handler = sirfsoc_timer_interrupt,
179 .dev_id = &sirfsoc_clockevent,
182 #ifdef CONFIG_LOCAL_TIMERS
184 static struct irqaction sirfsoc_timer1_irq = {
185 .name = "sirfsoc_timer1",
186 .flags = IRQF_TIMER | IRQF_NOBALANCING,
187 .handler = sirfsoc_timer_interrupt,
190 static int __cpuinit sirfsoc_local_timer_setup(struct clock_event_device *ce)
192 /* Use existing clock_event for cpu 0 */
193 if (!smp_processor_id())
196 ce->irq = sirfsoc_timer1_irq.irq;
197 ce->name = "local_timer";
198 ce->features = sirfsoc_clockevent.features;
199 ce->rating = sirfsoc_clockevent.rating;
200 ce->set_mode = sirfsoc_timer_set_mode;
201 ce->set_next_event = sirfsoc_timer_set_next_event;
202 ce->shift = sirfsoc_clockevent.shift;
203 ce->mult = sirfsoc_clockevent.mult;
204 ce->max_delta_ns = sirfsoc_clockevent.max_delta_ns;
205 ce->min_delta_ns = sirfsoc_clockevent.min_delta_ns;
207 sirfsoc_timer1_irq.dev_id = ce;
208 BUG_ON(setup_irq(ce->irq, &sirfsoc_timer1_irq));
209 irq_set_affinity(sirfsoc_timer1_irq.irq, cpumask_of(1));
211 clockevents_register_device(ce);
215 static void sirfsoc_local_timer_stop(struct clock_event_device *ce)
217 sirfsoc_timer_count_disable(1);
219 remove_irq(sirfsoc_timer1_irq.irq, &sirfsoc_timer1_irq);
222 static struct local_timer_ops sirfsoc_local_timer_ops __cpuinitdata = {
223 .setup = sirfsoc_local_timer_setup,
224 .stop = sirfsoc_local_timer_stop,
226 #endif /* CONFIG_LOCAL_TIMERS */
228 static void __init sirfsoc_clockevent_init(void)
230 clockevents_calc_mult_shift(&sirfsoc_clockevent, CLOCK_TICK_RATE, 60);
232 sirfsoc_clockevent.max_delta_ns =
233 clockevent_delta2ns(-2, &sirfsoc_clockevent);
234 sirfsoc_clockevent.min_delta_ns =
235 clockevent_delta2ns(2, &sirfsoc_clockevent);
237 sirfsoc_clockevent.cpumask = cpumask_of(0);
238 clockevents_register_device(&sirfsoc_clockevent);
239 #ifdef CONFIG_LOCAL_TIMERS
240 local_timer_register(&sirfsoc_local_timer_ops);
244 /* initialize the kernel jiffy timer source */
245 void __init sirfsoc_marco_timer_init(void)
251 /* initialize clocking early, we want to set the OS timer */
252 sirfsoc_of_clk_init();
254 /* timer's input clock is io clock */
255 clk = clk_get_sys("io", NULL);
258 rate = clk_get_rate(clk);
260 BUG_ON(rate < CLOCK_TICK_RATE);
261 BUG_ON(rate % CLOCK_TICK_RATE);
263 sirfsoc_of_timer_map();
265 /* Initialize the timer dividers */
266 timer_div = rate / CLOCK_TICK_RATE - 1;
267 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
268 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_0_CTRL);
269 writel_relaxed(timer_div << 16, sirfsoc_timer_base + SIRFSOC_TIMER_32COUNTER_1_CTRL);
271 /* Initialize timer counters to 0 */
272 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_LO);
273 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_LOAD_HI);
274 writel_relaxed(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL) |
275 BIT(1) | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_64COUNTER_CTRL);
276 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_0);
277 writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_1);
279 /* Clear all interrupts */
280 writel_relaxed(0xFFFF, sirfsoc_timer_base + SIRFSOC_TIMER_INTR_STATUS);
282 BUG_ON(clocksource_register_hz(&sirfsoc_clocksource, CLOCK_TICK_RATE));
284 BUG_ON(setup_irq(sirfsoc_timer_irq.irq, &sirfsoc_timer_irq));
286 sirfsoc_clockevent_init();
289 static struct of_device_id timer_ids[] = {
290 { .compatible = "sirf,marco-tick" },
294 static void __init sirfsoc_of_timer_map(void)
296 struct device_node *np;
298 np = of_find_matching_node(NULL, timer_ids);
301 sirfsoc_timer_base = of_iomap(np, 0);
302 if (!sirfsoc_timer_base)
303 panic("unable to map timer cpu registers\n");
305 sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0);
306 if (!sirfsoc_timer_irq.irq)
307 panic("No irq passed for timer0 via DT\n");
309 #ifdef CONFIG_LOCAL_TIMERS
310 sirfsoc_timer1_irq.irq = irq_of_parse_and_map(np, 1);
311 if (!sirfsoc_timer1_irq.irq)
312 panic("No irq passed for timer1 via DT\n");