GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / arch / arm / mach-pnx4008 / clock.c
blob7eab2461449dee6a376c7d81858117fd9481f969
1 /*
2 * arch/arm/mach-pnx4008/clock.c
4 * Clock control driver for PNX4008
6 * Authors: Vitaly Wool, Dmitry Chigirev <source@mvista.com>
7 * Generic clock management functions are partially based on:
8 * linux/arch/arm/mach-omap/clock.c
10 * 2005-2006 (c) MontaVista Software, Inc. This file is licensed under
11 * the terms of the GNU General Public License version 2. This program
12 * is licensed "as is" without any warranty of any kind, whether express
13 * or implied.
16 #include <linux/module.h>
17 #include <linux/kernel.h>
18 #include <linux/list.h>
19 #include <linux/errno.h>
20 #include <linux/device.h>
21 #include <linux/err.h>
22 #include <linux/delay.h>
23 #include <linux/io.h>
25 #include <asm/clkdev.h>
27 #include <mach/hardware.h>
28 #include <mach/clock.h>
29 #include "clock.h"
31 /*forward declaration*/
32 static struct clk per_ck;
33 static struct clk hclk_ck;
34 static struct clk ck_1MHz;
35 static struct clk ck_13MHz;
36 static struct clk ck_pll1;
37 static int local_set_rate(struct clk *clk, u32 rate);
39 static inline void clock_lock(void)
41 local_irq_disable();
44 static inline void clock_unlock(void)
46 local_irq_enable();
49 static void propagate_rate(struct clk *clk)
51 struct clk *tmp_clk;
53 tmp_clk = clk;
54 while (tmp_clk->propagate_next) {
55 tmp_clk = tmp_clk->propagate_next;
56 local_set_rate(tmp_clk, tmp_clk->user_rate);
60 static void clk_reg_disable(struct clk *clk)
62 if (clk->enable_reg)
63 __raw_writel(__raw_readl(clk->enable_reg) &
64 ~(1 << clk->enable_shift), clk->enable_reg);
67 static int clk_reg_enable(struct clk *clk)
69 if (clk->enable_reg)
70 __raw_writel(__raw_readl(clk->enable_reg) |
71 (1 << clk->enable_shift), clk->enable_reg);
72 return 0;
75 static inline void clk_reg_disable1(struct clk *clk)
77 if (clk->enable_reg1)
78 __raw_writel(__raw_readl(clk->enable_reg1) &
79 ~(1 << clk->enable_shift1), clk->enable_reg1);
82 static inline void clk_reg_enable1(struct clk *clk)
84 if (clk->enable_reg1)
85 __raw_writel(__raw_readl(clk->enable_reg1) |
86 (1 << clk->enable_shift1), clk->enable_reg1);
89 static int clk_wait_for_pll_lock(struct clk *clk)
91 int i;
92 i = 0;
93 while (i++ < 0xFFF && !(__raw_readl(clk->scale_reg) & 1)) ; /*wait for PLL to lock */
95 if (!(__raw_readl(clk->scale_reg) & 1)) {
96 printk(KERN_ERR
97 "%s ERROR: failed to lock, scale reg data: %x\n",
98 clk->name, __raw_readl(clk->scale_reg));
99 return -1;
101 return 0;
104 static int switch_to_dirty_13mhz(struct clk *clk)
106 int i;
107 int ret;
108 u32 tmp_reg;
110 ret = 0;
112 if (!clk->rate)
113 clk_reg_enable1(clk);
115 tmp_reg = __raw_readl(clk->parent_switch_reg);
116 /*if 13Mhz clock selected, select 13'MHz (dirty) source from OSC */
117 if (!(tmp_reg & 1)) {
118 tmp_reg |= (1 << 1); /* Trigger switch to 13'MHz (dirty) clock */
119 __raw_writel(tmp_reg, clk->parent_switch_reg);
120 i = 0;
121 while (i++ < 0xFFF && !(__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13'MHz selection status */
123 if (!(__raw_readl(clk->parent_switch_reg) & 1)) {
124 printk(KERN_ERR
125 "%s ERROR: failed to select 13'MHz, parent sw reg data: %x\n",
126 clk->name, __raw_readl(clk->parent_switch_reg));
127 ret = -1;
131 if (!clk->rate)
132 clk_reg_disable1(clk);
134 return ret;
137 static int switch_to_clean_13mhz(struct clk *clk)
139 int i;
140 int ret;
141 u32 tmp_reg;
143 ret = 0;
145 if (!clk->rate)
146 clk_reg_enable1(clk);
148 tmp_reg = __raw_readl(clk->parent_switch_reg);
149 /*if 13'Mhz clock selected, select 13MHz (clean) source from OSC */
150 if (tmp_reg & 1) {
151 tmp_reg &= ~(1 << 1); /* Trigger switch to 13MHz (clean) clock */
152 __raw_writel(tmp_reg, clk->parent_switch_reg);
153 i = 0;
154 while (i++ < 0xFFF && (__raw_readl(clk->parent_switch_reg) & 1)) ; /*wait for 13MHz selection status */
156 if (__raw_readl(clk->parent_switch_reg) & 1) {
157 printk(KERN_ERR
158 "%s ERROR: failed to select 13MHz, parent sw reg data: %x\n",
159 clk->name, __raw_readl(clk->parent_switch_reg));
160 ret = -1;
164 if (!clk->rate)
165 clk_reg_disable1(clk);
167 return ret;
170 static int set_13MHz_parent(struct clk *clk, struct clk *parent)
172 int ret = -EINVAL;
174 if (parent == &ck_13MHz)
175 ret = switch_to_clean_13mhz(clk);
176 else if (parent == &ck_pll1)
177 ret = switch_to_dirty_13mhz(clk);
179 return ret;
182 #define PLL160_MIN_FCCO 156000
183 #define PLL160_MAX_FCCO 320000
186 * Calculate pll160 settings.
187 * Possible input: up to 320MHz with step of clk->parent->rate.
188 * In PNX4008 parent rate for pll160s may be either 1 or 13MHz.
189 * Ignored paths: "feedback" (bit 13 set), "div-by-N".
190 * Setting ARM PLL4 rate to 0 will put CPU into direct run mode.
191 * Setting PLL5 and PLL3 rate to 0 will disable USB and DSP clock input.
192 * Please refer to PNX4008 IC manual for details.
195 static int pll160_set_rate(struct clk *clk, u32 rate)
197 u32 tmp_reg, tmp_m, tmp_2p, i;
198 u32 parent_rate;
199 int ret = -EINVAL;
201 parent_rate = clk->parent->rate;
203 if (!parent_rate)
204 goto out;
206 /* set direct run for ARM or disable output for others */
207 clk_reg_disable(clk);
209 /* disable source input as well (ignored for ARM) */
210 clk_reg_disable1(clk);
212 tmp_reg = __raw_readl(clk->scale_reg);
213 tmp_reg &= ~0x1ffff; /*clear all settings, power down */
214 __raw_writel(tmp_reg, clk->scale_reg);
216 rate -= rate % parent_rate; /*round down the input */
218 if (rate > PLL160_MAX_FCCO)
219 rate = PLL160_MAX_FCCO;
221 if (!rate) {
222 clk->rate = 0;
223 ret = 0;
224 goto out;
227 clk_reg_enable1(clk);
228 tmp_reg = __raw_readl(clk->scale_reg);
230 if (rate == parent_rate) {
231 /*enter direct bypass mode */
232 tmp_reg |= ((1 << 14) | (1 << 15));
233 __raw_writel(tmp_reg, clk->scale_reg);
234 clk->rate = parent_rate;
235 clk_reg_enable(clk);
236 ret = 0;
237 goto out;
240 i = 0;
241 for (tmp_2p = 1; tmp_2p < 16; tmp_2p <<= 1) {
242 if (rate * tmp_2p >= PLL160_MIN_FCCO)
243 break;
244 i++;
247 if (tmp_2p > 1)
248 tmp_reg |= ((i - 1) << 11);
249 else
250 tmp_reg |= (1 << 14); /*direct mode, no divide */
252 tmp_m = rate * tmp_2p;
253 tmp_m /= parent_rate;
255 tmp_reg |= (tmp_m - 1) << 1; /*calculate M */
256 tmp_reg |= (1 << 16); /*power up PLL */
257 __raw_writel(tmp_reg, clk->scale_reg);
259 if (clk_wait_for_pll_lock(clk) < 0) {
260 clk_reg_disable(clk);
261 clk_reg_disable1(clk);
263 tmp_reg = __raw_readl(clk->scale_reg);
264 tmp_reg &= ~0x1ffff; /*clear all settings, power down */
265 __raw_writel(tmp_reg, clk->scale_reg);
266 clk->rate = 0;
267 ret = -EFAULT;
268 goto out;
271 clk->rate = (tmp_m * parent_rate) / tmp_2p;
273 if (clk->flags & RATE_PROPAGATES)
274 propagate_rate(clk);
276 clk_reg_enable(clk);
277 ret = 0;
279 out:
280 return ret;
283 /*configure PER_CLK*/
284 static int per_clk_set_rate(struct clk *clk, u32 rate)
286 u32 tmp;
288 tmp = __raw_readl(clk->scale_reg);
289 tmp &= ~(0x1f << 2);
290 tmp |= ((clk->parent->rate / clk->rate) - 1) << 2;
291 __raw_writel(tmp, clk->scale_reg);
292 clk->rate = rate;
293 return 0;
296 /*configure HCLK*/
297 static int hclk_set_rate(struct clk *clk, u32 rate)
299 u32 tmp;
300 tmp = __raw_readl(clk->scale_reg);
301 tmp = tmp & ~0x3;
302 switch (rate) {
303 case 1:
304 break;
305 case 2:
306 tmp |= 1;
307 break;
308 case 4:
309 tmp |= 2;
310 break;
313 __raw_writel(tmp, clk->scale_reg);
314 clk->rate = rate;
315 return 0;
318 static u32 hclk_round_rate(struct clk *clk, u32 rate)
320 switch (rate) {
321 case 1:
322 case 4:
323 return rate;
325 return 2;
328 static u32 per_clk_round_rate(struct clk *clk, u32 rate)
330 return CLK_RATE_13MHZ;
333 static int on_off_set_rate(struct clk *clk, u32 rate)
335 if (rate) {
336 clk_reg_enable(clk);
337 clk->rate = 1;
338 } else {
339 clk_reg_disable(clk);
340 clk->rate = 0;
342 return 0;
345 static int on_off_inv_set_rate(struct clk *clk, u32 rate)
347 if (rate) {
348 clk_reg_disable(clk); /*enable bit is inverted */
349 clk->rate = 1;
350 } else {
351 clk_reg_enable(clk);
352 clk->rate = 0;
354 return 0;
357 static u32 on_off_round_rate(struct clk *clk, u32 rate)
359 return (rate ? 1 : 0);
362 static u32 pll4_round_rate(struct clk *clk, u32 rate)
364 if (rate > CLK_RATE_208MHZ)
365 rate = CLK_RATE_208MHZ;
366 if (rate == CLK_RATE_208MHZ && hclk_ck.user_rate == 1)
367 rate = CLK_RATE_208MHZ - CLK_RATE_13MHZ;
368 return (rate - (rate % (hclk_ck.user_rate * CLK_RATE_13MHZ)));
371 static u32 pll3_round_rate(struct clk *clk, u32 rate)
373 if (rate > CLK_RATE_208MHZ)
374 rate = CLK_RATE_208MHZ;
375 return (rate - rate % CLK_RATE_13MHZ);
378 static u32 pll5_round_rate(struct clk *clk, u32 rate)
380 return (rate ? CLK_RATE_48MHZ : 0);
383 static u32 ck_13MHz_round_rate(struct clk *clk, u32 rate)
385 return (rate ? CLK_RATE_13MHZ : 0);
388 static int ck_13MHz_set_rate(struct clk *clk, u32 rate)
390 if (rate) {
391 clk_reg_disable(clk); /*enable bit is inverted */
392 udelay(500);
393 clk->rate = CLK_RATE_13MHZ;
394 ck_1MHz.rate = CLK_RATE_1MHZ;
395 } else {
396 clk_reg_enable(clk);
397 clk->rate = 0;
398 ck_1MHz.rate = 0;
400 return 0;
403 static int pll1_set_rate(struct clk *clk, u32 rate)
405 return 0;
408 /* Clock sources */
410 static struct clk osc_13MHz = {
411 .name = "osc_13MHz",
412 .flags = FIXED_RATE,
413 .rate = CLK_RATE_13MHZ,
416 static struct clk ck_13MHz = {
417 .name = "ck_13MHz",
418 .parent = &osc_13MHz,
419 .flags = NEEDS_INITIALIZATION,
420 .round_rate = &ck_13MHz_round_rate,
421 .set_rate = &ck_13MHz_set_rate,
422 .enable_reg = OSC13CTRL_REG,
423 .enable_shift = 0,
424 .rate = CLK_RATE_13MHZ,
427 static struct clk osc_32KHz = {
428 .name = "osc_32KHz",
429 .flags = FIXED_RATE,
430 .rate = CLK_RATE_32KHZ,
433 /*attached to PLL5*/
434 static struct clk ck_1MHz = {
435 .name = "ck_1MHz",
436 .flags = FIXED_RATE | PARENT_SET_RATE,
437 .parent = &ck_13MHz,
440 /* PLL1 (397) - provides 13' MHz clock */
441 static struct clk ck_pll1 = {
442 .name = "ck_pll1",
443 .parent = &osc_32KHz,
444 .flags = NEEDS_INITIALIZATION,
445 .round_rate = &ck_13MHz_round_rate,
446 .set_rate = &pll1_set_rate,
447 .enable_reg = PLLCTRL_REG,
448 .enable_shift = 1,
449 .scale_reg = PLLCTRL_REG,
450 .rate = CLK_RATE_13MHZ,
453 /* CPU/Bus PLL */
454 static struct clk ck_pll4 = {
455 .name = "ck_pll4",
456 .parent = &ck_pll1,
457 .flags = RATE_PROPAGATES | NEEDS_INITIALIZATION,
458 .propagate_next = &per_ck,
459 .round_rate = &pll4_round_rate,
460 .set_rate = &pll160_set_rate,
461 .rate = CLK_RATE_208MHZ,
462 .scale_reg = HCLKPLLCTRL_REG,
463 .enable_reg = PWRCTRL_REG,
464 .enable_shift = 2,
465 .parent_switch_reg = SYSCLKCTRL_REG,
466 .set_parent = &set_13MHz_parent,
469 /* USB PLL */
470 static struct clk ck_pll5 = {
471 .name = "ck_pll5",
472 .parent = &ck_1MHz,
473 .flags = NEEDS_INITIALIZATION,
474 .round_rate = &pll5_round_rate,
475 .set_rate = &pll160_set_rate,
476 .scale_reg = USBCTRL_REG,
477 .enable_reg = USBCTRL_REG,
478 .enable_shift = 18,
479 .enable_reg1 = USBCTRL_REG,
480 .enable_shift1 = 17,
483 /* XPERTTeak DSP PLL */
484 static struct clk ck_pll3 = {
485 .name = "ck_pll3",
486 .parent = &ck_pll1,
487 .flags = NEEDS_INITIALIZATION,
488 .round_rate = &pll3_round_rate,
489 .set_rate = &pll160_set_rate,
490 .scale_reg = DSPPLLCTRL_REG,
491 .enable_reg = DSPCLKCTRL_REG,
492 .enable_shift = 3,
493 .enable_reg1 = DSPCLKCTRL_REG,
494 .enable_shift1 = 2,
495 .parent_switch_reg = DSPCLKCTRL_REG,
496 .set_parent = &set_13MHz_parent,
499 static struct clk hclk_ck = {
500 .name = "hclk_ck",
501 .parent = &ck_pll4,
502 .flags = PARENT_SET_RATE,
503 .set_rate = &hclk_set_rate,
504 .round_rate = &hclk_round_rate,
505 .scale_reg = HCLKDIVCTRL_REG,
506 .rate = 2,
507 .user_rate = 2,
510 static struct clk per_ck = {
511 .name = "per_ck",
512 .parent = &ck_pll4,
513 .flags = FIXED_RATE,
514 .propagate_next = &hclk_ck,
515 .set_rate = &per_clk_set_rate,
516 .round_rate = &per_clk_round_rate,
517 .scale_reg = HCLKDIVCTRL_REG,
518 .rate = CLK_RATE_13MHZ,
519 .user_rate = CLK_RATE_13MHZ,
522 static struct clk m2hclk_ck = {
523 .name = "m2hclk_ck",
524 .parent = &hclk_ck,
525 .flags = NEEDS_INITIALIZATION,
526 .round_rate = &on_off_round_rate,
527 .set_rate = &on_off_inv_set_rate,
528 .rate = 1,
529 .enable_shift = 6,
530 .enable_reg = PWRCTRL_REG,
533 static struct clk vfp9_ck = {
534 .name = "vfp9_ck",
535 .parent = &ck_pll4,
536 .flags = NEEDS_INITIALIZATION,
537 .round_rate = &on_off_round_rate,
538 .set_rate = &on_off_set_rate,
539 .rate = 1,
540 .enable_shift = 4,
541 .enable_reg = VFP9CLKCTRL_REG,
544 static struct clk keyscan_ck = {
545 .name = "keyscan_ck",
546 .parent = &osc_32KHz,
547 .flags = NEEDS_INITIALIZATION,
548 .round_rate = &on_off_round_rate,
549 .set_rate = &on_off_set_rate,
550 .enable_shift = 0,
551 .enable_reg = KEYCLKCTRL_REG,
554 static struct clk touch_ck = {
555 .name = "touch_ck",
556 .parent = &osc_32KHz,
557 .flags = NEEDS_INITIALIZATION,
558 .round_rate = &on_off_round_rate,
559 .set_rate = &on_off_set_rate,
560 .enable_shift = 0,
561 .enable_reg = TSCLKCTRL_REG,
564 static struct clk pwm1_ck = {
565 .name = "pwm1_ck",
566 .parent = &osc_32KHz,
567 .flags = NEEDS_INITIALIZATION,
568 .round_rate = &on_off_round_rate,
569 .set_rate = &on_off_set_rate,
570 .enable_shift = 0,
571 .enable_reg = PWMCLKCTRL_REG,
574 static struct clk pwm2_ck = {
575 .name = "pwm2_ck",
576 .parent = &osc_32KHz,
577 .flags = NEEDS_INITIALIZATION,
578 .round_rate = &on_off_round_rate,
579 .set_rate = &on_off_set_rate,
580 .enable_shift = 2,
581 .enable_reg = PWMCLKCTRL_REG,
584 static struct clk jpeg_ck = {
585 .name = "jpeg_ck",
586 .parent = &hclk_ck,
587 .flags = NEEDS_INITIALIZATION,
588 .round_rate = &on_off_round_rate,
589 .set_rate = &on_off_set_rate,
590 .enable_shift = 0,
591 .enable_reg = JPEGCLKCTRL_REG,
594 static struct clk ms_ck = {
595 .name = "ms_ck",
596 .parent = &ck_pll4,
597 .flags = NEEDS_INITIALIZATION,
598 .round_rate = &on_off_round_rate,
599 .set_rate = &on_off_set_rate,
600 .enable_shift = 5,
601 .enable_reg = MSCTRL_REG,
604 static struct clk dum_ck = {
605 .name = "dum_ck",
606 .parent = &hclk_ck,
607 .flags = NEEDS_INITIALIZATION,
608 .round_rate = &on_off_round_rate,
609 .set_rate = &on_off_set_rate,
610 .enable_shift = 0,
611 .enable_reg = DUMCLKCTRL_REG,
614 static struct clk flash_ck = {
615 .name = "flash_ck",
616 .parent = &hclk_ck,
617 .round_rate = &on_off_round_rate,
618 .set_rate = &on_off_set_rate,
619 .enable_shift = 1, /* Only MLC clock supported */
620 .enable_reg = FLASHCLKCTRL_REG,
623 static struct clk i2c0_ck = {
624 .name = "i2c0_ck",
625 .parent = &per_ck,
626 .flags = NEEDS_INITIALIZATION | FIXED_RATE,
627 .enable_shift = 0,
628 .enable_reg = I2CCLKCTRL_REG,
629 .rate = 13000000,
630 .enable = clk_reg_enable,
631 .disable = clk_reg_disable,
634 static struct clk i2c1_ck = {
635 .name = "i2c1_ck",
636 .parent = &per_ck,
637 .flags = NEEDS_INITIALIZATION | FIXED_RATE,
638 .enable_shift = 1,
639 .enable_reg = I2CCLKCTRL_REG,
640 .rate = 13000000,
641 .enable = clk_reg_enable,
642 .disable = clk_reg_disable,
645 static struct clk i2c2_ck = {
646 .name = "i2c2_ck",
647 .parent = &per_ck,
648 .flags = NEEDS_INITIALIZATION | FIXED_RATE,
649 .enable_shift = 2,
650 .enable_reg = USB_OTG_CLKCTRL_REG,
651 .rate = 13000000,
652 .enable = clk_reg_enable,
653 .disable = clk_reg_disable,
656 static struct clk spi0_ck = {
657 .name = "spi0_ck",
658 .parent = &hclk_ck,
659 .flags = NEEDS_INITIALIZATION,
660 .round_rate = &on_off_round_rate,
661 .set_rate = &on_off_set_rate,
662 .enable_shift = 0,
663 .enable_reg = SPICTRL_REG,
666 static struct clk spi1_ck = {
667 .name = "spi1_ck",
668 .parent = &hclk_ck,
669 .flags = NEEDS_INITIALIZATION,
670 .round_rate = &on_off_round_rate,
671 .set_rate = &on_off_set_rate,
672 .enable_shift = 4,
673 .enable_reg = SPICTRL_REG,
676 static struct clk dma_ck = {
677 .name = "dma_ck",
678 .parent = &hclk_ck,
679 .round_rate = &on_off_round_rate,
680 .set_rate = &on_off_set_rate,
681 .enable_shift = 0,
682 .enable_reg = DMACLKCTRL_REG,
685 static struct clk uart3_ck = {
686 .name = "uart3_ck",
687 .parent = &per_ck,
688 .flags = NEEDS_INITIALIZATION,
689 .round_rate = &on_off_round_rate,
690 .set_rate = &on_off_set_rate,
691 .rate = 1,
692 .enable_shift = 0,
693 .enable_reg = UARTCLKCTRL_REG,
696 static struct clk uart4_ck = {
697 .name = "uart4_ck",
698 .parent = &per_ck,
699 .flags = NEEDS_INITIALIZATION,
700 .round_rate = &on_off_round_rate,
701 .set_rate = &on_off_set_rate,
702 .enable_shift = 1,
703 .enable_reg = UARTCLKCTRL_REG,
706 static struct clk uart5_ck = {
707 .name = "uart5_ck",
708 .parent = &per_ck,
709 .flags = NEEDS_INITIALIZATION,
710 .round_rate = &on_off_round_rate,
711 .set_rate = &on_off_set_rate,
712 .rate = 1,
713 .enable_shift = 2,
714 .enable_reg = UARTCLKCTRL_REG,
717 static struct clk uart6_ck = {
718 .name = "uart6_ck",
719 .parent = &per_ck,
720 .flags = NEEDS_INITIALIZATION,
721 .round_rate = &on_off_round_rate,
722 .set_rate = &on_off_set_rate,
723 .enable_shift = 3,
724 .enable_reg = UARTCLKCTRL_REG,
727 static struct clk wdt_ck = {
728 .name = "wdt_ck",
729 .parent = &per_ck,
730 .flags = NEEDS_INITIALIZATION,
731 .enable_shift = 0,
732 .enable_reg = TIMCLKCTRL_REG,
733 .enable = clk_reg_enable,
734 .disable = clk_reg_disable,
737 /* These clocks are visible outside this module
738 * and can be initialized
740 static struct clk *onchip_clks[] __initdata = {
741 &ck_13MHz,
742 &ck_pll1,
743 &ck_pll4,
744 &ck_pll5,
745 &ck_pll3,
746 &vfp9_ck,
747 &m2hclk_ck,
748 &hclk_ck,
749 &dma_ck,
750 &flash_ck,
751 &dum_ck,
752 &keyscan_ck,
753 &pwm1_ck,
754 &pwm2_ck,
755 &jpeg_ck,
756 &ms_ck,
757 &touch_ck,
758 &i2c0_ck,
759 &i2c1_ck,
760 &i2c2_ck,
761 &spi0_ck,
762 &spi1_ck,
763 &uart3_ck,
764 &uart4_ck,
765 &uart5_ck,
766 &uart6_ck,
767 &wdt_ck,
770 static struct clk_lookup onchip_clkreg[] = {
771 { .clk = &ck_13MHz, .con_id = "ck_13MHz" },
772 { .clk = &ck_pll1, .con_id = "ck_pll1" },
773 { .clk = &ck_pll4, .con_id = "ck_pll4" },
774 { .clk = &ck_pll5, .con_id = "ck_pll5" },
775 { .clk = &ck_pll3, .con_id = "ck_pll3" },
776 { .clk = &vfp9_ck, .con_id = "vfp9_ck" },
777 { .clk = &m2hclk_ck, .con_id = "m2hclk_ck" },
778 { .clk = &hclk_ck, .con_id = "hclk_ck" },
779 { .clk = &dma_ck, .con_id = "dma_ck" },
780 { .clk = &flash_ck, .con_id = "flash_ck" },
781 { .clk = &dum_ck, .con_id = "dum_ck" },
782 { .clk = &keyscan_ck, .con_id = "keyscan_ck" },
783 { .clk = &pwm1_ck, .con_id = "pwm1_ck" },
784 { .clk = &pwm2_ck, .con_id = "pwm2_ck" },
785 { .clk = &jpeg_ck, .con_id = "jpeg_ck" },
786 { .clk = &ms_ck, .con_id = "ms_ck" },
787 { .clk = &touch_ck, .con_id = "touch_ck" },
788 { .clk = &i2c0_ck, .dev_id = "pnx-i2c.0" },
789 { .clk = &i2c1_ck, .dev_id = "pnx-i2c.1" },
790 { .clk = &i2c2_ck, .dev_id = "pnx-i2c.2" },
791 { .clk = &spi0_ck, .con_id = "spi0_ck" },
792 { .clk = &spi1_ck, .con_id = "spi1_ck" },
793 { .clk = &uart3_ck, .con_id = "uart3_ck" },
794 { .clk = &uart4_ck, .con_id = "uart4_ck" },
795 { .clk = &uart5_ck, .con_id = "uart5_ck" },
796 { .clk = &uart6_ck, .con_id = "uart6_ck" },
797 { .clk = &wdt_ck, .dev_id = "pnx4008-watchdog" },
800 static void local_clk_disable(struct clk *clk)
802 if (WARN_ON(clk->usecount == 0))
803 return;
805 if (!(--clk->usecount)) {
806 if (clk->disable)
807 clk->disable(clk);
808 else if (!(clk->flags & FIXED_RATE) && clk->rate && clk->set_rate)
809 clk->set_rate(clk, 0);
810 if (clk->parent)
811 local_clk_disable(clk->parent);
815 static int local_clk_enable(struct clk *clk)
817 int ret = 0;
819 if (clk->usecount == 0) {
820 if (clk->parent) {
821 ret = local_clk_enable(clk->parent);
822 if (ret != 0)
823 goto out;
826 if (clk->enable)
827 ret = clk->enable(clk);
828 else if (!(clk->flags & FIXED_RATE) && !clk->rate && clk->set_rate
829 && clk->user_rate)
830 ret = clk->set_rate(clk, clk->user_rate);
832 if (ret != 0 && clk->parent) {
833 local_clk_disable(clk->parent);
834 goto out;
837 clk->usecount++;
839 out:
840 return ret;
843 static int local_set_rate(struct clk *clk, u32 rate)
845 int ret = -EINVAL;
846 if (clk->set_rate) {
848 if (clk->user_rate == clk->rate && clk->parent->rate) {
849 /* if clock enabled or rate not set */
850 clk->user_rate = clk->round_rate(clk, rate);
851 ret = clk->set_rate(clk, clk->user_rate);
852 } else
853 clk->user_rate = clk->round_rate(clk, rate);
854 ret = 0;
856 return ret;
859 int clk_set_rate(struct clk *clk, unsigned long rate)
861 int ret = -EINVAL;
863 if (clk->flags & FIXED_RATE)
864 goto out;
866 clock_lock();
867 if ((clk->flags & PARENT_SET_RATE) && clk->parent) {
869 clk->user_rate = clk->round_rate(clk, rate);
870 /* parent clock needs to be refreshed
871 for the setting to take effect */
872 } else {
873 ret = local_set_rate(clk, rate);
875 ret = 0;
876 clock_unlock();
878 out:
879 return ret;
882 EXPORT_SYMBOL(clk_set_rate);
884 unsigned long clk_get_rate(struct clk *clk)
886 unsigned long ret;
887 clock_lock();
888 ret = clk->rate;
889 clock_unlock();
890 return ret;
892 EXPORT_SYMBOL(clk_get_rate);
894 int clk_enable(struct clk *clk)
896 int ret;
898 clock_lock();
899 ret = local_clk_enable(clk);
900 clock_unlock();
901 return ret;
904 EXPORT_SYMBOL(clk_enable);
906 void clk_disable(struct clk *clk)
908 clock_lock();
909 local_clk_disable(clk);
910 clock_unlock();
913 EXPORT_SYMBOL(clk_disable);
915 long clk_round_rate(struct clk *clk, unsigned long rate)
917 long ret;
918 clock_lock();
919 if (clk->round_rate)
920 ret = clk->round_rate(clk, rate);
921 else
922 ret = clk->rate;
923 clock_unlock();
924 return ret;
927 EXPORT_SYMBOL(clk_round_rate);
929 int clk_set_parent(struct clk *clk, struct clk *parent)
931 int ret = -ENODEV;
932 if (!clk->set_parent)
933 goto out;
935 clock_lock();
936 ret = clk->set_parent(clk, parent);
937 if (!ret)
938 clk->parent = parent;
939 clock_unlock();
941 out:
942 return ret;
945 EXPORT_SYMBOL(clk_set_parent);
947 static int __init clk_init(void)
949 struct clk **clkp;
951 /* Disable autoclocking, as it doesn't seem to work */
952 __raw_writel(0xff, AUTOCLK_CTRL);
954 for (clkp = onchip_clks; clkp < onchip_clks + ARRAY_SIZE(onchip_clks);
955 clkp++) {
956 struct clk *clk = *clkp;
957 if (clk->flags & NEEDS_INITIALIZATION) {
958 if (clk->set_rate) {
959 clk->user_rate = clk->rate;
960 local_set_rate(clk, clk->user_rate);
961 if (clk->set_parent)
962 clk->set_parent(clk, clk->parent);
964 if (clk->enable && clk->usecount)
965 clk->enable(clk);
966 if (clk->disable && !clk->usecount)
967 clk->disable(clk);
969 pr_debug("%s: clock %s, rate %ld\n",
970 __func__, clk->name, clk->rate);
973 local_clk_enable(&ck_pll4);
975 /* if ck_13MHz is not used, disable it. */
976 if (ck_13MHz.usecount == 0)
977 local_clk_disable(&ck_13MHz);
979 /* Disable autoclocking */
980 __raw_writeb(0xff, AUTOCLK_CTRL);
982 clkdev_add_table(onchip_clkreg, ARRAY_SIZE(onchip_clkreg));
984 return 0;
987 arch_initcall(clk_init);