1 // SPDX-License-Identifier: GPL-2.0+
3 * RDA8810PL SoC timer driver
5 * Copyright RDA Microelectronics Company Limited
6 * Copyright (c) 2017 Andreas Färber
7 * Copyright (c) 2018 Manivannan Sadhasivam
9 * RDA8810PL has two independent timers: OSTIMER (56 bit) and HWTIMER (64 bit).
10 * Each timer provides optional interrupt support. In this driver, OSTIMER is
11 * used for clockevents and HWTIMER is used for clocksource.
14 #include <linux/init.h>
15 #include <linux/interrupt.h>
19 #define RDA_OSTIMER_LOADVAL_L 0x000
20 #define RDA_OSTIMER_CTRL 0x004
21 #define RDA_HWTIMER_LOCKVAL_L 0x024
22 #define RDA_HWTIMER_LOCKVAL_H 0x028
23 #define RDA_TIMER_IRQ_MASK_SET 0x02c
24 #define RDA_TIMER_IRQ_MASK_CLR 0x030
25 #define RDA_TIMER_IRQ_CLR 0x034
27 #define RDA_OSTIMER_CTRL_ENABLE BIT(24)
28 #define RDA_OSTIMER_CTRL_REPEAT BIT(28)
29 #define RDA_OSTIMER_CTRL_LOAD BIT(30)
31 #define RDA_TIMER_IRQ_MASK_OSTIMER BIT(0)
33 #define RDA_TIMER_IRQ_CLR_OSTIMER BIT(0)
35 static int rda_ostimer_start(void __iomem
*base
, bool periodic
, u64 cycles
)
40 ctrl
= ((cycles
>> 32) & 0xffffff);
41 ctrl
|= RDA_OSTIMER_CTRL_LOAD
| RDA_OSTIMER_CTRL_ENABLE
;
43 ctrl
|= RDA_OSTIMER_CTRL_REPEAT
;
45 /* Enable ostimer interrupt first */
46 writel_relaxed(RDA_TIMER_IRQ_MASK_OSTIMER
,
47 base
+ RDA_TIMER_IRQ_MASK_SET
);
49 /* Write low 32 bits first, high 24 bits are with ctrl */
50 writel_relaxed(load_l
, base
+ RDA_OSTIMER_LOADVAL_L
);
51 writel_relaxed(ctrl
, base
+ RDA_OSTIMER_CTRL
);
56 static int rda_ostimer_stop(void __iomem
*base
)
58 /* Disable ostimer interrupt first */
59 writel_relaxed(RDA_TIMER_IRQ_MASK_OSTIMER
,
60 base
+ RDA_TIMER_IRQ_MASK_CLR
);
62 writel_relaxed(0, base
+ RDA_OSTIMER_CTRL
);
67 static int rda_ostimer_set_state_shutdown(struct clock_event_device
*evt
)
69 struct timer_of
*to
= to_timer_of(evt
);
71 rda_ostimer_stop(timer_of_base(to
));
76 static int rda_ostimer_set_state_oneshot(struct clock_event_device
*evt
)
78 struct timer_of
*to
= to_timer_of(evt
);
80 rda_ostimer_stop(timer_of_base(to
));
85 static int rda_ostimer_set_state_periodic(struct clock_event_device
*evt
)
87 struct timer_of
*to
= to_timer_of(evt
);
88 unsigned long cycles_per_jiffy
;
90 rda_ostimer_stop(timer_of_base(to
));
92 cycles_per_jiffy
= ((unsigned long long)NSEC_PER_SEC
/ HZ
*
93 evt
->mult
) >> evt
->shift
;
94 rda_ostimer_start(timer_of_base(to
), true, cycles_per_jiffy
);
99 static int rda_ostimer_tick_resume(struct clock_event_device
*evt
)
104 static int rda_ostimer_set_next_event(unsigned long evt
,
105 struct clock_event_device
*ev
)
107 struct timer_of
*to
= to_timer_of(ev
);
109 rda_ostimer_start(timer_of_base(to
), false, evt
);
114 static irqreturn_t
rda_ostimer_interrupt(int irq
, void *dev_id
)
116 struct clock_event_device
*evt
= dev_id
;
117 struct timer_of
*to
= to_timer_of(evt
);
119 /* clear timer int */
120 writel_relaxed(RDA_TIMER_IRQ_CLR_OSTIMER
,
121 timer_of_base(to
) + RDA_TIMER_IRQ_CLR
);
123 if (evt
->event_handler
)
124 evt
->event_handler(evt
);
129 static struct timer_of rda_ostimer_of
= {
130 .flags
= TIMER_OF_IRQ
| TIMER_OF_BASE
,
133 .name
= "rda-ostimer",
135 .features
= CLOCK_EVT_FEAT_PERIODIC
| CLOCK_EVT_FEAT_ONESHOT
|
136 CLOCK_EVT_FEAT_DYNIRQ
,
137 .set_state_shutdown
= rda_ostimer_set_state_shutdown
,
138 .set_state_oneshot
= rda_ostimer_set_state_oneshot
,
139 .set_state_periodic
= rda_ostimer_set_state_periodic
,
140 .tick_resume
= rda_ostimer_tick_resume
,
141 .set_next_event
= rda_ostimer_set_next_event
,
151 .handler
= rda_ostimer_interrupt
,
156 static u64
rda_hwtimer_read(struct clocksource
*cs
)
158 void __iomem
*base
= timer_of_base(&rda_ostimer_of
);
161 /* Always read low 32 bits first */
163 lo
= readl_relaxed(base
+ RDA_HWTIMER_LOCKVAL_L
);
164 hi
= readl_relaxed(base
+ RDA_HWTIMER_LOCKVAL_H
);
165 } while (hi
!= readl_relaxed(base
+ RDA_HWTIMER_LOCKVAL_H
));
167 return ((u64
)hi
<< 32) | lo
;
170 static struct clocksource rda_hwtimer_clocksource
= {
173 .read
= rda_hwtimer_read
,
174 .mask
= CLOCKSOURCE_MASK(64),
175 .flags
= CLOCK_SOURCE_IS_CONTINUOUS
,
178 static int __init
rda_timer_init(struct device_node
*np
)
180 unsigned long rate
= 2000000;
183 ret
= timer_of_init(np
, &rda_ostimer_of
);
187 clocksource_register_hz(&rda_hwtimer_clocksource
, rate
);
189 clockevents_config_and_register(&rda_ostimer_of
.clkevt
, rate
,
195 TIMER_OF_DECLARE(rda8810pl
, "rda,8810pl-timer", rda_timer_init
);