xref: /openbmc/linux/arch/arm/kernel/smp_twd.c (revision 54cbac81)
1 /*
2  *  linux/arch/arm/kernel/smp_twd.c
3  *
4  *  Copyright (C) 2002 ARM Ltd.
5  *  All Rights Reserved
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License version 2 as
9  * published by the Free Software Foundation.
10  */
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/clk.h>
14 #include <linux/delay.h>
15 #include <linux/device.h>
16 #include <linux/err.h>
17 #include <linux/smp.h>
18 #include <linux/jiffies.h>
19 #include <linux/clockchips.h>
20 #include <linux/interrupt.h>
21 #include <linux/io.h>
22 #include <linux/of_irq.h>
23 #include <linux/of_address.h>
24 
25 #include <asm/smp_twd.h>
26 #include <asm/localtimer.h>
27 #include <asm/hardware/gic.h>
28 
29 /* set up by the platform code */
30 static void __iomem *twd_base;
31 
32 static struct clk *twd_clk;
33 static unsigned long twd_timer_rate;
34 static bool common_setup_called;
35 static DEFINE_PER_CPU(bool, percpu_setup_called);
36 
37 static struct clock_event_device __percpu **twd_evt;
38 static int twd_ppi;
39 
40 static void twd_set_mode(enum clock_event_mode mode,
41 			struct clock_event_device *clk)
42 {
43 	unsigned long ctrl;
44 
45 	switch (mode) {
46 	case CLOCK_EVT_MODE_PERIODIC:
47 		ctrl = TWD_TIMER_CONTROL_ENABLE | TWD_TIMER_CONTROL_IT_ENABLE
48 			| TWD_TIMER_CONTROL_PERIODIC;
49 		__raw_writel(DIV_ROUND_CLOSEST(twd_timer_rate, HZ),
50 			twd_base + TWD_TIMER_LOAD);
51 		break;
52 	case CLOCK_EVT_MODE_ONESHOT:
53 		/* period set, and timer enabled in 'next_event' hook */
54 		ctrl = TWD_TIMER_CONTROL_IT_ENABLE | TWD_TIMER_CONTROL_ONESHOT;
55 		break;
56 	case CLOCK_EVT_MODE_UNUSED:
57 	case CLOCK_EVT_MODE_SHUTDOWN:
58 	default:
59 		ctrl = 0;
60 	}
61 
62 	__raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL);
63 }
64 
65 static int twd_set_next_event(unsigned long evt,
66 			struct clock_event_device *unused)
67 {
68 	unsigned long ctrl = __raw_readl(twd_base + TWD_TIMER_CONTROL);
69 
70 	ctrl |= TWD_TIMER_CONTROL_ENABLE;
71 
72 	__raw_writel(evt, twd_base + TWD_TIMER_COUNTER);
73 	__raw_writel(ctrl, twd_base + TWD_TIMER_CONTROL);
74 
75 	return 0;
76 }
77 
78 /*
79  * local_timer_ack: checks for a local timer interrupt.
80  *
81  * If a local timer interrupt has occurred, acknowledge and return 1.
82  * Otherwise, return 0.
83  */
84 static int twd_timer_ack(void)
85 {
86 	if (__raw_readl(twd_base + TWD_TIMER_INTSTAT)) {
87 		__raw_writel(1, twd_base + TWD_TIMER_INTSTAT);
88 		return 1;
89 	}
90 
91 	return 0;
92 }
93 
94 static void twd_timer_stop(struct clock_event_device *clk)
95 {
96 	twd_set_mode(CLOCK_EVT_MODE_UNUSED, clk);
97 	disable_percpu_irq(clk->irq);
98 }
99 
100 #ifdef CONFIG_COMMON_CLK
101 
102 /*
103  * Updates clockevent frequency when the cpu frequency changes.
104  * Called on the cpu that is changing frequency with interrupts disabled.
105  */
106 static void twd_update_frequency(void *new_rate)
107 {
108 	twd_timer_rate = *((unsigned long *) new_rate);
109 
110 	clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
111 }
112 
113 static int twd_rate_change(struct notifier_block *nb,
114 	unsigned long flags, void *data)
115 {
116 	struct clk_notifier_data *cnd = data;
117 
118 	/*
119 	 * The twd clock events must be reprogrammed to account for the new
120 	 * frequency.  The timer is local to a cpu, so cross-call to the
121 	 * changing cpu.
122 	 */
123 	if (flags == POST_RATE_CHANGE)
124 		smp_call_function(twd_update_frequency,
125 				  (void *)&cnd->new_rate, 1);
126 
127 	return NOTIFY_OK;
128 }
129 
130 static struct notifier_block twd_clk_nb = {
131 	.notifier_call = twd_rate_change,
132 };
133 
134 static int twd_clk_init(void)
135 {
136 	if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
137 		return clk_notifier_register(twd_clk, &twd_clk_nb);
138 
139 	return 0;
140 }
141 core_initcall(twd_clk_init);
142 
143 #elif defined (CONFIG_CPU_FREQ)
144 
145 #include <linux/cpufreq.h>
146 
147 /*
148  * Updates clockevent frequency when the cpu frequency changes.
149  * Called on the cpu that is changing frequency with interrupts disabled.
150  */
151 static void twd_update_frequency(void *data)
152 {
153 	twd_timer_rate = clk_get_rate(twd_clk);
154 
155 	clockevents_update_freq(*__this_cpu_ptr(twd_evt), twd_timer_rate);
156 }
157 
158 static int twd_cpufreq_transition(struct notifier_block *nb,
159 	unsigned long state, void *data)
160 {
161 	struct cpufreq_freqs *freqs = data;
162 
163 	/*
164 	 * The twd clock events must be reprogrammed to account for the new
165 	 * frequency.  The timer is local to a cpu, so cross-call to the
166 	 * changing cpu.
167 	 */
168 	if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE)
169 		smp_call_function_single(freqs->cpu, twd_update_frequency,
170 			NULL, 1);
171 
172 	return NOTIFY_OK;
173 }
174 
175 static struct notifier_block twd_cpufreq_nb = {
176 	.notifier_call = twd_cpufreq_transition,
177 };
178 
179 static int twd_cpufreq_init(void)
180 {
181 	if (twd_evt && *__this_cpu_ptr(twd_evt) && !IS_ERR(twd_clk))
182 		return cpufreq_register_notifier(&twd_cpufreq_nb,
183 			CPUFREQ_TRANSITION_NOTIFIER);
184 
185 	return 0;
186 }
187 core_initcall(twd_cpufreq_init);
188 
189 #endif
190 
191 static void __cpuinit twd_calibrate_rate(void)
192 {
193 	unsigned long count;
194 	u64 waitjiffies;
195 
196 	/*
197 	 * If this is the first time round, we need to work out how fast
198 	 * the timer ticks
199 	 */
200 	if (twd_timer_rate == 0) {
201 		printk(KERN_INFO "Calibrating local timer... ");
202 
203 		/* Wait for a tick to start */
204 		waitjiffies = get_jiffies_64() + 1;
205 
206 		while (get_jiffies_64() < waitjiffies)
207 			udelay(10);
208 
209 		/* OK, now the tick has started, let's get the timer going */
210 		waitjiffies += 5;
211 
212 				 /* enable, no interrupt or reload */
213 		__raw_writel(0x1, twd_base + TWD_TIMER_CONTROL);
214 
215 				 /* maximum value */
216 		__raw_writel(0xFFFFFFFFU, twd_base + TWD_TIMER_COUNTER);
217 
218 		while (get_jiffies_64() < waitjiffies)
219 			udelay(10);
220 
221 		count = __raw_readl(twd_base + TWD_TIMER_COUNTER);
222 
223 		twd_timer_rate = (0xFFFFFFFFU - count) * (HZ / 5);
224 
225 		printk("%lu.%02luMHz.\n", twd_timer_rate / 1000000,
226 			(twd_timer_rate / 10000) % 100);
227 	}
228 }
229 
230 static irqreturn_t twd_handler(int irq, void *dev_id)
231 {
232 	struct clock_event_device *evt = *(struct clock_event_device **)dev_id;
233 
234 	if (twd_timer_ack()) {
235 		evt->event_handler(evt);
236 		return IRQ_HANDLED;
237 	}
238 
239 	return IRQ_NONE;
240 }
241 
242 static struct clk *twd_get_clock(void)
243 {
244 	struct clk *clk;
245 	int err;
246 
247 	clk = clk_get_sys("smp_twd", NULL);
248 	if (IS_ERR(clk)) {
249 		pr_err("smp_twd: clock not found: %d\n", (int)PTR_ERR(clk));
250 		return clk;
251 	}
252 
253 	err = clk_prepare_enable(clk);
254 	if (err) {
255 		pr_err("smp_twd: clock failed to prepare+enable: %d\n", err);
256 		clk_put(clk);
257 		return ERR_PTR(err);
258 	}
259 
260 	return clk;
261 }
262 
263 /*
264  * Setup the local clock events for a CPU.
265  */
266 static int __cpuinit twd_timer_setup(struct clock_event_device *clk)
267 {
268 	struct clock_event_device **this_cpu_clk;
269 	int cpu = smp_processor_id();
270 
271 	/*
272 	 * If the basic setup for this CPU has been done before don't
273 	 * bother with the below.
274 	 */
275 	if (per_cpu(percpu_setup_called, cpu)) {
276 		__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
277 		clockevents_register_device(*__this_cpu_ptr(twd_evt));
278 		enable_percpu_irq(clk->irq, 0);
279 		return 0;
280 	}
281 	per_cpu(percpu_setup_called, cpu) = true;
282 
283 	/*
284 	 * This stuff only need to be done once for the entire TWD cluster
285 	 * during the runtime of the system.
286 	 */
287 	if (!common_setup_called) {
288 		twd_clk = twd_get_clock();
289 
290 		/*
291 		 * We use IS_ERR_OR_NULL() here, because if the clock stubs
292 		 * are active we will get a valid clk reference which is
293 		 * however NULL and will return the rate 0. In that case we
294 		 * need to calibrate the rate instead.
295 		 */
296 		if (!IS_ERR_OR_NULL(twd_clk))
297 			twd_timer_rate = clk_get_rate(twd_clk);
298 		else
299 			twd_calibrate_rate();
300 
301 		common_setup_called = true;
302 	}
303 
304 	/*
305 	 * The following is done once per CPU the first time .setup() is
306 	 * called.
307 	 */
308 	__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
309 
310 	clk->name = "local_timer";
311 	clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
312 			CLOCK_EVT_FEAT_C3STOP;
313 	clk->rating = 350;
314 	clk->set_mode = twd_set_mode;
315 	clk->set_next_event = twd_set_next_event;
316 	clk->irq = twd_ppi;
317 
318 	this_cpu_clk = __this_cpu_ptr(twd_evt);
319 	*this_cpu_clk = clk;
320 
321 	clockevents_config_and_register(clk, twd_timer_rate,
322 					0xf, 0xffffffff);
323 	enable_percpu_irq(clk->irq, 0);
324 
325 	return 0;
326 }
327 
328 static struct local_timer_ops twd_lt_ops __cpuinitdata = {
329 	.setup	= twd_timer_setup,
330 	.stop	= twd_timer_stop,
331 };
332 
333 static int __init twd_local_timer_common_register(void)
334 {
335 	int err;
336 
337 	twd_evt = alloc_percpu(struct clock_event_device *);
338 	if (!twd_evt) {
339 		err = -ENOMEM;
340 		goto out_free;
341 	}
342 
343 	err = request_percpu_irq(twd_ppi, twd_handler, "twd", twd_evt);
344 	if (err) {
345 		pr_err("twd: can't register interrupt %d (%d)\n", twd_ppi, err);
346 		goto out_free;
347 	}
348 
349 	err = local_timer_register(&twd_lt_ops);
350 	if (err)
351 		goto out_irq;
352 
353 	return 0;
354 
355 out_irq:
356 	free_percpu_irq(twd_ppi, twd_evt);
357 out_free:
358 	iounmap(twd_base);
359 	twd_base = NULL;
360 	free_percpu(twd_evt);
361 
362 	return err;
363 }
364 
365 int __init twd_local_timer_register(struct twd_local_timer *tlt)
366 {
367 	if (twd_base || twd_evt)
368 		return -EBUSY;
369 
370 	twd_ppi	= tlt->res[1].start;
371 
372 	twd_base = ioremap(tlt->res[0].start, resource_size(&tlt->res[0]));
373 	if (!twd_base)
374 		return -ENOMEM;
375 
376 	return twd_local_timer_common_register();
377 }
378 
379 #ifdef CONFIG_OF
380 const static struct of_device_id twd_of_match[] __initconst = {
381 	{ .compatible = "arm,cortex-a9-twd-timer",	},
382 	{ .compatible = "arm,cortex-a5-twd-timer",	},
383 	{ .compatible = "arm,arm11mp-twd-timer",	},
384 	{ },
385 };
386 
387 void __init twd_local_timer_of_register(void)
388 {
389 	struct device_node *np;
390 	int err;
391 
392 	np = of_find_matching_node(NULL, twd_of_match);
393 	if (!np)
394 		return;
395 
396 	twd_ppi = irq_of_parse_and_map(np, 0);
397 	if (!twd_ppi) {
398 		err = -EINVAL;
399 		goto out;
400 	}
401 
402 	twd_base = of_iomap(np, 0);
403 	if (!twd_base) {
404 		err = -ENOMEM;
405 		goto out;
406 	}
407 
408 	err = twd_local_timer_common_register();
409 
410 out:
411 	WARN(err, "twd_local_timer_of_register failed (%d)\n", err);
412 }
413 #endif
414