hc
2024-11-01 2f529f9b558ca1c1bd74be7437a84e4711743404
commit | author | age
a07526 1 // SPDX-License-Identifier: GPL-2.0-only
H 2 /*
3  * (C) Copyright 2009 Intel Corporation
4  * Author: Jacob Pan (jacob.jun.pan@intel.com)
5  *
6  * Shared with ARM platforms, Jamie Iles, Picochip 2011
7  *
8  * Support for the Synopsys DesignWare APB Timers.
9  */
10 #include <linux/dw_apb_timer.h>
11 #include <linux/delay.h>
12 #include <linux/kernel.h>
13 #include <linux/interrupt.h>
14 #include <linux/irq.h>
15 #include <linux/io.h>
16 #include <linux/slab.h>
17
18 #define APBT_MIN_PERIOD            4
19 #define APBT_MIN_DELTA_USEC        200
20
21 #define APBTMR_N_LOAD_COUNT        0x00
22 #define APBTMR_N_CURRENT_VALUE        0x04
23 #define APBTMR_N_CONTROL        0x08
24 #define APBTMR_N_EOI            0x0c
25 #define APBTMR_N_INT_STATUS        0x10
26
27 #define APBTMRS_INT_STATUS        0xa0
28 #define APBTMRS_EOI            0xa4
29 #define APBTMRS_RAW_INT_STATUS        0xa8
30 #define APBTMRS_COMP_VERSION        0xac
31
32 #define APBTMR_CONTROL_ENABLE        (1 << 0)
33 /* 1: periodic, 0:free running. */
34 #define APBTMR_CONTROL_MODE_PERIODIC    (1 << 1)
35 #define APBTMR_CONTROL_INT        (1 << 2)
36
37 static inline struct dw_apb_clock_event_device *
38 ced_to_dw_apb_ced(struct clock_event_device *evt)
39 {
40    return container_of(evt, struct dw_apb_clock_event_device, ced);
41 }
42
43 static inline struct dw_apb_clocksource *
44 clocksource_to_dw_apb_clocksource(struct clocksource *cs)
45 {
2f529f 46    return container_of(cs, struct dw_apb_clocksource, ummio.mmio.clksrc);
a07526 47 }
H 48
49 static inline u32 apbt_readl(struct dw_apb_timer *timer, unsigned long offs)
50 {
51    return readl(timer->base + offs);
52 }
53
54 static inline void apbt_writel(struct dw_apb_timer *timer, u32 val,
55            unsigned long offs)
56 {
57    writel(val, timer->base + offs);
58 }
59
60 static inline u32 apbt_readl_relaxed(struct dw_apb_timer *timer, unsigned long offs)
61 {
62    return readl_relaxed(timer->base + offs);
63 }
64
65 static inline void apbt_writel_relaxed(struct dw_apb_timer *timer, u32 val,
66            unsigned long offs)
67 {
68    writel_relaxed(val, timer->base + offs);
69 }
70
71 static void apbt_disable_int(struct dw_apb_timer *timer)
72 {
73    u32 ctrl = apbt_readl(timer, APBTMR_N_CONTROL);
74
75    ctrl |= APBTMR_CONTROL_INT;
76    apbt_writel(timer, ctrl, APBTMR_N_CONTROL);
77 }
78
79 /**
80  * dw_apb_clockevent_pause() - stop the clock_event_device from running
81  *
82  * @dw_ced:    The APB clock to stop generating events.
83  */
84 void dw_apb_clockevent_pause(struct dw_apb_clock_event_device *dw_ced)
85 {
86    disable_irq(dw_ced->timer.irq);
87    apbt_disable_int(&dw_ced->timer);
88 }
89
90 static void apbt_eoi(struct dw_apb_timer *timer)
91 {
92    apbt_readl_relaxed(timer, APBTMR_N_EOI);
93 }
94
95 static irqreturn_t dw_apb_clockevent_irq(int irq, void *data)
96 {
97    struct clock_event_device *evt = data;
98    struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
99
100    if (!evt->event_handler) {
101        pr_info("Spurious APBT timer interrupt %d\n", irq);
102        return IRQ_NONE;
103    }
104
105    if (dw_ced->eoi)
106        dw_ced->eoi(&dw_ced->timer);
107
108    evt->event_handler(evt);
109    return IRQ_HANDLED;
110 }
111
112 static void apbt_enable_int(struct dw_apb_timer *timer)
113 {
114    u32 ctrl = apbt_readl(timer, APBTMR_N_CONTROL);
115    /* clear pending intr */
116    apbt_readl(timer, APBTMR_N_EOI);
117    ctrl &= ~APBTMR_CONTROL_INT;
118    apbt_writel(timer, ctrl, APBTMR_N_CONTROL);
119 }
120
121 static int apbt_shutdown(struct clock_event_device *evt)
122 {
123    struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
124    u32 ctrl;
125
126    pr_debug("%s CPU %d state=shutdown\n", __func__,
127         cpumask_first(evt->cpumask));
128
129    ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL);
130    ctrl &= ~APBTMR_CONTROL_ENABLE;
131    apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
132    return 0;
133 }
134
135 static int apbt_set_oneshot(struct clock_event_device *evt)
136 {
137    struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
138    u32 ctrl;
139
140    pr_debug("%s CPU %d state=oneshot\n", __func__,
141         cpumask_first(evt->cpumask));
142
143    ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL);
144    /*
145     * set free running mode, this mode will let timer reload max
146     * timeout which will give time (3min on 25MHz clock) to rearm
147     * the next event, therefore emulate the one-shot mode.
148     */
149    ctrl &= ~APBTMR_CONTROL_ENABLE;
150    ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
151
152    apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
153    /* write again to set free running mode */
154    apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
155
156    /*
157     * DW APB p. 46, load counter with all 1s before starting free
158     * running mode.
159     */
160    apbt_writel(&dw_ced->timer, ~0, APBTMR_N_LOAD_COUNT);
161    ctrl &= ~APBTMR_CONTROL_INT;
162    ctrl |= APBTMR_CONTROL_ENABLE;
163    apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
164    return 0;
165 }
166
167 static int apbt_set_periodic(struct clock_event_device *evt)
168 {
169    struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
170    unsigned long period = DIV_ROUND_UP(dw_ced->timer.freq, HZ);
171    u32 ctrl;
172
173    pr_debug("%s CPU %d state=periodic\n", __func__,
174         cpumask_first(evt->cpumask));
175
176    ctrl = apbt_readl(&dw_ced->timer, APBTMR_N_CONTROL);
177    ctrl |= APBTMR_CONTROL_MODE_PERIODIC;
178    apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
179    /*
180     * DW APB p. 46, have to disable timer before load counter,
181     * may cause sync problem.
182     */
183    ctrl &= ~APBTMR_CONTROL_ENABLE;
184    apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
185    udelay(1);
186    pr_debug("Setting clock period %lu for HZ %d\n", period, HZ);
187    apbt_writel(&dw_ced->timer, period, APBTMR_N_LOAD_COUNT);
188    ctrl |= APBTMR_CONTROL_ENABLE;
189    apbt_writel(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
190    return 0;
191 }
192
193 static int apbt_resume(struct clock_event_device *evt)
194 {
195    struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
196
197    pr_debug("%s CPU %d state=resume\n", __func__,
198         cpumask_first(evt->cpumask));
199
200    apbt_enable_int(&dw_ced->timer);
201    return 0;
202 }
203
204 static int apbt_next_event(unsigned long delta,
205               struct clock_event_device *evt)
206 {
207    u32 ctrl;
208    struct dw_apb_clock_event_device *dw_ced = ced_to_dw_apb_ced(evt);
209
210    /* Disable timer */
211    ctrl = apbt_readl_relaxed(&dw_ced->timer, APBTMR_N_CONTROL);
212    ctrl &= ~APBTMR_CONTROL_ENABLE;
213    apbt_writel_relaxed(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
214    /* write new count */
215    apbt_writel_relaxed(&dw_ced->timer, delta, APBTMR_N_LOAD_COUNT);
216    ctrl |= APBTMR_CONTROL_ENABLE;
217    apbt_writel_relaxed(&dw_ced->timer, ctrl, APBTMR_N_CONTROL);
218
219    return 0;
220 }
221
222 /**
223  * dw_apb_clockevent_init() - use an APB timer as a clock_event_device
224  *
225  * @cpu:    The CPU the events will be targeted at or -1 if CPU affiliation
226  *        isn't required.
227  * @name:    The name used for the timer and the IRQ for it.
228  * @rating:    The rating to give the timer.
229  * @base:    I/O base for the timer registers.
230  * @irq:    The interrupt number to use for the timer.
231  * @freq:    The frequency that the timer counts at.
232  *
233  * This creates a clock_event_device for using with the generic clock layer
234  * but does not start and register it.  This should be done with
235  * dw_apb_clockevent_register() as the next step.  If this is the first time
236  * it has been called for a timer then the IRQ will be requested, if not it
237  * just be enabled to allow CPU hotplug to avoid repeatedly requesting and
238  * releasing the IRQ.
239  */
240 struct dw_apb_clock_event_device *
241 dw_apb_clockevent_init(int cpu, const char *name, unsigned rating,
242               void __iomem *base, int irq, unsigned long freq)
243 {
244    struct dw_apb_clock_event_device *dw_ced =
245        kzalloc(sizeof(*dw_ced), GFP_KERNEL);
246    int err;
247
248    if (!dw_ced)
249        return NULL;
250
251    dw_ced->timer.base = base;
252    dw_ced->timer.irq = irq;
253    dw_ced->timer.freq = freq;
254
255    clockevents_calc_mult_shift(&dw_ced->ced, freq, APBT_MIN_PERIOD);
256    dw_ced->ced.max_delta_ns = clockevent_delta2ns(0x7fffffff,
257                               &dw_ced->ced);
258    dw_ced->ced.max_delta_ticks = 0x7fffffff;
259    dw_ced->ced.min_delta_ns = clockevent_delta2ns(5000, &dw_ced->ced);
260    dw_ced->ced.min_delta_ticks = 5000;
261    dw_ced->ced.cpumask = cpu < 0 ? cpu_possible_mask : cpumask_of(cpu);
262    dw_ced->ced.features = CLOCK_EVT_FEAT_PERIODIC |
263                CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ;
264    dw_ced->ced.set_state_shutdown = apbt_shutdown;
265    dw_ced->ced.set_state_periodic = apbt_set_periodic;
266    dw_ced->ced.set_state_oneshot = apbt_set_oneshot;
267    dw_ced->ced.set_state_oneshot_stopped = apbt_shutdown;
268    dw_ced->ced.tick_resume = apbt_resume;
269    dw_ced->ced.set_next_event = apbt_next_event;
270    dw_ced->ced.irq = dw_ced->timer.irq;
271    dw_ced->ced.rating = rating;
272    dw_ced->ced.name = name;
273
274    dw_ced->eoi = apbt_eoi;
275    err = request_irq(irq, dw_apb_clockevent_irq,
276              IRQF_TIMER | IRQF_IRQPOLL | IRQF_NOBALANCING,
277              dw_ced->ced.name, &dw_ced->ced);
278    if (err) {
279        pr_err("failed to request timer irq\n");
280        kfree(dw_ced);
281        dw_ced = NULL;
282    }
283
284    return dw_ced;
285 }
286
287 /**
288  * dw_apb_clockevent_resume() - resume a clock that has been paused.
289  *
290  * @dw_ced:    The APB clock to resume.
291  */
292 void dw_apb_clockevent_resume(struct dw_apb_clock_event_device *dw_ced)
293 {
294    enable_irq(dw_ced->timer.irq);
295 }
296
297 /**
298  * dw_apb_clockevent_stop() - stop the clock_event_device and release the IRQ.
299  *
300  * @dw_ced:    The APB clock to stop generating the events.
301  */
302 void dw_apb_clockevent_stop(struct dw_apb_clock_event_device *dw_ced)
303 {
304    free_irq(dw_ced->timer.irq, &dw_ced->ced);
305 }
306
307 /**
308  * dw_apb_clockevent_register() - register the clock with the generic layer
309  *
310  * @dw_ced:    The APB clock to register as a clock_event_device.
311  */
312 void dw_apb_clockevent_register(struct dw_apb_clock_event_device *dw_ced)
313 {
314    apbt_writel(&dw_ced->timer, 0, APBTMR_N_CONTROL);
315    clockevents_register_device(&dw_ced->ced);
316    apbt_enable_int(&dw_ced->timer);
317 }
318
319 /**
320  * dw_apb_clocksource_start() - start the clocksource counting.
321  *
322  * @dw_cs:    The clocksource to start.
323  *
324  * This is used to start the clocksource before registration and can be used
325  * to enable calibration of timers.
326  */
327 void dw_apb_clocksource_start(struct dw_apb_clocksource *dw_cs)
328 {
329    /*
330     * start count down from 0xffff_ffff. this is done by toggling the
331     * enable bit then load initial load count to ~0.
332     */
333    u32 ctrl = apbt_readl(&dw_cs->timer, APBTMR_N_CONTROL);
334
335    ctrl &= ~APBTMR_CONTROL_ENABLE;
336    apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL);
337    apbt_writel(&dw_cs->timer, ~0, APBTMR_N_LOAD_COUNT);
338    /* enable, mask interrupt */
339    ctrl &= ~APBTMR_CONTROL_MODE_PERIODIC;
340    ctrl |= (APBTMR_CONTROL_ENABLE | APBTMR_CONTROL_INT);
341    apbt_writel(&dw_cs->timer, ctrl, APBTMR_N_CONTROL);
342    /* read it once to get cached counter value initialized */
343    dw_apb_clocksource_read(dw_cs);
344 }
345
346 static void apbt_restart_clocksource(struct clocksource *cs)
347 {
348    struct dw_apb_clocksource *dw_cs =
349        clocksource_to_dw_apb_clocksource(cs);
350
351    dw_apb_clocksource_start(dw_cs);
352 }
353
354 /**
355  * dw_apb_clocksource_init() - use an APB timer as a clocksource.
356  *
357  * @rating:    The rating to give the clocksource.
358  * @name:    The name for the clocksource.
359  * @base:    The I/O base for the timer registers.
360  * @freq:    The frequency that the timer counts at.
361  *
362  * This creates a clocksource using an APB timer but does not yet register it
363  * with the clocksource system.  This should be done with
364  * dw_apb_clocksource_register() as the next step.
365  */
366 struct dw_apb_clocksource *
2f529f 367 __init dw_apb_clocksource_init(unsigned rating, const char *name, void __iomem *base,
a07526 368            unsigned long freq)
H 369 {
370    struct dw_apb_clocksource *dw_cs = kzalloc(sizeof(*dw_cs), GFP_KERNEL);
371
372    if (!dw_cs)
373        return NULL;
374
375    dw_cs->timer.base = base;
376    dw_cs->timer.freq = freq;
2f529f 377    dw_cs->ummio.mmio.clksrc.name = name;
H 378    dw_cs->ummio.mmio.clksrc.rating = rating;
379    dw_cs->ummio.mmio.clksrc.read = clocksource_mmio_readl_down;
380    dw_cs->ummio.mmio.clksrc.mask = CLOCKSOURCE_MASK(32);
381    dw_cs->ummio.mmio.clksrc.flags = CLOCK_SOURCE_IS_CONTINUOUS;
382    dw_cs->ummio.mmio.clksrc.resume = apbt_restart_clocksource;
a07526 383
H 384    return dw_cs;
385 }
386
387 /**
388  * dw_apb_clocksource_register() - register the APB clocksource.
389  *
390  * @dw_cs:    The clocksource to register.
391  */
2f529f 392 void __init dw_apb_clocksource_register(struct dw_apb_clocksource *dw_cs)
a07526 393 {
2f529f 394    struct clocksource_mmio_regs mmr;
H 395
396    mmr.reg_lower = dw_cs->timer.base + APBTMR_N_CURRENT_VALUE;
397    mmr.bits_lower = 32;
398    mmr.reg_upper = 0;
399    mmr.bits_upper = 0;
400    mmr.revmap = NULL;
401
402    clocksource_user_mmio_init(&dw_cs->ummio, &mmr, dw_cs->timer.freq);
a07526 403 }
H 404
405 /**
406  * dw_apb_clocksource_read() - read the current value of a clocksource.
407  *
408  * @dw_cs:    The clocksource to read.
409  */
410 u64 dw_apb_clocksource_read(struct dw_apb_clocksource *dw_cs)
411 {
412    return (u64)~apbt_readl(&dw_cs->timer, APBTMR_N_CURRENT_VALUE);
413 }