2 * Clock interface for OMAP
4 * Copyright (C) 2001 RidgeRun, Inc
5 * Written by Gordon McNutt <gmcnutt@ridgerun.com>
6 * Updated 2004 for Linux 2.6 by Tony Lindgren <tony@atomide.com>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
14 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
16 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
19 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
20 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 * You should have received a copy of the GNU General Public License along
25 * with this program; if not, write to the Free Software Foundation, Inc.,
26 * 675 Mass Ave, Cambridge, MA 02139, USA.
29 #include <linux/kernel.h>
30 #include <linux/module.h>
31 #include <linux/init.h>
32 #include <linux/types.h>
33 #include <linux/spinlock.h>
34 #include <asm/errno.h>
36 #include <asm/arch/clocks.h>
37 #include <asm/arch/board.h>
39 /* Input clock in MHz */
40 static unsigned int source_clock = 12;
43 * We use one spinlock for all clock registers for now. We may want to
44 * change this to be clock register specific later on. Before we can do
45 * that, we need to map out the shared clock registers.
47 static spinlock_t clock_lock = SPIN_LOCK_UNLOCKED;
53 unsigned long rate_reg; /* Clock rate register */
54 unsigned long enbl_reg; /* Enable register */
55 unsigned long idle_reg; /* Idle register */
56 unsigned long slct_reg; /* Select register */
57 __s8 rate_shift; /* Clock rate bit shift */
58 __s8 enbl_shift; /* Clock enable bit shift */
59 __s8 idle_shift; /* Clock idle bit shift */
60 __s8 slct_shift; /* Clock select bit shift */
63 #define CK_NAME(ck) ck_info_table[ck].name
64 #define CK_FLAGS(ck) ck_info_table[ck].flags
65 #define CK_PARENT(ck) ck_info_table[ck].parent
66 #define CK_RATE_REG(ck) ck_info_table[ck].rate_reg
67 #define CK_ENABLE_REG(ck) ck_info_table[ck].enbl_reg
68 #define CK_IDLE_REG(ck) ck_info_table[ck].idle_reg
69 #define CK_SELECT_REG(ck) ck_info_table[ck].slct_reg
70 #define CK_RATE_SHIFT(ck) ck_info_table[ck].rate_shift
71 #define CK_ENABLE_SHIFT(ck) ck_info_table[ck].enbl_shift
72 #define CK_IDLE_SHIFT(ck) ck_info_table[ck].idle_shift
73 #define CK_SELECT_SHIFT(ck) ck_info_table[ck].slct_shift
74 #define CK_CAN_CHANGE_RATE(cl) (CK_FLAGS(ck) & CK_RATEF)
75 #define CK_CAN_DISABLE(cl) (CK_FLAGS(ck) & CK_ENABLEF)
76 #define CK_CAN_IDLE(cl) (CK_FLAGS(ck) & CK_IDLEF)
77 #define CK_CAN_SWITCH(cl) (CK_FLAGS(ck) & CK_SELECTF)
79 static ck_info_t ck_info_table[] = {
86 .flags = CK_RATEF | CK_IDLEF,
88 .idle_reg = ARM_IDLECT1,
89 .idle_shift = IDLDPLL_ARM,
94 .parent = OMAP_CK_GEN1,
98 .parent = OMAP_CK_GEN1,
101 .flags = CK_RATEF | CK_IDLEF,
102 .parent = OMAP_CK_GEN3,
103 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[TCDIV(9:8)] */
104 .idle_reg = ARM_IDLECT1,
106 .idle_shift = IDLIF_ARM
109 .flags = CK_IDLEF | CK_RATEF,
110 .parent = OMAP_CK_GEN1,
111 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[ARMDIV(5:4)] */
112 .idle_reg = ARM_IDLECT1,
113 .rate_shift = ARMDIV,
114 .idle_shift = SETARM_IDLE,
117 .flags = CK_RATEF | CK_IDLEF | CK_ENABLEF,
118 .parent = OMAP_CK_GEN1,
119 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[PERDIV(1:0)] */
120 .enbl_reg = ARM_IDLECT2,
121 .idle_reg = ARM_IDLECT1,
122 .rate_shift = PERDIV,
123 .enbl_shift = EN_PERCK,
124 .idle_shift = IDLPER_ARM
126 .name = "arm_gpio_ck",
128 .parent = OMAP_CK_GEN1,
129 .enbl_reg = ARM_IDLECT2,
130 .enbl_shift = EN_GPIOCK
133 .flags = CK_ENABLEF | CK_IDLEF,
134 .parent = OMAP_CLKIN,
135 .idle_reg = ARM_IDLECT1,
136 .enbl_reg = ARM_IDLECT2,
137 .idle_shift = IDLXORP_ARM,
138 .enbl_shift = EN_XORPCK
141 .flags = CK_IDLEF | CK_ENABLEF | CK_SELECTF,
142 .parent = OMAP_CLKIN,
143 .idle_reg = ARM_IDLECT1,
144 .enbl_reg = ARM_IDLECT2,
145 .slct_reg = ARM_CKCTL,
146 .idle_shift = IDLTIM_ARM,
147 .enbl_shift = EN_TIMCK,
148 .slct_shift = ARM_TIMXO
151 .flags = CK_IDLEF | CK_ENABLEF,
152 .parent = OMAP_CLKIN,
153 .idle_reg = ARM_IDLECT1,
154 .enbl_reg = ARM_IDLECT2,
155 .idle_shift = IDLWDT_ARM,
156 .enbl_shift = EN_WDTCK,
159 .flags = CK_RATEF | CK_ENABLEF,
160 .parent = OMAP_CK_GEN2,
161 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[DSPDIV(7:6)] */
162 .enbl_reg = ARM_CKCTL,
163 .rate_shift = DSPDIV,
164 .enbl_shift = EN_DSPCK,
167 .flags = CK_RATEF | CK_ENABLEF,
168 .parent = OMAP_CK_GEN2,
169 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[DSPMMUDIV(11:10)] */
170 .enbl_reg = ARM_CKCTL,
171 .rate_shift = DSPMMUDIV,
172 .enbl_shift = EN_DSPCK,
175 .flags = CK_RATEF | CK_IDLEF | CK_ENABLEF,
176 .parent = OMAP_CK_GEN3,
177 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[TCDIV(9:8)] */
178 .idle_reg = ARM_IDLECT1,
179 .enbl_reg = ARM_IDLECT2,
181 .idle_shift = IDLIF_ARM,
182 .enbl_shift = DMACK_REQ
185 .flags = CK_RATEF | CK_IDLEF | CK_ENABLEF,
186 .parent = OMAP_CK_GEN3,
187 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[TCDIV(9:8)] */
188 .idle_reg = ARM_IDLECT1,
189 .enbl_reg = ARM_IDLECT2,
191 .idle_shift = IDLAPI_ARM,
192 .enbl_shift = EN_APICK,
195 .flags = CK_RATEF | CK_IDLEF | CK_ENABLEF,
196 .parent = OMAP_CK_GEN3,
197 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[TCDIV(9:8)] */
198 .idle_reg = ARM_IDLECT1,
199 .enbl_reg = ARM_IDLECT2,
201 .idle_shift = IDLHSAB_ARM,
202 .enbl_shift = EN_HSABCK,
205 .flags = CK_RATEF | CK_ENABLEF,
206 .parent = OMAP_CK_GEN3,
207 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[TCDIV(9:8)] */
208 .enbl_reg = ARM_IDLECT2,
210 .enbl_shift = EN_LBFREECK,
213 .flags = CK_RATEF | CK_IDLEF | CK_ENABLEF,
214 .parent = OMAP_CK_GEN3,
215 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[TCDIV(9:8)] */
216 .idle_reg = ARM_IDLECT1,
217 .enbl_reg = ARM_IDLECT2,
219 .idle_shift = IDLLB_ARM,
220 .enbl_shift = EN_LBCK,
223 .flags = CK_RATEF | CK_IDLEF | CK_ENABLEF,
224 .parent = OMAP_CK_GEN3,
225 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[LCDDIV(3:2)] */
226 .idle_reg = ARM_IDLECT1,
227 .enbl_reg = ARM_IDLECT2,
228 .rate_shift = LCDDIV,
229 .idle_shift = IDLLCD_ARM,
230 .enbl_shift = EN_LCDCK,
234 /*****************************************************************************/
236 #define CK_IN_RANGE(ck) (!((ck < OMAP_CK_MIN) || (ck > OMAP_CK_MAX)))
238 int ck_auto_unclock = 1;
241 #define CK_MAX_PLL_FREQ OMAP_CK_MAX_RATE
242 static __u8 ck_valid_table[CK_MAX_PLL_FREQ / 8 + 1];
243 static __u8 ck_lookup_table[CK_MAX_PLL_FREQ];
246 ck_set_input(ck_t ck, ck_t input)
252 if (!CK_IN_RANGE(ck) || !CK_CAN_SWITCH(ck)) {
257 reg = omap_readw(CK_SELECT_REG(ck));
258 shift = CK_SELECT_SHIFT(ck);
260 spin_lock_irqsave(&clock_lock, flags);
261 if (input == OMAP_CLKIN) {
262 reg &= ~(1 << shift);
263 omap_writew(reg, CK_SELECT_REG(ck));
265 } else if (input == CK_PARENT(ck)) {
267 omap_writew(reg, CK_SELECT_REG(ck));
273 spin_unlock_irqrestore(&clock_lock, flags);
278 ck_get_input(ck_t ck, ck_t * input)
283 if (!CK_IN_RANGE(ck))
288 spin_lock_irqsave(&clock_lock, flags);
289 if (CK_CAN_SWITCH(ck)) {
293 reg = omap_readw(CK_SELECT_REG(ck));
294 shift = CK_SELECT_SHIFT(ck);
295 if (reg & (1 << shift)) {
296 *input = CK_PARENT(ck);
304 spin_unlock_irqrestore(&clock_lock, flags);
309 __ck_set_pll_rate(ck_t ck, int rate)
314 if ((rate < 0) || (rate > CK_MAX_PLL_FREQ))
317 /* Scan downward for the closest matching frequency */
318 while (rate && !test_bit(rate, (unsigned long *)&ck_valid_table))
322 printk(KERN_ERR "%s: couldn't find a matching rate\n",
327 spin_lock_irqsave(&clock_lock, flags);
328 pll = omap_readw(CK_RATE_REG(ck));
330 /* Clear the rate bits */
333 /* Set the rate bits */
334 pll |= (ck_lookup_table[rate - 1] << 5);
336 omap_writew(pll, CK_RATE_REG(ck));
338 spin_unlock_irqrestore(&clock_lock, flags);
344 __ck_set_clkm_rate(ck_t ck, int rate)
346 int shift, prate, div, ret;
350 spin_lock_irqsave(&clock_lock, flags);
353 * We can only set this clock's value to a fraction of its
354 * parent's value. The interface says I'll round down when necessary.
355 * So first let's get the parent's current rate.
357 prate = ck_get_rate(CK_PARENT(ck));
360 * Let's just start with the highest fraction and keep searching
361 * down through available rates until we find one less than or equal
362 * to the desired rate.
364 for (div = 0; div < 4; div++) {
371 * Oops. Looks like the caller wants a rate lower than we can support.
374 printk(KERN_ERR "%s: %d is too low\n",
381 * One more detail: if this clock supports more than one parent, then
382 * we're going to automatically switch over to the parent which runs
383 * through the divisor. For omap this is not ambiguous because for all
384 * such clocks one choice is always OMAP_CLKIN (which doesn't run
385 * through the divisor) and the other is whatever I encoded as
386 * CK_PARENT. Note that I wait until we get this far because I don't
387 * want to switch the input until we're sure this is going to work.
389 if (CK_CAN_SWITCH(ck))
390 if ((ret = ck_set_input(ck, CK_PARENT(ck))) < 0) {
396 * At last, we can set the divisor. Clear the old rate bits and
399 reg = omap_readw(CK_RATE_REG(ck));
400 shift = CK_RATE_SHIFT(ck);
401 reg &= ~(3 << shift);
402 reg |= (div << shift);
403 omap_writew(reg, CK_RATE_REG(ck));
405 /* And return the new (actual, after rounding down) rate. */
409 spin_unlock_irqrestore(&clock_lock, flags);
414 ck_set_rate(ck_t ck, int rate)
418 if (!CK_IN_RANGE(ck) || !CK_CAN_CHANGE_RATE(ck))
424 ret = __ck_set_clkm_rate(ck, rate);
428 ret = __ck_set_pll_rate(ck, rate);
438 __ck_get_pll_rate(ck_t ck)
442 unsigned short pll = omap_readw(CK_RATE_REG(ck));
444 m = (pll & (0x1f << 7)) >> 7;
446 d = (pll & (3 << 5)) >> 5;
449 return ((source_clock * m) / d);
453 __ck_get_clkm_rate(ck_t ck)
455 static int bits2div[] = { 1, 2, 4, 8 };
456 int in, bits, reg, shift;
458 reg = omap_readw(CK_RATE_REG(ck));
459 shift = CK_RATE_SHIFT(ck);
461 in = ck_get_rate(CK_PARENT(ck));
462 bits = (reg & (3 << shift)) >> shift;
464 return (in / bits2div[bits]);
473 if (!CK_IN_RANGE(ck)) {
481 ret = __ck_get_pll_rate(ck);
491 case OMAP_ARM_GPIO_CK:
492 ret = ck_get_rate(CK_PARENT(ck));
506 ret = __ck_get_clkm_rate(ck);
510 ck_get_input(ck, &parent);
511 ret = ck_get_rate(parent);
515 /* Note that this evaluates to zero if source_clock is 12MHz. */
516 ret = source_clock / 14;
531 int ret = -EINVAL, shift;
534 if (!CK_IN_RANGE(ck))
538 printk(KERN_DEBUG "%s: %s\n", __FUNCTION__, CK_NAME(ck));
542 if (!CK_CAN_DISABLE(ck))
543 /* Then it must be on... */
546 spin_lock_irqsave(&clock_lock, flags);
547 reg = omap_readw(CK_ENABLE_REG(ck));
548 shift = CK_ENABLE_SHIFT(ck);
550 omap_writew(reg, CK_ENABLE_REG(ck));
551 spin_unlock_irqrestore(&clock_lock, flags);
561 int ret = -EINVAL, shift;
564 if (!CK_IN_RANGE(ck))
568 printk(KERN_DEBUG "%s: %s\n", __FUNCTION__, CK_NAME(ck));
570 if (!CK_CAN_DISABLE(ck))
575 if (ck == OMAP_CLKIN)
578 spin_lock_irqsave(&clock_lock, flags);
579 reg = omap_readw(CK_ENABLE_REG(ck));
580 shift = CK_ENABLE_SHIFT(ck);
581 reg &= ~(1 << shift);
582 omap_writew(reg, CK_ENABLE_REG(ck));
583 spin_unlock_irqrestore(&clock_lock, flags);
589 int ck_valid_rate(int rate)
591 return test_bit(rate, (unsigned long *)&ck_valid_table);
595 __ck_make_lookup_table(void)
599 memset(ck_valid_table, 0, sizeof (ck_valid_table));
601 for (m = 1; m < 32; m++)
602 for (d = 1; d < 5; d++) {
604 int rate = ((source_clock * m) / (d));
606 if (rate > CK_MAX_PLL_FREQ)
608 if (test_bit(rate, (unsigned long *)&ck_valid_table))
610 set_bit(rate, (unsigned long *)&ck_valid_table);
611 ck_lookup_table[rate - 1] = (m << 2) | (d - 1);
618 const struct omap_clock_info *info;
619 int crystal_type = 0; /* Default 12 MHz */
621 __ck_make_lookup_table();
622 info = omap_get_per_info(OMAP_TAG_CLOCK, struct omap_clock_info);
624 if (!cpu_is_omap1510())
625 crystal_type = info->system_clock_type;
628 /* We want to be in syncronous scalable mode */
629 omap_writew(0x1000, ARM_SYSST);
630 #if defined(CONFIG_OMAP_ARM_30MHZ)
631 omap_writew(0x1555, ARM_CKCTL);
632 omap_writew(0x2290, DPLL_CTL);
633 #elif defined(CONFIG_OMAP_ARM_60MHZ)
634 omap_writew(0x1005, ARM_CKCTL);
635 omap_writew(0x2290, DPLL_CTL);
636 #elif defined(CONFIG_OMAP_ARM_96MHZ)
637 omap_writew(0x1005, ARM_CKCTL);
638 omap_writew(0x2410, DPLL_CTL);
639 #elif defined(CONFIG_OMAP_ARM_120MHZ)
640 omap_writew(0x110a, ARM_CKCTL);
641 omap_writew(0x2510, DPLL_CTL);
642 #elif defined(CONFIG_OMAP_ARM_168MHZ)
643 omap_writew(0x110f, ARM_CKCTL);
644 omap_writew(0x2710, DPLL_CTL);
645 #elif defined(CONFIG_OMAP_ARM_182MHZ) && defined(CONFIG_ARCH_OMAP730)
646 omap_writew(0x250E, ARM_CKCTL);
647 omap_writew(0x2710, DPLL_CTL);
648 #elif defined(CONFIG_OMAP_ARM_192MHZ) && (defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912))
649 omap_writew(0x150f, ARM_CKCTL);
650 if (crystal_type == 2) {
651 source_clock = 13; /* MHz */
652 omap_writew(0x2510, DPLL_CTL);
654 omap_writew(0x2810, DPLL_CTL);
655 #elif defined(CONFIG_OMAP_ARM_195MHZ) && defined(CONFIG_ARCH_OMAP730)
656 omap_writew(0x250E, ARM_CKCTL);
657 omap_writew(0x2790, DPLL_CTL);
659 #error "OMAP MHZ not set, please run make xconfig"
662 #ifdef CONFIG_MACH_OMAP_PERSEUS2
663 /* Select slicer output as OMAP input clock */
664 omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
667 /* Turn off some other junk the bootloader might have turned on */
669 /* Turn off DSP, ARM_INTHCK, ARM_TIMXO */
670 omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
672 /* Put DSP/MPUI into reset until needed */
673 omap_writew(0, ARM_RSTCT1);
674 omap_writew(1, ARM_RSTCT2);
675 omap_writew(0x400, ARM_IDLECT1);
678 * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
679 * of the ARM_IDLECT2 register must be set to zero. The power-on
680 * default value of this bit is one.
682 omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
685 * Only enable those clocks we will need, let the drivers
686 * enable other clocks as necessary
688 ck_enable(OMAP_MPUPER_CK);
689 ck_enable(OMAP_ARM_GPIO_CK);
690 ck_enable(OMAP_MPUXOR_CK);
691 //ck_set_rate(OMAP_MPUTIM_CK, OMAP_CLKIN);
692 ck_enable(OMAP_MPUTIM_CK);
693 start_mputimer1(0xffffffff);
699 EXPORT_SYMBOL(ck_get_rate);
700 EXPORT_SYMBOL(ck_set_rate);
701 EXPORT_SYMBOL(ck_enable);
702 EXPORT_SYMBOL(ck_disable);