1 // SPDX-License-Identifier: GPL-2.0
3 * Starfive Timer driver
5 * Copyright 2021 StarFive, Inc. All rights reserved.
9 #include <linux/clocksource.h>
10 #include <linux/clockchips.h>
11 #include <linux/err.h>
12 #include <linux/kernel.h>
13 #include <linux/interrupt.h>
14 #include <linux/irq.h>
16 #include <linux/iopoll.h>
18 #include <linux/of_address.h>
19 #include <linux/of_clk.h>
20 #include <linux/of_irq.h>
21 #include <linux/sched_clock.h>
22 #include <linux/module.h>
23 #include <linux/reset.h>
24 #include "timer-starfive.h"
26 #define CLOCK_SOURCE_RATE 200
29 #define TIMEOUT_US 10000
30 #define CLOCKEVENT_RATING 300
31 #define MAX_TICKS 0xffffffff
34 struct starfive_timer __initdata jh7110_starfive_timer = {
35 .ctrl = STF_TIMER_CTL,
36 .load = STF_TIMER_LOAD,
37 .enable = STF_TIMER_ENABLE,
38 .reload = STF_TIMER_RELOAD,
39 .value = STF_TIMER_VALUE,
40 .intclr = STF_TIMER_INT_CLR,
41 .intmask = STF_TIMER_INT_MASK,
42 .timer_base = {TIMER_BASE(0), TIMER_BASE(1), TIMER_BASE(2),
43 TIMER_BASE(3), TIMER_BASE(4), TIMER_BASE(5),
44 TIMER_BASE(6), TIMER_BASE(7)},
47 static inline struct starfive_clkevt *
48 to_starfive_clkevt(struct clock_event_device *evt)
50 return container_of(evt, struct starfive_clkevt, evt);
53 static inline void timer_set_mod(struct starfive_clkevt *clkevt, int mod)
55 writel(mod, clkevt->ctrl);
59 * After disable timer, then enable, the timer will start
60 * from the reload count value(0x08[31:0]).
62 static inline void timer_int_enable(struct starfive_clkevt *clkevt)
64 writel(INTMASK_ENABLE_DIS, clkevt->intmask);
67 static inline void timer_int_disable(struct starfive_clkevt *clkevt)
69 writel(INTMASK_ENABLE, clkevt->intmask);
72 static inline void timer_int_clear(struct starfive_clkevt *clkevt)
74 /* waiting interrupt can be to clearing */
78 value = readl(clkevt->intclr);
79 ret = readl_poll_timeout_atomic(clkevt->intclr, value,
80 !(value & INT_STATUS_CLR_AVA), DELAY_US, TIMEOUT_US);
82 writel(1, clkevt->intclr);
86 * The initial value to be loaded into the
87 * counter and is also used as the reload value.
89 static inline void timer_set_val(struct starfive_clkevt *clkevt, u32 val)
91 writel(val, clkevt->load);
94 static inline u32 timer_get_val(struct starfive_clkevt *clkevt)
96 return readl(clkevt->value);
100 * Write RELOAD register to reload preset value to counter.
101 * (Write 0 and write 1 are both ok)
104 timer_set_reload(struct starfive_clkevt *clkevt)
106 writel(1, clkevt->reload);
109 static inline void timer_enable(struct starfive_clkevt *clkevt)
111 writel(TIMER_ENA, clkevt->enable);
114 static inline void timer_disable(struct starfive_clkevt *clkevt)
116 writel(TIMER_ENA_DIS, clkevt->enable);
119 static void timer_shutdown(struct starfive_clkevt *clkevt)
121 timer_int_disable(clkevt);
122 timer_disable(clkevt);
123 timer_int_clear(clkevt);
126 static void starfive_timer_suspend(struct clock_event_device *evt)
128 struct starfive_clkevt *clkevt;
130 clkevt = to_starfive_clkevt(evt);
132 clkevt->reload_val = timer_get_val(clkevt);
134 timer_disable(clkevt);
135 timer_int_disable(clkevt);
136 timer_int_clear(clkevt);
139 static void starfive_timer_resume(struct clock_event_device *evt)
141 struct starfive_clkevt *clkevt;
143 clkevt = to_starfive_clkevt(evt);
144 timer_set_val(clkevt, clkevt->reload_val);
145 timer_set_reload(clkevt);
146 timer_int_enable(clkevt);
147 timer_enable(clkevt);
150 static int starfive_timer_tick_resume(struct clock_event_device *evt)
152 starfive_timer_resume(evt);
157 static int starfive_timer_shutdown(struct clock_event_device *evt)
159 struct starfive_clkevt *clkevt;
161 clkevt = to_starfive_clkevt(evt);
162 timer_shutdown(clkevt);
168 starfive_get_clock_rate(struct starfive_clkevt *clkevt, struct device_node *np)
174 clkevt->rate = clk_get_rate(clkevt->clk);
175 if (clkevt->rate > 0) {
176 pr_debug("clk_get_rate clkevt->rate: %lld\n",
182 /* Next we try to get clock-frequency from dts.*/
183 ret = of_property_read_u32(np, "clock-frequency", &rate);
185 pr_debug("Timer: try get clock-frequency:%d MHz\n", rate);
186 clkevt->rate = (u64)rate;
189 pr_err("Timer: get rate failed, need clock-frequency define in dts.\n");
194 static int starfive_clocksource_init(struct starfive_clkevt *clkevt,
195 const char *name, struct device_node *np)
197 timer_set_mod(clkevt, MOD_CONTIN);
198 timer_set_val(clkevt, MAX_TICKS); /* val = rate --> 1s */
199 timer_int_disable(clkevt);
200 timer_int_clear(clkevt);
201 timer_int_enable(clkevt);
202 timer_enable(clkevt);
204 clocksource_mmio_init(clkevt->value, name, clkevt->rate,
205 CLOCK_SOURCE_RATE, VALID_BITS,
206 clocksource_mmio_readl_down);
212 * IRQ handler for the timer
214 static irqreturn_t starfive_timer_interrupt(int irq, void *priv)
216 struct clock_event_device *evt = (struct clock_event_device *)priv;
217 struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
219 timer_int_clear(clkevt);
221 if (evt->event_handler)
222 evt->event_handler(evt);
227 static int starfive_timer_set_periodic(struct clock_event_device *evt)
229 struct starfive_clkevt *clkevt;
231 clkevt = to_starfive_clkevt(evt);
233 timer_disable(clkevt);
234 timer_set_mod(clkevt, MOD_CONTIN);
235 timer_set_val(clkevt, clkevt->periodic);
236 timer_int_disable(clkevt);
237 timer_int_clear(clkevt);
238 timer_int_enable(clkevt);
239 timer_enable(clkevt);
244 static int starfive_timer_set_oneshot(struct clock_event_device *evt)
246 struct starfive_clkevt *clkevt;
248 clkevt = to_starfive_clkevt(evt);
250 timer_disable(clkevt);
251 timer_set_mod(clkevt, MOD_SINGLE);
252 timer_set_val(clkevt, MAX_TICKS);
253 timer_int_disable(clkevt);
254 timer_int_clear(clkevt);
255 timer_int_enable(clkevt);
256 timer_enable(clkevt);
261 static int starfive_timer_set_next_event(unsigned long next,
262 struct clock_event_device *evt)
264 struct starfive_clkevt *clkevt;
266 clkevt = to_starfive_clkevt(evt);
268 timer_disable(clkevt);
269 timer_set_mod(clkevt, MOD_SINGLE);
270 timer_set_val(clkevt, next);
271 timer_enable(clkevt);
276 static void starfive_set_clockevent(struct clock_event_device *evt)
278 evt->features = CLOCK_EVT_FEAT_PERIODIC |
279 CLOCK_EVT_FEAT_ONESHOT |
280 CLOCK_EVT_FEAT_DYNIRQ;
281 evt->set_state_shutdown = starfive_timer_shutdown;
282 evt->set_state_periodic = starfive_timer_set_periodic;
283 evt->set_state_oneshot = starfive_timer_set_oneshot;
284 evt->set_state_oneshot_stopped = starfive_timer_shutdown;
285 evt->tick_resume = starfive_timer_tick_resume;
286 evt->set_next_event = starfive_timer_set_next_event;
287 evt->suspend = starfive_timer_suspend;
288 evt->resume = starfive_timer_resume;
289 evt->rating = CLOCKEVENT_RATING;
292 static int starfive_clockevents_register(struct starfive_clkevt *clkevt, unsigned int irq,
293 struct device_node *np, const char *name)
297 ret = starfive_get_clock_rate(clkevt, np);
301 clkevt->periodic = DIV_ROUND_CLOSEST(clkevt->rate, HZ);
303 starfive_set_clockevent(&clkevt->evt);
304 clkevt->evt.name = name;
305 clkevt->evt.irq = irq;
306 clkevt->evt.cpumask = cpu_possible_mask;
308 ret = request_irq(irq, starfive_timer_interrupt,
309 IRQF_TIMER | IRQF_IRQPOLL, name, &clkevt->evt);
311 pr_err("%s: request_irq failed\n", name);
313 clockevents_config_and_register(&clkevt->evt, clkevt->rate,
314 MIN_TICKS, MAX_TICKS);
319 static void __init starfive_clkevt_init(struct starfive_timer *timer,
320 struct starfive_clkevt *clkevt,
321 void __iomem *base, int index)
323 void __iomem *timer_base;
325 timer_base = base + timer->timer_base[index];
326 clkevt->base = timer_base;
327 clkevt->ctrl = timer_base + timer->ctrl;
328 clkevt->load = timer_base + timer->load;
329 clkevt->enable = timer_base + timer->enable;
330 clkevt->reload = timer_base + timer->reload;
331 clkevt->value = timer_base + timer->value;
332 clkevt->intclr = timer_base + timer->intclr;
333 clkevt->intmask = timer_base + timer->intmask;
336 static int __init do_starfive_timer_of_init(struct device_node *np,
337 struct starfive_timer *timer)
339 int index, count, irq, ret = -EINVAL;
340 const char *name = NULL;
343 struct reset_control *prst;
344 struct reset_control *rst;
345 struct starfive_clkevt *clkevt;
348 base = of_iomap(np, 0);
352 if (!of_device_is_available(np)) {
357 pclk = of_clk_get_by_name(np, "apb_clk");
359 if (clk_prepare_enable(pclk))
360 pr_warn("pclk for %pOFn is present,"
361 "but could not be activated\n", np);
363 prst = of_reset_control_get(np, "apb_rst");
365 reset_control_assert(prst);
366 reset_control_deassert(prst);
369 count = of_irq_count(np);
370 if (count > NR_TIMERS || count <= 0) {
375 for (index = 0; index < count; index++) {
376 /* one of timer is wdog-timer, skip...*/
377 of_property_read_string_index(np, "clock-names", index, &name);
378 if (strncmp(name, "timer", strlen("timer")))
381 clkevt = kzalloc(sizeof(*clkevt), GFP_KERNEL);
387 starfive_clkevt_init(timer, clkevt, base, index);
389 /* Ensure timers are disabled */
390 timer_disable(clkevt);
392 clk = of_clk_get_by_name(np, name);
395 if (clk_prepare_enable(clk))
396 pr_warn("clk for %pOFn is present,"
397 "but could not be activated\n", np);
400 rst = of_reset_control_get(np, name);
402 reset_control_assert(rst);
403 reset_control_deassert(rst);
406 irq = irq_of_parse_and_map(np, index);
412 snprintf(clkevt->name, sizeof(clkevt->name), "%s.ch%d",
413 np->full_name, index);
415 ret = starfive_clockevents_register(clkevt, irq, np, clkevt->name);
417 pr_err("%s: init clockevents failed.\n", clkevt->name);
422 ret = starfive_clocksource_init(clkevt, clkevt->name, np);
433 free_irq(clkevt->irq, &clkevt->evt);
436 reset_control_assert(rst);
437 reset_control_put(rst);
440 clk_disable_unprepare(clkevt->clk);
441 clk_put(clkevt->clk);
448 clk_disable_unprepare(pclk);
456 static int __init starfive_timer_of_init(struct device_node *np)
458 return do_starfive_timer_of_init(np, &jh7110_starfive_timer);
460 TIMER_OF_DECLARE(starfive_timer, "starfive,jh7110-timers", starfive_timer_of_init);
462 MODULE_AUTHOR("xingyu.wu <xingyu.wu@starfivetech.com>");
463 MODULE_AUTHOR("samin.guo <samin.guo@starfivetech.com>");
464 MODULE_DESCRIPTION("StarFive Timer Device Driver");
465 MODULE_LICENSE("GPL v2");