xref: /linux/drivers/clocksource/timer-rda.c (revision db6b35cffe59c619ea3772b21d7c7c8a7b885dc1)
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * RDA8810PL SoC timer driver
4  *
5  * Copyright RDA Microelectronics Company Limited
6  * Copyright (c) 2017 Andreas Färber
7  * Copyright (c) 2018 Manivannan Sadhasivam
8  *
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.
12  */
13 
14 #include <linux/init.h>
15 #include <linux/interrupt.h>
16 #include <linux/sched_clock.h>
17 
18 #include "timer-of.h"
19 
20 #define RDA_OSTIMER_LOADVAL_L	0x000
21 #define RDA_OSTIMER_CTRL	0x004
22 #define RDA_HWTIMER_LOCKVAL_L	0x024
23 #define RDA_HWTIMER_LOCKVAL_H	0x028
24 #define RDA_TIMER_IRQ_MASK_SET	0x02c
25 #define RDA_TIMER_IRQ_MASK_CLR	0x030
26 #define RDA_TIMER_IRQ_CLR	0x034
27 
28 #define RDA_OSTIMER_CTRL_ENABLE		BIT(24)
29 #define RDA_OSTIMER_CTRL_REPEAT		BIT(28)
30 #define RDA_OSTIMER_CTRL_LOAD		BIT(30)
31 
32 #define RDA_TIMER_IRQ_MASK_OSTIMER	BIT(0)
33 
34 #define RDA_TIMER_IRQ_CLR_OSTIMER	BIT(0)
35 
36 static int rda_ostimer_start(void __iomem *base, bool periodic, u64 cycles)
37 {
38 	u32 ctrl, load_l;
39 
40 	load_l = (u32)cycles;
41 	ctrl = ((cycles >> 32) & 0xffffff);
42 	ctrl |= RDA_OSTIMER_CTRL_LOAD | RDA_OSTIMER_CTRL_ENABLE;
43 	if (periodic)
44 		ctrl |= RDA_OSTIMER_CTRL_REPEAT;
45 
46 	/* Enable ostimer interrupt first */
47 	writel_relaxed(RDA_TIMER_IRQ_MASK_OSTIMER,
48 		       base + RDA_TIMER_IRQ_MASK_SET);
49 
50 	/* Write low 32 bits first, high 24 bits are with ctrl */
51 	writel_relaxed(load_l, base + RDA_OSTIMER_LOADVAL_L);
52 	writel_relaxed(ctrl, base + RDA_OSTIMER_CTRL);
53 
54 	return 0;
55 }
56 
57 static int rda_ostimer_stop(void __iomem *base)
58 {
59 	/* Disable ostimer interrupt first */
60 	writel_relaxed(RDA_TIMER_IRQ_MASK_OSTIMER,
61 		       base + RDA_TIMER_IRQ_MASK_CLR);
62 
63 	writel_relaxed(0, base + RDA_OSTIMER_CTRL);
64 
65 	return 0;
66 }
67 
68 static int rda_ostimer_set_state_shutdown(struct clock_event_device *evt)
69 {
70 	struct timer_of *to = to_timer_of(evt);
71 
72 	rda_ostimer_stop(timer_of_base(to));
73 
74 	return 0;
75 }
76 
77 static int rda_ostimer_set_state_oneshot(struct clock_event_device *evt)
78 {
79 	struct timer_of *to = to_timer_of(evt);
80 
81 	rda_ostimer_stop(timer_of_base(to));
82 
83 	return 0;
84 }
85 
86 static int rda_ostimer_set_state_periodic(struct clock_event_device *evt)
87 {
88 	struct timer_of *to = to_timer_of(evt);
89 	unsigned long cycles_per_jiffy;
90 
91 	rda_ostimer_stop(timer_of_base(to));
92 
93 	cycles_per_jiffy = ((unsigned long long)NSEC_PER_SEC / HZ *
94 			     evt->mult) >> evt->shift;
95 	rda_ostimer_start(timer_of_base(to), true, cycles_per_jiffy);
96 
97 	return 0;
98 }
99 
100 static int rda_ostimer_tick_resume(struct clock_event_device *evt)
101 {
102 	return 0;
103 }
104 
105 static int rda_ostimer_set_next_event(unsigned long evt,
106 				      struct clock_event_device *ev)
107 {
108 	struct timer_of *to = to_timer_of(ev);
109 
110 	rda_ostimer_start(timer_of_base(to), false, evt);
111 
112 	return 0;
113 }
114 
115 static irqreturn_t rda_ostimer_interrupt(int irq, void *dev_id)
116 {
117 	struct clock_event_device *evt = dev_id;
118 	struct timer_of *to = to_timer_of(evt);
119 
120 	/* clear timer int */
121 	writel_relaxed(RDA_TIMER_IRQ_CLR_OSTIMER,
122 		       timer_of_base(to) + RDA_TIMER_IRQ_CLR);
123 
124 	if (evt->event_handler)
125 		evt->event_handler(evt);
126 
127 	return IRQ_HANDLED;
128 }
129 
130 static struct timer_of rda_ostimer_of = {
131 	.flags = TIMER_OF_IRQ | TIMER_OF_BASE,
132 
133 	.clkevt = {
134 		.name = "rda-ostimer",
135 		.rating = 250,
136 		.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
137 			    CLOCK_EVT_FEAT_DYNIRQ,
138 		.set_state_shutdown = rda_ostimer_set_state_shutdown,
139 		.set_state_oneshot = rda_ostimer_set_state_oneshot,
140 		.set_state_periodic = rda_ostimer_set_state_periodic,
141 		.tick_resume = rda_ostimer_tick_resume,
142 		.set_next_event	= rda_ostimer_set_next_event,
143 	},
144 
145 	.of_base = {
146 		.name = "rda-timer",
147 		.index = 0,
148 	},
149 
150 	.of_irq = {
151 		.name = "ostimer",
152 		.handler = rda_ostimer_interrupt,
153 		.flags = IRQF_TIMER,
154 	},
155 };
156 
157 static u64 rda_hwtimer_clocksource_read(void)
158 {
159 	void __iomem *base = timer_of_base(&rda_ostimer_of);
160 	u32 lo, hi;
161 
162 	/* Always read low 32 bits first */
163 	do {
164 		lo = readl_relaxed(base + RDA_HWTIMER_LOCKVAL_L);
165 		hi = readl_relaxed(base + RDA_HWTIMER_LOCKVAL_H);
166 	} while (hi != readl_relaxed(base + RDA_HWTIMER_LOCKVAL_H));
167 
168 	return ((u64)hi << 32) | lo;
169 }
170 
171 static u64 rda_hwtimer_read(struct clocksource *cs)
172 {
173 	return rda_hwtimer_clocksource_read();
174 }
175 
176 static struct clocksource rda_hwtimer_clocksource = {
177 	.name           = "rda-timer",
178 	.rating         = 400,
179 	.read           = rda_hwtimer_read,
180 	.mask           = CLOCKSOURCE_MASK(64),
181 	.flags          = CLOCK_SOURCE_IS_CONTINUOUS,
182 };
183 
184 static int __init rda_timer_init(struct device_node *np)
185 {
186 	unsigned long rate = 2000000;
187 	int ret;
188 
189 	ret = timer_of_init(np, &rda_ostimer_of);
190 	if (ret)
191 		return ret;
192 
193 	clocksource_register_hz(&rda_hwtimer_clocksource, rate);
194 	sched_clock_register(rda_hwtimer_clocksource_read, 64, rate);
195 
196 	clockevents_config_and_register(&rda_ostimer_of.clkevt, rate,
197 					0x2, UINT_MAX);
198 
199 	return 0;
200 }
201 
202 TIMER_OF_DECLARE(rda8810pl, "rda,8810pl-timer", rda_timer_init);
203