initial commit with v2.6.9
[linux-2.6.9-moxart.git] / arch / arm / mach-omap / clocks.c
blobb507856597321c438d32ac3d5e1ddde61114b99c
1 /*
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>
35 #include <asm/io.h>
36 #include <asm/arch/clocks.h>
37 #include <asm/arch/board.h>
39 extern void start_mputimer1(unsigned long load_val);
41 /* Input clock in MHz */
42 static unsigned int source_clock = 12;
45 * We use one spinlock for all clock registers for now. We may want to
46 * change this to be clock register specific later on. Before we can do
47 * that, we need to map out the shared clock registers.
49 static spinlock_t clock_lock = SPIN_LOCK_UNLOCKED;
51 typedef struct {
52 char *name;
53 __u8 flags;
54 ck_t parent;
55 unsigned long rate_reg; /* Clock rate register */
56 unsigned long enbl_reg; /* Enable register */
57 unsigned long idle_reg; /* Idle register */
58 unsigned long slct_reg; /* Select register */
59 __s8 rate_shift; /* Clock rate bit shift */
60 __s8 enbl_shift; /* Clock enable bit shift */
61 __s8 idle_shift; /* Clock idle bit shift */
62 __s8 slct_shift; /* Clock select bit shift */
63 } ck_info_t;
65 #define CK_NAME(ck) ck_info_table[ck].name
66 #define CK_FLAGS(ck) ck_info_table[ck].flags
67 #define CK_PARENT(ck) ck_info_table[ck].parent
68 #define CK_RATE_REG(ck) ck_info_table[ck].rate_reg
69 #define CK_ENABLE_REG(ck) ck_info_table[ck].enbl_reg
70 #define CK_IDLE_REG(ck) ck_info_table[ck].idle_reg
71 #define CK_SELECT_REG(ck) ck_info_table[ck].slct_reg
72 #define CK_RATE_SHIFT(ck) ck_info_table[ck].rate_shift
73 #define CK_ENABLE_SHIFT(ck) ck_info_table[ck].enbl_shift
74 #define CK_IDLE_SHIFT(ck) ck_info_table[ck].idle_shift
75 #define CK_SELECT_SHIFT(ck) ck_info_table[ck].slct_shift
76 #define CK_CAN_CHANGE_RATE(cl) (CK_FLAGS(ck) & CK_RATEF)
77 #define CK_CAN_DISABLE(cl) (CK_FLAGS(ck) & CK_ENABLEF)
78 #define CK_CAN_IDLE(cl) (CK_FLAGS(ck) & CK_IDLEF)
79 #define CK_CAN_SWITCH(cl) (CK_FLAGS(ck) & CK_SELECTF)
81 static ck_info_t ck_info_table[] = {
83 .name = "clkin",
84 .flags = 0,
85 .parent = OMAP_CLKIN,
86 }, {
87 .name = "ck_gen1",
88 .flags = CK_RATEF | CK_IDLEF,
89 .rate_reg = DPLL_CTL,
90 .idle_reg = ARM_IDLECT1,
91 .idle_shift = IDLDPLL_ARM,
92 .parent = OMAP_CLKIN,
93 }, {
94 .name = "ck_gen2",
95 .flags = 0,
96 .parent = OMAP_CK_GEN1,
97 }, {
98 .name = "ck_gen3",
99 .flags = 0,
100 .parent = OMAP_CK_GEN1,
101 }, {
102 .name = "tc_ck",
103 .flags = CK_RATEF | CK_IDLEF,
104 .parent = OMAP_CK_GEN3,
105 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[TCDIV(9:8)] */
106 .idle_reg = ARM_IDLECT1,
107 .rate_shift = TCDIV,
108 .idle_shift = IDLIF_ARM
109 }, {
110 .name = "arm_ck",
111 .flags = CK_IDLEF | CK_RATEF,
112 .parent = OMAP_CK_GEN1,
113 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[ARMDIV(5:4)] */
114 .idle_reg = ARM_IDLECT1,
115 .rate_shift = ARMDIV,
116 .idle_shift = SETARM_IDLE,
117 }, {
118 .name = "mpuper_ck",
119 .flags = CK_RATEF | CK_IDLEF | CK_ENABLEF,
120 .parent = OMAP_CK_GEN1,
121 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[PERDIV(1:0)] */
122 .enbl_reg = ARM_IDLECT2,
123 .idle_reg = ARM_IDLECT1,
124 .rate_shift = PERDIV,
125 .enbl_shift = EN_PERCK,
126 .idle_shift = IDLPER_ARM
127 }, {
128 .name = "arm_gpio_ck",
129 .flags = CK_ENABLEF,
130 .parent = OMAP_CK_GEN1,
131 .enbl_reg = ARM_IDLECT2,
132 .enbl_shift = EN_GPIOCK
133 }, {
134 .name = "mpuxor_ck",
135 .flags = CK_ENABLEF | CK_IDLEF,
136 .parent = OMAP_CLKIN,
137 .idle_reg = ARM_IDLECT1,
138 .enbl_reg = ARM_IDLECT2,
139 .idle_shift = IDLXORP_ARM,
140 .enbl_shift = EN_XORPCK
141 }, {
142 .name = "mputim_ck",
143 .flags = CK_IDLEF | CK_ENABLEF | CK_SELECTF,
144 .parent = OMAP_CLKIN,
145 .idle_reg = ARM_IDLECT1,
146 .enbl_reg = ARM_IDLECT2,
147 .slct_reg = ARM_CKCTL,
148 .idle_shift = IDLTIM_ARM,
149 .enbl_shift = EN_TIMCK,
150 .slct_shift = ARM_TIMXO
151 }, {
152 .name = "mpuwd_ck",
153 .flags = CK_IDLEF | CK_ENABLEF,
154 .parent = OMAP_CLKIN,
155 .idle_reg = ARM_IDLECT1,
156 .enbl_reg = ARM_IDLECT2,
157 .idle_shift = IDLWDT_ARM,
158 .enbl_shift = EN_WDTCK,
159 }, {
160 .name = "dsp_ck",
161 .flags = CK_RATEF | CK_ENABLEF,
162 .parent = OMAP_CK_GEN2,
163 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[DSPDIV(7:6)] */
164 .enbl_reg = ARM_CKCTL,
165 .rate_shift = DSPDIV,
166 .enbl_shift = EN_DSPCK,
167 }, {
168 .name = "dspmmu_ck",
169 .flags = CK_RATEF | CK_ENABLEF,
170 .parent = OMAP_CK_GEN2,
171 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[DSPMMUDIV(11:10)] */
172 .enbl_reg = ARM_CKCTL,
173 .rate_shift = DSPMMUDIV,
174 .enbl_shift = EN_DSPCK,
175 }, {
176 .name = "dma_ck",
177 .flags = CK_RATEF | CK_IDLEF | CK_ENABLEF,
178 .parent = OMAP_CK_GEN3,
179 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[TCDIV(9:8)] */
180 .idle_reg = ARM_IDLECT1,
181 .enbl_reg = ARM_IDLECT2,
182 .rate_shift = TCDIV,
183 .idle_shift = IDLIF_ARM,
184 .enbl_shift = DMACK_REQ
185 }, {
186 .name = "api_ck",
187 .flags = CK_RATEF | CK_IDLEF | CK_ENABLEF,
188 .parent = OMAP_CK_GEN3,
189 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[TCDIV(9:8)] */
190 .idle_reg = ARM_IDLECT1,
191 .enbl_reg = ARM_IDLECT2,
192 .rate_shift = TCDIV,
193 .idle_shift = IDLAPI_ARM,
194 .enbl_shift = EN_APICK,
195 }, {
196 .name = "hsab_ck",
197 .flags = CK_RATEF | CK_IDLEF | CK_ENABLEF,
198 .parent = OMAP_CK_GEN3,
199 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[TCDIV(9:8)] */
200 .idle_reg = ARM_IDLECT1,
201 .enbl_reg = ARM_IDLECT2,
202 .rate_shift = TCDIV,
203 .idle_shift = IDLHSAB_ARM,
204 .enbl_shift = EN_HSABCK,
205 }, {
206 .name = "lbfree_ck",
207 .flags = CK_RATEF | CK_ENABLEF,
208 .parent = OMAP_CK_GEN3,
209 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[TCDIV(9:8)] */
210 .enbl_reg = ARM_IDLECT2,
211 .rate_shift = TCDIV,
212 .enbl_shift = EN_LBFREECK,
213 }, {
214 .name = "lb_ck",
215 .flags = CK_RATEF | CK_IDLEF | CK_ENABLEF,
216 .parent = OMAP_CK_GEN3,
217 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[TCDIV(9:8)] */
218 .idle_reg = ARM_IDLECT1,
219 .enbl_reg = ARM_IDLECT2,
220 .rate_shift = TCDIV,
221 .idle_shift = IDLLB_ARM,
222 .enbl_shift = EN_LBCK,
223 }, {
224 .name = "lcd_ck",
225 .flags = CK_RATEF | CK_IDLEF | CK_ENABLEF,
226 .parent = OMAP_CK_GEN3,
227 .rate_reg = ARM_CKCTL, /* ARM_CKCTL[LCDDIV(3:2)] */
228 .idle_reg = ARM_IDLECT1,
229 .enbl_reg = ARM_IDLECT2,
230 .rate_shift = LCDDIV,
231 .idle_shift = IDLLCD_ARM,
232 .enbl_shift = EN_LCDCK,
236 /*****************************************************************************/
238 #define CK_IN_RANGE(ck) (!((ck < OMAP_CK_MIN) || (ck > OMAP_CK_MAX)))
240 int ck_auto_unclock = 1;
241 int ck_debug = 0;
243 #define CK_MAX_PLL_FREQ OMAP_CK_MAX_RATE
244 static __u32 ck_valid_table[CK_MAX_PLL_FREQ / 32 + 1];
245 static __u8 ck_lookup_table[CK_MAX_PLL_FREQ];
248 ck_set_input(ck_t ck, ck_t input)
250 int ret = 0, shift;
251 unsigned short reg;
252 unsigned long flags;
254 if (!CK_IN_RANGE(ck) || !CK_CAN_SWITCH(ck)) {
255 ret = -EINVAL;
256 goto exit;
259 reg = omap_readw(CK_SELECT_REG(ck));
260 shift = CK_SELECT_SHIFT(ck);
262 spin_lock_irqsave(&clock_lock, flags);
263 if (input == OMAP_CLKIN) {
264 reg &= ~(1 << shift);
265 omap_writew(reg, CK_SELECT_REG(ck));
266 goto exit;
267 } else if (input == CK_PARENT(ck)) {
268 reg |= (1 << shift);
269 omap_writew(reg, CK_SELECT_REG(ck));
270 goto exit;
273 ret = -EINVAL;
274 exit:
275 spin_unlock_irqrestore(&clock_lock, flags);
276 return ret;
280 ck_get_input(ck_t ck, ck_t * input)
282 int ret = -EINVAL;
283 unsigned long flags;
285 if (!CK_IN_RANGE(ck))
286 goto exit;
288 ret = 0;
290 spin_lock_irqsave(&clock_lock, flags);
291 if (CK_CAN_SWITCH(ck)) {
292 int shift;
293 unsigned short reg;
295 reg = omap_readw(CK_SELECT_REG(ck));
296 shift = CK_SELECT_SHIFT(ck);
297 if (reg & (1 << shift)) {
298 *input = CK_PARENT(ck);
299 goto exit;
303 *input = OMAP_CLKIN;
305 exit:
306 spin_unlock_irqrestore(&clock_lock, flags);
307 return ret;
310 static int
311 __ck_set_pll_rate(ck_t ck, int rate)
313 unsigned short pll;
314 unsigned long flags;
316 if ((rate < 0) || (rate > CK_MAX_PLL_FREQ))
317 return -EINVAL;
319 /* Scan downward for the closest matching frequency */
320 while (rate && !test_bit(rate, (unsigned long *)&ck_valid_table))
321 rate--;
323 if (!rate) {
324 printk(KERN_ERR "%s: couldn't find a matching rate\n",
325 __FUNCTION__);
326 return -EINVAL;
329 spin_lock_irqsave(&clock_lock, flags);
330 pll = omap_readw(CK_RATE_REG(ck));
332 /* Clear the rate bits */
333 pll &= ~(0x1f << 5);
335 /* Set the rate bits */
336 pll |= (ck_lookup_table[rate - 1] << 5);
338 omap_writew(pll, CK_RATE_REG(ck));
340 spin_unlock_irqrestore(&clock_lock, flags);
342 return 0;
345 static int
346 __ck_set_clkm_rate(ck_t ck, int rate)
348 int shift, prate, div, ret;
349 unsigned short reg;
350 unsigned long flags;
352 spin_lock_irqsave(&clock_lock, flags);
355 * We can only set this clock's value to a fraction of its
356 * parent's value. The interface says I'll round down when necessary.
357 * So first let's get the parent's current rate.
359 prate = ck_get_rate(CK_PARENT(ck));
362 * Let's just start with the highest fraction and keep searching
363 * down through available rates until we find one less than or equal
364 * to the desired rate.
366 for (div = 0; div < 4; div++) {
367 if (prate <= rate)
368 break;
369 prate = prate / 2;
373 * Oops. Looks like the caller wants a rate lower than we can support.
375 if (div == 5) {
376 printk(KERN_ERR "%s: %d is too low\n",
377 __FUNCTION__, rate);
378 ret = -EINVAL;
379 goto exit;
383 * One more detail: if this clock supports more than one parent, then
384 * we're going to automatically switch over to the parent which runs
385 * through the divisor. For omap this is not ambiguous because for all
386 * such clocks one choice is always OMAP_CLKIN (which doesn't run
387 * through the divisor) and the other is whatever I encoded as
388 * CK_PARENT. Note that I wait until we get this far because I don't
389 * want to switch the input until we're sure this is going to work.
391 if (CK_CAN_SWITCH(ck))
392 if ((ret = ck_set_input(ck, CK_PARENT(ck))) < 0) {
393 BUG();
394 goto exit;
398 * At last, we can set the divisor. Clear the old rate bits and
399 * set the new ones.
401 reg = omap_readw(CK_RATE_REG(ck));
402 shift = CK_RATE_SHIFT(ck);
403 reg &= ~(3 << shift);
404 reg |= (div << shift);
405 omap_writew(reg, CK_RATE_REG(ck));
407 /* And return the new (actual, after rounding down) rate. */
408 ret = prate;
410 exit:
411 spin_unlock_irqrestore(&clock_lock, flags);
412 return ret;
416 ck_set_rate(ck_t ck, int rate)
418 int ret = -EINVAL;
420 if (!CK_IN_RANGE(ck) || !CK_CAN_CHANGE_RATE(ck))
421 goto exit;
423 switch (ck) {
425 default:
426 ret = __ck_set_clkm_rate(ck, rate);
427 break;
429 case OMAP_CK_GEN1:
430 ret = __ck_set_pll_rate(ck, rate);
431 break;
435 exit:
436 return ret;
439 static int
440 __ck_get_pll_rate(ck_t ck)
442 int m, d;
444 unsigned short pll = omap_readw(CK_RATE_REG(ck));
446 m = (pll & (0x1f << 7)) >> 7;
447 m = m ? m : 1;
448 d = (pll & (3 << 5)) >> 5;
449 d++;
451 return ((source_clock * m) / d);
454 static int
455 __ck_get_clkm_rate(ck_t ck)
457 static int bits2div[] = { 1, 2, 4, 8 };
458 int in, bits, reg, shift;
460 reg = omap_readw(CK_RATE_REG(ck));
461 shift = CK_RATE_SHIFT(ck);
463 in = ck_get_rate(CK_PARENT(ck));
464 bits = (reg & (3 << shift)) >> shift;
466 return (in / bits2div[bits]);
470 ck_get_rate(ck_t ck)
472 int ret = 0;
473 ck_t parent;
475 if (!CK_IN_RANGE(ck)) {
476 ret = -EINVAL;
477 goto exit;
480 switch (ck) {
482 case OMAP_CK_GEN1:
483 ret = __ck_get_pll_rate(ck);
484 break;
486 case OMAP_CLKIN:
487 ret = source_clock;
488 break;
490 case OMAP_MPUXOR_CK:
491 case OMAP_CK_GEN2:
492 case OMAP_CK_GEN3:
493 case OMAP_ARM_GPIO_CK:
494 ret = ck_get_rate(CK_PARENT(ck));
495 break;
497 case OMAP_ARM_CK:
498 case OMAP_MPUPER_CK:
499 case OMAP_DSP_CK:
500 case OMAP_DSPMMU_CK:
501 case OMAP_LCD_CK:
502 case OMAP_TC_CK:
503 case OMAP_DMA_CK:
504 case OMAP_API_CK:
505 case OMAP_HSAB_CK:
506 case OMAP_LBFREE_CK:
507 case OMAP_LB_CK:
508 ret = __ck_get_clkm_rate(ck);
509 break;
511 case OMAP_MPUTIM_CK:
512 ck_get_input(ck, &parent);
513 ret = ck_get_rate(parent);
514 break;
516 case OMAP_MPUWD_CK:
517 /* Note that this evaluates to zero if source_clock is 12MHz. */
518 ret = source_clock / 14;
519 break;
520 default:
521 ret = -EINVAL;
522 break;
525 exit:
526 return ret;
530 ck_enable(ck_t ck)
532 unsigned short reg;
533 int ret = -EINVAL, shift;
534 unsigned long flags;
536 if (!CK_IN_RANGE(ck))
537 goto exit;
539 if (ck_debug)
540 printk(KERN_DEBUG "%s: %s\n", __FUNCTION__, CK_NAME(ck));
542 ret = 0;
544 if (!CK_CAN_DISABLE(ck))
545 /* Then it must be on... */
546 goto exit;
548 spin_lock_irqsave(&clock_lock, flags);
549 reg = omap_readw(CK_ENABLE_REG(ck));
550 shift = CK_ENABLE_SHIFT(ck);
551 reg |= (1 << shift);
552 omap_writew(reg, CK_ENABLE_REG(ck));
553 spin_unlock_irqrestore(&clock_lock, flags);
555 exit:
556 return ret;
560 ck_disable(ck_t ck)
562 unsigned short reg;
563 int ret = -EINVAL, shift;
564 unsigned long flags;
566 if (!CK_IN_RANGE(ck))
567 goto exit;
569 if (ck_debug)
570 printk(KERN_DEBUG "%s: %s\n", __FUNCTION__, CK_NAME(ck));
572 if (!CK_CAN_DISABLE(ck))
573 goto exit;
575 ret = 0;
577 if (ck == OMAP_CLKIN)
578 return -EINVAL;
580 spin_lock_irqsave(&clock_lock, flags);
581 reg = omap_readw(CK_ENABLE_REG(ck));
582 shift = CK_ENABLE_SHIFT(ck);
583 reg &= ~(1 << shift);
584 omap_writew(reg, CK_ENABLE_REG(ck));
585 spin_unlock_irqrestore(&clock_lock, flags);
587 exit:
588 return ret;
591 int ck_valid_rate(int rate)
593 return test_bit(rate, (unsigned long *)&ck_valid_table);
596 static void
597 __ck_make_lookup_table(void)
599 __u8 m, d;
601 memset(ck_valid_table, 0, sizeof (ck_valid_table));
603 for (m = 1; m < 32; m++)
604 for (d = 1; d < 5; d++) {
606 int rate = ((source_clock * m) / (d));
608 if (rate > CK_MAX_PLL_FREQ)
609 continue;
610 if (test_bit(rate, (unsigned long *)&ck_valid_table))
611 continue;
612 set_bit(rate, (unsigned long *)&ck_valid_table);
613 ck_lookup_table[rate - 1] = (m << 2) | (d - 1);
617 int __init
618 init_ck(void)
620 const struct omap_clock_config *info;
621 int crystal_type = 0; /* Default 12 MHz */
623 __ck_make_lookup_table();
624 info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
625 if (info != NULL) {
626 if (!cpu_is_omap1510())
627 crystal_type = info->system_clock_type;
630 /* We want to be in syncronous scalable mode */
631 omap_writew(0x1000, ARM_SYSST);
632 #if defined(CONFIG_OMAP_ARM_30MHZ)
633 omap_writew(0x1555, ARM_CKCTL);
634 omap_writew(0x2290, DPLL_CTL);
635 #elif defined(CONFIG_OMAP_ARM_60MHZ)
636 omap_writew(0x1005, ARM_CKCTL);
637 omap_writew(0x2290, DPLL_CTL);
638 #elif defined(CONFIG_OMAP_ARM_96MHZ)
639 omap_writew(0x1005, ARM_CKCTL);
640 omap_writew(0x2410, DPLL_CTL);
641 #elif defined(CONFIG_OMAP_ARM_120MHZ)
642 omap_writew(0x110a, ARM_CKCTL);
643 omap_writew(0x2510, DPLL_CTL);
644 #elif defined(CONFIG_OMAP_ARM_168MHZ)
645 omap_writew(0x110f, ARM_CKCTL);
646 omap_writew(0x2710, DPLL_CTL);
647 #elif defined(CONFIG_OMAP_ARM_182MHZ) && defined(CONFIG_ARCH_OMAP730)
648 omap_writew(0x250E, ARM_CKCTL);
649 omap_writew(0x2710, DPLL_CTL);
650 #elif defined(CONFIG_OMAP_ARM_192MHZ) && (defined(CONFIG_ARCH_OMAP1610) || defined(CONFIG_ARCH_OMAP5912) \
651 || defined(CONFIG_ARCH_OMAP1710))
652 omap_writew(0x150f, ARM_CKCTL);
653 if (crystal_type == 2) {
654 source_clock = 13; /* MHz */
655 omap_writew(0x2510, DPLL_CTL);
656 } else
657 omap_writew(0x2810, DPLL_CTL);
658 #elif defined(CONFIG_OMAP_ARM_195MHZ) && defined(CONFIG_ARCH_OMAP730)
659 omap_writew(0x250E, ARM_CKCTL);
660 omap_writew(0x2790, DPLL_CTL);
661 #else
662 #error "OMAP MHZ not set, please run make xconfig"
663 #endif
665 #ifdef CONFIG_MACH_OMAP_PERSEUS2
666 /* Select slicer output as OMAP input clock */
667 omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
668 #endif
670 /* Turn off some other junk the bootloader might have turned on */
672 /* Turn off DSP, ARM_INTHCK, ARM_TIMXO */
673 omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
675 /* Put DSP/MPUI into reset until needed */
676 omap_writew(0, ARM_RSTCT1);
677 omap_writew(1, ARM_RSTCT2);
678 omap_writew(0x400, ARM_IDLECT1);
681 * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
682 * of the ARM_IDLECT2 register must be set to zero. The power-on
683 * default value of this bit is one.
685 omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
688 * Only enable those clocks we will need, let the drivers
689 * enable other clocks as necessary
691 ck_enable(OMAP_MPUPER_CK);
692 ck_enable(OMAP_ARM_GPIO_CK);
693 ck_enable(OMAP_MPUXOR_CK);
694 //ck_set_rate(OMAP_MPUTIM_CK, OMAP_CLKIN);
695 ck_enable(OMAP_MPUTIM_CK);
696 start_mputimer1(0xffffffff);
698 return 0;
702 EXPORT_SYMBOL(ck_get_rate);
703 EXPORT_SYMBOL(ck_set_rate);
704 EXPORT_SYMBOL(ck_enable);
705 EXPORT_SYMBOL(ck_disable);