1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/clk.h>
19#include <linux/interrupt.h>
20#include <linux/clockchips.h>
21#include <linux/of_address.h>
22#include <linux/of_irq.h>
23#include <linux/slab.h>
24#include <linux/clk-provider.h>
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45#define TTC_CLK_CNTRL_OFFSET 0x00
46#define TTC_CNT_CNTRL_OFFSET 0x0C
47#define TTC_COUNT_VAL_OFFSET 0x18
48#define TTC_INTR_VAL_OFFSET 0x24
49#define TTC_ISR_OFFSET 0x54
50#define TTC_IER_OFFSET 0x60
51
52#define TTC_CNT_CNTRL_DISABLE_MASK 0x1
53
54
55
56
57
58#define PRESCALE_EXPONENT 11
59#define PRESCALE 2048
60#define CLK_CNTRL_PRESCALE ((PRESCALE_EXPONENT - 1) << 1)
61#define CLK_CNTRL_PRESCALE_EN 1
62#define CNT_CNTRL_RESET (1 << 4)
63
64
65
66
67
68
69
70
71struct ttc_timer {
72 void __iomem *base_addr;
73 struct clk *clk;
74 struct notifier_block clk_rate_change_nb;
75};
76
77#define to_ttc_timer(x) \
78 container_of(x, struct ttc_timer, clk_rate_change_nb)
79
80struct ttc_timer_clocksource {
81 struct ttc_timer ttc;
82 struct clocksource cs;
83};
84
85#define to_ttc_timer_clksrc(x) \
86 container_of(x, struct ttc_timer_clocksource, cs)
87
88struct ttc_timer_clockevent {
89 struct ttc_timer ttc;
90 struct clock_event_device ce;
91};
92
93#define to_ttc_timer_clkevent(x) \
94 container_of(x, struct ttc_timer_clockevent, ce)
95
96
97
98
99
100
101
102static void ttc_set_interval(struct ttc_timer *timer,
103 unsigned long cycles)
104{
105 u32 ctrl_reg;
106
107
108 ctrl_reg = __raw_readl(timer->base_addr + TTC_CNT_CNTRL_OFFSET);
109 ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK;
110 __raw_writel(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
111
112 __raw_writel(cycles, timer->base_addr + TTC_INTR_VAL_OFFSET);
113
114
115
116
117
118 ctrl_reg |= CNT_CNTRL_RESET;
119 ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK;
120 __raw_writel(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET);
121}
122
123
124
125
126
127
128
129
130
131static irqreturn_t ttc_clock_event_interrupt(int irq, void *dev_id)
132{
133 struct ttc_timer_clockevent *ttce = dev_id;
134 struct ttc_timer *timer = &ttce->ttc;
135
136
137 __raw_readl(timer->base_addr + TTC_ISR_OFFSET);
138
139 ttce->ce.event_handler(&ttce->ce);
140
141 return IRQ_HANDLED;
142}
143
144
145
146
147
148
149static cycle_t __ttc_clocksource_read(struct clocksource *cs)
150{
151 struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc;
152
153 return (cycle_t)__raw_readl(timer->base_addr +
154 TTC_COUNT_VAL_OFFSET);
155}
156
157
158
159
160
161
162
163
164
165static int ttc_set_next_event(unsigned long cycles,
166 struct clock_event_device *evt)
167{
168 struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
169 struct ttc_timer *timer = &ttce->ttc;
170
171 ttc_set_interval(timer, cycles);
172 return 0;
173}
174
175
176
177
178
179
180
181static void ttc_set_mode(enum clock_event_mode mode,
182 struct clock_event_device *evt)
183{
184 struct ttc_timer_clockevent *ttce = to_ttc_timer_clkevent(evt);
185 struct ttc_timer *timer = &ttce->ttc;
186 u32 ctrl_reg;
187
188 switch (mode) {
189 case CLOCK_EVT_MODE_PERIODIC:
190 ttc_set_interval(timer,
191 DIV_ROUND_CLOSEST(clk_get_rate(ttce->ttc.clk),
192 PRESCALE * HZ));
193 break;
194 case CLOCK_EVT_MODE_ONESHOT:
195 case CLOCK_EVT_MODE_UNUSED:
196 case CLOCK_EVT_MODE_SHUTDOWN:
197 ctrl_reg = __raw_readl(timer->base_addr +
198 TTC_CNT_CNTRL_OFFSET);
199 ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK;
200 __raw_writel(ctrl_reg,
201 timer->base_addr + TTC_CNT_CNTRL_OFFSET);
202 break;
203 case CLOCK_EVT_MODE_RESUME:
204 ctrl_reg = __raw_readl(timer->base_addr +
205 TTC_CNT_CNTRL_OFFSET);
206 ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK;
207 __raw_writel(ctrl_reg,
208 timer->base_addr + TTC_CNT_CNTRL_OFFSET);
209 break;
210 }
211}
212
213static int ttc_rate_change_clocksource_cb(struct notifier_block *nb,
214 unsigned long event, void *data)
215{
216 struct clk_notifier_data *ndata = data;
217 struct ttc_timer *ttc = to_ttc_timer(nb);
218 struct ttc_timer_clocksource *ttccs = container_of(ttc,
219 struct ttc_timer_clocksource, ttc);
220
221 switch (event) {
222 case POST_RATE_CHANGE:
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239 clocksource_unregister(&ttccs->cs);
240 clocksource_register_hz(&ttccs->cs,
241 ndata->new_rate / PRESCALE);
242
243 case PRE_RATE_CHANGE:
244 case ABORT_RATE_CHANGE:
245 default:
246 return NOTIFY_DONE;
247 }
248}
249
250static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base)
251{
252 struct ttc_timer_clocksource *ttccs;
253 int err;
254
255 ttccs = kzalloc(sizeof(*ttccs), GFP_KERNEL);
256 if (WARN_ON(!ttccs))
257 return;
258
259 ttccs->ttc.clk = clk;
260
261 err = clk_prepare_enable(ttccs->ttc.clk);
262 if (WARN_ON(err)) {
263 kfree(ttccs);
264 return;
265 }
266
267 ttccs->ttc.clk_rate_change_nb.notifier_call =
268 ttc_rate_change_clocksource_cb;
269 ttccs->ttc.clk_rate_change_nb.next = NULL;
270 if (clk_notifier_register(ttccs->ttc.clk,
271 &ttccs->ttc.clk_rate_change_nb))
272 pr_warn("Unable to register clock notifier.\n");
273
274 ttccs->ttc.base_addr = base;
275 ttccs->cs.name = "ttc_clocksource";
276 ttccs->cs.rating = 200;
277 ttccs->cs.read = __ttc_clocksource_read;
278 ttccs->cs.mask = CLOCKSOURCE_MASK(16);
279 ttccs->cs.flags = CLOCK_SOURCE_IS_CONTINUOUS;
280
281
282
283
284
285
286 __raw_writel(0x0, ttccs->ttc.base_addr + TTC_IER_OFFSET);
287 __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN,
288 ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
289 __raw_writel(CNT_CNTRL_RESET,
290 ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET);
291
292 err = clocksource_register_hz(&ttccs->cs,
293 clk_get_rate(ttccs->ttc.clk) / PRESCALE);
294 if (WARN_ON(err)) {
295 kfree(ttccs);
296 return;
297 }
298}
299
300static int ttc_rate_change_clockevent_cb(struct notifier_block *nb,
301 unsigned long event, void *data)
302{
303 struct clk_notifier_data *ndata = data;
304 struct ttc_timer *ttc = to_ttc_timer(nb);
305 struct ttc_timer_clockevent *ttcce = container_of(ttc,
306 struct ttc_timer_clockevent, ttc);
307
308 switch (event) {
309 case POST_RATE_CHANGE:
310 {
311 unsigned long flags;
312
313
314
315
316
317
318
319 local_irq_save(flags);
320 clockevents_update_freq(&ttcce->ce,
321 ndata->new_rate / PRESCALE);
322 local_irq_restore(flags);
323
324
325 }
326 case PRE_RATE_CHANGE:
327 case ABORT_RATE_CHANGE:
328 default:
329 return NOTIFY_DONE;
330 }
331}
332
333static void __init ttc_setup_clockevent(struct clk *clk,
334 void __iomem *base, u32 irq)
335{
336 struct ttc_timer_clockevent *ttcce;
337 int err;
338
339 ttcce = kzalloc(sizeof(*ttcce), GFP_KERNEL);
340 if (WARN_ON(!ttcce))
341 return;
342
343 ttcce->ttc.clk = clk;
344
345 err = clk_prepare_enable(ttcce->ttc.clk);
346 if (WARN_ON(err)) {
347 kfree(ttcce);
348 return;
349 }
350
351 ttcce->ttc.clk_rate_change_nb.notifier_call =
352 ttc_rate_change_clockevent_cb;
353 ttcce->ttc.clk_rate_change_nb.next = NULL;
354 if (clk_notifier_register(ttcce->ttc.clk,
355 &ttcce->ttc.clk_rate_change_nb))
356 pr_warn("Unable to register clock notifier.\n");
357
358 ttcce->ttc.base_addr = base;
359 ttcce->ce.name = "ttc_clockevent";
360 ttcce->ce.features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT;
361 ttcce->ce.set_next_event = ttc_set_next_event;
362 ttcce->ce.set_mode = ttc_set_mode;
363 ttcce->ce.rating = 200;
364 ttcce->ce.irq = irq;
365 ttcce->ce.cpumask = cpu_possible_mask;
366
367
368
369
370
371
372 __raw_writel(0x23, ttcce->ttc.base_addr + TTC_CNT_CNTRL_OFFSET);
373 __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN,
374 ttcce->ttc.base_addr + TTC_CLK_CNTRL_OFFSET);
375 __raw_writel(0x1, ttcce->ttc.base_addr + TTC_IER_OFFSET);
376
377 err = request_irq(irq, ttc_clock_event_interrupt,
378 IRQF_DISABLED | IRQF_TIMER,
379 ttcce->ce.name, ttcce);
380 if (WARN_ON(err)) {
381 kfree(ttcce);
382 return;
383 }
384
385 clockevents_config_and_register(&ttcce->ce,
386 clk_get_rate(ttcce->ttc.clk) / PRESCALE, 1, 0xfffe);
387}
388
389
390
391
392
393
394
395static void __init ttc_timer_init(struct device_node *timer)
396{
397 unsigned int irq;
398 void __iomem *timer_baseaddr;
399 struct clk *clk;
400 static int initialized;
401
402 if (initialized)
403 return;
404
405 initialized = 1;
406
407
408
409
410
411
412 timer_baseaddr = of_iomap(timer, 0);
413 if (!timer_baseaddr) {
414 pr_err("ERROR: invalid timer base address\n");
415 BUG();
416 }
417
418 irq = irq_of_parse_and_map(timer, 1);
419 if (irq <= 0) {
420 pr_err("ERROR: invalid interrupt number\n");
421 BUG();
422 }
423
424 clk = of_clk_get_by_name(timer, "cpu_1x");
425 if (IS_ERR(clk)) {
426 pr_err("ERROR: timer input clock not found\n");
427 BUG();
428 }
429
430 ttc_setup_clocksource(clk, timer_baseaddr);
431 ttc_setup_clockevent(clk, timer_baseaddr + 4, irq);
432
433 pr_info("%s #0 at %p, irq=%d\n", timer->name, timer_baseaddr, irq);
434}
435
436CLOCKSOURCE_OF_DECLARE(ttc, "cdns,ttc", ttc_timer_init);
437