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
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.
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>
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
26 --- a/arch/mips/ralink/Kconfig
27 +++ b/arch/mips/ralink/Kconfig
29 # SPDX-License-Identifier: GPL-2.0
34 - depends on SOC_RT305X || SOC_MT7620
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
48 -obj-$(CONFIG_CLKEVT_RT3352) += cevt-rt3352.o
50 obj-$(CONFIG_RALINK_ILL_ACC) += ill_acc.o
52 obj-$(CONFIG_IRQ_INTC) += irq.o
53 --- a/arch/mips/ralink/cevt-rt3352.c
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
61 - * Copyright (C) 2013 by John Crispin <john@phrozen.org>
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>
74 -#include <asm/mach-ralink/ralink_regs.h>
76 -#define SYSTICK_FREQ (50 * 1000)
78 -#define SYSTICK_CONFIG 0x00
79 -#define SYSTICK_COMPARE 0x04
80 -#define SYSTICK_COUNT 0x08
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
87 -struct systick_device {
88 - void __iomem *membase;
89 - struct clock_event_device dev;
94 -static int systick_set_oneshot(struct clock_event_device *evt);
95 -static int systick_shutdown(struct clock_event_device *evt);
97 -static int systick_next_event(unsigned long delta,
98 - struct clock_event_device *evt)
100 - struct systick_device *sdev;
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);
111 -static void systick_event_handler(struct clock_event_device *dev)
113 - /* noting to do here */
116 -static irqreturn_t systick_interrupt(int irq, void *dev_id)
118 - struct clock_event_device *dev = (struct clock_event_device *) dev_id;
120 - dev->event_handler(dev);
122 - return IRQ_HANDLED;
125 -static struct systick_device systick = {
128 - * cevt-r4k uses 300, make sure systick
129 - * gets used if available
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,
140 -static int systick_shutdown(struct clock_event_device *evt)
142 - struct systick_device *sdev;
144 - sdev = container_of(evt, struct systick_device, dev);
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);
154 -static int systick_set_oneshot(struct clock_event_device *evt)
156 - const char *name = systick.dev.name;
157 - struct systick_device *sdev;
158 - int irq = systick.dev.irq;
160 - sdev = container_of(evt, struct systick_device, dev);
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);
167 - sdev->irq_requested = 1;
168 - iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,
169 - systick.membase + SYSTICK_CONFIG);
174 -static int __init ralink_systick_init(struct device_node *np)
178 - systick.membase = of_iomap(np, 0);
179 - if (!systick.membase)
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);
194 - ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
195 - SYSTICK_FREQ, 301, 16,
196 - clocksource_mmio_readl_up);
200 - clockevents_register_device(&systick.dev);
202 - pr_info("%pOFn: running - mult: %d, shift: %d\n",
203 - np, systick.dev.mult, systick.dev.shift);
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
213 Support for the timer/counter of goldfish-rtc
216 + bool "Ralink System Tick Counter"
217 + depends on SOC_RT305X || SOC_MT7620 || COMPILE_TEST
221 + Enables support for system tick counter present on
222 + Ralink SoCs RT3352 and MT7620.
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
233 +++ b/drivers/clocksource/timer-ralink.c
235 +// SPDX-License-Identifier: GPL-2.0
237 + * Ralink System Tick Counter driver present on RT3352 and MT7620 SoCs.
239 + * Copyright (C) 2013 by John Crispin <john@phrozen.org>
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>
252 +#define SYSTICK_FREQ (50 * 1000)
254 +#define SYSTICK_CONFIG 0x00
255 +#define SYSTICK_COMPARE 0x04
256 +#define SYSTICK_COUNT 0x08
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
263 +struct systick_device {
264 + void __iomem *membase;
265 + struct clock_event_device dev;
270 +static int systick_set_oneshot(struct clock_event_device *evt);
271 +static int systick_shutdown(struct clock_event_device *evt);
273 +static int systick_next_event(unsigned long delta,
274 + struct clock_event_device *evt)
276 + struct systick_device *sdev;
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);
287 +static void systick_event_handler(struct clock_event_device *dev)
289 + /* noting to do here */
292 +static irqreturn_t systick_interrupt(int irq, void *dev_id)
294 + struct clock_event_device *dev = (struct clock_event_device *)dev_id;
296 + dev->event_handler(dev);
298 + return IRQ_HANDLED;
301 +static struct systick_device systick = {
304 + * cevt-r4k uses 300, make sure systick
305 + * gets used if available
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,
316 +static int systick_shutdown(struct clock_event_device *evt)
318 + struct systick_device *sdev;
320 + sdev = container_of(evt, struct systick_device, dev);
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);
330 +static int systick_set_oneshot(struct clock_event_device *evt)
332 + const char *name = systick.dev.name;
333 + struct systick_device *sdev;
334 + int irq = systick.dev.irq;
336 + sdev = container_of(evt, struct systick_device, dev);
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);
343 + sdev->irq_requested = 1;
344 + iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,
345 + systick.membase + SYSTICK_CONFIG);
350 +static int __init ralink_systick_init(struct device_node *np)
354 + systick.membase = of_iomap(np, 0);
355 + if (!systick.membase)
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);
370 + ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
371 + SYSTICK_FREQ, 301, 16,
372 + clocksource_mmio_readl_up);
376 + clockevents_register_device(&systick.dev);
378 + pr_info("%pOFn: running - mult: %d, shift: %d\n",
379 + np, systick.dev.mult, systick.dev.shift);
384 +TIMER_OF_DECLARE(systick, "ralink,cevt-systick", ralink_systick_init);