ARM: Consolidate clks_register() and similar
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / arch / arm / plat-stmp3xxx / clock.c
blobe593a2a801c63370efea993d529adf8b8960e0f4
1 /*
2 * Clock manipulation routines for Freescale STMP37XX/STMP378X
4 * Author: Vitaly Wool <vital@embeddedalley.com>
6 * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
7 * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
8 */
11 * The code contained herein is licensed under the GNU General Public
12 * License. You may obtain a copy of the GNU General Public License
13 * Version 2 or later at the following locations:
15 * http://www.opensource.org/licenses/gpl-license.html
16 * http://www.gnu.org/copyleft/gpl.html
18 #define DEBUG
19 #include <linux/kernel.h>
20 #include <linux/module.h>
21 #include <linux/init.h>
22 #include <linux/clk.h>
23 #include <linux/spinlock.h>
24 #include <linux/errno.h>
25 #include <linux/err.h>
26 #include <linux/delay.h>
27 #include <linux/io.h>
29 #include <asm/mach-types.h>
30 #include <asm/clkdev.h>
31 #include <mach/platform.h>
32 #include <mach/regs-clkctrl.h>
34 #include "clock.h"
36 static DEFINE_SPINLOCK(clocks_lock);
38 static struct clk osc_24M;
39 static struct clk pll_clk;
40 static struct clk cpu_clk;
41 static struct clk hclk;
43 static int propagate_rate(struct clk *);
45 static inline int clk_is_busy(struct clk *clk)
47 return __raw_readl(clk->busy_reg) & (1 << clk->busy_bit);
50 static inline int clk_good(struct clk *clk)
52 return clk && !IS_ERR(clk) && clk->ops;
55 static int std_clk_enable(struct clk *clk)
57 if (clk->enable_reg) {
58 u32 clk_reg = __raw_readl(clk->enable_reg);
59 if (clk->enable_negate)
60 clk_reg &= ~(1 << clk->enable_shift);
61 else
62 clk_reg |= (1 << clk->enable_shift);
63 __raw_writel(clk_reg, clk->enable_reg);
64 if (clk->enable_wait)
65 udelay(clk->enable_wait);
66 return 0;
67 } else
68 return -EINVAL;
71 static int std_clk_disable(struct clk *clk)
73 if (clk->enable_reg) {
74 u32 clk_reg = __raw_readl(clk->enable_reg);
75 if (clk->enable_negate)
76 clk_reg |= (1 << clk->enable_shift);
77 else
78 clk_reg &= ~(1 << clk->enable_shift);
79 __raw_writel(clk_reg, clk->enable_reg);
80 return 0;
81 } else
82 return -EINVAL;
85 static int io_set_rate(struct clk *clk, u32 rate)
87 u32 reg_frac, clkctrl_frac;
88 int i, ret = 0, mask = 0x1f;
90 clkctrl_frac = (clk->parent->rate * 18 + rate - 1) / rate;
92 if (clkctrl_frac < 18 || clkctrl_frac > 35) {
93 ret = -EINVAL;
94 goto out;
97 reg_frac = __raw_readl(clk->scale_reg);
98 reg_frac &= ~(mask << clk->scale_shift);
99 __raw_writel(reg_frac | (clkctrl_frac << clk->scale_shift),
100 clk->scale_reg);
101 if (clk->busy_reg) {
102 for (i = 10000; i; i--)
103 if (!clk_is_busy(clk))
104 break;
105 if (!i)
106 ret = -ETIMEDOUT;
107 else
108 ret = 0;
110 out:
111 return ret;
114 static long io_get_rate(struct clk *clk)
116 long rate = clk->parent->rate * 18;
117 int mask = 0x1f;
119 rate /= (__raw_readl(clk->scale_reg) >> clk->scale_shift) & mask;
120 clk->rate = rate;
122 return rate;
125 static long per_get_rate(struct clk *clk)
127 long rate = clk->parent->rate;
128 long div;
129 const int mask = 0xff;
131 if (clk->enable_reg &&
132 !(__raw_readl(clk->enable_reg) & clk->enable_shift))
133 clk->rate = 0;
134 else {
135 div = (__raw_readl(clk->scale_reg) >> clk->scale_shift) & mask;
136 if (div)
137 rate /= div;
138 clk->rate = rate;
141 return clk->rate;
144 static int per_set_rate(struct clk *clk, u32 rate)
146 int ret = -EINVAL;
147 int div = (clk->parent->rate + rate - 1) / rate;
148 u32 reg_frac;
149 const int mask = 0xff;
150 int try = 10;
151 int i = -1;
153 if (div == 0 || div > mask)
154 goto out;
156 reg_frac = __raw_readl(clk->scale_reg);
157 reg_frac &= ~(mask << clk->scale_shift);
159 while (try--) {
160 __raw_writel(reg_frac | (div << clk->scale_shift),
161 clk->scale_reg);
163 if (clk->busy_reg) {
164 for (i = 10000; i; i--)
165 if (!clk_is_busy(clk))
166 break;
168 if (i)
169 break;
172 if (!i)
173 ret = -ETIMEDOUT;
174 else
175 ret = 0;
177 out:
178 if (ret != 0)
179 printk(KERN_ERR "%s: error %d\n", __func__, ret);
180 return ret;
183 static long lcdif_get_rate(struct clk *clk)
185 long rate = clk->parent->rate;
186 long div;
187 const int mask = 0xff;
189 div = (__raw_readl(clk->scale_reg) >> clk->scale_shift) & mask;
190 if (div) {
191 rate /= div;
192 div = (__raw_readl(REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC) &
193 BM_CLKCTRL_FRAC_PIXFRAC) >> BP_CLKCTRL_FRAC_PIXFRAC;
194 rate /= div;
196 clk->rate = rate;
198 return rate;
201 static int lcdif_set_rate(struct clk *clk, u32 rate)
203 int ret = 0;
205 * On 3700, we can get most timings exact by modifying ref_pix
206 * and the divider, but keeping the phase timings at 1 (2
207 * phases per cycle).
209 * ref_pix can be between 480e6*18/35=246.9MHz and 480e6*18/18=480MHz,
210 * which is between 18/(18*480e6)=2.084ns and 35/(18*480e6)=4.050ns.
212 * ns_cycle >= 2*18e3/(18*480) = 25/6
213 * ns_cycle <= 2*35e3/(18*480) = 875/108
215 * Multiply the ns_cycle by 'div' to lengthen it until it fits the
216 * bounds. This is the divider we'll use after ref_pix.
218 * 6 * ns_cycle >= 25 * div
219 * 108 * ns_cycle <= 875 * div
221 u32 ns_cycle = 1000000 / rate;
222 u32 div, reg_val;
223 u32 lowest_result = (u32) -1;
224 u32 lowest_div = 0, lowest_fracdiv = 0;
226 for (div = 1; div < 256; ++div) {
227 u32 fracdiv;
228 u32 ps_result;
229 int lower_bound = 6 * ns_cycle >= 25 * div;
230 int upper_bound = 108 * ns_cycle <= 875 * div;
231 if (!lower_bound)
232 break;
233 if (!upper_bound)
234 continue;
236 * Found a matching div. Calculate fractional divider needed,
237 * rounded up.
239 fracdiv = ((clk->parent->rate / 1000 * 18 / 2) *
240 ns_cycle + 1000 * div - 1) /
241 (1000 * div);
242 if (fracdiv < 18 || fracdiv > 35) {
243 ret = -EINVAL;
244 goto out;
246 /* Calculate the actual cycle time this results in */
247 ps_result = 6250 * div * fracdiv / 27;
249 /* Use the fastest result that doesn't break ns_cycle */
250 if (ps_result <= lowest_result) {
251 lowest_result = ps_result;
252 lowest_div = div;
253 lowest_fracdiv = fracdiv;
257 if (div >= 256 || lowest_result == (u32) -1) {
258 ret = -EINVAL;
259 goto out;
261 pr_debug("Programming PFD=%u,DIV=%u ref_pix=%uMHz "
262 "PIXCLK=%uMHz cycle=%u.%03uns\n",
263 lowest_fracdiv, lowest_div,
264 480*18/lowest_fracdiv, 480*18/lowest_fracdiv/lowest_div,
265 lowest_result / 1000, lowest_result % 1000);
267 /* Program ref_pix phase fractional divider */
268 reg_val = __raw_readl(REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC);
269 reg_val &= ~BM_CLKCTRL_FRAC_PIXFRAC;
270 reg_val |= BF(lowest_fracdiv, CLKCTRL_FRAC_PIXFRAC);
271 __raw_writel(reg_val, REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC);
273 /* Ungate PFD */
274 stmp3xxx_clearl(BM_CLKCTRL_FRAC_CLKGATEPIX,
275 REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC);
277 /* Program pix divider */
278 reg_val = __raw_readl(clk->scale_reg);
279 reg_val &= ~(BM_CLKCTRL_PIX_DIV | BM_CLKCTRL_PIX_CLKGATE);
280 reg_val |= BF(lowest_div, CLKCTRL_PIX_DIV);
281 __raw_writel(reg_val, clk->scale_reg);
283 /* Wait for divider update */
284 if (clk->busy_reg) {
285 int i;
286 for (i = 10000; i; i--)
287 if (!clk_is_busy(clk))
288 break;
289 if (!i) {
290 ret = -ETIMEDOUT;
291 goto out;
295 /* Switch to ref_pix source */
296 reg_val = __raw_readl(REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ);
297 reg_val &= ~BM_CLKCTRL_CLKSEQ_BYPASS_PIX;
298 __raw_writel(reg_val, REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ);
300 out:
301 return ret;
305 static int cpu_set_rate(struct clk *clk, u32 rate)
307 u32 reg_val;
309 if (rate < 24000)
310 return -EINVAL;
311 else if (rate == 24000) {
312 /* switch to the 24M source */
313 clk_set_parent(clk, &osc_24M);
314 } else {
315 int i;
316 u32 clkctrl_cpu = 1;
317 u32 c = clkctrl_cpu;
318 u32 clkctrl_frac = 1;
319 u32 val;
320 for ( ; c < 0x40; c++) {
321 u32 f = (pll_clk.rate*18/c + rate/2) / rate;
322 int s1, s2;
324 if (f < 18 || f > 35)
325 continue;
326 s1 = pll_clk.rate*18/clkctrl_frac/clkctrl_cpu - rate;
327 s2 = pll_clk.rate*18/c/f - rate;
328 pr_debug("%s: s1 %d, s2 %d\n", __func__, s1, s2);
329 if (abs(s1) > abs(s2)) {
330 clkctrl_cpu = c;
331 clkctrl_frac = f;
333 if (s2 == 0)
334 break;
336 pr_debug("%s: clkctrl_cpu %d, clkctrl_frac %d\n", __func__,
337 clkctrl_cpu, clkctrl_frac);
338 if (c == 0x40) {
339 int d = pll_clk.rate*18/clkctrl_frac/clkctrl_cpu -
340 rate;
341 if (abs(d) > 100 ||
342 clkctrl_frac < 18 || clkctrl_frac > 35)
343 return -EINVAL;
346 /* 4.6.2 */
347 val = __raw_readl(clk->scale_reg);
348 val &= ~(0x3f << clk->scale_shift);
349 val |= clkctrl_frac;
350 clk_set_parent(clk, &osc_24M);
351 udelay(10);
352 __raw_writel(val, clk->scale_reg);
353 /* ungate */
354 __raw_writel(1<<7, clk->scale_reg + 8);
355 /* write clkctrl_cpu */
356 clk->saved_div = clkctrl_cpu;
358 reg_val = __raw_readl(REGS_CLKCTRL_BASE + HW_CLKCTRL_CPU);
359 reg_val &= ~0x3F;
360 reg_val |= clkctrl_cpu;
361 __raw_writel(reg_val, REGS_CLKCTRL_BASE + HW_CLKCTRL_CPU);
363 for (i = 10000; i; i--)
364 if (!clk_is_busy(clk))
365 break;
366 if (!i) {
367 printk(KERN_ERR "couldn't set up CPU divisor\n");
368 return -ETIMEDOUT;
370 clk_set_parent(clk, &pll_clk);
371 clk->saved_div = 0;
372 udelay(10);
374 return 0;
377 static long cpu_get_rate(struct clk *clk)
379 long rate = clk->parent->rate * 18;
381 rate /= (__raw_readl(clk->scale_reg) >> clk->scale_shift) & 0x3f;
382 rate /= __raw_readl(REGS_CLKCTRL_BASE + HW_CLKCTRL_CPU) & 0x3f;
383 rate = ((rate + 9) / 10) * 10;
384 clk->rate = rate;
386 return rate;
389 static long cpu_round_rate(struct clk *clk, u32 rate)
391 unsigned long r = 0;
393 if (rate <= 24000)
394 r = 24000;
395 else {
396 u32 clkctrl_cpu = 1;
397 u32 clkctrl_frac;
398 do {
399 clkctrl_frac =
400 (pll_clk.rate*18 / clkctrl_cpu + rate/2) / rate;
401 if (clkctrl_frac > 35)
402 continue;
403 if (pll_clk.rate*18 / clkctrl_frac / clkctrl_cpu/10 ==
404 rate / 10)
405 break;
406 } while (pll_clk.rate / 2 >= clkctrl_cpu++ * rate);
407 if (pll_clk.rate / 2 < (clkctrl_cpu - 1) * rate)
408 clkctrl_cpu--;
409 pr_debug("%s: clkctrl_cpu %d, clkctrl_frac %d\n", __func__,
410 clkctrl_cpu, clkctrl_frac);
411 if (clkctrl_frac < 18)
412 clkctrl_frac = 18;
413 if (clkctrl_frac > 35)
414 clkctrl_frac = 35;
416 r = pll_clk.rate * 18;
417 r /= clkctrl_frac;
418 r /= clkctrl_cpu;
419 r = 10 * ((r + 9) / 10);
421 return r;
424 static long emi_get_rate(struct clk *clk)
426 long rate = clk->parent->rate * 18;
428 rate /= (__raw_readl(clk->scale_reg) >> clk->scale_shift) & 0x3f;
429 rate /= __raw_readl(REGS_CLKCTRL_BASE + HW_CLKCTRL_EMI) & 0x3f;
430 clk->rate = rate;
432 return rate;
435 static int clkseq_set_parent(struct clk *clk, struct clk *parent)
437 int ret = -EINVAL;
438 int shift = 8;
440 /* bypass? */
441 if (parent == &osc_24M)
442 shift = 4;
444 if (clk->bypass_reg) {
445 #ifdef CONFIG_ARCH_STMP378X
446 u32 hbus_val, cpu_val;
448 if (clk == &cpu_clk && shift == 4) {
449 hbus_val = __raw_readl(REGS_CLKCTRL_BASE +
450 HW_CLKCTRL_HBUS);
451 cpu_val = __raw_readl(REGS_CLKCTRL_BASE +
452 HW_CLKCTRL_CPU);
454 hbus_val &= ~(BM_CLKCTRL_HBUS_DIV_FRAC_EN |
455 BM_CLKCTRL_HBUS_DIV);
456 clk->saved_div = cpu_val & BM_CLKCTRL_CPU_DIV_CPU;
457 cpu_val &= ~BM_CLKCTRL_CPU_DIV_CPU;
458 cpu_val |= 1;
460 if (machine_is_stmp378x()) {
461 __raw_writel(hbus_val,
462 REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS);
463 __raw_writel(cpu_val,
464 REGS_CLKCTRL_BASE + HW_CLKCTRL_CPU);
465 hclk.rate = 0;
467 } else if (clk == &cpu_clk && shift == 8) {
468 hbus_val = __raw_readl(REGS_CLKCTRL_BASE +
469 HW_CLKCTRL_HBUS);
470 cpu_val = __raw_readl(REGS_CLKCTRL_BASE +
471 HW_CLKCTRL_CPU);
472 hbus_val &= ~(BM_CLKCTRL_HBUS_DIV_FRAC_EN |
473 BM_CLKCTRL_HBUS_DIV);
474 hbus_val |= 2;
475 cpu_val &= ~BM_CLKCTRL_CPU_DIV_CPU;
476 if (clk->saved_div)
477 cpu_val |= clk->saved_div;
478 else
479 cpu_val |= 2;
481 if (machine_is_stmp378x()) {
482 __raw_writel(hbus_val,
483 REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS);
484 __raw_writel(cpu_val,
485 REGS_CLKCTRL_BASE + HW_CLKCTRL_CPU);
486 hclk.rate = 0;
489 #endif
490 __raw_writel(1 << clk->bypass_shift, clk->bypass_reg + shift);
492 ret = 0;
495 return ret;
498 static int hbus_set_rate(struct clk *clk, u32 rate)
500 u8 div = 0;
501 int is_frac = 0;
502 u32 clkctrl_hbus;
503 struct clk *parent = clk->parent;
505 pr_debug("%s: rate %d, parent rate %d\n", __func__, rate,
506 parent->rate);
508 if (rate > parent->rate)
509 return -EINVAL;
511 if (((parent->rate + rate/2) / rate) * rate != parent->rate &&
512 parent->rate / rate < 32) {
513 pr_debug("%s: switching to fractional mode\n", __func__);
514 is_frac = 1;
517 if (is_frac)
518 div = (32 * rate + parent->rate / 2) / parent->rate;
519 else
520 div = (parent->rate + rate - 1) / rate;
521 pr_debug("%s: div calculated is %d\n", __func__, div);
522 if (!div || div > 0x1f)
523 return -EINVAL;
525 clk_set_parent(&cpu_clk, &osc_24M);
526 udelay(10);
527 clkctrl_hbus = __raw_readl(clk->scale_reg);
528 clkctrl_hbus &= ~0x3f;
529 clkctrl_hbus |= div;
530 clkctrl_hbus |= (is_frac << 5);
532 __raw_writel(clkctrl_hbus, clk->scale_reg);
533 if (clk->busy_reg) {
534 int i;
535 for (i = 10000; i; i--)
536 if (!clk_is_busy(clk))
537 break;
538 if (!i) {
539 printk(KERN_ERR "couldn't set up CPU divisor\n");
540 return -ETIMEDOUT;
543 clk_set_parent(&cpu_clk, &pll_clk);
544 __raw_writel(clkctrl_hbus, clk->scale_reg);
545 udelay(10);
546 return 0;
549 static long hbus_get_rate(struct clk *clk)
551 long rate = clk->parent->rate;
553 if (__raw_readl(clk->scale_reg) & 0x20) {
554 rate *= __raw_readl(clk->scale_reg) & 0x1f;
555 rate /= 32;
556 } else
557 rate /= __raw_readl(clk->scale_reg) & 0x1f;
558 clk->rate = rate;
560 return rate;
563 static int xbus_set_rate(struct clk *clk, u32 rate)
565 u16 div = 0;
566 u32 clkctrl_xbus;
568 pr_debug("%s: rate %d, parent rate %d\n", __func__, rate,
569 clk->parent->rate);
571 div = (clk->parent->rate + rate - 1) / rate;
572 pr_debug("%s: div calculated is %d\n", __func__, div);
573 if (!div || div > 0x3ff)
574 return -EINVAL;
576 clkctrl_xbus = __raw_readl(clk->scale_reg);
577 clkctrl_xbus &= ~0x3ff;
578 clkctrl_xbus |= div;
579 __raw_writel(clkctrl_xbus, clk->scale_reg);
580 if (clk->busy_reg) {
581 int i;
582 for (i = 10000; i; i--)
583 if (!clk_is_busy(clk))
584 break;
585 if (!i) {
586 printk(KERN_ERR "couldn't set up xbus divisor\n");
587 return -ETIMEDOUT;
590 return 0;
593 static long xbus_get_rate(struct clk *clk)
595 long rate = clk->parent->rate;
597 rate /= __raw_readl(clk->scale_reg) & 0x3ff;
598 clk->rate = rate;
600 return rate;
604 /* Clock ops */
606 static struct clk_ops std_ops = {
607 .enable = std_clk_enable,
608 .disable = std_clk_disable,
609 .get_rate = per_get_rate,
610 .set_rate = per_set_rate,
611 .set_parent = clkseq_set_parent,
614 static struct clk_ops min_ops = {
615 .enable = std_clk_enable,
616 .disable = std_clk_disable,
619 static struct clk_ops cpu_ops = {
620 .enable = std_clk_enable,
621 .disable = std_clk_disable,
622 .get_rate = cpu_get_rate,
623 .set_rate = cpu_set_rate,
624 .round_rate = cpu_round_rate,
625 .set_parent = clkseq_set_parent,
628 static struct clk_ops io_ops = {
629 .enable = std_clk_enable,
630 .disable = std_clk_disable,
631 .get_rate = io_get_rate,
632 .set_rate = io_set_rate,
635 static struct clk_ops hbus_ops = {
636 .get_rate = hbus_get_rate,
637 .set_rate = hbus_set_rate,
640 static struct clk_ops xbus_ops = {
641 .get_rate = xbus_get_rate,
642 .set_rate = xbus_set_rate,
645 static struct clk_ops lcdif_ops = {
646 .enable = std_clk_enable,
647 .disable = std_clk_disable,
648 .get_rate = lcdif_get_rate,
649 .set_rate = lcdif_set_rate,
650 .set_parent = clkseq_set_parent,
653 static struct clk_ops emi_ops = {
654 .get_rate = emi_get_rate,
657 /* List of on-chip clocks */
659 static struct clk osc_24M = {
660 .flags = FIXED_RATE | ENABLED,
661 .rate = 24000,
664 static struct clk pll_clk = {
665 .parent = &osc_24M,
666 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_PLLCTRL0,
667 .enable_shift = 16,
668 .enable_wait = 10,
669 .flags = FIXED_RATE | ENABLED,
670 .rate = 480000,
671 .ops = &min_ops,
674 static struct clk cpu_clk = {
675 .parent = &pll_clk,
676 .scale_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC,
677 .scale_shift = 0,
678 .bypass_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
679 .bypass_shift = 7,
680 .busy_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_CPU,
681 .busy_bit = 28,
682 .flags = RATE_PROPAGATES | ENABLED,
683 .ops = &cpu_ops,
686 static struct clk io_clk = {
687 .parent = &pll_clk,
688 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC,
689 .enable_shift = 31,
690 .enable_negate = 1,
691 .scale_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC,
692 .scale_shift = 24,
693 .flags = RATE_PROPAGATES | ENABLED,
694 .ops = &io_ops,
697 static struct clk hclk = {
698 .parent = &cpu_clk,
699 .scale_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS,
700 .bypass_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
701 .bypass_shift = 7,
702 .busy_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS,
703 .busy_bit = 29,
704 .flags = RATE_PROPAGATES | ENABLED,
705 .ops = &hbus_ops,
708 static struct clk xclk = {
709 .parent = &osc_24M,
710 .scale_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_XBUS,
711 .busy_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_XBUS,
712 .busy_bit = 31,
713 .flags = RATE_PROPAGATES | ENABLED,
714 .ops = &xbus_ops,
717 static struct clk uart_clk = {
718 .parent = &xclk,
719 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_XTAL,
720 .enable_shift = 31,
721 .enable_negate = 1,
722 .flags = ENABLED,
723 .ops = &min_ops,
726 static struct clk audio_clk = {
727 .parent = &xclk,
728 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_XTAL,
729 .enable_shift = 30,
730 .enable_negate = 1,
731 .ops = &min_ops,
734 static struct clk pwm_clk = {
735 .parent = &xclk,
736 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_XTAL,
737 .enable_shift = 29,
738 .enable_negate = 1,
739 .ops = &min_ops,
742 static struct clk dri_clk = {
743 .parent = &xclk,
744 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_XTAL,
745 .enable_shift = 28,
746 .enable_negate = 1,
747 .ops = &min_ops,
750 static struct clk digctl_clk = {
751 .parent = &xclk,
752 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_XTAL,
753 .enable_shift = 27,
754 .enable_negate = 1,
755 .ops = &min_ops,
758 static struct clk timer_clk = {
759 .parent = &xclk,
760 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_XTAL,
761 .enable_shift = 26,
762 .enable_negate = 1,
763 .flags = ENABLED,
764 .ops = &min_ops,
767 static struct clk lcdif_clk = {
768 .parent = &pll_clk,
769 .scale_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_PIX,
770 .busy_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_PIX,
771 .busy_bit = 29,
772 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_PIX,
773 .enable_shift = 31,
774 .enable_negate = 1,
775 .bypass_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
776 .bypass_shift = 1,
777 .flags = NEEDS_SET_PARENT,
778 .ops = &lcdif_ops,
781 static struct clk ssp_clk = {
782 .parent = &io_clk,
783 .scale_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_SSP,
784 .busy_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_SSP,
785 .busy_bit = 29,
786 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_SSP,
787 .enable_shift = 31,
788 .bypass_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
789 .bypass_shift = 5,
790 .enable_negate = 1,
791 .flags = NEEDS_SET_PARENT,
792 .ops = &std_ops,
795 static struct clk gpmi_clk = {
796 .parent = &io_clk,
797 .scale_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_GPMI,
798 .busy_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_GPMI,
799 .busy_bit = 29,
800 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_GPMI,
801 .enable_shift = 31,
802 .enable_negate = 1,
803 .bypass_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
804 .bypass_shift = 4,
805 .flags = NEEDS_SET_PARENT,
806 .ops = &std_ops,
809 static struct clk spdif_clk = {
810 .parent = &pll_clk,
811 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_SPDIF,
812 .enable_shift = 31,
813 .enable_negate = 1,
814 .ops = &min_ops,
817 static struct clk emi_clk = {
818 .parent = &pll_clk,
819 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_EMI,
820 .enable_shift = 31,
821 .enable_negate = 1,
822 .scale_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_FRAC,
823 .scale_shift = 8,
824 .busy_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_EMI,
825 .busy_bit = 28,
826 .bypass_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
827 .bypass_shift = 6,
828 .flags = ENABLED,
829 .ops = &emi_ops,
832 static struct clk ir_clk = {
833 .parent = &io_clk,
834 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_IR,
835 .enable_shift = 31,
836 .enable_negate = 1,
837 .bypass_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
838 .bypass_shift = 3,
839 .ops = &min_ops,
842 static struct clk saif_clk = {
843 .parent = &pll_clk,
844 .scale_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_SAIF,
845 .busy_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_SAIF,
846 .busy_bit = 29,
847 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_SAIF,
848 .enable_shift = 31,
849 .enable_negate = 1,
850 .bypass_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_CLKSEQ,
851 .bypass_shift = 0,
852 .ops = &std_ops,
855 static struct clk usb_clk = {
856 .parent = &pll_clk,
857 .enable_reg = REGS_CLKCTRL_BASE + HW_CLKCTRL_PLLCTRL0,
858 .enable_shift = 18,
859 .enable_negate = 1,
860 .ops = &min_ops,
863 /* list of all the clocks */
864 static struct clk_lookup onchip_clks[] = {
866 .con_id = "osc_24M",
867 .clk = &osc_24M,
868 }, {
869 .con_id = "pll",
870 .clk = &pll_clk,
871 }, {
872 .con_id = "cpu",
873 .clk = &cpu_clk,
874 }, {
875 .con_id = "hclk",
876 .clk = &hclk,
877 }, {
878 .con_id = "xclk",
879 .clk = &xclk,
880 }, {
881 .con_id = "io",
882 .clk = &io_clk,
883 }, {
884 .con_id = "uart",
885 .clk = &uart_clk,
886 }, {
887 .con_id = "audio",
888 .clk = &audio_clk,
889 }, {
890 .con_id = "pwm",
891 .clk = &pwm_clk,
892 }, {
893 .con_id = "dri",
894 .clk = &dri_clk,
895 }, {
896 .con_id = "digctl",
897 .clk = &digctl_clk,
898 }, {
899 .con_id = "timer",
900 .clk = &timer_clk,
901 }, {
902 .con_id = "lcdif",
903 .clk = &lcdif_clk,
904 }, {
905 .con_id = "ssp",
906 .clk = &ssp_clk,
907 }, {
908 .con_id = "gpmi",
909 .clk = &gpmi_clk,
910 }, {
911 .con_id = "spdif",
912 .clk = &spdif_clk,
913 }, {
914 .con_id = "emi",
915 .clk = &emi_clk,
916 }, {
917 .con_id = "ir",
918 .clk = &ir_clk,
919 }, {
920 .con_id = "saif",
921 .clk = &saif_clk,
922 }, {
923 .con_id = "usb",
924 .clk = &usb_clk,
928 static int __init propagate_rate(struct clk *clk)
930 struct clk_lookup *cl;
932 for (cl = onchip_clks; cl < onchip_clks + ARRAY_SIZE(onchip_clks);
933 cl++) {
934 if (unlikely(!clk_good(cl->clk)))
935 continue;
936 if (cl->clk->parent == clk && cl->clk->ops->get_rate) {
937 cl->clk->ops->get_rate(cl->clk);
938 if (cl->clk->flags & RATE_PROPAGATES)
939 propagate_rate(cl->clk);
943 return 0;
946 /* Exported API */
947 unsigned long clk_get_rate(struct clk *clk)
949 if (unlikely(!clk_good(clk)))
950 return 0;
952 if (clk->rate != 0)
953 return clk->rate;
955 if (clk->ops->get_rate != NULL)
956 return clk->ops->get_rate(clk);
958 return clk_get_rate(clk->parent);
960 EXPORT_SYMBOL(clk_get_rate);
962 long clk_round_rate(struct clk *clk, unsigned long rate)
964 if (unlikely(!clk_good(clk)))
965 return 0;
967 if (clk->ops->round_rate)
968 return clk->ops->round_rate(clk, rate);
970 return 0;
972 EXPORT_SYMBOL(clk_round_rate);
974 static inline int close_enough(long rate1, long rate2)
976 return rate1 && !((rate2 - rate1) * 1000 / rate1);
979 int clk_set_rate(struct clk *clk, unsigned long rate)
981 int ret = -EINVAL;
983 if (unlikely(!clk_good(clk)))
984 goto out;
986 if (clk->flags & FIXED_RATE || !clk->ops->set_rate)
987 goto out;
989 else if (!close_enough(clk->rate, rate)) {
990 ret = clk->ops->set_rate(clk, rate);
991 if (ret < 0)
992 goto out;
993 clk->rate = rate;
994 if (clk->flags & RATE_PROPAGATES)
995 propagate_rate(clk);
996 } else
997 ret = 0;
999 out:
1000 return ret;
1002 EXPORT_SYMBOL(clk_set_rate);
1004 int clk_enable(struct clk *clk)
1006 unsigned long clocks_flags;
1008 if (unlikely(!clk_good(clk)))
1009 return -EINVAL;
1011 if (clk->parent)
1012 clk_enable(clk->parent);
1014 spin_lock_irqsave(&clocks_lock, clocks_flags);
1016 clk->usage++;
1017 if (clk->ops && clk->ops->enable)
1018 clk->ops->enable(clk);
1020 spin_unlock_irqrestore(&clocks_lock, clocks_flags);
1021 return 0;
1023 EXPORT_SYMBOL(clk_enable);
1025 static void local_clk_disable(struct clk *clk)
1027 if (unlikely(!clk_good(clk)))
1028 return;
1030 if (clk->usage == 0 && clk->ops->disable)
1031 clk->ops->disable(clk);
1033 if (clk->parent)
1034 local_clk_disable(clk->parent);
1037 void clk_disable(struct clk *clk)
1039 unsigned long clocks_flags;
1041 if (unlikely(!clk_good(clk)))
1042 return;
1044 spin_lock_irqsave(&clocks_lock, clocks_flags);
1046 if ((--clk->usage) == 0 && clk->ops->disable)
1047 clk->ops->disable(clk);
1049 spin_unlock_irqrestore(&clocks_lock, clocks_flags);
1050 if (clk->parent)
1051 clk_disable(clk->parent);
1053 EXPORT_SYMBOL(clk_disable);
1055 /* Some additional API */
1056 int clk_set_parent(struct clk *clk, struct clk *parent)
1058 int ret = -ENODEV;
1059 unsigned long clocks_flags;
1061 if (unlikely(!clk_good(clk)))
1062 goto out;
1064 if (!clk->ops->set_parent)
1065 goto out;
1067 spin_lock_irqsave(&clocks_lock, clocks_flags);
1069 ret = clk->ops->set_parent(clk, parent);
1070 if (!ret) {
1071 /* disable if usage count is 0 */
1072 local_clk_disable(parent);
1074 parent->usage += clk->usage;
1075 clk->parent->usage -= clk->usage;
1077 /* disable if new usage count is 0 */
1078 local_clk_disable(clk->parent);
1080 clk->parent = parent;
1082 spin_unlock_irqrestore(&clocks_lock, clocks_flags);
1084 out:
1085 return ret;
1087 EXPORT_SYMBOL(clk_set_parent);
1089 struct clk *clk_get_parent(struct clk *clk)
1091 if (unlikely(!clk_good(clk)))
1092 return NULL;
1093 return clk->parent;
1095 EXPORT_SYMBOL(clk_get_parent);
1097 static int __init clk_init(void)
1099 struct clk_lookup *cl;
1100 struct clk_ops *ops;
1102 spin_lock_init(&clocks_lock);
1104 for (cl = onchip_clks; cl < onchip_clks + ARRAY_SIZE(onchip_clks);
1105 cl++) {
1106 if (cl->clk->flags & ENABLED)
1107 clk_enable(cl->clk);
1108 else
1109 local_clk_disable(cl->clk);
1111 ops = cl->clk->ops;
1113 if ((cl->clk->flags & NEEDS_INITIALIZATION) &&
1114 ops && ops->set_rate)
1115 ops->set_rate(cl->clk, cl->clk->rate);
1117 if (cl->clk->flags & FIXED_RATE) {
1118 if (cl->clk->flags & RATE_PROPAGATES)
1119 propagate_rate(cl->clk);
1120 } else {
1121 if (ops && ops->get_rate)
1122 ops->get_rate(cl->clk);
1125 if (cl->clk->flags & NEEDS_SET_PARENT) {
1126 if (ops && ops->set_parent)
1127 ops->set_parent(cl->clk, cl->clk->parent);
1130 clkdev_add_table(onchip_clks, ARRAY_SIZE(onchip_clks));
1131 return 0;
1134 arch_initcall(clk_init);