rk30: add clock support
[firefly-linux-kernel-4.4.55.git] / arch / arm / mach-rk30 / clock.c
1 /* linux/arch/arm/mach-rk30/clock.c
2  *
3  * Copyright (C) 2012 ROCKCHIP, Inc.
4  *
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.
8  *
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.
13  *
14  */
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>
25 #include "clock.h"
26 #include <mach/dvfs.h>
27 #include <linux/delay.h>
28
29 #define CLOCK_PRINTK_DBG(fmt, args...) printk(fmt, ## args);
30 #define CLOCK_PRINTK_ERR(fmt, args...) printk(fmt, ## args);
31
32 /* Clock flags */
33 /* bit 0 is free */
34 #define RATE_FIXED              (1 << 1)        /* Fixed clock rate */
35 #define CONFIG_PARTICIPANT      (1 << 10)       /* Fundamental clock */
36
37 #define MHZ                     (1000*1000)
38 #define KHZ                     (1000)
39
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);
43
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);
50
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;
55
56 void clk_register_default_ops_clk(struct clk *clk)
57 {
58         def_ops_clk=clk;
59 }
60
61 static struct clk *clk_default_get_parent(struct clk *clk)
62 {
63         if(def_ops_clk&&def_ops_clk->get_parent)
64                 return def_ops_clk->get_parent(clk);
65         else return NULL;
66
67
68
69 }
70 static int clk_default_set_parent(struct clk *clk, struct clk *parent)
71 {
72         if(def_ops_clk&&def_ops_clk->set_parent)
73                 return def_ops_clk->set_parent(clk,parent);
74         else
75                 return -EINVAL;
76 }
77
78 int __init clk_disable_unused(void)
79 {
80         struct clk *ck;
81         CLOCK_PRINTK_DBG("clk_disable_unused in\n");
82
83         list_for_each_entry(ck, &clocks, node) {
84         if (ck->usecount > 0 || ck->mode == NULL || (ck->flags & IS_PD))
85                 continue;
86                 CLOCK_PRINTK_DBG("disbale %s\n",ck->name);
87                 LOCK();
88                 clk_enable_nolock(ck);
89                 //clk_disable_nolock(ck);
90                 UNLOCK();
91         }
92         return 0;
93 }
94 /**
95  * recalculate_root_clocks - recalculate and propagate all root clocks
96  *
97  * Recalculates all root clocks (clocks with no parent), which if the
98  * clock's .recalc is set correctly, should also propagate their rates.
99  * Called at init.
100  */
101 void clk_recalculate_root_clocks_nolock(void)
102 {
103         struct clk *clkp;
104
105         list_for_each_entry(clkp, &root_clks, sibling) {
106                 __clk_recalc(clkp);
107                 __propagate_rate(clkp);
108         }
109 }
110 /*
111 void clk_recalculate_root_clocks(void)
112 {
113         LOCK();
114         clk_recalculate_root_clocks_nolock();
115         UNLOCK();
116 }*/
117         
118 /**
119  * clk_preinit - initialize any fields in the struct clk before clk init
120  * @clk: struct clk * to initialize
121  *
122  * Initialize any struct clk fields needed before normal clk initialization
123  * can run.  No return value.
124  */
125 int clk_register(struct clk *clk)
126 {
127         if (clk == NULL || IS_ERR(clk))
128                 return -EINVAL;
129         //INIT_LIST_HEAD(&clk->sibling);
130         INIT_LIST_HEAD(&clk->children);
131
132         /*
133          * trap out already registered clocks
134          */
135         if (clk->node.next || clk->node.prev)
136                 return 0;
137
138         mutex_lock(&clocks_mutex);
139         if (clk->get_parent)
140                 clk->parent = clk->get_parent(clk);
141         else if (clk->parents)
142                 clk->parent =clk_default_get_parent(clk);
143         
144         if (clk->parent)
145                 list_add(&clk->sibling, &clk->parent->children);
146         else
147                 list_add(&clk->sibling, &root_clks);
148         list_add(&clk->node, &clocks);
149         mutex_unlock(&clocks_mutex);    
150         return 0;
151 }
152
153 /************************************************************/
154 static void __clk_recalc(struct clk *clk)
155 {
156         if (unlikely(clk->flags & RATE_FIXED))
157                 return;
158         if (clk->recalc)
159                 clk->rate = clk->recalc(clk);
160         else if (clk->parent)
161                 clk->rate = clk->parent->rate;
162 }
163 static void __clk_reparent(struct clk *child, struct clk *parent)
164 {
165         if (child->parent == parent)
166                 return;
167         CLOCK_PRINTK_DBG("%s reparent to %s (was %s)\n", child->name, parent->name, ((child->parent) ? child->parent->name : "NULL"));
168
169         list_del_init(&child->sibling);
170         if (parent)
171                 list_add(&child->sibling, &parent->children);
172         child->parent = parent;
173 }
174
175 /* Propagate rate to children */
176 static void __propagate_rate(struct clk *tclk)
177 {
178         struct clk *clkp;
179         
180         //CLOCK_PRINTK_DBG("propagate_rate clk %s\n",clkp->name);
181         
182         list_for_each_entry(clkp, &tclk->children, sibling) {
183                 __clk_recalc(clkp);
184                 __propagate_rate(clkp);
185         }
186         //CLOCK_PRINTK_DBG("propagate_rate clk %s end\n",clkp->name);
187 }
188
189 int clk_enable_nolock(struct clk *clk)
190 {
191         int ret = 0;
192
193         if (clk->usecount == 0) {
194                 if (clk->parent) {
195                         ret = clk_enable_nolock(clk->parent);
196                         if (ret)
197                                 return ret;
198                 }
199
200                 if (clk->notifier_count)
201                         clk_notify(clk, CLK_PRE_ENABLE, clk->rate, clk->rate);
202                 if (clk->mode)
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);
206                 if (ret) {
207                         if (clk->parent)
208                                 clk_disable_nolock(clk->parent);
209                         return ret;
210                 }
211                 pr_debug("%s enabled\n", clk->name);
212         }
213         clk->usecount++;
214
215         return ret;
216 }
217  
218 void clk_disable_nolock(struct clk *clk)
219 {
220         if (clk->usecount == 0) {
221                 printk(KERN_ERR "Trying disable clock %s with 0 usecount\n", clk->name);
222                 WARN_ON(1);
223                 return;
224         }
225         if (--clk->usecount == 0) {
226                 int ret = 0;
227                 if (clk->notifier_count)
228                         clk_notify(clk, CLK_PRE_DISABLE, clk->rate, clk->rate);
229                 if (clk->mode)
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);
236         }
237 }
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)
240 {
241         if (clk->round_rate)
242                 return clk->round_rate(clk, rate);
243
244         if (clk->flags & RATE_FIXED)
245                 printk(KERN_ERR "clock: clk_round_rate called on fixed-rate clock %s\n", clk->name);
246
247         return clk->rate;
248 }
249 int clk_set_rate_nolock(struct clk *clk, unsigned long rate)
250 {
251         int ret;
252         unsigned long old_rate;
253
254         if (rate == clk->rate)
255                 return 0;
256         if (clk->flags & CONFIG_PARTICIPANT)
257                 return -EINVAL;
258
259         if (!clk->set_rate)
260                 return -EINVAL;
261         
262         //CLOCK_PRINTK_DBG("**will set %s rate %lu\n", clk->name, rate);
263
264         old_rate = clk->rate;
265         if (clk->notifier_count)
266                 clk_notify(clk, CLK_PRE_RATE_CHANGE, old_rate, rate);
267
268         ret = clk->set_rate(clk, rate);
269
270         if (ret == 0) {
271                 __clk_recalc(clk);
272                 //CLOCK_PRINTK_DBG("**set %s rate recalc=%lu\n",clk->name,clk->rate);
273                 __propagate_rate(clk);
274         }
275
276         if (clk->notifier_count)
277                 clk_notify(clk, ret ? CLK_ABORT_RATE_CHANGE : CLK_POST_RATE_CHANGE, old_rate, clk->rate);
278
279         return ret;
280 }
281  
282 int clk_set_parent_nolock(struct clk *clk, struct clk *parent)
283 {
284         int ret;
285         int enabled = clk->usecount > 0;
286         struct clk *old_parent = clk->parent;
287
288         if (clk->parent == parent)
289                 return 0;
290
291         /* if clk is already enabled, enable new parent first and disable old parent later. */
292         if (enabled)
293                 clk_enable_nolock(parent);
294
295         if (clk->set_parent)
296                 ret = clk->set_parent(clk, parent);
297         else
298                 ret = clk_default_set_parent(clk,parent);
299
300         if (ret == 0) {
301                 /* OK */
302                 
303                 //CLOCK_PRINTK_DBG("set_parent %s reparent\n",clk->name,parent->name);
304                 __clk_reparent(clk, parent);
305                 __clk_recalc(clk);
306                 __propagate_rate(clk);
307                 if (enabled)
308                         clk_disable_nolock(old_parent);
309         } else {
310                 //CLOCK_PRINTK_DBG("set_parent err\n",clk->name,parent->name);
311                 if (enabled)
312                         clk_disable_nolock(parent);
313         }
314
315         return ret;
316 }
317 /**********************************dvfs****************************************************/
318
319 struct clk_node *clk_get_dvfs_info(struct clk *clk)
320 {
321     return clk->dvfs_info;
322 }
323
324 int clk_set_rate_locked(struct clk * clk,unsigned long rate)
325 {
326         int ret;
327         CLOCK_PRINTK_DBG("%s dvfs clk_set_locked\n",clk->name);
328         LOCK();
329     ret=clk_set_rate_nolock(clk, rate);;
330     UNLOCK();
331         return ret;
332         
333 }
334 void clk_register_dvfs(struct clk_node *dvfs_clk, struct clk *clk)
335 {
336     clk->dvfs_info = dvfs_clk;
337 }
338
339
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)
345 #else
346 long clk_round_rate(struct clk *clk, unsigned long rate)
347 #endif
348 {
349         long ret = 0;
350
351         if (clk == NULL || IS_ERR(clk))
352                 return ret;
353
354         LOCK();
355         ret = clk_round_rate_nolock(clk, rate);
356         UNLOCK();
357
358         return ret;
359 }
360
361 #ifdef RK30_CLK_OFFBOARD_TEST
362 EXPORT_SYMBOL(rk30_clk_round_rate);
363 #else
364 EXPORT_SYMBOL(clk_round_rate);
365 #endif
366
367 #ifdef RK30_CLK_OFFBOARD_TEST
368 unsigned long rk30_clk_get_rate(struct clk *clk)
369 #else
370 unsigned long clk_get_rate(struct clk *clk)
371 #endif
372 {
373         if (clk == NULL || IS_ERR(clk))
374                 return 0;
375
376         return clk->rate;
377 }
378 #ifdef RK30_CLK_OFFBOARD_TEST
379 EXPORT_SYMBOL(rk30_clk_get_rate);
380 #else
381 EXPORT_SYMBOL(clk_get_rate);
382 #endif
383
384
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)
388 #else
389 int clk_set_rate(struct clk *clk, unsigned long rate)
390 #endif
391 {
392         int ret = -EINVAL;
393         if (clk == NULL || IS_ERR(clk)){
394                 return ret;
395         }
396         if (clk->dvfs_info!=NULL&&is_support_dvfs(clk->dvfs_info))
397                 return dvfs_set_rate(clk, rate);
398
399         LOCK();
400         ret = clk_set_rate_nolock(clk, rate);
401         UNLOCK();
402
403         return ret;
404 }
405 #ifdef RK30_CLK_OFFBOARD_TEST
406 EXPORT_SYMBOL(rk30_clk_set_rate);
407 #else
408 EXPORT_SYMBOL(clk_set_rate);
409 #endif
410
411
412 #ifdef RK30_CLK_OFFBOARD_TEST
413 int rk30_clk_set_parent(struct clk *clk, struct clk *parent)
414 #else
415 int clk_set_parent(struct clk *clk, struct clk *parent)
416 #endif
417 {
418         int ret = -EINVAL;
419
420         if (clk == NULL || IS_ERR(clk) || parent == NULL || IS_ERR(parent))
421                 return ret;
422
423         if (clk->set_parent==NULL||clk->parents == NULL)
424                 return ret;
425
426         LOCK();
427         if (clk->usecount == 0)
428                 ret = clk_set_parent_nolock(clk, parent);
429         else
430                 ret = -EBUSY;
431         UNLOCK();
432
433         return ret;
434 }
435
436 #ifdef RK30_CLK_OFFBOARD_TEST
437 EXPORT_SYMBOL(rk30_clk_set_parent);
438 #else
439 EXPORT_SYMBOL(clk_set_parent);
440 #endif
441
442 #ifdef RK30_CLK_OFFBOARD_TEST
443 struct clk *rk30_clk_get_parent(struct clk *clk)
444 #else
445 struct clk *clk_get_parent(struct clk *clk)
446 #endif
447 {
448         return clk->parent;
449 }
450
451 #ifdef RK30_CLK_OFFBOARD_TEST
452 EXPORT_SYMBOL(rk30_clk_get_parent);
453 #else
454 EXPORT_SYMBOL(clk_get_parent);
455 #endif
456
457 #ifdef RK30_CLK_OFFBOARD_TEST
458 void rk30_clk_disable(struct clk *clk)
459 #else
460 void clk_disable(struct clk *clk)
461 #endif
462 {
463         if (clk == NULL || IS_ERR(clk))
464                 return;
465
466         LOCK();
467         clk_disable_nolock(clk);
468         UNLOCK();
469 }
470 #ifdef RK30_CLK_OFFBOARD_TEST
471 EXPORT_SYMBOL(rk30_clk_disable);
472 #else
473 EXPORT_SYMBOL(clk_disable);
474 #endif
475
476 #ifdef RK30_CLK_OFFBOARD_TEST
477 int rk30_clk_enable(struct clk *clk)
478 #else
479 int  clk_enable(struct clk *clk)
480 #endif
481 {
482         int ret = 0;
483
484         if (clk == NULL || IS_ERR(clk))
485                 return -EINVAL;
486
487         LOCK();
488         ret = clk_enable_nolock(clk);
489         UNLOCK();
490
491         return ret;
492 }
493 #ifdef RK30_CLK_OFFBOARD_TEST
494 EXPORT_SYMBOL(rk30_clk_enable);
495 #else
496 EXPORT_SYMBOL(clk_enable);
497 #endif
498
499 /* Clk notifier implementation */
500
501 /**
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
506  *
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
510  * @notifier_head.
511  */
512 struct clk_notifier {
513         struct clk                      *clk;
514         struct raw_notifier_head        notifier_head;
515         struct list_head                node;
516 };
517 static LIST_HEAD(clk_notifier_list);
518 /**
519  * _clk_free_notifier_chain - safely remove struct clk_notifier
520  * @cn: struct clk_notifier *
521  *
522  * Removes the struct clk_notifier @cn from the clk_notifier_list and
523  * frees it.
524  */
525 static void _clk_free_notifier_chain(struct clk_notifier *cn)
526 {
527         list_del(&cn->node);
528         kfree(cn);
529 }
530
531 /**
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
537  *
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.
542  */
543 static void clk_notify(struct clk *clk, unsigned long msg,
544                        unsigned long old_rate, unsigned long new_rate)
545 {
546         struct clk_notifier *cn;
547         struct clk_notifier_data cnd;
548
549         cnd.clk = clk;
550         cnd.old_rate = old_rate;
551         cnd.new_rate = new_rate;
552
553         UNLOCK();
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);
558                         break;
559                 }
560         }
561         LOCK();
562 }
563
564 /**
565  * clk_notifier_register - add a clock parameter change notifier
566  * @clk: struct clk * to watch
567  * @nb: struct notifier_block * with callback info
568  *
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.
573  *
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().
578  */
579 int rk30_clk_notifier_register(struct clk *clk, struct notifier_block *nb)
580 {
581         struct clk_notifier *cn = NULL, *cn_new = NULL;
582         int r;
583         struct clk *clkp;
584
585         if (!clk || IS_ERR(clk) || !nb)
586                 return -EINVAL;
587
588         mutex_lock(&clocks_mutex);
589
590         list_for_each_entry(cn, &clk_notifier_list, node)
591                 if (cn->clk == clk)
592                         break;
593
594         if (cn->clk != clk) {
595                 cn_new = kzalloc(sizeof(struct clk_notifier), GFP_KERNEL);
596                 if (!cn_new) {
597                         r = -ENOMEM;
598                         goto cnr_out;
599                 };
600
601                 cn_new->clk = clk;
602                 RAW_INIT_NOTIFIER_HEAD(&cn_new->notifier_head);
603
604                 list_add(&cn_new->node, &clk_notifier_list);
605                 cn = cn_new;
606         }
607
608         r = raw_notifier_chain_register(&cn->notifier_head, nb);
609         if (!IS_ERR_VALUE(r)) {
610                 clkp = clk;
611                 do {
612                         clkp->notifier_count++;
613                 } while ((clkp = clkp->parent));
614         } else {
615                 if (cn_new)
616                         _clk_free_notifier_chain(cn);
617         }
618
619 cnr_out:
620         mutex_unlock(&clocks_mutex);
621
622         return r;
623 }
624 EXPORT_SYMBOL(rk30_clk_notifier_register);
625
626 /**
627  * clk_notifier_unregister - remove a clock change notifier
628  * @clk: struct clk *
629  * @nb: struct notifier_block * with callback info
630  *
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().
634  */
635 int rk30_clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
636 {
637         struct clk_notifier *cn = NULL;
638         struct clk *clkp;
639         int r = -EINVAL;
640
641         if (!clk || IS_ERR(clk) || !nb)
642                 return -EINVAL;
643
644         mutex_lock(&clocks_mutex);
645
646         list_for_each_entry(cn, &clk_notifier_list, node)
647                 if (cn->clk == clk)
648                         break;
649
650         if (cn->clk != clk) {
651                 r = -ENOENT;
652                 goto cnu_out;
653         };
654
655         r = raw_notifier_chain_unregister(&cn->notifier_head, nb);
656         if (!IS_ERR_VALUE(r)) {
657                 clkp = clk;
658                 do {
659                         clkp->notifier_count--;
660                 } while ((clkp = clkp->parent));
661         }
662
663         /*
664          * XXX ugh, layering violation.  There should be some
665          * support in the notifier code for this.
666          */
667         if (!cn->notifier_head.head)
668                 _clk_free_notifier_chain(cn);
669
670 cnu_out:
671         mutex_unlock(&clocks_mutex);
672
673         return r;
674 }
675 EXPORT_SYMBOL(rk30_clk_notifier_unregister);
676
677 #ifdef CONFIG_PROC_FS
678 static struct clk_dump_ops *dump_def_ops;
679
680 void clk_register_dump_ops(struct clk_dump_ops *ops)
681 {
682         dump_def_ops=ops;
683 }
684         
685 static int proc_clk_show(struct seq_file *s, void *v)
686 {
687         struct clk* clk;
688         
689         if(!dump_def_ops)
690                 return 0;
691
692         if(dump_def_ops->dump_clk)
693         {
694                 mutex_lock(&clocks_mutex);
695                 list_for_each_entry(clk, &clocks, node) {
696                         if (!clk->parent)
697                         {
698                                 dump_def_ops->dump_clk(s, clk, 0,&clocks);
699                         }
700                 }
701                 mutex_unlock(&clocks_mutex);
702         }
703         if(dump_def_ops->dump_regs)
704                 dump_def_ops->dump_regs(s);
705         return 0;
706 }
707
708
709 static int proc_clk_open(struct inode *inode, struct file *file)
710 {
711         return single_open(file, proc_clk_show, NULL);
712 }
713
714 static const struct file_operations proc_clk_fops = {
715         .open           = proc_clk_open,
716         .read           = seq_read,
717         .llseek         = seq_lseek,
718         .release        = single_release,
719 };
720
721 static int __init clk_proc_init(void)
722 {
723         proc_create("clocks", 0, NULL, &proc_clk_fops);
724         return 0;
725
726 }
727 late_initcall(clk_proc_init);
728 #endif /* CONFIG_PROC_FS */
729