]> git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blame - arch/arm/mach-tegra/clock.c
ARM: 6483/1: arm & sh: factorised duplicated clkdev.c
[mirror_ubuntu-zesty-kernel.git] / arch / arm / mach-tegra / clock.c
CommitLineData
d8611961
CC
1/*
2 *
3 * Copyright (C) 2010 Google, Inc.
4 *
5 * Author:
6 * Colin Cross <ccross@google.com>
7 *
8 * This software is licensed under the terms of the GNU General Public
9 * License version 2, as published by the Free Software Foundation, and
10 * may be copied, distributed, and modified under those terms.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 */
18
19#include <linux/kernel.h>
20#include <linux/clk.h>
21#include <linux/list.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/debugfs.h>
25#include <linux/slab.h>
26#include <linux/seq_file.h>
71fc84cc 27#include <linux/regulator/consumer.h>
6d803ba7 28#include <linux/clkdev.h>
d8611961
CC
29
30#include "clock.h"
71fc84cc
CC
31#include "board.h"
32#include "fuse.h"
d8611961
CC
33
34static LIST_HEAD(clocks);
35
36static DEFINE_SPINLOCK(clock_lock);
71fc84cc
CC
37static DEFINE_MUTEX(dvfs_lock);
38
39static int clk_is_dvfs(struct clk *c)
40{
41 return (c->dvfs != NULL);
42};
43
44static int dvfs_set_rate(struct dvfs *d, unsigned long rate)
45{
46 struct dvfs_table *t;
47
48 if (d->table == NULL)
49 return -ENODEV;
50
51 for (t = d->table; t->rate != 0; t++) {
52 if (rate <= t->rate) {
53 if (!d->reg)
54 return 0;
55
56 return regulator_set_voltage(d->reg,
57 t->millivolts * 1000,
58 d->max_millivolts * 1000);
59 }
60 }
61
62 return -EINVAL;
63}
64
65static void dvfs_init(struct clk *c)
66{
67 int process_id;
68 int i;
69 struct dvfs_table *table;
70
71 process_id = c->dvfs->cpu ? tegra_core_process_id() :
72 tegra_cpu_process_id();
73
74 for (i = 0; i < c->dvfs->process_id_table_length; i++)
75 if (process_id == c->dvfs->process_id_table[i].process_id)
76 c->dvfs->table = c->dvfs->process_id_table[i].table;
77
78 if (c->dvfs->table == NULL) {
79 pr_err("Failed to find dvfs table for clock %s process %d\n",
80 c->name, process_id);
81 return;
82 }
83
84 c->dvfs->max_millivolts = 0;
85 for (table = c->dvfs->table; table->rate != 0; table++)
86 if (c->dvfs->max_millivolts < table->millivolts)
87 c->dvfs->max_millivolts = table->millivolts;
88
89 c->dvfs->reg = regulator_get(NULL, c->dvfs->reg_id);
90
91 if (IS_ERR(c->dvfs->reg)) {
92 pr_err("Failed to get regulator %s for clock %s\n",
93 c->dvfs->reg_id, c->name);
94 c->dvfs->reg = NULL;
95 return;
96 }
97
98 if (c->refcnt > 0)
99 dvfs_set_rate(c->dvfs, c->rate);
100}
d8611961
CC
101
102struct clk *tegra_get_clock_by_name(const char *name)
103{
104 struct clk *c;
105 struct clk *ret = NULL;
106 unsigned long flags;
107 spin_lock_irqsave(&clock_lock, flags);
108 list_for_each_entry(c, &clocks, node) {
109 if (strcmp(c->name, name) == 0) {
110 ret = c;
111 break;
112 }
113 }
114 spin_unlock_irqrestore(&clock_lock, flags);
115 return ret;
116}
117
71fc84cc
CC
118static void clk_recalculate_rate(struct clk *c)
119{
120 u64 rate;
121
122 if (!c->parent)
123 return;
124
125 rate = c->parent->rate;
126
127 if (c->mul != 0 && c->div != 0) {
128 rate = rate * c->mul;
129 do_div(rate, c->div);
130 }
131
132 if (rate > c->max_rate)
133 pr_warn("clocks: Set clock %s to rate %llu, max is %lu\n",
134 c->name, rate, c->max_rate);
135
136 c->rate = rate;
137}
138
d8611961
CC
139int clk_reparent(struct clk *c, struct clk *parent)
140{
141 pr_debug("%s: %s\n", __func__, c->name);
d8611961 142 c->parent = parent;
d8611961
CC
143 list_del(&c->sibling);
144 list_add_tail(&c->sibling, &parent->children);
145 return 0;
146}
147
148static void propagate_rate(struct clk *c)
149{
150 struct clk *clkp;
151 pr_debug("%s: %s\n", __func__, c->name);
152 list_for_each_entry(clkp, &c->children, sibling) {
153 pr_debug(" %s\n", clkp->name);
71fc84cc 154 clk_recalculate_rate(clkp);
d8611961
CC
155 propagate_rate(clkp);
156 }
157}
158
159void clk_init(struct clk *c)
160{
161 unsigned long flags;
162
71fc84cc
CC
163 pr_debug("%s: %s\n", __func__, c->name);
164
d8611961
CC
165 spin_lock_irqsave(&clock_lock, flags);
166
167 INIT_LIST_HEAD(&c->children);
168 INIT_LIST_HEAD(&c->sibling);
169
170 if (c->ops && c->ops->init)
171 c->ops->init(c);
172
71fc84cc
CC
173 clk_recalculate_rate(c);
174
d8611961
CC
175 list_add(&c->node, &clocks);
176
177 if (c->parent)
178 list_add_tail(&c->sibling, &c->parent->children);
179
180 spin_unlock_irqrestore(&clock_lock, flags);
181}
182
183int clk_enable_locked(struct clk *c)
184{
185 int ret;
186 pr_debug("%s: %s\n", __func__, c->name);
187 if (c->refcnt == 0) {
188 if (c->parent) {
189 ret = clk_enable_locked(c->parent);
190 if (ret)
191 return ret;
192 }
193
194 if (c->ops && c->ops->enable) {
195 ret = c->ops->enable(c);
196 if (ret) {
197 if (c->parent)
198 clk_disable_locked(c->parent);
199 return ret;
200 }
201 c->state = ON;
202#ifdef CONFIG_DEBUG_FS
203 c->set = 1;
204#endif
205 }
206 }
207 c->refcnt++;
208
209 return 0;
210}
211
71fc84cc
CC
212int clk_enable_cansleep(struct clk *c)
213{
214 int ret;
215 unsigned long flags;
216
217 mutex_lock(&dvfs_lock);
218
219 if (clk_is_dvfs(c) && c->refcnt > 0)
220 dvfs_set_rate(c->dvfs, c->rate);
221
222 spin_lock_irqsave(&clock_lock, flags);
223 ret = clk_enable_locked(c);
224 spin_unlock_irqrestore(&clock_lock, flags);
225
226 mutex_unlock(&dvfs_lock);
227
228 return ret;
229}
230EXPORT_SYMBOL(clk_enable_cansleep);
231
d8611961
CC
232int clk_enable(struct clk *c)
233{
234 int ret;
235 unsigned long flags;
71fc84cc
CC
236
237 if (clk_is_dvfs(c))
238 BUG();
239
d8611961
CC
240 spin_lock_irqsave(&clock_lock, flags);
241 ret = clk_enable_locked(c);
242 spin_unlock_irqrestore(&clock_lock, flags);
71fc84cc 243
d8611961
CC
244 return ret;
245}
246EXPORT_SYMBOL(clk_enable);
247
248void clk_disable_locked(struct clk *c)
249{
250 pr_debug("%s: %s\n", __func__, c->name);
251 if (c->refcnt == 0) {
252 WARN(1, "Attempting to disable clock %s with refcnt 0", c->name);
253 return;
254 }
255 if (c->refcnt == 1) {
256 if (c->ops && c->ops->disable)
257 c->ops->disable(c);
258
259 if (c->parent)
260 clk_disable_locked(c->parent);
261
262 c->state = OFF;
263 }
264 c->refcnt--;
265}
266
71fc84cc
CC
267void clk_disable_cansleep(struct clk *c)
268{
269 unsigned long flags;
270
271 mutex_lock(&dvfs_lock);
272
273 spin_lock_irqsave(&clock_lock, flags);
274 clk_disable_locked(c);
275 spin_unlock_irqrestore(&clock_lock, flags);
276
277 if (clk_is_dvfs(c) && c->refcnt == 0)
278 dvfs_set_rate(c->dvfs, c->rate);
279
280 mutex_unlock(&dvfs_lock);
281}
282EXPORT_SYMBOL(clk_disable_cansleep);
283
d8611961
CC
284void clk_disable(struct clk *c)
285{
286 unsigned long flags;
71fc84cc
CC
287
288 if (clk_is_dvfs(c))
289 BUG();
290
d8611961
CC
291 spin_lock_irqsave(&clock_lock, flags);
292 clk_disable_locked(c);
293 spin_unlock_irqrestore(&clock_lock, flags);
294}
295EXPORT_SYMBOL(clk_disable);
296
297int clk_set_parent_locked(struct clk *c, struct clk *parent)
298{
299 int ret;
300
301 pr_debug("%s: %s\n", __func__, c->name);
302
303 if (!c->ops || !c->ops->set_parent)
304 return -ENOSYS;
305
306 ret = c->ops->set_parent(c, parent);
307
308 if (ret)
309 return ret;
310
71fc84cc
CC
311 clk_recalculate_rate(c);
312
d8611961
CC
313 propagate_rate(c);
314
315 return 0;
316}
317
318int clk_set_parent(struct clk *c, struct clk *parent)
319{
320 int ret;
321 unsigned long flags;
322 spin_lock_irqsave(&clock_lock, flags);
323 ret = clk_set_parent_locked(c, parent);
324 spin_unlock_irqrestore(&clock_lock, flags);
325 return ret;
326}
327EXPORT_SYMBOL(clk_set_parent);
328
329struct clk *clk_get_parent(struct clk *c)
330{
331 return c->parent;
332}
333EXPORT_SYMBOL(clk_get_parent);
334
71fc84cc
CC
335int clk_set_rate_locked(struct clk *c, unsigned long rate)
336{
337 int ret;
338
339 if (rate > c->max_rate)
340 rate = c->max_rate;
341
342 if (!c->ops || !c->ops->set_rate)
343 return -ENOSYS;
344
345 ret = c->ops->set_rate(c, rate);
346
347 if (ret)
348 return ret;
349
350 clk_recalculate_rate(c);
351
352 propagate_rate(c);
353
354 return 0;
355}
356
357int clk_set_rate_cansleep(struct clk *c, unsigned long rate)
d8611961
CC
358{
359 int ret = 0;
360 unsigned long flags;
361
71fc84cc
CC
362 pr_debug("%s: %s\n", __func__, c->name);
363
364 mutex_lock(&dvfs_lock);
365
366 if (rate > c->rate)
367 ret = dvfs_set_rate(c->dvfs, rate);
368 if (ret)
369 goto out;
370
d8611961 371 spin_lock_irqsave(&clock_lock, flags);
71fc84cc
CC
372 ret = clk_set_rate_locked(c, rate);
373 spin_unlock_irqrestore(&clock_lock, flags);
d8611961 374
71fc84cc
CC
375 if (ret)
376 goto out;
d8611961 377
71fc84cc 378 ret = dvfs_set_rate(c->dvfs, rate);
d8611961 379
71fc84cc
CC
380out:
381 mutex_unlock(&dvfs_lock);
382 return ret;
383}
384EXPORT_SYMBOL(clk_set_rate_cansleep);
385
386int clk_set_rate(struct clk *c, unsigned long rate)
387{
388 int ret = 0;
389 unsigned long flags;
390
391 pr_debug("%s: %s\n", __func__, c->name);
392
393 if (clk_is_dvfs(c))
394 BUG();
d8611961 395
71fc84cc
CC
396 spin_lock_irqsave(&clock_lock, flags);
397 ret = clk_set_rate_locked(c, rate);
d8611961
CC
398 spin_unlock_irqrestore(&clock_lock, flags);
399
400 return ret;
401}
402EXPORT_SYMBOL(clk_set_rate);
403
404unsigned long clk_get_rate(struct clk *c)
405{
406 unsigned long flags;
407 unsigned long ret;
408
409 spin_lock_irqsave(&clock_lock, flags);
410
411 pr_debug("%s: %s\n", __func__, c->name);
412
413 ret = c->rate;
414
415 spin_unlock_irqrestore(&clock_lock, flags);
416 return ret;
417}
418EXPORT_SYMBOL(clk_get_rate);
419
71fc84cc
CC
420long clk_round_rate(struct clk *c, unsigned long rate)
421{
422 pr_debug("%s: %s\n", __func__, c->name);
423
424 if (!c->ops || !c->ops->round_rate)
425 return -ENOSYS;
426
427 if (rate > c->max_rate)
428 rate = c->max_rate;
429
430 return c->ops->round_rate(c, rate);
431}
432EXPORT_SYMBOL(clk_round_rate);
433
d8611961
CC
434static int tegra_clk_init_one_from_table(struct tegra_clk_init_table *table)
435{
436 struct clk *c;
437 struct clk *p;
438
439 int ret = 0;
440
441 c = tegra_get_clock_by_name(table->name);
442
443 if (!c) {
444 pr_warning("Unable to initialize clock %s\n",
445 table->name);
446 return -ENODEV;
447 }
448
449 if (table->parent) {
450 p = tegra_get_clock_by_name(table->parent);
451 if (!p) {
452 pr_warning("Unable to find parent %s of clock %s\n",
453 table->parent, table->name);
454 return -ENODEV;
455 }
456
457 if (c->parent != p) {
458 ret = clk_set_parent(c, p);
459 if (ret) {
460 pr_warning("Unable to set parent %s of clock %s: %d\n",
461 table->parent, table->name, ret);
462 return -EINVAL;
463 }
464 }
465 }
466
467 if (table->rate && table->rate != clk_get_rate(c)) {
468 ret = clk_set_rate(c, table->rate);
469 if (ret) {
470 pr_warning("Unable to set clock %s to rate %lu: %d\n",
471 table->name, table->rate, ret);
472 return -EINVAL;
473 }
474 }
475
476 if (table->enabled) {
477 ret = clk_enable(c);
478 if (ret) {
479 pr_warning("Unable to enable clock %s: %d\n",
480 table->name, ret);
481 return -EINVAL;
482 }
483 }
484
485 return 0;
486}
487
488void tegra_clk_init_from_table(struct tegra_clk_init_table *table)
489{
490 for (; table->name; table++)
491 tegra_clk_init_one_from_table(table);
492}
493EXPORT_SYMBOL(tegra_clk_init_from_table);
494
495void tegra_periph_reset_deassert(struct clk *c)
496{
497 tegra2_periph_reset_deassert(c);
498}
499EXPORT_SYMBOL(tegra_periph_reset_deassert);
500
501void tegra_periph_reset_assert(struct clk *c)
502{
503 tegra2_periph_reset_assert(c);
504}
505EXPORT_SYMBOL(tegra_periph_reset_assert);
506
71fc84cc 507void __init tegra_init_clock(void)
d8611961
CC
508{
509 tegra2_init_clocks();
71fc84cc
CC
510}
511
512int __init tegra_init_dvfs(void)
513{
514 struct clk *c, *safe;
515
516 mutex_lock(&dvfs_lock);
517
518 list_for_each_entry_safe(c, safe, &clocks, node)
519 if (c->dvfs)
520 dvfs_init(c);
521
522 mutex_unlock(&dvfs_lock);
d8611961
CC
523
524 return 0;
525}
526
71fc84cc
CC
527late_initcall(tegra_init_dvfs);
528
d8611961
CC
529#ifdef CONFIG_DEBUG_FS
530static struct dentry *clk_debugfs_root;
531
532
533static void clock_tree_show_one(struct seq_file *s, struct clk *c, int level)
534{
535 struct clk *child;
536 struct clk *safe;
537 const char *state = "uninit";
71fc84cc 538 char div[8] = {0};
d8611961
CC
539
540 if (c->state == ON)
541 state = "on";
542 else if (c->state == OFF)
543 state = "off";
544
545 if (c->mul != 0 && c->div != 0) {
71fc84cc
CC
546 if (c->mul > c->div) {
547 int mul = c->mul / c->div;
548 int mul2 = (c->mul * 10 / c->div) % 10;
549 int mul3 = (c->mul * 10) % c->div;
550 if (mul2 == 0 && mul3 == 0)
551 snprintf(div, sizeof(div), "x%d", mul);
552 else if (mul3 == 0)
553 snprintf(div, sizeof(div), "x%d.%d", mul, mul2);
554 else
555 snprintf(div, sizeof(div), "x%d.%d..", mul, mul2);
556 } else {
d8611961
CC
557 snprintf(div, sizeof(div), "%d%s", c->div / c->mul,
558 (c->div % c->mul) ? ".5" : "");
71fc84cc 559 }
d8611961
CC
560 }
561
71fc84cc
CC
562 seq_printf(s, "%*s%c%c%-*s %-6s %-3d %-8s %-10lu\n",
563 level * 3 + 1, "",
564 c->rate > c->max_rate ? '!' : ' ',
565 !c->set ? '*' : ' ',
d8611961
CC
566 30 - level * 3, c->name,
567 state, c->refcnt, div, c->rate);
568 list_for_each_entry_safe(child, safe, &c->children, sibling) {
569 clock_tree_show_one(s, child, level + 1);
570 }
571}
572
573static int clock_tree_show(struct seq_file *s, void *data)
574{
575 struct clk *c;
576 unsigned long flags;
71fc84cc
CC
577 seq_printf(s, " clock state ref div rate\n");
578 seq_printf(s, "--------------------------------------------------------------\n");
d8611961
CC
579 spin_lock_irqsave(&clock_lock, flags);
580 list_for_each_entry(c, &clocks, node)
581 if (c->parent == NULL)
582 clock_tree_show_one(s, c, 0);
583 spin_unlock_irqrestore(&clock_lock, flags);
584 return 0;
585}
586
587static int clock_tree_open(struct inode *inode, struct file *file)
588{
589 return single_open(file, clock_tree_show, inode->i_private);
590}
591
592static const struct file_operations clock_tree_fops = {
593 .open = clock_tree_open,
594 .read = seq_read,
595 .llseek = seq_lseek,
596 .release = single_release,
597};
598
599static int possible_parents_show(struct seq_file *s, void *data)
600{
601 struct clk *c = s->private;
602 int i;
603
604 for (i = 0; c->inputs[i].input; i++) {
605 char *first = (i == 0) ? "" : " ";
606 seq_printf(s, "%s%s", first, c->inputs[i].input->name);
607 }
608 seq_printf(s, "\n");
609 return 0;
610}
611
612static int possible_parents_open(struct inode *inode, struct file *file)
613{
614 return single_open(file, possible_parents_show, inode->i_private);
615}
616
617static const struct file_operations possible_parents_fops = {
618 .open = possible_parents_open,
619 .read = seq_read,
620 .llseek = seq_lseek,
621 .release = single_release,
622};
623
624static int clk_debugfs_register_one(struct clk *c)
625{
626 struct dentry *d, *child, *child_tmp;
627
628 d = debugfs_create_dir(c->name, clk_debugfs_root);
629 if (!d)
630 return -ENOMEM;
631 c->dent = d;
632
633 d = debugfs_create_u8("refcnt", S_IRUGO, c->dent, (u8 *)&c->refcnt);
634 if (!d)
635 goto err_out;
636
637 d = debugfs_create_u32("rate", S_IRUGO, c->dent, (u32 *)&c->rate);
638 if (!d)
639 goto err_out;
640
641 d = debugfs_create_x32("flags", S_IRUGO, c->dent, (u32 *)&c->flags);
642 if (!d)
643 goto err_out;
644
645 if (c->inputs) {
646 d = debugfs_create_file("possible_parents", S_IRUGO, c->dent,
647 c, &possible_parents_fops);
648 if (!d)
649 goto err_out;
650 }
651
652 return 0;
653
654err_out:
655 d = c->dent;
656 list_for_each_entry_safe(child, child_tmp, &d->d_subdirs, d_u.d_child)
657 debugfs_remove(child);
658 debugfs_remove(c->dent);
659 return -ENOMEM;
660}
661
662static int clk_debugfs_register(struct clk *c)
663{
664 int err;
665 struct clk *pa = c->parent;
666
667 if (pa && !pa->dent) {
668 err = clk_debugfs_register(pa);
669 if (err)
670 return err;
671 }
672
673 if (!c->dent) {
674 err = clk_debugfs_register_one(c);
675 if (err)
676 return err;
677 }
678 return 0;
679}
680
681static int __init clk_debugfs_init(void)
682{
683 struct clk *c;
684 struct dentry *d;
685 int err = -ENOMEM;
686
687 d = debugfs_create_dir("clock", NULL);
688 if (!d)
689 return -ENOMEM;
690 clk_debugfs_root = d;
691
692 d = debugfs_create_file("clock_tree", S_IRUGO, clk_debugfs_root, NULL,
693 &clock_tree_fops);
694 if (!d)
695 goto err_out;
696
697 list_for_each_entry(c, &clocks, node) {
698 err = clk_debugfs_register(c);
699 if (err)
700 goto err_out;
701 }
702 return 0;
703err_out:
704 debugfs_remove_recursive(clk_debugfs_root);
705 return err;
706}
707
708late_initcall(clk_debugfs_init);
709#endif