cd2a90826c767d4fe44ecd851faef99c32624774
[openwrt/staging/svanheule.git] /
1 From 57cbfd333c9d65bfab1a06b49c75536ee28dc2ce Mon Sep 17 00:00:00 2001
2 From: Sergio Paracuellos <sergio.paracuellos@gmail.com>
3 Date: Mon, 28 Oct 2024 21:36:43 +0100
4 Subject: clocksource/drivers/ralink: Add Ralink System Tick Counter driver
5
6 System Tick Counter is present on Ralink SoCs RT3352 and MT7620. This
7 driver has been in 'arch/mips/ralink' directory since the beggining of
8 Ralink architecture support. However, it can be moved into a more proper
9 place in 'drivers/clocksource'. Hence add it here adding also support for
10 compile test targets and reducing LOC in architecture code folder.
11
12 Signed-off-by: Sergio Paracuellos <sergio.paracuellos@gmail.com>
13 Link: https://lore.kernel.org/r/20241028203643.191268-2-sergio.paracuellos@gmail.com
14 Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
15 ---
16 arch/mips/ralink/Kconfig | 7 --
17 arch/mips/ralink/Makefile | 2 -
18 arch/mips/ralink/cevt-rt3352.c | 153 -------------------------------------
19 drivers/clocksource/Kconfig | 9 +++
20 drivers/clocksource/Makefile | 1 +
21 drivers/clocksource/timer-ralink.c | 150 ++++++++++++++++++++++++++++++++++++
22 6 files changed, 160 insertions(+), 162 deletions(-)
23 delete mode 100644 arch/mips/ralink/cevt-rt3352.c
24 create mode 100644 drivers/clocksource/timer-ralink.c
25
26 --- a/arch/mips/ralink/Kconfig
27 +++ b/arch/mips/ralink/Kconfig
28 @@ -1,13 +1,6 @@
29 # SPDX-License-Identifier: GPL-2.0
30 if RALINK
31
32 -config CLKEVT_RT3352
33 - bool
34 - depends on SOC_RT305X || SOC_MT7620
35 - default y
36 - select TIMER_OF
37 - select CLKSRC_MMIO
38 -
39 config RALINK_ILL_ACC
40 bool
41 depends on SOC_RT305X
42 --- a/arch/mips/ralink/Makefile
43 +++ b/arch/mips/ralink/Makefile
44 @@ -10,8 +10,6 @@ ifndef CONFIG_MIPS_GIC
45 obj-y += clk.o timer.o
46 endif
47
48 -obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o
49 -
50 obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o
51
52 obj-$(CONFIG_IRQ_INTC) += irq.o
53 --- a/arch/mips/ralink/cevt-rt3352.c
54 +++ /dev/null
55 @@ -1,153 +0,0 @@
56 -/*
57 - * This file is subject to the terms and conditions of the GNU General Public
58 - * License. See the file "COPYING" in the main directory of this archive
59 - * for more details.
60 - *
61 - * Copyright (C) 2013 by John Crispin <john@phrozen.org>
62 - */
63 -
64 -#include <linux/clockchips.h>
65 -#include <linux/clocksource.h>
66 -#include <linux/interrupt.h>
67 -#include <linux/reset.h>
68 -#include <linux/init.h>
69 -#include <linux/time.h>
70 -#include <linux/of.h>
71 -#include <linux/of_irq.h>
72 -#include <linux/of_address.h>
73 -
74 -#include <asm/mach-ralink/ralink_regs.h>
75 -
76 -#define SYSTICK_FREQ (50 * 1000)
77 -
78 -#define SYSTICK_CONFIG 0x00
79 -#define SYSTICK_COMPARE 0x04
80 -#define SYSTICK_COUNT 0x08
81 -
82 -/* route systick irq to mips irq 7 instead of the r4k-timer */
83 -#define CFG_EXT_STK_EN 0x2
84 -/* enable the counter */
85 -#define CFG_CNT_EN 0x1
86 -
87 -struct systick_device {
88 - void __iomem *membase;
89 - struct clock_event_device dev;
90 - int irq_requested;
91 - int freq_scale;
92 -};
93 -
94 -static int systick_set_oneshot(struct clock_event_device *evt);
95 -static int systick_shutdown(struct clock_event_device *evt);
96 -
97 -static int systick_next_event(unsigned long delta,
98 - struct clock_event_device *evt)
99 -{
100 - struct systick_device *sdev;
101 - u32 count;
102 -
103 - sdev = container_of(evt, struct systick_device, dev);
104 - count = ioread32(sdev->membase + SYSTICK_COUNT);
105 - count = (count + delta) % SYSTICK_FREQ;
106 - iowrite32(count, sdev->membase + SYSTICK_COMPARE);
107 -
108 - return 0;
109 -}
110 -
111 -static void systick_event_handler(struct clock_event_device *dev)
112 -{
113 - /* noting to do here */
114 -}
115 -
116 -static irqreturn_t systick_interrupt(int irq, void *dev_id)
117 -{
118 - struct clock_event_device *dev = (struct clock_event_device *) dev_id;
119 -
120 - dev->event_handler(dev);
121 -
122 - return IRQ_HANDLED;
123 -}
124 -
125 -static struct systick_device systick = {
126 - .dev = {
127 - /*
128 - * cevt-r4k uses 300, make sure systick
129 - * gets used if available
130 - */
131 - .rating = 310,
132 - .features = CLOCK_EVT_FEAT_ONESHOT,
133 - .set_next_event = systick_next_event,
134 - .set_state_shutdown = systick_shutdown,
135 - .set_state_oneshot = systick_set_oneshot,
136 - .event_handler = systick_event_handler,
137 - },
138 -};
139 -
140 -static int systick_shutdown(struct clock_event_device *evt)
141 -{
142 - struct systick_device *sdev;
143 -
144 - sdev = container_of(evt, struct systick_device, dev);
145 -
146 - if (sdev->irq_requested)
147 - free_irq(systick.dev.irq, &systick.dev);
148 - sdev->irq_requested = 0;
149 - iowrite32(0, systick.membase + SYSTICK_CONFIG);
150 -
151 - return 0;
152 -}
153 -
154 -static int systick_set_oneshot(struct clock_event_device *evt)
155 -{
156 - const char *name = systick.dev.name;
157 - struct systick_device *sdev;
158 - int irq = systick.dev.irq;
159 -
160 - sdev = container_of(evt, struct systick_device, dev);
161 -
162 - if (!sdev->irq_requested) {
163 - if (request_irq(irq, systick_interrupt,
164 - IRQF_PERCPU | IRQF_TIMER, name, &systick.dev))
165 - pr_err("Failed to request irq %d (%s)\n", irq, name);
166 - }
167 - sdev->irq_requested = 1;
168 - iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,
169 - systick.membase + SYSTICK_CONFIG);
170 -
171 - return 0;
172 -}
173 -
174 -static int __init ralink_systick_init(struct device_node *np)
175 -{
176 - int ret;
177 -
178 - systick.membase = of_iomap(np, 0);
179 - if (!systick.membase)
180 - return -ENXIO;
181 -
182 - systick.dev.name = np->name;
183 - clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
184 - systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev);
185 - systick.dev.max_delta_ticks = 0x7fff;
186 - systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev);
187 - systick.dev.min_delta_ticks = 0x3;
188 - systick.dev.irq = irq_of_parse_and_map(np, 0);
189 - if (!systick.dev.irq) {
190 - pr_err("%pOFn: request_irq failed", np);
191 - return -EINVAL;
192 - }
193 -
194 - ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
195 - SYSTICK_FREQ, 301, 16,
196 - clocksource_mmio_readl_up);
197 - if (ret)
198 - return ret;
199 -
200 - clockevents_register_device(&systick.dev);
201 -
202 - pr_info("%pOFn: running - mult: %d, shift: %d\n",
203 - np, systick.dev.mult, systick.dev.shift);
204 -
205 - return 0;
206 -}
207 -
208 -TIMER_OF_DECLARE(systick, "ralink,cevt-systick", ralink_systick_init);
209 --- a/drivers/clocksource/Kconfig
210 +++ b/drivers/clocksource/Kconfig
211 @@ -732,4 +732,13 @@ config GOLDFISH_TIMER
212 help
213 Support for the timer/counter of goldfish-rtc
214
215 +config RALINK_TIMER
216 + bool "Ralink System Tick Counter"
217 + depends on SOC_RT305X || SOC_MT7620 || COMPILE_TEST
218 + select CLKSRC_MMIO
219 + select TIMER_OF
220 + help
221 + Enables support for system tick counter present on
222 + Ralink SoCs RT3352 and MT7620.
223 +
224 endmenu
225 --- a/drivers/clocksource/Makefile
226 +++ b/drivers/clocksource/Makefile
227 @@ -89,3 +89,4 @@ obj-$(CONFIG_MSC313E_TIMER) += timer-ms
228 obj-$(CONFIG_GOLDFISH_TIMER) += timer-goldfish.o
229 obj-$(CONFIG_GXP_TIMER) += timer-gxp.o
230 obj-$(CONFIG_CLKSRC_LOONGSON1_PWM) += timer-loongson1-pwm.o
231 +obj-$(CONFIG_RALINK_TIMER) += timer-ralink.o
232 --- /dev/null
233 +++ b/drivers/clocksource/timer-ralink.c
234 @@ -0,0 +1,150 @@
235 +// SPDX-License-Identifier: GPL-2.0
236 +/*
237 + * Ralink System Tick Counter driver present on RT3352 and MT7620 SoCs.
238 + *
239 + * Copyright (C) 2013 by John Crispin <john@phrozen.org>
240 + */
241 +
242 +#include <linux/clockchips.h>
243 +#include <linux/clocksource.h>
244 +#include <linux/interrupt.h>
245 +#include <linux/reset.h>
246 +#include <linux/init.h>
247 +#include <linux/time.h>
248 +#include <linux/of.h>
249 +#include <linux/of_irq.h>
250 +#include <linux/of_address.h>
251 +
252 +#define SYSTICK_FREQ (50 * 1000)
253 +
254 +#define SYSTICK_CONFIG 0x00
255 +#define SYSTICK_COMPARE 0x04
256 +#define SYSTICK_COUNT 0x08
257 +
258 +/* route systick irq to mips irq 7 instead of the r4k-timer */
259 +#define CFG_EXT_STK_EN 0x2
260 +/* enable the counter */
261 +#define CFG_CNT_EN 0x1
262 +
263 +struct systick_device {
264 + void __iomem *membase;
265 + struct clock_event_device dev;
266 + int irq_requested;
267 + int freq_scale;
268 +};
269 +
270 +static int systick_set_oneshot(struct clock_event_device *evt);
271 +static int systick_shutdown(struct clock_event_device *evt);
272 +
273 +static int systick_next_event(unsigned long delta,
274 + struct clock_event_device *evt)
275 +{
276 + struct systick_device *sdev;
277 + u32 count;
278 +
279 + sdev = container_of(evt, struct systick_device, dev);
280 + count = ioread32(sdev->membase + SYSTICK_COUNT);
281 + count = (count + delta) % SYSTICK_FREQ;
282 + iowrite32(count, sdev->membase + SYSTICK_COMPARE);
283 +
284 + return 0;
285 +}
286 +
287 +static void systick_event_handler(struct clock_event_device *dev)
288 +{
289 + /* noting to do here */
290 +}
291 +
292 +static irqreturn_t systick_interrupt(int irq, void *dev_id)
293 +{
294 + struct clock_event_device *dev = (struct clock_event_device *)dev_id;
295 +
296 + dev->event_handler(dev);
297 +
298 + return IRQ_HANDLED;
299 +}
300 +
301 +static struct systick_device systick = {
302 + .dev = {
303 + /*
304 + * cevt-r4k uses 300, make sure systick
305 + * gets used if available
306 + */
307 + .rating = 310,
308 + .features = CLOCK_EVT_FEAT_ONESHOT,
309 + .set_next_event = systick_next_event,
310 + .set_state_shutdown = systick_shutdown,
311 + .set_state_oneshot = systick_set_oneshot,
312 + .event_handler = systick_event_handler,
313 + },
314 +};
315 +
316 +static int systick_shutdown(struct clock_event_device *evt)
317 +{
318 + struct systick_device *sdev;
319 +
320 + sdev = container_of(evt, struct systick_device, dev);
321 +
322 + if (sdev->irq_requested)
323 + free_irq(systick.dev.irq, &systick.dev);
324 + sdev->irq_requested = 0;
325 + iowrite32(0, systick.membase + SYSTICK_CONFIG);
326 +
327 + return 0;
328 +}
329 +
330 +static int systick_set_oneshot(struct clock_event_device *evt)
331 +{
332 + const char *name = systick.dev.name;
333 + struct systick_device *sdev;
334 + int irq = systick.dev.irq;
335 +
336 + sdev = container_of(evt, struct systick_device, dev);
337 +
338 + if (!sdev->irq_requested) {
339 + if (request_irq(irq, systick_interrupt,
340 + IRQF_PERCPU | IRQF_TIMER, name, &systick.dev))
341 + pr_err("Failed to request irq %d (%s)\n", irq, name);
342 + }
343 + sdev->irq_requested = 1;
344 + iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,
345 + systick.membase + SYSTICK_CONFIG);
346 +
347 + return 0;
348 +}
349 +
350 +static int __init ralink_systick_init(struct device_node *np)
351 +{
352 + int ret;
353 +
354 + systick.membase = of_iomap(np, 0);
355 + if (!systick.membase)
356 + return -ENXIO;
357 +
358 + systick.dev.name = np->name;
359 + clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
360 + systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev);
361 + systick.dev.max_delta_ticks = 0x7fff;
362 + systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev);
363 + systick.dev.min_delta_ticks = 0x3;
364 + systick.dev.irq = irq_of_parse_and_map(np, 0);
365 + if (!systick.dev.irq) {
366 + pr_err("%pOFn: request_irq failed", np);
367 + return -EINVAL;
368 + }
369 +
370 + ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
371 + SYSTICK_FREQ, 301, 16,
372 + clocksource_mmio_readl_up);
373 + if (ret)
374 + return ret;
375 +
376 + clockevents_register_device(&systick.dev);
377 +
378 + pr_info("%pOFn: running - mult: %d, shift: %d\n",
379 + np, systick.dev.mult, systick.dev.shift);
380 +
381 + return 0;
382 +}
383 +
384 +TIMER_OF_DECLARE(systick, "ralink,cevt-systick", ralink_systick_init);