1 /* linux/arch/arm/mach-rk30/clock.c
3 * Copyright (C) 2012 ROCKCHIP, Inc.
5 * This software is licensed under the terms of the GNU General Public
6 * License version 2, as published by the Free Software Foundation, and
7 * may be copied, distributed, and modified under those terms.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
15 #include <linux/clk.h>
16 #include <linux/clkdev.h>
17 #include <linux/err.h>
18 #include <linux/init.h>
19 #include <linux/kernel.h>
20 #include <linux/list.h>
21 #include <linux/module.h>
22 #include <linux/hardirq.h>
23 #include <linux/delay.h>
24 #include <mach/clock.h>
26 #include <mach/dvfs.h>
27 #include <linux/delay.h>
29 #define CLOCK_PRINTK_DBG(fmt, args...) printk(fmt, ## args);
30 #define CLOCK_PRINTK_ERR(fmt, args...) printk(fmt, ## args);
34 #define RATE_FIXED (1 << 1) /* Fixed clock rate */
35 #define CONFIG_PARTICIPANT (1 << 10) /* Fundamental clock */
37 #define MHZ (1000*1000)
40 static void __clk_recalc(struct clk *clk);
41 static void __propagate_rate(struct clk *tclk);
42 static void __clk_reparent(struct clk *child, struct clk *parent);
44 static LIST_HEAD(clocks);
45 static DEFINE_MUTEX(clocks_mutex);
46 static DEFINE_SPINLOCK(clockfw_lock);
47 static LIST_HEAD(root_clks);
48 static void clk_notify(struct clk *clk, unsigned long msg,
49 unsigned long old_rate, unsigned long new_rate);
51 #define LOCK() do { WARN_ON(in_irq()); if (!irqs_disabled()) spin_lock_bh(&clockfw_lock); } while (0)
52 #define UNLOCK() do { if (!irqs_disabled()) spin_unlock_bh(&clockfw_lock); } while (0)
53 /**********************************************for clock data****************************************************/
54 static struct clk *def_ops_clk=NULL;
56 void clk_register_default_ops_clk(struct clk *clk)
61 static struct clk *clk_default_get_parent(struct clk *clk)
63 if(def_ops_clk&&def_ops_clk->get_parent)
64 return def_ops_clk->get_parent(clk);
70 static int clk_default_set_parent(struct clk *clk, struct clk *parent)
72 if(def_ops_clk&&def_ops_clk->set_parent)
73 return def_ops_clk->set_parent(clk,parent);
78 int __init clk_disable_unused(void)
81 CLOCK_PRINTK_DBG("clk_disable_unused in\n");
83 list_for_each_entry(ck, &clocks, node) {
84 if (ck->usecount > 0 || ck->mode == NULL || (ck->flags & IS_PD))
86 CLOCK_PRINTK_DBG("disbale %s\n",ck->name);
88 clk_enable_nolock(ck);
89 //clk_disable_nolock(ck);
95 * recalculate_root_clocks - recalculate and propagate all root clocks
97 * Recalculates all root clocks (clocks with no parent), which if the
98 * clock's .recalc is set correctly, should also propagate their rates.
101 void clk_recalculate_root_clocks_nolock(void)
105 list_for_each_entry(clkp, &root_clks, sibling) {
107 __propagate_rate(clkp);
111 void clk_recalculate_root_clocks(void)
114 clk_recalculate_root_clocks_nolock();
119 * clk_preinit - initialize any fields in the struct clk before clk init
120 * @clk: struct clk * to initialize
122 * Initialize any struct clk fields needed before normal clk initialization
123 * can run. No return value.
125 int clk_register(struct clk *clk)
127 if (clk == NULL || IS_ERR(clk))
129 //INIT_LIST_HEAD(&clk->sibling);
130 INIT_LIST_HEAD(&clk->children);
133 * trap out already registered clocks
135 if (clk->node.next || clk->node.prev)
138 mutex_lock(&clocks_mutex);
140 clk->parent = clk->get_parent(clk);
141 else if (clk->parents)
142 clk->parent =clk_default_get_parent(clk);
145 list_add(&clk->sibling, &clk->parent->children);
147 list_add(&clk->sibling, &root_clks);
148 list_add(&clk->node, &clocks);
149 mutex_unlock(&clocks_mutex);
153 /************************************************************/
154 static void __clk_recalc(struct clk *clk)
156 if (unlikely(clk->flags & RATE_FIXED))
159 clk->rate = clk->recalc(clk);
160 else if (clk->parent)
161 clk->rate = clk->parent->rate;
163 static void __clk_reparent(struct clk *child, struct clk *parent)
165 if (child->parent == parent)
167 CLOCK_PRINTK_DBG("%s reparent to %s (was %s)\n", child->name, parent->name, ((child->parent) ? child->parent->name : "NULL"));
169 list_del_init(&child->sibling);
171 list_add(&child->sibling, &parent->children);
172 child->parent = parent;
175 /* Propagate rate to children */
176 static void __propagate_rate(struct clk *tclk)
180 //CLOCK_PRINTK_DBG("propagate_rate clk %s\n",clkp->name);
182 list_for_each_entry(clkp, &tclk->children, sibling) {
184 __propagate_rate(clkp);
186 //CLOCK_PRINTK_DBG("propagate_rate clk %s end\n",clkp->name);
189 int clk_enable_nolock(struct clk *clk)
193 if (clk->usecount == 0) {
195 ret = clk_enable_nolock(clk->parent);
200 if (clk->notifier_count)
201 clk_notify(clk, CLK_PRE_ENABLE, clk->rate, clk->rate);
203 ret = clk->mode(clk, 1);
204 if (clk->notifier_count)
205 clk_notify(clk, ret ? CLK_ABORT_ENABLE : CLK_POST_ENABLE, clk->rate, clk->rate);
208 clk_disable_nolock(clk->parent);
211 pr_debug("%s enabled\n", clk->name);
218 void clk_disable_nolock(struct clk *clk)
220 if (clk->usecount == 0) {
221 printk(KERN_ERR "Trying disable clock %s with 0 usecount\n", clk->name);
225 if (--clk->usecount == 0) {
227 if (clk->notifier_count)
228 clk_notify(clk, CLK_PRE_DISABLE, clk->rate, clk->rate);
230 ret = clk->mode(clk, 0);
231 if (clk->notifier_count)
232 clk_notify(clk, ret ? CLK_ABORT_DISABLE : CLK_POST_DISABLE, clk->rate, clk->rate);
233 pr_debug("%s disabled\n", clk->name);
234 if (ret == 0 && clk->parent)
235 clk_disable_nolock(clk->parent);
238 /* Given a clock and a rate apply a clock specific rounding function */
239 long clk_round_rate_nolock(struct clk *clk, unsigned long rate)
242 return clk->round_rate(clk, rate);
244 if (clk->flags & RATE_FIXED)
245 printk(KERN_ERR "clock: clk_round_rate called on fixed-rate clock %s\n", clk->name);
249 int clk_set_rate_nolock(struct clk *clk, unsigned long rate)
252 unsigned long old_rate;
254 if (rate == clk->rate)
256 if (clk->flags & CONFIG_PARTICIPANT)
262 //CLOCK_PRINTK_DBG("**will set %s rate %lu\n", clk->name, rate);
264 old_rate = clk->rate;
265 if (clk->notifier_count)
266 clk_notify(clk, CLK_PRE_RATE_CHANGE, old_rate, rate);
268 ret = clk->set_rate(clk, rate);
272 //CLOCK_PRINTK_DBG("**set %s rate recalc=%lu\n",clk->name,clk->rate);
273 __propagate_rate(clk);
276 if (clk->notifier_count)
277 clk_notify(clk, ret ? CLK_ABORT_RATE_CHANGE : CLK_POST_RATE_CHANGE, old_rate, clk->rate);
282 int clk_set_parent_nolock(struct clk *clk, struct clk *parent)
285 int enabled = clk->usecount > 0;
286 struct clk *old_parent = clk->parent;
288 if (clk->parent == parent)
291 /* if clk is already enabled, enable new parent first and disable old parent later. */
293 clk_enable_nolock(parent);
296 ret = clk->set_parent(clk, parent);
298 ret = clk_default_set_parent(clk,parent);
303 //CLOCK_PRINTK_DBG("set_parent %s reparent\n",clk->name,parent->name);
304 __clk_reparent(clk, parent);
306 __propagate_rate(clk);
308 clk_disable_nolock(old_parent);
310 //CLOCK_PRINTK_DBG("set_parent err\n",clk->name,parent->name);
312 clk_disable_nolock(parent);
317 /**********************************dvfs****************************************************/
319 struct clk_node *clk_get_dvfs_info(struct clk *clk)
321 return clk->dvfs_info;
324 int clk_set_rate_locked(struct clk * clk,unsigned long rate)
327 CLOCK_PRINTK_DBG("%s dvfs clk_set_locked\n",clk->name);
329 ret=clk_set_rate_nolock(clk, rate);;
334 void clk_register_dvfs(struct clk_node *dvfs_clk, struct clk *clk)
336 clk->dvfs_info = dvfs_clk;
340 /*-------------------------------------------------------------------------
341 * Optional clock functions defined in include/linux/clk.h
342 *-------------------------------------------------------------------------*/
343 #ifdef RK30_CLK_OFFBOARD_TEST
344 long rk30_clk_round_rate(struct clk *clk, unsigned long rate)
346 long clk_round_rate(struct clk *clk, unsigned long rate)
351 if (clk == NULL || IS_ERR(clk))
355 ret = clk_round_rate_nolock(clk, rate);
361 #ifdef RK30_CLK_OFFBOARD_TEST
362 EXPORT_SYMBOL(rk30_clk_round_rate);
364 EXPORT_SYMBOL(clk_round_rate);
367 #ifdef RK30_CLK_OFFBOARD_TEST
368 unsigned long rk30_clk_get_rate(struct clk *clk)
370 unsigned long clk_get_rate(struct clk *clk)
373 if (clk == NULL || IS_ERR(clk))
378 #ifdef RK30_CLK_OFFBOARD_TEST
379 EXPORT_SYMBOL(rk30_clk_get_rate);
381 EXPORT_SYMBOL(clk_get_rate);
385 /* Set the clock rate for a clock source */
386 #ifdef RK30_CLK_OFFBOARD_TEST
387 int rk30_clk_set_rate(struct clk *clk, unsigned long rate)
389 int clk_set_rate(struct clk *clk, unsigned long rate)
393 if (clk == NULL || IS_ERR(clk)){
396 if (clk->dvfs_info!=NULL&&is_support_dvfs(clk->dvfs_info))
397 return dvfs_set_rate(clk, rate);
400 ret = clk_set_rate_nolock(clk, rate);
405 #ifdef RK30_CLK_OFFBOARD_TEST
406 EXPORT_SYMBOL(rk30_clk_set_rate);
408 EXPORT_SYMBOL(clk_set_rate);
412 #ifdef RK30_CLK_OFFBOARD_TEST
413 int rk30_clk_set_parent(struct clk *clk, struct clk *parent)
415 int clk_set_parent(struct clk *clk, struct clk *parent)
420 if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
423 if (clk->set_parent==NULL||clk->parents == NULL)
427 if (clk->usecount == 0)
428 ret = clk_set_parent_nolock(clk, parent);
436 #ifdef RK30_CLK_OFFBOARD_TEST
437 EXPORT_SYMBOL(rk30_clk_set_parent);
439 EXPORT_SYMBOL(clk_set_parent);
442 #ifdef RK30_CLK_OFFBOARD_TEST
443 struct clk *rk30_clk_get_parent(struct clk *clk)
445 struct clk *clk_get_parent(struct clk *clk)
451 #ifdef RK30_CLK_OFFBOARD_TEST
452 EXPORT_SYMBOL(rk30_clk_get_parent);
454 EXPORT_SYMBOL(clk_get_parent);
457 #ifdef RK30_CLK_OFFBOARD_TEST
458 void rk30_clk_disable(struct clk *clk)
460 void clk_disable(struct clk *clk)
463 if (clk == NULL || IS_ERR(clk))
467 clk_disable_nolock(clk);
470 #ifdef RK30_CLK_OFFBOARD_TEST
471 EXPORT_SYMBOL(rk30_clk_disable);
473 EXPORT_SYMBOL(clk_disable);
476 #ifdef RK30_CLK_OFFBOARD_TEST
477 int rk30_clk_enable(struct clk *clk)
479 int clk_enable(struct clk *clk)
484 if (clk == NULL || IS_ERR(clk))
488 ret = clk_enable_nolock(clk);
493 #ifdef RK30_CLK_OFFBOARD_TEST
494 EXPORT_SYMBOL(rk30_clk_enable);
496 EXPORT_SYMBOL(clk_enable);
499 /* Clk notifier implementation */
502 * struct clk_notifier - associate a clk with a notifier
503 * @clk: struct clk * to associate the notifier with
504 * @notifier_head: a raw_notifier_head for this clk
505 * @node: linked list pointers
507 * A list of struct clk_notifier is maintained by the notifier code.
508 * An entry is created whenever code registers the first notifier on a
509 * particular @clk. Future notifiers on that @clk are added to the
512 struct clk_notifier {
514 struct raw_notifier_head notifier_head;
515 struct list_head node;
517 static LIST_HEAD(clk_notifier_list);
519 * _clk_free_notifier_chain - safely remove struct clk_notifier
520 * @cn: struct clk_notifier *
522 * Removes the struct clk_notifier @cn from the clk_notifier_list and
525 static void _clk_free_notifier_chain(struct clk_notifier *cn)
532 * clk_notify - call clk notifier chain
533 * @clk: struct clk * that is changing rate
534 * @msg: clk notifier type (i.e., CLK_POST_RATE_CHANGE; see mach/clock.h)
535 * @old_rate: old rate
536 * @new_rate: new rate
538 * Triggers a notifier call chain on the post-clk-rate-change notifier
539 * for clock 'clk'. Passes a pointer to the struct clk and the
540 * previous and current rates to the notifier callback. Intended to be
541 * called by internal clock code only. No return value.
543 static void clk_notify(struct clk *clk, unsigned long msg,
544 unsigned long old_rate, unsigned long new_rate)
546 struct clk_notifier *cn;
547 struct clk_notifier_data cnd;
550 cnd.old_rate = old_rate;
551 cnd.new_rate = new_rate;
554 list_for_each_entry(cn, &clk_notifier_list, node) {
555 if (cn->clk == clk) {
556 pr_debug("%s msg %lu rate %lu -> %lu\n", clk->name, msg, old_rate, new_rate);
557 raw_notifier_call_chain(&cn->notifier_head, msg, &cnd);
565 * clk_notifier_register - add a clock parameter change notifier
566 * @clk: struct clk * to watch
567 * @nb: struct notifier_block * with callback info
569 * Request notification for changes to the clock 'clk'. This uses a
570 * blocking notifier. Callback code must not call into the clock
571 * framework, as clocks_mutex is held. Pre-notifier callbacks will be
572 * passed the previous and new rate of the clock.
574 * clk_notifier_register() must be called from process
575 * context. Returns -EINVAL if called with null arguments, -ENOMEM
576 * upon allocation failure; otherwise, passes along the return value
577 * of blocking_notifier_chain_register().
579 int rk30_clk_notifier_register(struct clk *clk, struct notifier_block *nb)
581 struct clk_notifier *cn = NULL, *cn_new = NULL;
585 if (!clk || IS_ERR(clk) || !nb)
588 mutex_lock(&clocks_mutex);
590 list_for_each_entry(cn, &clk_notifier_list, node)
594 if (cn->clk != clk) {
595 cn_new = kzalloc(sizeof(struct clk_notifier), GFP_KERNEL);
602 RAW_INIT_NOTIFIER_HEAD(&cn_new->notifier_head);
604 list_add(&cn_new->node, &clk_notifier_list);
608 r = raw_notifier_chain_register(&cn->notifier_head, nb);
609 if (!IS_ERR_VALUE(r)) {
612 clkp->notifier_count++;
613 } while ((clkp = clkp->parent));
616 _clk_free_notifier_chain(cn);
620 mutex_unlock(&clocks_mutex);
624 EXPORT_SYMBOL(rk30_clk_notifier_register);
627 * clk_notifier_unregister - remove a clock change notifier
629 * @nb: struct notifier_block * with callback info
631 * Request no further notification for changes to clock 'clk'.
632 * Returns -EINVAL if called with null arguments; otherwise, passes
633 * along the return value of blocking_notifier_chain_unregister().
635 int rk30_clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
637 struct clk_notifier *cn = NULL;
641 if (!clk || IS_ERR(clk) || !nb)
644 mutex_lock(&clocks_mutex);
646 list_for_each_entry(cn, &clk_notifier_list, node)
650 if (cn->clk != clk) {
655 r = raw_notifier_chain_unregister(&cn->notifier_head, nb);
656 if (!IS_ERR_VALUE(r)) {
659 clkp->notifier_count--;
660 } while ((clkp = clkp->parent));
664 * XXX ugh, layering violation. There should be some
665 * support in the notifier code for this.
667 if (!cn->notifier_head.head)
668 _clk_free_notifier_chain(cn);
671 mutex_unlock(&clocks_mutex);
675 EXPORT_SYMBOL(rk30_clk_notifier_unregister);
677 #ifdef CONFIG_PROC_FS
678 static struct clk_dump_ops *dump_def_ops;
680 void clk_register_dump_ops(struct clk_dump_ops *ops)
685 static int proc_clk_show(struct seq_file *s, void *v)
692 if(dump_def_ops->dump_clk)
694 mutex_lock(&clocks_mutex);
695 list_for_each_entry(clk, &clocks, node) {
698 dump_def_ops->dump_clk(s, clk, 0,&clocks);
701 mutex_unlock(&clocks_mutex);
703 if(dump_def_ops->dump_regs)
704 dump_def_ops->dump_regs(s);
709 static int proc_clk_open(struct inode *inode, struct file *file)
711 return single_open(file, proc_clk_show, NULL);
714 static const struct file_operations proc_clk_fops = {
715 .open = proc_clk_open,
718 .release = single_release,
721 static int __init clk_proc_init(void)
723 proc_create("clocks", 0, NULL, &proc_clk_fops);
727 late_initcall(clk_proc_init);
728 #endif /* CONFIG_PROC_FS */