drm:verisilicon:hdmi-audio:Adjust when to configure registers
[platform/kernel/linux-starfive.git] / drivers / clocksource / timer-starfive.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Starfive Timer driver
4  *
5  * Copyright 2021 StarFive, Inc. All rights reserved.
6  */
7
8 #include <linux/clk.h>
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>
15 #include <linux/io.h>
16 #include <linux/iopoll.h>
17 #include <linux/of.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"
25
26 #define CLOCK_SOURCE_RATE       200
27 #define VALID_BITS              32
28 #define DELAY_US                0
29 #define TIMEOUT_US              10000
30 #define CLOCKEVENT_RATING       300
31 #define MAX_TICKS               0xffffffff
32 #define MIN_TICKS               0xf
33
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)},
45 };
46
47 static inline struct starfive_clkevt *
48 to_starfive_clkevt(struct clock_event_device *evt)
49 {
50         return container_of(evt, struct starfive_clkevt, evt);
51 }
52
53 static inline void timer_set_mod(struct starfive_clkevt *clkevt, int mod)
54 {
55         writel(mod, clkevt->ctrl);
56 }
57
58 /*
59  * After disable timer, then enable, the timer will start
60  * from the reload count value(0x08[31:0]).
61  */
62 static inline void timer_int_enable(struct starfive_clkevt *clkevt)
63 {
64         writel(INTMASK_ENABLE_DIS, clkevt->intmask);
65 }
66
67 static inline void timer_int_disable(struct starfive_clkevt *clkevt)
68 {
69         writel(INTMASK_ENABLE, clkevt->intmask);
70 }
71
72 static inline void timer_int_clear(struct starfive_clkevt *clkevt)
73 {
74         /* waiting interrupt can be to clearing */
75         u32 value;
76         int ret = 0;
77
78         value = readl(clkevt->intclr);
79         ret = readl_poll_timeout_atomic(clkevt->intclr, value,
80                         !(value & INT_STATUS_CLR_AVA), DELAY_US, TIMEOUT_US);
81         if (!ret)
82                 writel(1, clkevt->intclr);
83 }
84
85 /*
86  * The initial value to be loaded into the
87  * counter and is also used as the reload value.
88  */
89 static inline void timer_set_val(struct starfive_clkevt *clkevt, u32 val)
90 {
91         writel(val, clkevt->load);
92 }
93
94 static inline u32 timer_get_val(struct starfive_clkevt *clkevt)
95 {
96         return readl(clkevt->value);
97 }
98
99 /*
100  * Write RELOAD register to reload preset value to counter.
101  * (Write 0 and write 1 are both ok)
102  */
103 static inline void
104 timer_set_reload(struct starfive_clkevt *clkevt)
105 {
106         writel(1, clkevt->reload);
107 }
108
109 static inline void timer_enable(struct starfive_clkevt *clkevt)
110 {
111         writel(TIMER_ENA, clkevt->enable);
112 }
113
114 static inline void timer_disable(struct starfive_clkevt *clkevt)
115 {
116         writel(TIMER_ENA_DIS, clkevt->enable);
117 }
118
119 static void timer_shutdown(struct starfive_clkevt *clkevt)
120 {
121         timer_int_disable(clkevt);
122         timer_disable(clkevt);
123         timer_int_clear(clkevt);
124 }
125
126 static void starfive_timer_suspend(struct clock_event_device *evt)
127 {
128         struct starfive_clkevt *clkevt;
129
130         clkevt = to_starfive_clkevt(evt);
131
132         clkevt->reload_val = timer_get_val(clkevt);
133
134         timer_disable(clkevt);
135         timer_int_disable(clkevt);
136         timer_int_clear(clkevt);
137 }
138
139 static void starfive_timer_resume(struct clock_event_device *evt)
140 {
141         struct starfive_clkevt *clkevt;
142
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);
148 }
149
150 static int starfive_timer_tick_resume(struct clock_event_device *evt)
151 {
152         starfive_timer_resume(evt);
153
154         return 0;
155 }
156
157 static int starfive_timer_shutdown(struct clock_event_device *evt)
158 {
159         struct starfive_clkevt *clkevt;
160
161         clkevt = to_starfive_clkevt(evt);
162         timer_shutdown(clkevt);
163
164         return 0;
165 }
166
167 static int
168 starfive_get_clock_rate(struct starfive_clkevt *clkevt, struct device_node *np)
169 {
170         int ret;
171         u32 rate;
172
173         if (clkevt->clk) {
174                 clkevt->rate = clk_get_rate(clkevt->clk);
175                 if (clkevt->rate > 0) {
176                         pr_debug("clk_get_rate clkevt->rate: %lld\n",
177                                 clkevt->rate);
178                         return 0;
179                 }
180         }
181
182         /* Next we try to get clock-frequency from dts.*/
183         ret = of_property_read_u32(np, "clock-frequency", &rate);
184         if (!ret) {
185                 pr_debug("Timer: try get clock-frequency:%d MHz\n", rate);
186                 clkevt->rate = (u64)rate;
187                 return 0;
188         }
189         pr_err("Timer: get rate failed, need clock-frequency define in dts.\n");
190
191         return -ENOENT;
192 }
193
194 static int starfive_clocksource_init(struct starfive_clkevt *clkevt,
195                                 const char *name, struct device_node *np)
196 {
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);
203
204         clocksource_mmio_init(clkevt->value, name, clkevt->rate,
205                         CLOCK_SOURCE_RATE, VALID_BITS,
206                         clocksource_mmio_readl_down);
207
208         return 0;
209 }
210
211 /*
212  * IRQ handler for the timer
213  */
214 static irqreturn_t starfive_timer_interrupt(int irq, void *priv)
215 {
216         struct clock_event_device *evt = (struct clock_event_device  *)priv;
217         struct starfive_clkevt *clkevt = to_starfive_clkevt(evt);
218
219         timer_int_clear(clkevt);
220
221         if (evt->event_handler)
222                 evt->event_handler(evt);
223
224         return IRQ_HANDLED;
225 }
226
227 static int starfive_timer_set_periodic(struct clock_event_device *evt)
228 {
229         struct starfive_clkevt *clkevt;
230
231         clkevt = to_starfive_clkevt(evt);
232
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);
240
241         return 0;
242 }
243
244 static int starfive_timer_set_oneshot(struct clock_event_device *evt)
245 {
246         struct starfive_clkevt *clkevt;
247
248         clkevt = to_starfive_clkevt(evt);
249
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);
257
258         return 0;
259 }
260
261 static int starfive_timer_set_next_event(unsigned long next,
262                                         struct clock_event_device *evt)
263 {
264         struct starfive_clkevt *clkevt;
265
266         clkevt = to_starfive_clkevt(evt);
267
268         timer_disable(clkevt);
269         timer_set_mod(clkevt, MOD_SINGLE);
270         timer_set_val(clkevt, next);
271         timer_enable(clkevt);
272
273         return 0;
274 }
275
276 static void starfive_set_clockevent(struct clock_event_device *evt)
277 {
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;
290 }
291
292 static int starfive_clockevents_register(struct starfive_clkevt *clkevt, unsigned int irq,
293                                 struct device_node *np, const char *name)
294 {
295         int ret = 0;
296
297         ret = starfive_get_clock_rate(clkevt, np);
298         if (ret)
299                 return -EINVAL;
300
301         clkevt->periodic = DIV_ROUND_CLOSEST(clkevt->rate, HZ);
302
303         starfive_set_clockevent(&clkevt->evt);
304         clkevt->evt.name = name;
305         clkevt->evt.irq = irq;
306         clkevt->evt.cpumask = cpu_possible_mask;
307
308         ret = request_irq(irq, starfive_timer_interrupt,
309                         IRQF_TIMER | IRQF_IRQPOLL, name, &clkevt->evt);
310         if (ret)
311                 pr_err("%s: request_irq failed\n", name);
312
313         clockevents_config_and_register(&clkevt->evt, clkevt->rate,
314                         MIN_TICKS, MAX_TICKS);
315
316         return ret;
317 }
318
319 static void __init starfive_clkevt_init(struct starfive_timer *timer,
320                                         struct starfive_clkevt *clkevt,
321                                         void __iomem *base, int index)
322 {
323         void __iomem *timer_base;
324
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;
334 }
335
336 static int __init do_starfive_timer_of_init(struct device_node *np,
337                                         struct starfive_timer *timer)
338 {
339         int index, count, irq, ret = -EINVAL;
340         const char *name = NULL;
341         struct clk *clk;
342         struct clk *pclk;
343         struct reset_control *prst;
344         struct reset_control *rst;
345         struct starfive_clkevt *clkevt;
346         void __iomem *base;
347
348         base = of_iomap(np, 0);
349         if (!base)
350                 return -ENXIO;
351
352         if (!of_device_is_available(np)) {
353                 ret = -EINVAL;
354                 goto err;
355         }
356
357         pclk = of_clk_get_by_name(np, "apb_clk");
358         if (!IS_ERR(pclk))
359                 if (clk_prepare_enable(pclk))
360                         pr_warn("pclk for %pOFn is present,"
361                                 "but could not be activated\n", np);
362
363         prst = of_reset_control_get(np, "apb_rst");
364         if (!IS_ERR(prst)) {
365                 reset_control_assert(prst);
366                 reset_control_deassert(prst);
367         }
368
369         count = of_irq_count(np);
370         if (count > NR_TIMERS || count <= 0) {
371                 ret = -EINVAL;
372                 goto count_err;
373         }
374
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")))
379                         continue;
380
381                 clkevt = kzalloc(sizeof(*clkevt), GFP_KERNEL);
382                 if (!clkevt) {
383                         ret = -ENOMEM;
384                         goto clkevt_err;
385                 }
386
387                 starfive_clkevt_init(timer, clkevt, base, index);
388
389                 /* Ensure timers are disabled */
390                 timer_disable(clkevt);
391
392                 clk = of_clk_get_by_name(np, name);
393                 if (!IS_ERR(clk)) {
394                         clkevt->clk = clk;
395                         if (clk_prepare_enable(clk))
396                                 pr_warn("clk for %pOFn is present,"
397                                         "but could not be activated\n", np);
398                 }
399
400                 rst = of_reset_control_get(np, name);
401                 if (!IS_ERR(rst)) {
402                         reset_control_assert(rst);
403                         reset_control_deassert(rst);
404                 }
405
406                 irq = irq_of_parse_and_map(np, index);
407                 if (irq < 0) {
408                         ret = -EINVAL;
409                         goto irq_err;
410                 }
411
412                 snprintf(clkevt->name, sizeof(clkevt->name), "%s.ch%d",
413                                         np->full_name, index);
414
415                 ret = starfive_clockevents_register(clkevt, irq, np, clkevt->name);
416                 if (ret) {
417                         pr_err("%s: init clockevents failed.\n", clkevt->name);
418                         goto register_err;
419                 }
420                 clkevt->irq = irq;
421
422                 ret = starfive_clocksource_init(clkevt, clkevt->name, np);
423                 if (ret)
424                         goto init_err;
425         }
426         if (!IS_ERR(pclk))
427                 clk_put(pclk);
428
429         return 0;
430
431 init_err:
432 register_err:
433         free_irq(clkevt->irq, &clkevt->evt);
434 irq_err:
435         if (!rst) {
436                 reset_control_assert(rst);
437                 reset_control_put(rst);
438         }
439         if (!clkevt->clk) {
440                 clk_disable_unprepare(clkevt->clk);
441                 clk_put(clkevt->clk);
442         }
443         kfree(clkevt);
444 clkevt_err:
445 count_err:
446         if (!IS_ERR(pclk)) {
447                 if (!index)
448                         clk_disable_unprepare(pclk);
449                 clk_put(pclk);
450         }
451 err:
452         iounmap(base);
453         return ret;
454 }
455
456 static int __init starfive_timer_of_init(struct device_node *np)
457 {
458         return do_starfive_timer_of_init(np, &jh7110_starfive_timer);
459 }
460 TIMER_OF_DECLARE(starfive_timer, "starfive,jh7110-timers", starfive_timer_of_init);
461
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");