Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/clocksource/timer-fttmr010.c
26278 views
1
// SPDX-License-Identifier: GPL-2.0
2
/*
3
* Faraday Technology FTTMR010 timer driver
4
* Copyright (C) 2017 Linus Walleij <[email protected]>
5
*
6
* Based on a rewrite of arch/arm/mach-gemini/timer.c:
7
* Copyright (C) 2001-2006 Storlink, Corp.
8
* Copyright (C) 2008-2009 Paulius Zaleckas <[email protected]>
9
*/
10
#include <linux/interrupt.h>
11
#include <linux/io.h>
12
#include <linux/of.h>
13
#include <linux/of_address.h>
14
#include <linux/of_irq.h>
15
#include <linux/clockchips.h>
16
#include <linux/clocksource.h>
17
#include <linux/sched_clock.h>
18
#include <linux/clk.h>
19
#include <linux/slab.h>
20
#include <linux/bitops.h>
21
#include <linux/delay.h>
22
23
/*
24
* Register definitions common for all the timer variants.
25
*/
26
#define TIMER1_COUNT (0x00)
27
#define TIMER1_LOAD (0x04)
28
#define TIMER1_MATCH1 (0x08)
29
#define TIMER1_MATCH2 (0x0c)
30
#define TIMER2_COUNT (0x10)
31
#define TIMER2_LOAD (0x14)
32
#define TIMER2_MATCH1 (0x18)
33
#define TIMER2_MATCH2 (0x1c)
34
#define TIMER3_COUNT (0x20)
35
#define TIMER3_LOAD (0x24)
36
#define TIMER3_MATCH1 (0x28)
37
#define TIMER3_MATCH2 (0x2c)
38
#define TIMER_CR (0x30)
39
40
/*
41
* Control register set to clear for ast2600 only.
42
*/
43
#define AST2600_TIMER_CR_CLR (0x3c)
44
45
/*
46
* Control register (TMC30) bit fields for fttmr010/gemini/moxart timers.
47
*/
48
#define TIMER_1_CR_ENABLE BIT(0)
49
#define TIMER_1_CR_CLOCK BIT(1)
50
#define TIMER_1_CR_INT BIT(2)
51
#define TIMER_2_CR_ENABLE BIT(3)
52
#define TIMER_2_CR_CLOCK BIT(4)
53
#define TIMER_2_CR_INT BIT(5)
54
#define TIMER_3_CR_ENABLE BIT(6)
55
#define TIMER_3_CR_CLOCK BIT(7)
56
#define TIMER_3_CR_INT BIT(8)
57
#define TIMER_1_CR_UPDOWN BIT(9)
58
#define TIMER_2_CR_UPDOWN BIT(10)
59
#define TIMER_3_CR_UPDOWN BIT(11)
60
61
/*
62
* Control register (TMC30) bit fields for aspeed ast2400/ast2500 timers.
63
* The aspeed timers move bits around in the control register and lacks
64
* bits for setting the timer to count upwards.
65
*/
66
#define TIMER_1_CR_ASPEED_ENABLE BIT(0)
67
#define TIMER_1_CR_ASPEED_CLOCK BIT(1)
68
#define TIMER_1_CR_ASPEED_INT BIT(2)
69
#define TIMER_2_CR_ASPEED_ENABLE BIT(4)
70
#define TIMER_2_CR_ASPEED_CLOCK BIT(5)
71
#define TIMER_2_CR_ASPEED_INT BIT(6)
72
#define TIMER_3_CR_ASPEED_ENABLE BIT(8)
73
#define TIMER_3_CR_ASPEED_CLOCK BIT(9)
74
#define TIMER_3_CR_ASPEED_INT BIT(10)
75
76
/*
77
* Interrupt status/mask register definitions for fttmr010/gemini/moxart
78
* timers.
79
* The registers don't exist and they are not needed on aspeed timers
80
* because:
81
* - aspeed timer overflow interrupt is controlled by bits in Control
82
* Register (TMC30).
83
* - aspeed timers always generate interrupt when either one of the
84
* Match registers equals to Status register.
85
*/
86
#define TIMER_INTR_STATE (0x34)
87
#define TIMER_INTR_MASK (0x38)
88
#define TIMER_1_INT_MATCH1 BIT(0)
89
#define TIMER_1_INT_MATCH2 BIT(1)
90
#define TIMER_1_INT_OVERFLOW BIT(2)
91
#define TIMER_2_INT_MATCH1 BIT(3)
92
#define TIMER_2_INT_MATCH2 BIT(4)
93
#define TIMER_2_INT_OVERFLOW BIT(5)
94
#define TIMER_3_INT_MATCH1 BIT(6)
95
#define TIMER_3_INT_MATCH2 BIT(7)
96
#define TIMER_3_INT_OVERFLOW BIT(8)
97
#define TIMER_INT_ALL_MASK 0x1ff
98
99
struct fttmr010 {
100
void __iomem *base;
101
unsigned int tick_rate;
102
bool is_aspeed;
103
u32 t1_enable_val;
104
struct clock_event_device clkevt;
105
int (*timer_shutdown)(struct clock_event_device *evt);
106
#ifdef CONFIG_ARM
107
struct delay_timer delay_timer;
108
#endif
109
};
110
111
/*
112
* A local singleton used by sched_clock and delay timer reads, which are
113
* fast and stateless
114
*/
115
static struct fttmr010 *local_fttmr;
116
117
static inline struct fttmr010 *to_fttmr010(struct clock_event_device *evt)
118
{
119
return container_of(evt, struct fttmr010, clkevt);
120
}
121
122
static unsigned long fttmr010_read_current_timer_up(void)
123
{
124
return readl(local_fttmr->base + TIMER2_COUNT);
125
}
126
127
static unsigned long fttmr010_read_current_timer_down(void)
128
{
129
return ~readl(local_fttmr->base + TIMER2_COUNT);
130
}
131
132
static u64 notrace fttmr010_read_sched_clock_up(void)
133
{
134
return fttmr010_read_current_timer_up();
135
}
136
137
static u64 notrace fttmr010_read_sched_clock_down(void)
138
{
139
return fttmr010_read_current_timer_down();
140
}
141
142
static int fttmr010_timer_set_next_event(unsigned long cycles,
143
struct clock_event_device *evt)
144
{
145
struct fttmr010 *fttmr010 = to_fttmr010(evt);
146
u32 cr;
147
148
/* Stop */
149
fttmr010->timer_shutdown(evt);
150
151
if (fttmr010->is_aspeed) {
152
/*
153
* ASPEED Timer Controller will load TIMER1_LOAD register
154
* into TIMER1_COUNT register when the timer is re-enabled.
155
*/
156
writel(cycles, fttmr010->base + TIMER1_LOAD);
157
} else {
158
/* Setup the match register forward in time */
159
cr = readl(fttmr010->base + TIMER1_COUNT);
160
writel(cr + cycles, fttmr010->base + TIMER1_MATCH1);
161
}
162
163
/* Start */
164
cr = readl(fttmr010->base + TIMER_CR);
165
cr |= fttmr010->t1_enable_val;
166
writel(cr, fttmr010->base + TIMER_CR);
167
168
return 0;
169
}
170
171
static int ast2600_timer_shutdown(struct clock_event_device *evt)
172
{
173
struct fttmr010 *fttmr010 = to_fttmr010(evt);
174
175
/* Stop */
176
writel(fttmr010->t1_enable_val, fttmr010->base + AST2600_TIMER_CR_CLR);
177
178
return 0;
179
}
180
181
static int fttmr010_timer_shutdown(struct clock_event_device *evt)
182
{
183
struct fttmr010 *fttmr010 = to_fttmr010(evt);
184
u32 cr;
185
186
/* Stop */
187
cr = readl(fttmr010->base + TIMER_CR);
188
cr &= ~fttmr010->t1_enable_val;
189
writel(cr, fttmr010->base + TIMER_CR);
190
191
return 0;
192
}
193
194
static int fttmr010_timer_set_oneshot(struct clock_event_device *evt)
195
{
196
struct fttmr010 *fttmr010 = to_fttmr010(evt);
197
u32 cr;
198
199
/* Stop */
200
fttmr010->timer_shutdown(evt);
201
202
/* Setup counter start from 0 or ~0 */
203
writel(0, fttmr010->base + TIMER1_COUNT);
204
if (fttmr010->is_aspeed) {
205
writel(~0, fttmr010->base + TIMER1_LOAD);
206
} else {
207
writel(0, fttmr010->base + TIMER1_LOAD);
208
209
/* Enable interrupt */
210
cr = readl(fttmr010->base + TIMER_INTR_MASK);
211
cr &= ~(TIMER_1_INT_OVERFLOW | TIMER_1_INT_MATCH2);
212
cr |= TIMER_1_INT_MATCH1;
213
writel(cr, fttmr010->base + TIMER_INTR_MASK);
214
}
215
216
return 0;
217
}
218
219
static int fttmr010_timer_set_periodic(struct clock_event_device *evt)
220
{
221
struct fttmr010 *fttmr010 = to_fttmr010(evt);
222
u32 period = DIV_ROUND_CLOSEST(fttmr010->tick_rate, HZ);
223
u32 cr;
224
225
/* Stop */
226
fttmr010->timer_shutdown(evt);
227
228
/* Setup timer to fire at 1/HZ intervals. */
229
if (fttmr010->is_aspeed) {
230
writel(period, fttmr010->base + TIMER1_LOAD);
231
} else {
232
cr = 0xffffffff - (period - 1);
233
writel(cr, fttmr010->base + TIMER1_COUNT);
234
writel(cr, fttmr010->base + TIMER1_LOAD);
235
236
/* Enable interrupt on overflow */
237
cr = readl(fttmr010->base + TIMER_INTR_MASK);
238
cr &= ~(TIMER_1_INT_MATCH1 | TIMER_1_INT_MATCH2);
239
cr |= TIMER_1_INT_OVERFLOW;
240
writel(cr, fttmr010->base + TIMER_INTR_MASK);
241
}
242
243
/* Start the timer */
244
cr = readl(fttmr010->base + TIMER_CR);
245
cr |= fttmr010->t1_enable_val;
246
writel(cr, fttmr010->base + TIMER_CR);
247
248
return 0;
249
}
250
251
/*
252
* IRQ handler for the timer
253
*/
254
static irqreturn_t fttmr010_timer_interrupt(int irq, void *dev_id)
255
{
256
struct clock_event_device *evt = dev_id;
257
258
evt->event_handler(evt);
259
return IRQ_HANDLED;
260
}
261
262
static irqreturn_t ast2600_timer_interrupt(int irq, void *dev_id)
263
{
264
struct clock_event_device *evt = dev_id;
265
struct fttmr010 *fttmr010 = to_fttmr010(evt);
266
267
writel(0x1, fttmr010->base + TIMER_INTR_STATE);
268
269
evt->event_handler(evt);
270
return IRQ_HANDLED;
271
}
272
273
static int __init fttmr010_common_init(struct device_node *np,
274
bool is_aspeed, bool is_ast2600)
275
{
276
struct fttmr010 *fttmr010;
277
int irq;
278
struct clk *clk;
279
int ret;
280
u32 val;
281
282
/*
283
* These implementations require a clock reference.
284
* FIXME: we currently only support clocking using PCLK
285
* and using EXTCLK is not supported in the driver.
286
*/
287
clk = of_clk_get_by_name(np, "PCLK");
288
if (IS_ERR(clk)) {
289
pr_err("could not get PCLK\n");
290
return PTR_ERR(clk);
291
}
292
ret = clk_prepare_enable(clk);
293
if (ret) {
294
pr_err("failed to enable PCLK\n");
295
return ret;
296
}
297
298
fttmr010 = kzalloc(sizeof(*fttmr010), GFP_KERNEL);
299
if (!fttmr010) {
300
ret = -ENOMEM;
301
goto out_disable_clock;
302
}
303
fttmr010->tick_rate = clk_get_rate(clk);
304
305
fttmr010->base = of_iomap(np, 0);
306
if (!fttmr010->base) {
307
pr_err("Can't remap registers\n");
308
ret = -ENXIO;
309
goto out_free;
310
}
311
/* IRQ for timer 1 */
312
irq = irq_of_parse_and_map(np, 0);
313
if (irq <= 0) {
314
pr_err("Can't parse IRQ\n");
315
ret = -EINVAL;
316
goto out_unmap;
317
}
318
319
/*
320
* The Aspeed timers move bits around in the control register.
321
*/
322
if (is_aspeed) {
323
fttmr010->t1_enable_val = TIMER_1_CR_ASPEED_ENABLE |
324
TIMER_1_CR_ASPEED_INT;
325
fttmr010->is_aspeed = true;
326
} else {
327
fttmr010->t1_enable_val = TIMER_1_CR_ENABLE | TIMER_1_CR_INT;
328
329
/*
330
* Reset the interrupt mask and status
331
*/
332
writel(TIMER_INT_ALL_MASK, fttmr010->base + TIMER_INTR_MASK);
333
writel(0, fttmr010->base + TIMER_INTR_STATE);
334
}
335
336
/*
337
* Enable timer 1 count up, timer 2 count up, except on Aspeed,
338
* where everything just counts down.
339
*/
340
if (is_aspeed)
341
val = TIMER_2_CR_ASPEED_ENABLE;
342
else {
343
val = TIMER_2_CR_ENABLE | TIMER_1_CR_UPDOWN |
344
TIMER_2_CR_UPDOWN;
345
}
346
writel(val, fttmr010->base + TIMER_CR);
347
348
/*
349
* Setup free-running clocksource timer (interrupts
350
* disabled.)
351
*/
352
local_fttmr = fttmr010;
353
writel(0, fttmr010->base + TIMER2_COUNT);
354
writel(0, fttmr010->base + TIMER2_MATCH1);
355
writel(0, fttmr010->base + TIMER2_MATCH2);
356
357
if (fttmr010->is_aspeed) {
358
writel(~0, fttmr010->base + TIMER2_LOAD);
359
clocksource_mmio_init(fttmr010->base + TIMER2_COUNT,
360
"FTTMR010-TIMER2",
361
fttmr010->tick_rate,
362
300, 32, clocksource_mmio_readl_down);
363
sched_clock_register(fttmr010_read_sched_clock_down, 32,
364
fttmr010->tick_rate);
365
} else {
366
writel(0, fttmr010->base + TIMER2_LOAD);
367
clocksource_mmio_init(fttmr010->base + TIMER2_COUNT,
368
"FTTMR010-TIMER2",
369
fttmr010->tick_rate,
370
300, 32, clocksource_mmio_readl_up);
371
sched_clock_register(fttmr010_read_sched_clock_up, 32,
372
fttmr010->tick_rate);
373
}
374
375
/*
376
* Setup clockevent timer (interrupt-driven) on timer 1.
377
*/
378
writel(0, fttmr010->base + TIMER1_COUNT);
379
writel(0, fttmr010->base + TIMER1_LOAD);
380
writel(0, fttmr010->base + TIMER1_MATCH1);
381
writel(0, fttmr010->base + TIMER1_MATCH2);
382
383
if (is_ast2600) {
384
fttmr010->timer_shutdown = ast2600_timer_shutdown;
385
ret = request_irq(irq, ast2600_timer_interrupt,
386
IRQF_TIMER, "FTTMR010-TIMER1",
387
&fttmr010->clkevt);
388
} else {
389
fttmr010->timer_shutdown = fttmr010_timer_shutdown;
390
ret = request_irq(irq, fttmr010_timer_interrupt,
391
IRQF_TIMER, "FTTMR010-TIMER1",
392
&fttmr010->clkevt);
393
}
394
if (ret) {
395
pr_err("FTTMR010-TIMER1 no IRQ\n");
396
goto out_unmap;
397
}
398
399
fttmr010->clkevt.name = "FTTMR010-TIMER1";
400
/* Reasonably fast and accurate clock event */
401
fttmr010->clkevt.rating = 300;
402
fttmr010->clkevt.features = CLOCK_EVT_FEAT_PERIODIC |
403
CLOCK_EVT_FEAT_ONESHOT;
404
fttmr010->clkevt.set_next_event = fttmr010_timer_set_next_event;
405
fttmr010->clkevt.set_state_shutdown = fttmr010->timer_shutdown;
406
fttmr010->clkevt.set_state_periodic = fttmr010_timer_set_periodic;
407
fttmr010->clkevt.set_state_oneshot = fttmr010_timer_set_oneshot;
408
fttmr010->clkevt.tick_resume = fttmr010->timer_shutdown;
409
fttmr010->clkevt.cpumask = cpumask_of(0);
410
fttmr010->clkevt.irq = irq;
411
clockevents_config_and_register(&fttmr010->clkevt,
412
fttmr010->tick_rate,
413
1, 0xffffffff);
414
415
#ifdef CONFIG_ARM
416
/* Also use this timer for delays */
417
if (fttmr010->is_aspeed)
418
fttmr010->delay_timer.read_current_timer =
419
fttmr010_read_current_timer_down;
420
else
421
fttmr010->delay_timer.read_current_timer =
422
fttmr010_read_current_timer_up;
423
fttmr010->delay_timer.freq = fttmr010->tick_rate;
424
register_current_timer_delay(&fttmr010->delay_timer);
425
#endif
426
427
return 0;
428
429
out_unmap:
430
iounmap(fttmr010->base);
431
out_free:
432
kfree(fttmr010);
433
out_disable_clock:
434
clk_disable_unprepare(clk);
435
436
return ret;
437
}
438
439
static __init int ast2600_timer_init(struct device_node *np)
440
{
441
return fttmr010_common_init(np, true, true);
442
}
443
444
static __init int aspeed_timer_init(struct device_node *np)
445
{
446
return fttmr010_common_init(np, true, false);
447
}
448
449
static __init int fttmr010_timer_init(struct device_node *np)
450
{
451
return fttmr010_common_init(np, false, false);
452
}
453
454
TIMER_OF_DECLARE(fttmr010, "faraday,fttmr010", fttmr010_timer_init);
455
TIMER_OF_DECLARE(gemini, "cortina,gemini-timer", fttmr010_timer_init);
456
TIMER_OF_DECLARE(moxart, "moxa,moxart-timer", fttmr010_timer_init);
457
TIMER_OF_DECLARE(ast2400, "aspeed,ast2400-timer", aspeed_timer_init);
458
TIMER_OF_DECLARE(ast2500, "aspeed,ast2500-timer", aspeed_timer_init);
459
TIMER_OF_DECLARE(ast2600, "aspeed,ast2600-timer", ast2600_timer_init);
460
461