ARC: move mcip.h into include/soc and adjust the includes
[linux-2.6-block.git] / arch / arc / kernel / time.c
CommitLineData
d8005e6b
VG
1/*
2 * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.com)
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 *
8 * vineetg: Jan 1011
9 * -sched_clock( ) no longer jiffies based. Uses the same clocksource
10 * as gtod
11 *
12 * Rajeshwarr/Vineetg: Mar 2008
13 * -Implemented CONFIG_GENERIC_TIME (rather deleted arch specific code)
14 * for arch independent gettimeofday()
15 * -Implemented CONFIG_GENERIC_CLOCKEVENTS as base for hrtimers
16 *
17 * Vineetg: Mar 2008: Forked off from time.c which now is time-jiff.c
18 */
19
20/* ARC700 has two 32bit independent prog Timers: TIMER0 and TIMER1
21 * Each can programmed to go from @count to @limit and optionally
22 * interrupt when that happens.
23 * A write to Control Register clears the Interrupt
24 *
25 * We've designated TIMER0 for events (clockevents)
26 * while TIMER1 for free running (clocksource)
27 *
28 * Newer ARC700 cores have 64bit clk fetching RTSC insn, preferred over TIMER1
565a9b49 29 * which however is currently broken
d8005e6b
VG
30 */
31
d8005e6b 32#include <linux/interrupt.h>
69fbd098
NC
33#include <linux/clk.h>
34#include <linux/clk-provider.h>
d8005e6b
VG
35#include <linux/clocksource.h>
36#include <linux/clockchips.h>
eec3c58e 37#include <linux/cpu.h>
77c8d0d6
VG
38#include <linux/of.h>
39#include <linux/of_irq.h>
d8005e6b
VG
40#include <asm/irq.h>
41#include <asm/arcregs.h>
d8005e6b 42
2d7f5c48 43#include <soc/arc/mcip.h>
72d72880 44
da1677b0
VG
45/* Timer related Aux registers */
46#define ARC_REG_TIMER0_LIMIT 0x23 /* timer 0 limit */
47#define ARC_REG_TIMER0_CTRL 0x22 /* timer 0 control */
48#define ARC_REG_TIMER0_CNT 0x21 /* timer 0 count */
49#define ARC_REG_TIMER1_LIMIT 0x102 /* timer 1 limit */
50#define ARC_REG_TIMER1_CTRL 0x101 /* timer 1 control */
51#define ARC_REG_TIMER1_CNT 0x100 /* timer 1 count */
52
7423cc0c
AB
53#define TIMER_CTRL_IE (1 << 0) /* Interrupt when Count reaches limit */
54#define TIMER_CTRL_NH (1 << 1) /* Count only when CPU NOT halted */
da1677b0 55
d8005e6b
VG
56#define ARC_TIMER_MAX 0xFFFFFFFF
57
77c8d0d6
VG
58static unsigned long arc_timer_freq;
59
60static int noinline arc_get_timer_clk(struct device_node *node)
61{
62 struct clk *clk;
63 int ret;
64
65 clk = of_clk_get(node, 0);
66 if (IS_ERR(clk)) {
67 pr_err("timer missing clk");
68 return PTR_ERR(clk);
69 }
70
71 ret = clk_prepare_enable(clk);
72 if (ret) {
73 pr_err("Couldn't enable parent clk\n");
74 return ret;
75 }
76
77 arc_timer_freq = clk_get_rate(clk);
78
79 return 0;
80}
81
d8005e6b
VG
82/********** Clock Source Device *********/
83
04421420 84#ifdef CONFIG_ARC_TIMERS_64BIT
72d72880 85
e608b53e 86static cycle_t arc_read_gfrc(struct clocksource *cs)
72d72880
VG
87{
88 unsigned long flags;
2cd690ea 89 u32 l, h;
72d72880
VG
90
91 local_irq_save(flags);
92
d584f0fb 93 __mcip_cmd(CMD_GFRC_READ_LO, 0);
2cd690ea 94 l = read_aux_reg(ARC_REG_MCIP_READBACK);
72d72880 95
d584f0fb 96 __mcip_cmd(CMD_GFRC_READ_HI, 0);
2cd690ea 97 h = read_aux_reg(ARC_REG_MCIP_READBACK);
72d72880
VG
98
99 local_irq_restore(flags);
100
2cd690ea 101 return (((cycle_t)h) << 32) | l;
72d72880
VG
102}
103
e608b53e 104static struct clocksource arc_counter_gfrc = {
d584f0fb 105 .name = "ARConnect GFRC",
72d72880 106 .rating = 400,
e608b53e 107 .read = arc_read_gfrc,
72d72880
VG
108 .mask = CLOCKSOURCE_MASK(64),
109 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
110};
111
43d75604 112static int __init arc_cs_setup_gfrc(struct device_node *node)
e608b53e 113{
ec7cb87b 114 struct mcip_bcr mp;
e608b53e
VG
115 int ret;
116
ec7cb87b
VG
117 READ_BCR(ARC_REG_MCIP_BCR, mp);
118 if (!mp.gfrc) {
119 pr_warn("Global-64-bit-Ctr clocksource not detected");
43d75604 120 return -ENXIO;
ec7cb87b 121 }
e608b53e
VG
122
123 ret = arc_get_timer_clk(node);
124 if (ret)
43d75604 125 return ret;
e608b53e 126
43d75604 127 return clocksource_register_hz(&arc_counter_gfrc, arc_timer_freq);
e608b53e 128}
177cf6e5 129CLOCKSOURCE_OF_DECLARE(arc_gfrc, "snps,archs-timer-gfrc", arc_cs_setup_gfrc);
e608b53e 130
aa93e8ef
VG
131#define AUX_RTC_CTRL 0x103
132#define AUX_RTC_LOW 0x104
133#define AUX_RTC_HIGH 0x105
134
e608b53e 135static cycle_t arc_read_rtc(struct clocksource *cs)
aa93e8ef
VG
136{
137 unsigned long status;
2cd690ea 138 u32 l, h;
aa93e8ef 139
922cc171
VG
140 /*
141 * hardware has an internal state machine which tracks readout of
142 * low/high and updates the CTRL.status if
143 * - interrupt/exception taken between the two reads
144 * - high increments after low has been read
145 */
146 do {
2cd690ea
VG
147 l = read_aux_reg(AUX_RTC_LOW);
148 h = read_aux_reg(AUX_RTC_HIGH);
922cc171
VG
149 status = read_aux_reg(AUX_RTC_CTRL);
150 } while (!(status & _BITUL(31)));
aa93e8ef 151
2cd690ea 152 return (((cycle_t)h) << 32) | l;
aa93e8ef
VG
153}
154
e608b53e 155static struct clocksource arc_counter_rtc = {
aa93e8ef
VG
156 .name = "ARCv2 RTC",
157 .rating = 350,
e608b53e 158 .read = arc_read_rtc,
aa93e8ef
VG
159 .mask = CLOCKSOURCE_MASK(64),
160 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
161};
162
43d75604 163static int __init arc_cs_setup_rtc(struct device_node *node)
d8005e6b 164{
ec7cb87b 165 struct bcr_timer timer;
e608b53e
VG
166 int ret;
167
ec7cb87b
VG
168 READ_BCR(ARC_REG_TIMERS_BCR, timer);
169 if (!timer.rtc) {
170 pr_warn("Local-64-bit-Ctr clocksource not detected");
43d75604 171 return -ENXIO;
ec7cb87b 172 }
e608b53e
VG
173
174 /* Local to CPU hence not usable in SMP */
ec7cb87b
VG
175 if (IS_ENABLED(CONFIG_SMP)) {
176 pr_warn("Local-64-bit-Ctr not usable in SMP");
43d75604 177 return -EINVAL;
ec7cb87b 178 }
e608b53e
VG
179
180 ret = arc_get_timer_clk(node);
181 if (ret)
43d75604 182 return ret;
d8005e6b 183
e608b53e
VG
184 write_aux_reg(AUX_RTC_CTRL, 1);
185
43d75604 186 return clocksource_register_hz(&arc_counter_rtc, arc_timer_freq);
d8005e6b 187}
177cf6e5 188CLOCKSOURCE_OF_DECLARE(arc_rtc, "snps,archs-timer-rtc", arc_cs_setup_rtc);
e608b53e
VG
189
190#endif
d8005e6b 191
e608b53e
VG
192/*
193 * 32bit TIMER1 to keep counting monotonically and wraparound
194 */
195
196static cycle_t arc_read_timer1(struct clocksource *cs)
d8005e6b
VG
197{
198 return (cycle_t) read_aux_reg(ARC_REG_TIMER1_CNT);
199}
200
e608b53e 201static struct clocksource arc_counter_timer1 = {
d8005e6b
VG
202 .name = "ARC Timer1",
203 .rating = 300,
e608b53e 204 .read = arc_read_timer1,
d8005e6b
VG
205 .mask = CLOCKSOURCE_MASK(32),
206 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
207};
208
43d75604 209static int __init arc_cs_setup_timer1(struct device_node *node)
e608b53e
VG
210{
211 int ret;
212
213 /* Local to CPU hence not usable in SMP */
214 if (IS_ENABLED(CONFIG_SMP))
43d75604 215 return -EINVAL;
e608b53e
VG
216
217 ret = arc_get_timer_clk(node);
218 if (ret)
43d75604 219 return ret;
e608b53e
VG
220
221 write_aux_reg(ARC_REG_TIMER1_LIMIT, ARC_TIMER_MAX);
222 write_aux_reg(ARC_REG_TIMER1_CNT, 0);
223 write_aux_reg(ARC_REG_TIMER1_CTRL, TIMER_CTRL_NH);
224
43d75604 225 return clocksource_register_hz(&arc_counter_timer1, arc_timer_freq);
e608b53e 226}
aa93e8ef 227
d8005e6b
VG
228/********** Clock Event Device *********/
229
77c8d0d6 230static int arc_timer_irq;
eec3c58e 231
d8005e6b 232/*
c9a98e18 233 * Arm the timer to interrupt after @cycles
d8005e6b
VG
234 * The distinction for oneshot/periodic is done in arc_event_timer_ack() below
235 */
c9a98e18 236static void arc_timer_event_setup(unsigned int cycles)
d8005e6b 237{
c9a98e18 238 write_aux_reg(ARC_REG_TIMER0_LIMIT, cycles);
d8005e6b
VG
239 write_aux_reg(ARC_REG_TIMER0_CNT, 0); /* start from 0 */
240
241 write_aux_reg(ARC_REG_TIMER0_CTRL, TIMER_CTRL_IE | TIMER_CTRL_NH);
242}
243
d8005e6b
VG
244
245static int arc_clkevent_set_next_event(unsigned long delta,
246 struct clock_event_device *dev)
247{
248 arc_timer_event_setup(delta);
249 return 0;
250}
251
aeec6cda 252static int arc_clkevent_set_periodic(struct clock_event_device *dev)
d8005e6b 253{
aeec6cda
VK
254 /*
255 * At X Hz, 1 sec = 1000ms -> X cycles;
256 * 10ms -> X / 100 cycles
257 */
77c8d0d6 258 arc_timer_event_setup(arc_timer_freq / HZ);
aeec6cda 259 return 0;
d8005e6b
VG
260}
261
262static DEFINE_PER_CPU(struct clock_event_device, arc_clockevent_device) = {
aeec6cda
VK
263 .name = "ARC Timer0",
264 .features = CLOCK_EVT_FEAT_ONESHOT |
265 CLOCK_EVT_FEAT_PERIODIC,
266 .rating = 300,
aeec6cda
VK
267 .set_next_event = arc_clkevent_set_next_event,
268 .set_state_periodic = arc_clkevent_set_periodic,
d8005e6b
VG
269};
270
271static irqreturn_t timer_irq_handler(int irq, void *dev_id)
272{
f8b34c3f
VG
273 /*
274 * Note that generic IRQ core could have passed @evt for @dev_id if
275 * irq_set_chip_and_handler() asked for handle_percpu_devid_irq()
276 */
277 struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
aeec6cda 278 int irq_reenable = clockevent_state_periodic(evt);
f8b34c3f
VG
279
280 /*
281 * Any write to CTRL reg ACks the interrupt, we rewrite the
282 * Count when [N]ot [H]alted bit.
283 * And re-arm it if perioid by [I]nterrupt [E]nable bit
284 */
285 write_aux_reg(ARC_REG_TIMER0_CTRL, irq_reenable | TIMER_CTRL_NH);
286
287 evt->event_handler(evt);
d8005e6b 288
d8005e6b
VG
289 return IRQ_HANDLED;
290}
291
ecd8081f
AMG
292
293static int arc_timer_starting_cpu(unsigned int cpu)
eec3c58e
NC
294{
295 struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
296
297 evt->cpumask = cpumask_of(smp_processor_id());
298
ecd8081f
AMG
299 clockevents_config_and_register(evt, arc_timer_freq, 0, ARC_TIMER_MAX);
300 enable_percpu_irq(arc_timer_irq, 0);
301 return 0;
eec3c58e
NC
302}
303
ecd8081f
AMG
304static int arc_timer_dying_cpu(unsigned int cpu)
305{
306 disable_percpu_irq(arc_timer_irq);
307 return 0;
308}
eec3c58e 309
d8005e6b 310/*
eec3c58e 311 * clockevent setup for boot CPU
d8005e6b 312 */
43d75604 313static int __init arc_clockevent_setup(struct device_node *node)
d8005e6b 314{
2d4899f6 315 struct clock_event_device *evt = this_cpu_ptr(&arc_clockevent_device);
eec3c58e 316 int ret;
d8005e6b 317
77c8d0d6 318 arc_timer_irq = irq_of_parse_and_map(node, 0);
43d75604
DL
319 if (arc_timer_irq <= 0) {
320 pr_err("clockevent: missing irq");
321 return -EINVAL;
322 }
77c8d0d6
VG
323
324 ret = arc_get_timer_clk(node);
43d75604
DL
325 if (ret) {
326 pr_err("clockevent: missing clk");
327 return ret;
328 }
77c8d0d6 329
eec3c58e
NC
330 /* Needs apriori irq_set_percpu_devid() done in intc map function */
331 ret = request_percpu_irq(arc_timer_irq, timer_irq_handler,
332 "Timer0 (per-cpu-tick)", evt);
43d75604
DL
333 if (ret) {
334 pr_err("clockevent: unable to request irq\n");
335 return ret;
336 }
56957940 337
ecd8081f
AMG
338 ret = cpuhp_setup_state(CPUHP_AP_ARC_TIMER_STARTING,
339 "AP_ARC_TIMER_STARTING",
340 arc_timer_starting_cpu,
341 arc_timer_dying_cpu);
342 if (ret) {
343 pr_err("Failed to setup hotplug state");
344 return ret;
345 }
43d75604 346 return 0;
d8005e6b 347}
e608b53e 348
43d75604 349static int __init arc_of_timer_init(struct device_node *np)
e608b53e
VG
350{
351 static int init_count = 0;
43d75604 352 int ret;
e608b53e
VG
353
354 if (!init_count) {
355 init_count = 1;
43d75604 356 ret = arc_clockevent_setup(np);
e608b53e 357 } else {
43d75604 358 ret = arc_cs_setup_timer1(np);
e608b53e 359 }
43d75604
DL
360
361 return ret;
e608b53e 362}
177cf6e5 363CLOCKSOURCE_OF_DECLARE(arc_clkevt, "snps,arc-timer", arc_of_timer_init);