1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Clocksource driver for NXP LPC32xx/18xx/43xx timer
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (C) 2015 Joachim Eastwood <manabian@gmail.com>
5*4882a593Smuzhiyun *
6*4882a593Smuzhiyun * Based on:
7*4882a593Smuzhiyun * time-efm32 Copyright (C) 2013 Pengutronix
8*4882a593Smuzhiyun * mach-lpc32xx/timer.c Copyright (C) 2009 - 2010 NXP Semiconductors
9*4882a593Smuzhiyun *
10*4882a593Smuzhiyun * This file is licensed under the terms of the GNU General Public
11*4882a593Smuzhiyun * License version 2. This program is licensed "as is" without any
12*4882a593Smuzhiyun * warranty of any kind, whether express or implied.
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun */
15*4882a593Smuzhiyun
16*4882a593Smuzhiyun #define pr_fmt(fmt) "%s: " fmt, __func__
17*4882a593Smuzhiyun
18*4882a593Smuzhiyun #include <linux/clk.h>
19*4882a593Smuzhiyun #include <linux/clockchips.h>
20*4882a593Smuzhiyun #include <linux/clocksource.h>
21*4882a593Smuzhiyun #include <linux/delay.h>
22*4882a593Smuzhiyun #include <linux/interrupt.h>
23*4882a593Smuzhiyun #include <linux/irq.h>
24*4882a593Smuzhiyun #include <linux/kernel.h>
25*4882a593Smuzhiyun #include <linux/of.h>
26*4882a593Smuzhiyun #include <linux/of_address.h>
27*4882a593Smuzhiyun #include <linux/of_irq.h>
28*4882a593Smuzhiyun #include <linux/sched_clock.h>
29*4882a593Smuzhiyun
30*4882a593Smuzhiyun #define LPC32XX_TIMER_IR 0x000
31*4882a593Smuzhiyun #define LPC32XX_TIMER_IR_MR0INT BIT(0)
32*4882a593Smuzhiyun #define LPC32XX_TIMER_TCR 0x004
33*4882a593Smuzhiyun #define LPC32XX_TIMER_TCR_CEN BIT(0)
34*4882a593Smuzhiyun #define LPC32XX_TIMER_TCR_CRST BIT(1)
35*4882a593Smuzhiyun #define LPC32XX_TIMER_TC 0x008
36*4882a593Smuzhiyun #define LPC32XX_TIMER_PR 0x00c
37*4882a593Smuzhiyun #define LPC32XX_TIMER_MCR 0x014
38*4882a593Smuzhiyun #define LPC32XX_TIMER_MCR_MR0I BIT(0)
39*4882a593Smuzhiyun #define LPC32XX_TIMER_MCR_MR0R BIT(1)
40*4882a593Smuzhiyun #define LPC32XX_TIMER_MCR_MR0S BIT(2)
41*4882a593Smuzhiyun #define LPC32XX_TIMER_MR0 0x018
42*4882a593Smuzhiyun #define LPC32XX_TIMER_CTCR 0x070
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun struct lpc32xx_clock_event_ddata {
45*4882a593Smuzhiyun struct clock_event_device evtdev;
46*4882a593Smuzhiyun void __iomem *base;
47*4882a593Smuzhiyun u32 ticks_per_jiffy;
48*4882a593Smuzhiyun };
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun /* Needed for the sched clock */
51*4882a593Smuzhiyun static void __iomem *clocksource_timer_counter;
52*4882a593Smuzhiyun
lpc32xx_read_sched_clock(void)53*4882a593Smuzhiyun static u64 notrace lpc32xx_read_sched_clock(void)
54*4882a593Smuzhiyun {
55*4882a593Smuzhiyun return readl(clocksource_timer_counter);
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun
lpc32xx_delay_timer_read(void)58*4882a593Smuzhiyun static unsigned long lpc32xx_delay_timer_read(void)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun return readl(clocksource_timer_counter);
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun static struct delay_timer lpc32xx_delay_timer = {
64*4882a593Smuzhiyun .read_current_timer = lpc32xx_delay_timer_read,
65*4882a593Smuzhiyun };
66*4882a593Smuzhiyun
lpc32xx_clkevt_next_event(unsigned long delta,struct clock_event_device * evtdev)67*4882a593Smuzhiyun static int lpc32xx_clkevt_next_event(unsigned long delta,
68*4882a593Smuzhiyun struct clock_event_device *evtdev)
69*4882a593Smuzhiyun {
70*4882a593Smuzhiyun struct lpc32xx_clock_event_ddata *ddata =
71*4882a593Smuzhiyun container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev);
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun /*
74*4882a593Smuzhiyun * Place timer in reset and program the delta in the match
75*4882a593Smuzhiyun * channel 0 (MR0). When the timer counter matches the value
76*4882a593Smuzhiyun * in MR0 register the match will trigger an interrupt.
77*4882a593Smuzhiyun * After setup the timer is released from reset and enabled.
78*4882a593Smuzhiyun */
79*4882a593Smuzhiyun writel_relaxed(LPC32XX_TIMER_TCR_CRST, ddata->base + LPC32XX_TIMER_TCR);
80*4882a593Smuzhiyun writel_relaxed(delta, ddata->base + LPC32XX_TIMER_MR0);
81*4882a593Smuzhiyun writel_relaxed(LPC32XX_TIMER_TCR_CEN, ddata->base + LPC32XX_TIMER_TCR);
82*4882a593Smuzhiyun
83*4882a593Smuzhiyun return 0;
84*4882a593Smuzhiyun }
85*4882a593Smuzhiyun
lpc32xx_clkevt_shutdown(struct clock_event_device * evtdev)86*4882a593Smuzhiyun static int lpc32xx_clkevt_shutdown(struct clock_event_device *evtdev)
87*4882a593Smuzhiyun {
88*4882a593Smuzhiyun struct lpc32xx_clock_event_ddata *ddata =
89*4882a593Smuzhiyun container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev);
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun /* Disable the timer */
92*4882a593Smuzhiyun writel_relaxed(0, ddata->base + LPC32XX_TIMER_TCR);
93*4882a593Smuzhiyun
94*4882a593Smuzhiyun return 0;
95*4882a593Smuzhiyun }
96*4882a593Smuzhiyun
lpc32xx_clkevt_oneshot(struct clock_event_device * evtdev)97*4882a593Smuzhiyun static int lpc32xx_clkevt_oneshot(struct clock_event_device *evtdev)
98*4882a593Smuzhiyun {
99*4882a593Smuzhiyun struct lpc32xx_clock_event_ddata *ddata =
100*4882a593Smuzhiyun container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev);
101*4882a593Smuzhiyun
102*4882a593Smuzhiyun /*
103*4882a593Smuzhiyun * When using oneshot, we must also disable the timer
104*4882a593Smuzhiyun * to wait for the first call to set_next_event().
105*4882a593Smuzhiyun */
106*4882a593Smuzhiyun writel_relaxed(0, ddata->base + LPC32XX_TIMER_TCR);
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun /* Enable interrupt, reset on match and stop on match (MCR). */
109*4882a593Smuzhiyun writel_relaxed(LPC32XX_TIMER_MCR_MR0I | LPC32XX_TIMER_MCR_MR0R |
110*4882a593Smuzhiyun LPC32XX_TIMER_MCR_MR0S, ddata->base + LPC32XX_TIMER_MCR);
111*4882a593Smuzhiyun return 0;
112*4882a593Smuzhiyun }
113*4882a593Smuzhiyun
lpc32xx_clkevt_periodic(struct clock_event_device * evtdev)114*4882a593Smuzhiyun static int lpc32xx_clkevt_periodic(struct clock_event_device *evtdev)
115*4882a593Smuzhiyun {
116*4882a593Smuzhiyun struct lpc32xx_clock_event_ddata *ddata =
117*4882a593Smuzhiyun container_of(evtdev, struct lpc32xx_clock_event_ddata, evtdev);
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun /* Enable interrupt and reset on match. */
120*4882a593Smuzhiyun writel_relaxed(LPC32XX_TIMER_MCR_MR0I | LPC32XX_TIMER_MCR_MR0R,
121*4882a593Smuzhiyun ddata->base + LPC32XX_TIMER_MCR);
122*4882a593Smuzhiyun
123*4882a593Smuzhiyun /*
124*4882a593Smuzhiyun * Place timer in reset and program the delta in the match
125*4882a593Smuzhiyun * channel 0 (MR0).
126*4882a593Smuzhiyun */
127*4882a593Smuzhiyun writel_relaxed(LPC32XX_TIMER_TCR_CRST, ddata->base + LPC32XX_TIMER_TCR);
128*4882a593Smuzhiyun writel_relaxed(ddata->ticks_per_jiffy, ddata->base + LPC32XX_TIMER_MR0);
129*4882a593Smuzhiyun writel_relaxed(LPC32XX_TIMER_TCR_CEN, ddata->base + LPC32XX_TIMER_TCR);
130*4882a593Smuzhiyun
131*4882a593Smuzhiyun return 0;
132*4882a593Smuzhiyun }
133*4882a593Smuzhiyun
lpc32xx_clock_event_handler(int irq,void * dev_id)134*4882a593Smuzhiyun static irqreturn_t lpc32xx_clock_event_handler(int irq, void *dev_id)
135*4882a593Smuzhiyun {
136*4882a593Smuzhiyun struct lpc32xx_clock_event_ddata *ddata = dev_id;
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun /* Clear match on channel 0 */
139*4882a593Smuzhiyun writel_relaxed(LPC32XX_TIMER_IR_MR0INT, ddata->base + LPC32XX_TIMER_IR);
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun ddata->evtdev.event_handler(&ddata->evtdev);
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun return IRQ_HANDLED;
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun static struct lpc32xx_clock_event_ddata lpc32xx_clk_event_ddata = {
147*4882a593Smuzhiyun .evtdev = {
148*4882a593Smuzhiyun .name = "lpc3220 clockevent",
149*4882a593Smuzhiyun .features = CLOCK_EVT_FEAT_ONESHOT |
150*4882a593Smuzhiyun CLOCK_EVT_FEAT_PERIODIC,
151*4882a593Smuzhiyun .rating = 300,
152*4882a593Smuzhiyun .set_next_event = lpc32xx_clkevt_next_event,
153*4882a593Smuzhiyun .set_state_shutdown = lpc32xx_clkevt_shutdown,
154*4882a593Smuzhiyun .set_state_oneshot = lpc32xx_clkevt_oneshot,
155*4882a593Smuzhiyun .set_state_periodic = lpc32xx_clkevt_periodic,
156*4882a593Smuzhiyun },
157*4882a593Smuzhiyun };
158*4882a593Smuzhiyun
lpc32xx_clocksource_init(struct device_node * np)159*4882a593Smuzhiyun static int __init lpc32xx_clocksource_init(struct device_node *np)
160*4882a593Smuzhiyun {
161*4882a593Smuzhiyun void __iomem *base;
162*4882a593Smuzhiyun unsigned long rate;
163*4882a593Smuzhiyun struct clk *clk;
164*4882a593Smuzhiyun int ret;
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun clk = of_clk_get_by_name(np, "timerclk");
167*4882a593Smuzhiyun if (IS_ERR(clk)) {
168*4882a593Smuzhiyun pr_err("clock get failed (%ld)\n", PTR_ERR(clk));
169*4882a593Smuzhiyun return PTR_ERR(clk);
170*4882a593Smuzhiyun }
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun ret = clk_prepare_enable(clk);
173*4882a593Smuzhiyun if (ret) {
174*4882a593Smuzhiyun pr_err("clock enable failed (%d)\n", ret);
175*4882a593Smuzhiyun goto err_clk_enable;
176*4882a593Smuzhiyun }
177*4882a593Smuzhiyun
178*4882a593Smuzhiyun base = of_iomap(np, 0);
179*4882a593Smuzhiyun if (!base) {
180*4882a593Smuzhiyun pr_err("unable to map registers\n");
181*4882a593Smuzhiyun ret = -EADDRNOTAVAIL;
182*4882a593Smuzhiyun goto err_iomap;
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun /*
186*4882a593Smuzhiyun * Disable and reset timer then set it to free running timer
187*4882a593Smuzhiyun * mode (CTCR) with no prescaler (PR) or match operations (MCR).
188*4882a593Smuzhiyun * After setup the timer is released from reset and enabled.
189*4882a593Smuzhiyun */
190*4882a593Smuzhiyun writel_relaxed(LPC32XX_TIMER_TCR_CRST, base + LPC32XX_TIMER_TCR);
191*4882a593Smuzhiyun writel_relaxed(0, base + LPC32XX_TIMER_PR);
192*4882a593Smuzhiyun writel_relaxed(0, base + LPC32XX_TIMER_MCR);
193*4882a593Smuzhiyun writel_relaxed(0, base + LPC32XX_TIMER_CTCR);
194*4882a593Smuzhiyun writel_relaxed(LPC32XX_TIMER_TCR_CEN, base + LPC32XX_TIMER_TCR);
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun rate = clk_get_rate(clk);
197*4882a593Smuzhiyun ret = clocksource_mmio_init(base + LPC32XX_TIMER_TC, "lpc3220 timer",
198*4882a593Smuzhiyun rate, 300, 32, clocksource_mmio_readl_up);
199*4882a593Smuzhiyun if (ret) {
200*4882a593Smuzhiyun pr_err("failed to init clocksource (%d)\n", ret);
201*4882a593Smuzhiyun goto err_clocksource_init;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun clocksource_timer_counter = base + LPC32XX_TIMER_TC;
205*4882a593Smuzhiyun lpc32xx_delay_timer.freq = rate;
206*4882a593Smuzhiyun register_current_timer_delay(&lpc32xx_delay_timer);
207*4882a593Smuzhiyun sched_clock_register(lpc32xx_read_sched_clock, 32, rate);
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun return 0;
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun err_clocksource_init:
212*4882a593Smuzhiyun iounmap(base);
213*4882a593Smuzhiyun err_iomap:
214*4882a593Smuzhiyun clk_disable_unprepare(clk);
215*4882a593Smuzhiyun err_clk_enable:
216*4882a593Smuzhiyun clk_put(clk);
217*4882a593Smuzhiyun return ret;
218*4882a593Smuzhiyun }
219*4882a593Smuzhiyun
lpc32xx_clockevent_init(struct device_node * np)220*4882a593Smuzhiyun static int __init lpc32xx_clockevent_init(struct device_node *np)
221*4882a593Smuzhiyun {
222*4882a593Smuzhiyun void __iomem *base;
223*4882a593Smuzhiyun unsigned long rate;
224*4882a593Smuzhiyun struct clk *clk;
225*4882a593Smuzhiyun int ret, irq;
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun clk = of_clk_get_by_name(np, "timerclk");
228*4882a593Smuzhiyun if (IS_ERR(clk)) {
229*4882a593Smuzhiyun pr_err("clock get failed (%ld)\n", PTR_ERR(clk));
230*4882a593Smuzhiyun return PTR_ERR(clk);
231*4882a593Smuzhiyun }
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun ret = clk_prepare_enable(clk);
234*4882a593Smuzhiyun if (ret) {
235*4882a593Smuzhiyun pr_err("clock enable failed (%d)\n", ret);
236*4882a593Smuzhiyun goto err_clk_enable;
237*4882a593Smuzhiyun }
238*4882a593Smuzhiyun
239*4882a593Smuzhiyun base = of_iomap(np, 0);
240*4882a593Smuzhiyun if (!base) {
241*4882a593Smuzhiyun pr_err("unable to map registers\n");
242*4882a593Smuzhiyun ret = -EADDRNOTAVAIL;
243*4882a593Smuzhiyun goto err_iomap;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun irq = irq_of_parse_and_map(np, 0);
247*4882a593Smuzhiyun if (!irq) {
248*4882a593Smuzhiyun pr_err("get irq failed\n");
249*4882a593Smuzhiyun ret = -ENOENT;
250*4882a593Smuzhiyun goto err_irq;
251*4882a593Smuzhiyun }
252*4882a593Smuzhiyun
253*4882a593Smuzhiyun /*
254*4882a593Smuzhiyun * Disable timer and clear any pending interrupt (IR) on match
255*4882a593Smuzhiyun * channel 0 (MR0). Clear the prescaler as it's not used.
256*4882a593Smuzhiyun */
257*4882a593Smuzhiyun writel_relaxed(0, base + LPC32XX_TIMER_TCR);
258*4882a593Smuzhiyun writel_relaxed(0, base + LPC32XX_TIMER_PR);
259*4882a593Smuzhiyun writel_relaxed(0, base + LPC32XX_TIMER_CTCR);
260*4882a593Smuzhiyun writel_relaxed(LPC32XX_TIMER_IR_MR0INT, base + LPC32XX_TIMER_IR);
261*4882a593Smuzhiyun
262*4882a593Smuzhiyun rate = clk_get_rate(clk);
263*4882a593Smuzhiyun lpc32xx_clk_event_ddata.base = base;
264*4882a593Smuzhiyun lpc32xx_clk_event_ddata.ticks_per_jiffy = DIV_ROUND_CLOSEST(rate, HZ);
265*4882a593Smuzhiyun clockevents_config_and_register(&lpc32xx_clk_event_ddata.evtdev,
266*4882a593Smuzhiyun rate, 1, -1);
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun ret = request_irq(irq, lpc32xx_clock_event_handler,
269*4882a593Smuzhiyun IRQF_TIMER | IRQF_IRQPOLL, "lpc3220 clockevent",
270*4882a593Smuzhiyun &lpc32xx_clk_event_ddata);
271*4882a593Smuzhiyun if (ret) {
272*4882a593Smuzhiyun pr_err("request irq failed\n");
273*4882a593Smuzhiyun goto err_irq;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun
276*4882a593Smuzhiyun return 0;
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun err_irq:
279*4882a593Smuzhiyun iounmap(base);
280*4882a593Smuzhiyun err_iomap:
281*4882a593Smuzhiyun clk_disable_unprepare(clk);
282*4882a593Smuzhiyun err_clk_enable:
283*4882a593Smuzhiyun clk_put(clk);
284*4882a593Smuzhiyun return ret;
285*4882a593Smuzhiyun }
286*4882a593Smuzhiyun
287*4882a593Smuzhiyun /*
288*4882a593Smuzhiyun * This function asserts that we have exactly one clocksource and one
289*4882a593Smuzhiyun * clock_event_device in the end.
290*4882a593Smuzhiyun */
lpc32xx_timer_init(struct device_node * np)291*4882a593Smuzhiyun static int __init lpc32xx_timer_init(struct device_node *np)
292*4882a593Smuzhiyun {
293*4882a593Smuzhiyun static int has_clocksource, has_clockevent;
294*4882a593Smuzhiyun int ret = 0;
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun if (!has_clocksource) {
297*4882a593Smuzhiyun ret = lpc32xx_clocksource_init(np);
298*4882a593Smuzhiyun if (!ret) {
299*4882a593Smuzhiyun has_clocksource = 1;
300*4882a593Smuzhiyun return 0;
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun }
303*4882a593Smuzhiyun
304*4882a593Smuzhiyun if (!has_clockevent) {
305*4882a593Smuzhiyun ret = lpc32xx_clockevent_init(np);
306*4882a593Smuzhiyun if (!ret) {
307*4882a593Smuzhiyun has_clockevent = 1;
308*4882a593Smuzhiyun return 0;
309*4882a593Smuzhiyun }
310*4882a593Smuzhiyun }
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun return ret;
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun TIMER_OF_DECLARE(lpc32xx_timer, "nxp,lpc3220-timer", lpc32xx_timer_init);
315