1 | /* |
2 | * SuperH clock framework |
3 | * |
4 | * Copyright (C) 2005 - 2010 Paul Mundt |
5 | * |
6 | * This clock framework is derived from the OMAP version by: |
7 | * |
8 | * Copyright (C) 2004 - 2008 Nokia Corporation |
9 | * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com> |
10 | * |
11 | * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com> |
12 | * |
13 | * This file is subject to the terms and conditions of the GNU General Public |
14 | * License. See the file "COPYING" in the main directory of this archive |
15 | * for more details. |
16 | */ |
17 | #define pr_fmt(fmt) "clock: " fmt |
18 | |
19 | #include <linux/kernel.h> |
20 | #include <linux/init.h> |
21 | #include <linux/module.h> |
22 | #include <linux/mutex.h> |
23 | #include <linux/list.h> |
24 | #include <linux/syscore_ops.h> |
25 | #include <linux/seq_file.h> |
26 | #include <linux/err.h> |
27 | #include <linux/io.h> |
28 | #include <linux/cpufreq.h> |
29 | #include <linux/clk.h> |
30 | #include <linux/sh_clk.h> |
31 | |
32 | static LIST_HEAD(clock_list); |
33 | static DEFINE_SPINLOCK(clock_lock); |
34 | static DEFINE_MUTEX(clock_list_sem); |
35 | |
36 | /* clock disable operations are not passed on to hardware during boot */ |
37 | static int allow_disable; |
38 | |
39 | void clk_rate_table_build(struct clk *clk, |
40 | struct cpufreq_frequency_table *freq_table, |
41 | int nr_freqs, |
42 | struct clk_div_mult_table *src_table, |
43 | unsigned long *bitmap) |
44 | { |
45 | unsigned long mult, div; |
46 | unsigned long freq; |
47 | int i; |
48 | |
49 | clk->nr_freqs = nr_freqs; |
50 | |
51 | for (i = 0; i < nr_freqs; i++) { |
52 | div = 1; |
53 | mult = 1; |
54 | |
55 | if (src_table->divisors && i < src_table->nr_divisors) |
56 | div = src_table->divisors[i]; |
57 | |
58 | if (src_table->multipliers && i < src_table->nr_multipliers) |
59 | mult = src_table->multipliers[i]; |
60 | |
61 | if (!div || !mult || (bitmap && !test_bit(i, bitmap))) |
62 | freq = CPUFREQ_ENTRY_INVALID; |
63 | else |
64 | freq = clk->parent->rate * mult / div; |
65 | |
66 | freq_table[i].driver_data = i; |
67 | freq_table[i].frequency = freq; |
68 | } |
69 | |
70 | /* Termination entry */ |
71 | freq_table[i].driver_data = i; |
72 | freq_table[i].frequency = CPUFREQ_TABLE_END; |
73 | } |
74 | |
75 | struct clk_rate_round_data; |
76 | |
77 | struct clk_rate_round_data { |
78 | unsigned long rate; |
79 | unsigned int min, max; |
80 | long (*func)(unsigned int, struct clk_rate_round_data *); |
81 | void *arg; |
82 | }; |
83 | |
84 | #define for_each_frequency(pos, r, freq) \ |
85 | for (pos = r->min, freq = r->func(pos, r); \ |
86 | pos <= r->max; pos++, freq = r->func(pos, r)) \ |
87 | if (unlikely(freq == 0)) \ |
88 | ; \ |
89 | else |
90 | |
91 | static long clk_rate_round_helper(struct clk_rate_round_data *rounder) |
92 | { |
93 | unsigned long rate_error, rate_error_prev = ~0UL; |
94 | unsigned long highest, lowest, freq; |
95 | long rate_best_fit = -ENOENT; |
96 | int i; |
97 | |
98 | highest = 0; |
99 | lowest = ~0UL; |
100 | |
101 | for_each_frequency(i, rounder, freq) { |
102 | if (freq > highest) |
103 | highest = freq; |
104 | if (freq < lowest) |
105 | lowest = freq; |
106 | |
107 | rate_error = abs(freq - rounder->rate); |
108 | if (rate_error < rate_error_prev) { |
109 | rate_best_fit = freq; |
110 | rate_error_prev = rate_error; |
111 | } |
112 | |
113 | if (rate_error == 0) |
114 | break; |
115 | } |
116 | |
117 | if (rounder->rate >= highest) |
118 | rate_best_fit = highest; |
119 | if (rounder->rate <= lowest) |
120 | rate_best_fit = lowest; |
121 | |
122 | return rate_best_fit; |
123 | } |
124 | |
125 | static long clk_rate_table_iter(unsigned int pos, |
126 | struct clk_rate_round_data *rounder) |
127 | { |
128 | struct cpufreq_frequency_table *freq_table = rounder->arg; |
129 | unsigned long freq = freq_table[pos].frequency; |
130 | |
131 | if (freq == CPUFREQ_ENTRY_INVALID) |
132 | freq = 0; |
133 | |
134 | return freq; |
135 | } |
136 | |
137 | long clk_rate_table_round(struct clk *clk, |
138 | struct cpufreq_frequency_table *freq_table, |
139 | unsigned long rate) |
140 | { |
141 | struct clk_rate_round_data table_round = { |
142 | .min = 0, |
143 | .max = clk->nr_freqs - 1, |
144 | .func = clk_rate_table_iter, |
145 | .arg = freq_table, |
146 | .rate = rate, |
147 | }; |
148 | |
149 | if (clk->nr_freqs < 1) |
150 | return -ENOSYS; |
151 | |
152 | return clk_rate_round_helper(rounder: &table_round); |
153 | } |
154 | |
155 | static long clk_rate_div_range_iter(unsigned int pos, |
156 | struct clk_rate_round_data *rounder) |
157 | { |
158 | return clk_get_rate(clk: rounder->arg) / pos; |
159 | } |
160 | |
161 | long clk_rate_div_range_round(struct clk *clk, unsigned int div_min, |
162 | unsigned int div_max, unsigned long rate) |
163 | { |
164 | struct clk_rate_round_data div_range_round = { |
165 | .min = div_min, |
166 | .max = div_max, |
167 | .func = clk_rate_div_range_iter, |
168 | .arg = clk_get_parent(clk), |
169 | .rate = rate, |
170 | }; |
171 | |
172 | return clk_rate_round_helper(rounder: &div_range_round); |
173 | } |
174 | |
175 | static long clk_rate_mult_range_iter(unsigned int pos, |
176 | struct clk_rate_round_data *rounder) |
177 | { |
178 | return clk_get_rate(clk: rounder->arg) * pos; |
179 | } |
180 | |
181 | long clk_rate_mult_range_round(struct clk *clk, unsigned int mult_min, |
182 | unsigned int mult_max, unsigned long rate) |
183 | { |
184 | struct clk_rate_round_data mult_range_round = { |
185 | .min = mult_min, |
186 | .max = mult_max, |
187 | .func = clk_rate_mult_range_iter, |
188 | .arg = clk_get_parent(clk), |
189 | .rate = rate, |
190 | }; |
191 | |
192 | return clk_rate_round_helper(rounder: &mult_range_round); |
193 | } |
194 | |
195 | int clk_rate_table_find(struct clk *clk, |
196 | struct cpufreq_frequency_table *freq_table, |
197 | unsigned long rate) |
198 | { |
199 | struct cpufreq_frequency_table *pos; |
200 | int idx; |
201 | |
202 | cpufreq_for_each_valid_entry_idx(pos, freq_table, idx) |
203 | if (pos->frequency == rate) |
204 | return idx; |
205 | |
206 | return -ENOENT; |
207 | } |
208 | |
209 | /* Used for clocks that always have same value as the parent clock */ |
210 | unsigned long followparent_recalc(struct clk *clk) |
211 | { |
212 | return clk->parent ? clk->parent->rate : 0; |
213 | } |
214 | |
215 | int clk_reparent(struct clk *child, struct clk *parent) |
216 | { |
217 | list_del_init(entry: &child->sibling); |
218 | if (parent) |
219 | list_add(new: &child->sibling, head: &parent->children); |
220 | child->parent = parent; |
221 | |
222 | return 0; |
223 | } |
224 | |
225 | /* Propagate rate to children */ |
226 | void propagate_rate(struct clk *tclk) |
227 | { |
228 | struct clk *clkp; |
229 | |
230 | list_for_each_entry(clkp, &tclk->children, sibling) { |
231 | if (clkp->ops && clkp->ops->recalc) |
232 | clkp->rate = clkp->ops->recalc(clkp); |
233 | |
234 | propagate_rate(tclk: clkp); |
235 | } |
236 | } |
237 | |
238 | static void __clk_disable(struct clk *clk) |
239 | { |
240 | if (WARN(!clk->usecount, "Trying to disable clock %p with 0 usecount\n" , |
241 | clk)) |
242 | return; |
243 | |
244 | if (!(--clk->usecount)) { |
245 | if (likely(allow_disable && clk->ops && clk->ops->disable)) |
246 | clk->ops->disable(clk); |
247 | if (likely(clk->parent)) |
248 | __clk_disable(clk: clk->parent); |
249 | } |
250 | } |
251 | |
252 | void clk_disable(struct clk *clk) |
253 | { |
254 | unsigned long flags; |
255 | |
256 | if (!clk) |
257 | return; |
258 | |
259 | spin_lock_irqsave(&clock_lock, flags); |
260 | __clk_disable(clk); |
261 | spin_unlock_irqrestore(lock: &clock_lock, flags); |
262 | } |
263 | EXPORT_SYMBOL_GPL(clk_disable); |
264 | |
265 | static int __clk_enable(struct clk *clk) |
266 | { |
267 | int ret = 0; |
268 | |
269 | if (clk->usecount++ == 0) { |
270 | if (clk->parent) { |
271 | ret = __clk_enable(clk: clk->parent); |
272 | if (unlikely(ret)) |
273 | goto err; |
274 | } |
275 | |
276 | if (clk->ops && clk->ops->enable) { |
277 | ret = clk->ops->enable(clk); |
278 | if (ret) { |
279 | if (clk->parent) |
280 | __clk_disable(clk: clk->parent); |
281 | goto err; |
282 | } |
283 | } |
284 | } |
285 | |
286 | return ret; |
287 | err: |
288 | clk->usecount--; |
289 | return ret; |
290 | } |
291 | |
292 | int clk_enable(struct clk *clk) |
293 | { |
294 | unsigned long flags; |
295 | int ret; |
296 | |
297 | if (!clk) |
298 | return 0; |
299 | |
300 | spin_lock_irqsave(&clock_lock, flags); |
301 | ret = __clk_enable(clk); |
302 | spin_unlock_irqrestore(lock: &clock_lock, flags); |
303 | |
304 | return ret; |
305 | } |
306 | EXPORT_SYMBOL_GPL(clk_enable); |
307 | |
308 | static LIST_HEAD(root_clks); |
309 | |
310 | /** |
311 | * recalculate_root_clocks - recalculate and propagate all root clocks |
312 | * |
313 | * Recalculates all root clocks (clocks with no parent), which if the |
314 | * clock's .recalc is set correctly, should also propagate their rates. |
315 | * Called at init. |
316 | */ |
317 | void recalculate_root_clocks(void) |
318 | { |
319 | struct clk *clkp; |
320 | |
321 | list_for_each_entry(clkp, &root_clks, sibling) { |
322 | if (clkp->ops && clkp->ops->recalc) |
323 | clkp->rate = clkp->ops->recalc(clkp); |
324 | propagate_rate(tclk: clkp); |
325 | } |
326 | } |
327 | |
328 | static struct clk_mapping dummy_mapping; |
329 | |
330 | static struct clk *lookup_root_clock(struct clk *clk) |
331 | { |
332 | while (clk->parent) |
333 | clk = clk->parent; |
334 | |
335 | return clk; |
336 | } |
337 | |
338 | static int clk_establish_mapping(struct clk *clk) |
339 | { |
340 | struct clk_mapping *mapping = clk->mapping; |
341 | |
342 | /* |
343 | * Propagate mappings. |
344 | */ |
345 | if (!mapping) { |
346 | struct clk *clkp; |
347 | |
348 | /* |
349 | * dummy mapping for root clocks with no specified ranges |
350 | */ |
351 | if (!clk->parent) { |
352 | clk->mapping = &dummy_mapping; |
353 | goto out; |
354 | } |
355 | |
356 | /* |
357 | * If we're on a child clock and it provides no mapping of its |
358 | * own, inherit the mapping from its root clock. |
359 | */ |
360 | clkp = lookup_root_clock(clk); |
361 | mapping = clkp->mapping; |
362 | BUG_ON(!mapping); |
363 | } |
364 | |
365 | /* |
366 | * Establish initial mapping. |
367 | */ |
368 | if (!mapping->base && mapping->phys) { |
369 | kref_init(kref: &mapping->ref); |
370 | |
371 | mapping->base = ioremap(offset: mapping->phys, size: mapping->len); |
372 | if (unlikely(!mapping->base)) |
373 | return -ENXIO; |
374 | } else if (mapping->base) { |
375 | /* |
376 | * Bump the refcount for an existing mapping |
377 | */ |
378 | kref_get(kref: &mapping->ref); |
379 | } |
380 | |
381 | clk->mapping = mapping; |
382 | out: |
383 | clk->mapped_reg = clk->mapping->base; |
384 | clk->mapped_reg += (phys_addr_t)clk->enable_reg - clk->mapping->phys; |
385 | return 0; |
386 | } |
387 | |
388 | static void clk_destroy_mapping(struct kref *kref) |
389 | { |
390 | struct clk_mapping *mapping; |
391 | |
392 | mapping = container_of(kref, struct clk_mapping, ref); |
393 | |
394 | iounmap(addr: mapping->base); |
395 | } |
396 | |
397 | static void clk_teardown_mapping(struct clk *clk) |
398 | { |
399 | struct clk_mapping *mapping = clk->mapping; |
400 | |
401 | /* Nothing to do */ |
402 | if (mapping == &dummy_mapping) |
403 | goto out; |
404 | |
405 | kref_put(kref: &mapping->ref, release: clk_destroy_mapping); |
406 | clk->mapping = NULL; |
407 | out: |
408 | clk->mapped_reg = NULL; |
409 | } |
410 | |
411 | int clk_register(struct clk *clk) |
412 | { |
413 | int ret; |
414 | |
415 | if (IS_ERR_OR_NULL(ptr: clk)) |
416 | return -EINVAL; |
417 | |
418 | /* |
419 | * trap out already registered clocks |
420 | */ |
421 | if (clk->node.next || clk->node.prev) |
422 | return 0; |
423 | |
424 | mutex_lock(&clock_list_sem); |
425 | |
426 | INIT_LIST_HEAD(list: &clk->children); |
427 | clk->usecount = 0; |
428 | |
429 | ret = clk_establish_mapping(clk); |
430 | if (unlikely(ret)) |
431 | goto out_unlock; |
432 | |
433 | if (clk->parent) |
434 | list_add(new: &clk->sibling, head: &clk->parent->children); |
435 | else |
436 | list_add(new: &clk->sibling, head: &root_clks); |
437 | |
438 | list_add(new: &clk->node, head: &clock_list); |
439 | |
440 | #ifdef CONFIG_SH_CLK_CPG_LEGACY |
441 | if (clk->ops && clk->ops->init) |
442 | clk->ops->init(clk); |
443 | #endif |
444 | |
445 | out_unlock: |
446 | mutex_unlock(lock: &clock_list_sem); |
447 | |
448 | return ret; |
449 | } |
450 | EXPORT_SYMBOL_GPL(clk_register); |
451 | |
452 | void clk_unregister(struct clk *clk) |
453 | { |
454 | mutex_lock(&clock_list_sem); |
455 | list_del(entry: &clk->sibling); |
456 | list_del(entry: &clk->node); |
457 | clk_teardown_mapping(clk); |
458 | mutex_unlock(lock: &clock_list_sem); |
459 | } |
460 | EXPORT_SYMBOL_GPL(clk_unregister); |
461 | |
462 | void clk_enable_init_clocks(void) |
463 | { |
464 | struct clk *clkp; |
465 | |
466 | list_for_each_entry(clkp, &clock_list, node) |
467 | if (clkp->flags & CLK_ENABLE_ON_INIT) |
468 | clk_enable(clkp); |
469 | } |
470 | |
471 | unsigned long clk_get_rate(struct clk *clk) |
472 | { |
473 | if (!clk) |
474 | return 0; |
475 | |
476 | return clk->rate; |
477 | } |
478 | EXPORT_SYMBOL_GPL(clk_get_rate); |
479 | |
480 | int clk_set_rate(struct clk *clk, unsigned long rate) |
481 | { |
482 | int ret = -EOPNOTSUPP; |
483 | unsigned long flags; |
484 | |
485 | if (!clk) |
486 | return 0; |
487 | |
488 | spin_lock_irqsave(&clock_lock, flags); |
489 | |
490 | if (likely(clk->ops && clk->ops->set_rate)) { |
491 | ret = clk->ops->set_rate(clk, rate); |
492 | if (ret != 0) |
493 | goto out_unlock; |
494 | } else { |
495 | clk->rate = rate; |
496 | ret = 0; |
497 | } |
498 | |
499 | if (clk->ops && clk->ops->recalc) |
500 | clk->rate = clk->ops->recalc(clk); |
501 | |
502 | propagate_rate(tclk: clk); |
503 | |
504 | out_unlock: |
505 | spin_unlock_irqrestore(lock: &clock_lock, flags); |
506 | |
507 | return ret; |
508 | } |
509 | EXPORT_SYMBOL_GPL(clk_set_rate); |
510 | |
511 | int clk_set_parent(struct clk *clk, struct clk *parent) |
512 | { |
513 | unsigned long flags; |
514 | int ret = -EINVAL; |
515 | |
516 | if (!parent || !clk) |
517 | return ret; |
518 | if (clk->parent == parent) |
519 | return 0; |
520 | |
521 | spin_lock_irqsave(&clock_lock, flags); |
522 | if (clk->usecount == 0) { |
523 | if (clk->ops->set_parent) |
524 | ret = clk->ops->set_parent(clk, parent); |
525 | else |
526 | ret = clk_reparent(child: clk, parent); |
527 | |
528 | if (ret == 0) { |
529 | if (clk->ops->recalc) |
530 | clk->rate = clk->ops->recalc(clk); |
531 | pr_debug("set parent of %p to %p (new rate %ld)\n" , |
532 | clk, clk->parent, clk->rate); |
533 | propagate_rate(tclk: clk); |
534 | } |
535 | } else |
536 | ret = -EBUSY; |
537 | spin_unlock_irqrestore(lock: &clock_lock, flags); |
538 | |
539 | return ret; |
540 | } |
541 | EXPORT_SYMBOL_GPL(clk_set_parent); |
542 | |
543 | struct clk *clk_get_parent(struct clk *clk) |
544 | { |
545 | if (!clk) |
546 | return NULL; |
547 | |
548 | return clk->parent; |
549 | } |
550 | EXPORT_SYMBOL_GPL(clk_get_parent); |
551 | |
552 | long clk_round_rate(struct clk *clk, unsigned long rate) |
553 | { |
554 | if (!clk) |
555 | return 0; |
556 | |
557 | if (likely(clk->ops && clk->ops->round_rate)) { |
558 | unsigned long flags, rounded; |
559 | |
560 | spin_lock_irqsave(&clock_lock, flags); |
561 | rounded = clk->ops->round_rate(clk, rate); |
562 | spin_unlock_irqrestore(lock: &clock_lock, flags); |
563 | |
564 | return rounded; |
565 | } |
566 | |
567 | return clk_get_rate(clk); |
568 | } |
569 | EXPORT_SYMBOL_GPL(clk_round_rate); |
570 | |
571 | #ifdef CONFIG_PM |
572 | static void clks_core_resume(void) |
573 | { |
574 | struct clk *clkp; |
575 | |
576 | list_for_each_entry(clkp, &clock_list, node) { |
577 | if (likely(clkp->usecount && clkp->ops)) { |
578 | unsigned long rate = clkp->rate; |
579 | |
580 | if (likely(clkp->ops->set_parent)) |
581 | clkp->ops->set_parent(clkp, |
582 | clkp->parent); |
583 | if (likely(clkp->ops->set_rate)) |
584 | clkp->ops->set_rate(clkp, rate); |
585 | else if (likely(clkp->ops->recalc)) |
586 | clkp->rate = clkp->ops->recalc(clkp); |
587 | } |
588 | } |
589 | } |
590 | |
591 | static struct syscore_ops clks_syscore_ops = { |
592 | .resume = clks_core_resume, |
593 | }; |
594 | |
595 | static int __init clk_syscore_init(void) |
596 | { |
597 | register_syscore_ops(ops: &clks_syscore_ops); |
598 | |
599 | return 0; |
600 | } |
601 | subsys_initcall(clk_syscore_init); |
602 | #endif |
603 | |
604 | static int __init clk_late_init(void) |
605 | { |
606 | unsigned long flags; |
607 | struct clk *clk; |
608 | |
609 | /* disable all clocks with zero use count */ |
610 | mutex_lock(&clock_list_sem); |
611 | spin_lock_irqsave(&clock_lock, flags); |
612 | |
613 | list_for_each_entry(clk, &clock_list, node) |
614 | if (!clk->usecount && clk->ops && clk->ops->disable) |
615 | clk->ops->disable(clk); |
616 | |
617 | /* from now on allow clock disable operations */ |
618 | allow_disable = 1; |
619 | |
620 | spin_unlock_irqrestore(lock: &clock_lock, flags); |
621 | mutex_unlock(lock: &clock_list_sem); |
622 | return 0; |
623 | } |
624 | late_initcall(clk_late_init); |
625 | |