1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * linux/drivers/clocksource/timer-sp.c
5 * Copyright (C) 1999 - 2003 ARM Limited
6 * Copyright (C) 2000 Deep Blue Solutions Ltd
9 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
11 #include <linux/clk.h>
12 #include <linux/clocksource.h>
13 #include <linux/clockchips.h>
14 #include <linux/err.h>
15 #include <linux/interrupt.h>
16 #include <linux/irq.h>
19 #include <linux/of_address.h>
20 #include <linux/of_clk.h>
21 #include <linux/of_irq.h>
22 #include <linux/sched_clock.h>
26 /* Hisilicon 64-bit timer(a variant of ARM SP804) */
27 #define HISI_TIMER_1_BASE 0x00
28 #define HISI_TIMER_2_BASE 0x40
29 #define HISI_TIMER_LOAD 0x00
30 #define HISI_TIMER_LOAD_H 0x04
31 #define HISI_TIMER_VALUE 0x08
32 #define HISI_TIMER_VALUE_H 0x0c
33 #define HISI_TIMER_CTRL 0x10
34 #define HISI_TIMER_INTCLR 0x14
35 #define HISI_TIMER_RIS 0x18
36 #define HISI_TIMER_MIS 0x1c
37 #define HISI_TIMER_BGLOAD 0x20
38 #define HISI_TIMER_BGLOAD_H 0x24
40 static struct sp804_timer arm_sp804_timer __initdata
= {
44 .intclr
= TIMER_INTCLR
,
45 .timer_base
= {TIMER_1_BASE
, TIMER_2_BASE
},
49 static struct sp804_timer hisi_sp804_timer __initdata
= {
50 .load
= HISI_TIMER_LOAD
,
51 .load_h
= HISI_TIMER_LOAD_H
,
52 .value
= HISI_TIMER_VALUE
,
53 .value_h
= HISI_TIMER_VALUE_H
,
54 .ctrl
= HISI_TIMER_CTRL
,
55 .intclr
= HISI_TIMER_INTCLR
,
56 .timer_base
= {HISI_TIMER_1_BASE
, HISI_TIMER_2_BASE
},
60 static struct sp804_clkevt sp804_clkevt
[NR_TIMERS
];
62 static long __init
sp804_get_clock_rate(struct clk
*clk
, const char *name
)
67 clk
= clk_get_sys("sp804", name
);
69 pr_err("%s clock not found: %ld\n", name
, PTR_ERR(clk
));
73 err
= clk_prepare_enable(clk
);
75 pr_err("clock failed to enable: %d\n", err
);
80 return clk_get_rate(clk
);
83 static struct sp804_clkevt
* __init
sp804_clkevt_get(void __iomem
*base
)
87 for (i
= 0; i
< NR_TIMERS
; i
++) {
88 if (sp804_clkevt
[i
].base
== base
)
89 return &sp804_clkevt
[i
];
92 /* It's impossible to reach here */
98 static struct sp804_clkevt
*sched_clkevt
;
100 static u64 notrace
sp804_read(void)
102 return ~readl_relaxed(sched_clkevt
->value
);
105 static int __init
sp804_clocksource_and_sched_clock_init(void __iomem
*base
,
111 struct sp804_clkevt
*clkevt
;
113 rate
= sp804_get_clock_rate(clk
, name
);
117 clkevt
= sp804_clkevt_get(base
);
119 writel(0, clkevt
->ctrl
);
120 writel(0xffffffff, clkevt
->load
);
121 writel(0xffffffff, clkevt
->value
);
122 if (clkevt
->width
== 64) {
123 writel(0xffffffff, clkevt
->load_h
);
124 writel(0xffffffff, clkevt
->value_h
);
126 writel(TIMER_CTRL_32BIT
| TIMER_CTRL_ENABLE
| TIMER_CTRL_PERIODIC
,
129 clocksource_mmio_init(clkevt
->value
, name
,
130 rate
, 200, 32, clocksource_mmio_readl_down
);
132 if (use_sched_clock
) {
133 sched_clkevt
= clkevt
;
134 sched_clock_register(sp804_read
, 32, rate
);
141 static struct sp804_clkevt
*common_clkevt
;
144 * IRQ handler for the timer
146 static irqreturn_t
sp804_timer_interrupt(int irq
, void *dev_id
)
148 struct clock_event_device
*evt
= dev_id
;
150 /* clear the interrupt */
151 writel(1, common_clkevt
->intclr
);
153 evt
->event_handler(evt
);
158 static inline void timer_shutdown(struct clock_event_device
*evt
)
160 writel(0, common_clkevt
->ctrl
);
163 static int sp804_shutdown(struct clock_event_device
*evt
)
169 static int sp804_set_periodic(struct clock_event_device
*evt
)
171 unsigned long ctrl
= TIMER_CTRL_32BIT
| TIMER_CTRL_IE
|
172 TIMER_CTRL_PERIODIC
| TIMER_CTRL_ENABLE
;
175 writel(common_clkevt
->reload
, common_clkevt
->load
);
176 writel(ctrl
, common_clkevt
->ctrl
);
180 static int sp804_set_next_event(unsigned long next
,
181 struct clock_event_device
*evt
)
183 unsigned long ctrl
= TIMER_CTRL_32BIT
| TIMER_CTRL_IE
|
184 TIMER_CTRL_ONESHOT
| TIMER_CTRL_ENABLE
;
186 writel(next
, common_clkevt
->load
);
187 writel(ctrl
, common_clkevt
->ctrl
);
192 static struct clock_event_device sp804_clockevent
= {
193 .features
= CLOCK_EVT_FEAT_PERIODIC
|
194 CLOCK_EVT_FEAT_ONESHOT
|
195 CLOCK_EVT_FEAT_DYNIRQ
,
196 .set_state_shutdown
= sp804_shutdown
,
197 .set_state_periodic
= sp804_set_periodic
,
198 .set_state_oneshot
= sp804_shutdown
,
199 .tick_resume
= sp804_shutdown
,
200 .set_next_event
= sp804_set_next_event
,
204 static int __init
sp804_clockevents_init(void __iomem
*base
, unsigned int irq
,
205 struct clk
*clk
, const char *name
)
207 struct clock_event_device
*evt
= &sp804_clockevent
;
210 rate
= sp804_get_clock_rate(clk
, name
);
214 common_clkevt
= sp804_clkevt_get(base
);
215 common_clkevt
->reload
= DIV_ROUND_CLOSEST(rate
, HZ
);
218 evt
->cpumask
= cpu_possible_mask
;
220 writel(0, common_clkevt
->ctrl
);
222 if (request_irq(irq
, sp804_timer_interrupt
, IRQF_TIMER
| IRQF_IRQPOLL
,
223 "timer", &sp804_clockevent
))
224 pr_err("request_irq() failed\n");
225 clockevents_config_and_register(evt
, rate
, 0xf, 0xffffffff);
230 static void __init
sp804_clkevt_init(struct sp804_timer
*timer
, void __iomem
*base
)
234 for (i
= 0; i
< NR_TIMERS
; i
++) {
235 void __iomem
*timer_base
;
236 struct sp804_clkevt
*clkevt
;
238 timer_base
= base
+ timer
->timer_base
[i
];
239 clkevt
= &sp804_clkevt
[i
];
240 clkevt
->base
= timer_base
;
241 clkevt
->load
= timer_base
+ timer
->load
;
242 clkevt
->load_h
= timer_base
+ timer
->load_h
;
243 clkevt
->value
= timer_base
+ timer
->value
;
244 clkevt
->value_h
= timer_base
+ timer
->value_h
;
245 clkevt
->ctrl
= timer_base
+ timer
->ctrl
;
246 clkevt
->intclr
= timer_base
+ timer
->intclr
;
247 clkevt
->width
= timer
->width
;
251 static int __init
sp804_of_init(struct device_node
*np
, struct sp804_timer
*timer
)
253 static bool initialized
= false;
255 void __iomem
*timer1_base
;
256 void __iomem
*timer2_base
;
257 int irq
, ret
= -EINVAL
;
259 struct clk
*clk1
, *clk2
;
260 const char *name
= of_get_property(np
, "compatible", NULL
);
262 base
= of_iomap(np
, 0);
266 timer1_base
= base
+ timer
->timer_base
[0];
267 timer2_base
= base
+ timer
->timer_base
[1];
269 /* Ensure timers are disabled */
270 writel(0, timer1_base
+ timer
->ctrl
);
271 writel(0, timer2_base
+ timer
->ctrl
);
273 if (initialized
|| !of_device_is_available(np
)) {
278 clk1
= of_clk_get(np
, 0);
282 /* Get the 2nd clock if the timer has 3 timer clocks */
283 if (of_clk_get_parent_count(np
) == 3) {
284 clk2
= of_clk_get(np
, 1);
286 pr_err("%pOFn clock not found: %d\n", np
,
293 irq
= irq_of_parse_and_map(np
, 0);
297 sp804_clkevt_init(timer
, base
);
299 of_property_read_u32(np
, "arm,sp804-has-irq", &irq_num
);
302 ret
= sp804_clockevents_init(timer2_base
, irq
, clk2
, name
);
306 ret
= sp804_clocksource_and_sched_clock_init(timer1_base
,
312 ret
= sp804_clockevents_init(timer1_base
, irq
, clk1
, name
);
316 ret
= sp804_clocksource_and_sched_clock_init(timer2_base
,
329 static int __init
arm_sp804_of_init(struct device_node
*np
)
331 return sp804_of_init(np
, &arm_sp804_timer
);
333 TIMER_OF_DECLARE(sp804
, "arm,sp804", arm_sp804_of_init
);
335 static int __init
hisi_sp804_of_init(struct device_node
*np
)
337 return sp804_of_init(np
, &hisi_sp804_timer
);
339 TIMER_OF_DECLARE(hisi_sp804
, "hisilicon,sp804", hisi_sp804_of_init
);
341 static int __init
integrator_cp_of_init(struct device_node
*np
)
343 static int init_count
= 0;
345 int irq
, ret
= -EINVAL
;
346 const char *name
= of_get_property(np
, "compatible", NULL
);
349 base
= of_iomap(np
, 0);
351 pr_err("Failed to iomap\n");
355 clk
= of_clk_get(np
, 0);
357 pr_err("Failed to get clock\n");
361 /* Ensure timer is disabled */
362 writel(0, base
+ arm_sp804_timer
.ctrl
);
364 if (init_count
== 2 || !of_device_is_available(np
))
367 sp804_clkevt_init(&arm_sp804_timer
, base
);
370 ret
= sp804_clocksource_and_sched_clock_init(base
,
375 irq
= irq_of_parse_and_map(np
, 0);
379 ret
= sp804_clockevents_init(base
, irq
, clk
, name
);
390 TIMER_OF_DECLARE(intcp
, "arm,integrator-cp-timer", integrator_cp_of_init
);