2 * linux/arch/arm/mach-omap/clock.c
4 * Copyright (C) 2004 Nokia corporation
5 * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 #include <linux/module.h>
12 #include <linux/kernel.h>
13 #include <linux/list.h>
14 #include <linux/errno.h>
15 #include <linux/err.h>
17 #include <asm/semaphore.h>
18 #include <asm/hardware/clock.h>
19 #include <asm/arch/board.h>
23 static LIST_HEAD(clocks);
24 static DECLARE_MUTEX(clocks_sem);
25 static spinlock_t clockfw_lock = SPIN_LOCK_UNLOCKED;
26 static void propagate_rate(struct clk * clk);
27 /* MPU virtual clock functions */
28 static int select_table_rate(unsigned long rate);
29 static long round_to_table_rate(unsigned long rate);
30 void clk_setdpll(__u16, __u16);
32 struct mpu_rate rate_table[] = {
33 /* MPU MHz, xtal MHz, dpll1 MHz, CKCTL, DPLL_CTL
34 * armdiv, dspdiv, dspmmu, tcdiv, perdiv, lcddiv
36 #if defined(CONFIG_OMAP_ARM_216MHZ) && defined(CONFIG_ARCH_OMAP16XX)
37 { 216000000, 12000000, 216000000, 0x050d, 0x2910 }, /* 1/1/2/2/2/8 */
39 #if defined(CONFIG_OMAP_ARM_195MHZ) && defined(CONFIG_ARCH_OMAP730)
40 { 195000000, 13000000, 195000000, 0x050e, 0x2790 }, /* 1/1/2/2/4/8 */
42 #if defined(CONFIG_OMAP_ARM_192MHZ) && defined(CONFIG_ARCH_OMAP16XX)
43 { 192000000, 19200000, 192000000, 0x050f, 0x2510 }, /* 1/1/2/2/8/8 */
44 { 192000000, 12000000, 192000000, 0x050f, 0x2810 }, /* 1/1/2/2/8/8 */
45 { 96000000, 12000000, 192000000, 0x055f, 0x2810 }, /* 2/2/2/2/8/8 */
46 { 48000000, 12000000, 192000000, 0x0ccf, 0x2810 }, /* 4/4/4/4/8/8 */
47 { 24000000, 12000000, 192000000, 0x0fff, 0x2810 }, /* 8/8/8/8/8/8 */
49 #if defined(CONFIG_OMAP_ARM_182MHZ) && defined(CONFIG_ARCH_OMAP730)
50 { 182000000, 13000000, 182000000, 0x050e, 0x2710 }, /* 1/1/2/2/4/8 */
52 #if defined(CONFIG_OMAP_ARM_168MHZ)
53 { 168000000, 12000000, 168000000, 0x010f, 0x2710 }, /* 1/1/1/2/8/8 */
55 #if defined(CONFIG_OMAP_ARM_120MHZ)
56 { 120000000, 12000000, 120000000, 0x010a, 0x2510 }, /* 1/1/1/2/4/4 */
58 #if defined(CONFIG_OMAP_ARM_96MHZ)
59 { 96000000, 12000000, 96000000, 0x0005, 0x2410 }, /* 1/1/1/1/2/2 */
61 #if defined(CONFIG_OMAP_ARM_60MHZ)
62 { 60000000, 12000000, 60000000, 0x0005, 0x2290 }, /* 1/1/1/1/2/2 */
64 #if defined(CONFIG_OMAP_ARM_30MHZ)
65 { 30000000, 12000000, 60000000, 0x0555, 0x2290 }, /* 2/2/2/2/2/2 */
71 static void ckctl_recalc(struct clk * clk)
75 /* Calculate divisor encoded as 2-bit exponent */
76 dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
77 if (unlikely(clk->rate == clk->parent->rate / dsor))
78 return; /* No change, quick exit */
79 clk->rate = clk->parent->rate / dsor;
81 if (unlikely(clk->flags & RATE_PROPAGATES))
86 static void followparent_recalc(struct clk * clk)
88 clk->rate = clk->parent->rate;
92 static void watchdog_recalc(struct clk * clk)
94 clk->rate = clk->parent->rate / 14;
98 static struct clk ck_ref = {
101 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
105 static struct clk ck_dpll1 = {
108 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
109 RATE_PROPAGATES | ALWAYS_ENABLED,
112 static struct clk ck_dpll1out = {
113 .name = "ck_dpll1out",
115 .flags = CLOCK_IN_OMAP16XX,
116 .enable_reg = ARM_IDLECT2,
117 .enable_bit = EN_CKOUT_ARM,
118 .recalc = &followparent_recalc,
121 static struct clk arm_ck = {
124 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
125 RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
126 .rate_offset = CKCTL_ARMDIV_OFFSET,
127 .recalc = &ckctl_recalc,
130 static struct clk armper_ck = {
133 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
135 .enable_reg = ARM_IDLECT2,
136 .enable_bit = EN_PERCK,
137 .rate_offset = CKCTL_PERDIV_OFFSET,
138 .recalc = &ckctl_recalc,
141 static struct clk arm_gpio_ck = {
142 .name = "arm_gpio_ck",
144 .flags = CLOCK_IN_OMAP1510,
145 .enable_reg = ARM_IDLECT2,
146 .enable_bit = EN_GPIOCK,
147 .recalc = &followparent_recalc,
150 static struct clk armxor_ck = {
153 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
154 .enable_reg = ARM_IDLECT2,
155 .enable_bit = EN_XORPCK,
156 .recalc = &followparent_recalc,
159 static struct clk armtim_ck = {
162 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
163 .enable_reg = ARM_IDLECT2,
164 .enable_bit = EN_TIMCK,
165 .recalc = &followparent_recalc,
168 static struct clk armwdt_ck = {
171 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
172 .enable_reg = ARM_IDLECT2,
173 .enable_bit = EN_WDTCK,
174 .recalc = &watchdog_recalc,
177 static struct clk arminth_ck1610 = {
178 .name = "arminth_ck",
180 .flags = CLOCK_IN_OMAP16XX,
181 .recalc = &followparent_recalc,
182 /* Note: On 1610/1710 frequency can be divided by 2 by programming
183 * ARM_CKCTL:ARM_INTHCK_SEL(14) to 1
185 * 1510 version is in TC clocks.
189 static struct clk dsp_ck = {
192 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
194 .enable_reg = ARM_CKCTL,
195 .enable_bit = EN_DSPCK,
196 .rate_offset = CKCTL_DSPDIV_OFFSET,
197 .recalc = &ckctl_recalc,
200 static struct clk dspmmu_ck = {
203 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
204 RATE_CKCTL | ALWAYS_ENABLED,
205 .rate_offset = CKCTL_DSPMMUDIV_OFFSET,
206 .recalc = &ckctl_recalc,
209 static struct clk tc_ck = {
212 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
213 RATE_CKCTL | RATE_PROPAGATES | ALWAYS_ENABLED,
214 .rate_offset = CKCTL_TCDIV_OFFSET,
215 .recalc = &ckctl_recalc,
218 static struct clk arminth_ck1510 = {
219 .name = "arminth_ck",
221 .flags = CLOCK_IN_OMAP1510,
222 .recalc = &followparent_recalc,
223 /* Note: On 1510 frequency follows TC_CK
225 * 1610/1710 version is in MPU clocks.
229 static struct clk tipb_ck = {
232 .flags = CLOCK_IN_OMAP1510,
233 .recalc = &followparent_recalc,
236 static struct clk l3_ocpi_ck = {
237 .name = "l3_ocpi_ck",
239 .flags = CLOCK_IN_OMAP16XX,
240 .enable_reg = ARM_IDLECT3,
241 .enable_bit = EN_OCPI_CK,
242 .recalc = &followparent_recalc,
245 static struct clk tc1_ck = {
248 .flags = CLOCK_IN_OMAP16XX,
249 .enable_reg = ARM_IDLECT3,
250 .enable_bit = EN_TC1_CK,
251 .recalc = &followparent_recalc,
254 static struct clk tc2_ck = {
257 .flags = CLOCK_IN_OMAP16XX,
258 .enable_reg = ARM_IDLECT3,
259 .enable_bit = EN_TC2_CK,
260 .recalc = &followparent_recalc,
263 static struct clk dma_ck = {
266 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
267 .recalc = &followparent_recalc,
270 static struct clk dma_lcdfree_ck = {
271 .name = "dma_lcdfree_ck",
273 .flags = CLOCK_IN_OMAP16XX,
274 .recalc = &followparent_recalc,
277 static struct clk api_ck = {
280 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX,
281 .enable_reg = ARM_IDLECT2,
282 .enable_bit = EN_APICK,
283 .recalc = &followparent_recalc,
286 static struct clk lb_ck = {
289 .flags = CLOCK_IN_OMAP1510,
290 .enable_reg = ARM_IDLECT2,
291 .enable_bit = EN_LBCK,
292 .recalc = &followparent_recalc,
295 static struct clk rhea1_ck = {
298 .flags = CLOCK_IN_OMAP16XX,
299 .recalc = &followparent_recalc,
302 static struct clk rhea2_ck = {
305 .flags = CLOCK_IN_OMAP16XX,
306 .recalc = &followparent_recalc,
309 static struct clk lcd_ck = {
312 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
314 .enable_reg = ARM_IDLECT2,
315 .enable_bit = EN_LCDCK,
316 .rate_offset = CKCTL_LCDDIV_OFFSET,
317 .recalc = &ckctl_recalc,
320 static struct clk uart1_ck = {
322 /* Direct from ULPD, no parent */
324 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
325 RATE_FIXED | ENABLE_REG_32BIT,
326 .enable_reg = MOD_CONF_CTRL_0,
329 * The "enable bit" actually chooses between 48MHz and 12MHz.
333 static struct clk uart2_ck = {
335 /* Direct from ULPD, no parent */
337 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
338 RATE_FIXED | ENABLE_REG_32BIT,
339 .enable_reg = MOD_CONF_CTRL_0,
342 * The "enable bit" actually chooses between 48MHz and 12MHz/32kHz.
346 static struct clk uart3_ck = {
348 /* Direct from ULPD, no parent */
350 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
351 RATE_FIXED | ENABLE_REG_32BIT,
352 .enable_reg = MOD_CONF_CTRL_0,
355 * The "enable bit" actually chooses between 48MHz and 12MHz.
359 static struct clk usb_ck1610 = {
361 /* Direct from ULPD, no parent */
363 .flags = CLOCK_IN_OMAP16XX |
364 RATE_FIXED | ENABLE_REG_32BIT,
365 .enable_reg = ULPD_CLOCK_CTRL,
366 .enable_bit = USB_MCLK_EN,
369 static struct clk usb_ck1510 = {
371 /* Direct from ULPD, no parent */
373 .flags = CLOCK_IN_OMAP1510 | RATE_FIXED,
376 static struct clk usb_hhc_ck = {
377 .name = "usb_hhc_ck",
378 /* Direct from ULPD, no parent */
379 .rate = 48000000, /* Actually 2 clocks, 12MHz and 48MHz */
380 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
381 RATE_FIXED | ENABLE_REG_32BIT,
382 .enable_reg = MOD_CONF_CTRL_0,
383 .enable_bit = USB_HOST_HHC_UHOST_EN,
387 static struct clk mclk = {
391 static struct clk bclk = {
396 static struct clk mmc1_ck = {
398 /* Functional clock is direct from ULPD, interface clock is ARMPER */
399 .parent = &armper_ck,
401 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
402 RATE_FIXED | ENABLE_REG_32BIT,
403 .enable_reg = MOD_CONF_CTRL_0,
407 static struct clk mmc2_ck = {
409 /* Functional clock is direct from ULPD, interface clock is ARMPER */
410 .parent = &armper_ck,
412 .flags = CLOCK_IN_OMAP16XX |
413 RATE_FIXED | ENABLE_REG_32BIT,
414 .enable_reg = MOD_CONF_CTRL_0,
418 static struct clk virtual_ck_mpu = {
420 .flags = CLOCK_IN_OMAP1510 | CLOCK_IN_OMAP16XX |
421 VIRTUAL_CLOCK | ALWAYS_ENABLED,
422 .parent = &arm_ck, /* Is smarter alias for */
423 .recalc = &followparent_recalc,
424 .set_rate = &select_table_rate,
425 .round_rate = &round_to_table_rate,
429 static struct clk * onchip_clks[] = {
430 /* non-ULPD clocks */
476 struct clk *clk_get(struct device *dev, const char *id)
478 struct clk *p, *clk = ERR_PTR(-ENOENT);
481 list_for_each_entry(p, &clocks, node) {
482 if (strcmp(id, p->name) == 0 && try_module_get(p->owner)) {
491 EXPORT_SYMBOL(clk_get);
494 void clk_put(struct clk *clk)
496 if (clk && !IS_ERR(clk))
497 module_put(clk->owner);
499 EXPORT_SYMBOL(clk_put);
502 int __clk_enable(struct clk *clk)
507 if (clk->flags & ALWAYS_ENABLED)
510 if (unlikely(clk->enable_reg == 0)) {
511 printk(KERN_ERR "clock.c: Enable for %s without enable code\n",
516 if (clk->flags & ENABLE_REG_32BIT) {
517 regval32 = omap_readl(clk->enable_reg);
518 regval32 |= (1 << clk->enable_bit);
519 omap_writel(regval32, clk->enable_reg);
521 regval16 = omap_readw(clk->enable_reg);
522 regval16 |= (1 << clk->enable_bit);
523 omap_writew(regval16, clk->enable_reg);
530 void __clk_disable(struct clk *clk)
535 if (clk->enable_reg == 0)
538 if (clk->flags & ENABLE_REG_32BIT) {
539 regval32 = omap_readl(clk->enable_reg);
540 regval32 &= ~(1 << clk->enable_bit);
541 omap_writel(regval32, clk->enable_reg);
543 regval16 = omap_readw(clk->enable_reg);
544 regval16 &= ~(1 << clk->enable_bit);
545 omap_writew(regval16, clk->enable_reg);
550 void __clk_unuse(struct clk *clk)
552 if (clk->usecount > 0 && !(--clk->usecount)) {
554 if (likely(clk->parent))
555 __clk_unuse(clk->parent);
560 int __clk_use(struct clk *clk)
563 if (clk->usecount++ == 0) {
564 if (likely(clk->parent))
565 ret = __clk_use(clk->parent);
567 if (unlikely(ret != 0)) {
572 ret = __clk_enable(clk);
574 if (unlikely(ret != 0) && clk->parent) {
575 __clk_unuse(clk->parent);
584 int clk_enable(struct clk *clk)
589 spin_lock_irqsave(&clockfw_lock, flags);
590 ret = __clk_enable(clk);
591 spin_unlock_irqrestore(&clockfw_lock, flags);
594 EXPORT_SYMBOL(clk_enable);
597 void clk_disable(struct clk *clk)
601 spin_lock_irqsave(&clockfw_lock, flags);
603 spin_unlock_irqrestore(&clockfw_lock, flags);
605 EXPORT_SYMBOL(clk_disable);
608 int clk_use(struct clk *clk)
613 spin_lock_irqsave(&clockfw_lock, flags);
614 ret = __clk_use(clk);
615 spin_unlock_irqrestore(&clockfw_lock, flags);
618 EXPORT_SYMBOL(clk_use);
621 void clk_unuse(struct clk *clk)
625 spin_lock_irqsave(&clockfw_lock, flags);
627 spin_unlock_irqrestore(&clockfw_lock, flags);
629 EXPORT_SYMBOL(clk_unuse);
632 unsigned long clk_get_rate(struct clk *clk)
636 EXPORT_SYMBOL(clk_get_rate);
639 static __u16 verify_ckctl_value(__u16 newval)
641 /* This function checks for following limitations set
642 * by the hardware (all conditions must be true):
643 * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
648 * In addition following rules are enforced:
652 * However, maximum frequencies are not checked for!
661 per_exp = (newval >> CKCTL_PERDIV_OFFSET) & 3;
662 lcd_exp = (newval >> CKCTL_LCDDIV_OFFSET) & 3;
663 arm_exp = (newval >> CKCTL_ARMDIV_OFFSET) & 3;
664 dsp_exp = (newval >> CKCTL_DSPDIV_OFFSET) & 3;
665 tc_exp = (newval >> CKCTL_TCDIV_OFFSET) & 3;
666 dspmmu_exp = (newval >> CKCTL_DSPMMUDIV_OFFSET) & 3;
668 if (dspmmu_exp < dsp_exp)
669 dspmmu_exp = dsp_exp;
670 if (dspmmu_exp > dsp_exp+1)
671 dspmmu_exp = dsp_exp+1;
672 if (tc_exp < arm_exp)
674 if (tc_exp < dspmmu_exp)
676 if (tc_exp > lcd_exp)
678 if (tc_exp > per_exp)
682 newval |= per_exp << CKCTL_PERDIV_OFFSET;
683 newval |= lcd_exp << CKCTL_LCDDIV_OFFSET;
684 newval |= arm_exp << CKCTL_ARMDIV_OFFSET;
685 newval |= dsp_exp << CKCTL_DSPDIV_OFFSET;
686 newval |= tc_exp << CKCTL_TCDIV_OFFSET;
687 newval |= dspmmu_exp << CKCTL_DSPMMUDIV_OFFSET;
693 static int calc_dsor_exp(struct clk *clk, unsigned long rate)
695 /* Note: If target frequency is too low, this function will return 4,
696 * which is invalid value. Caller must check for this value and act
699 * Note: This function does not check for following limitations set
700 * by the hardware (all conditions must be true):
701 * DSPMMU_CK == DSP_CK or DSPMMU_CK == DSP_CK/2
706 unsigned long realrate;
710 if (unlikely(!(clk->flags & RATE_CKCTL)))
713 parent = clk->parent;
714 if (unlikely(parent == 0))
717 realrate = parent->rate;
718 for (dsor_exp=0; dsor_exp<4; dsor_exp++) {
719 if (realrate <= rate)
728 long clk_round_rate(struct clk *clk, unsigned long rate)
732 if (clk->flags & RATE_FIXED)
735 if (clk->flags & RATE_CKCTL) {
736 dsor_exp = calc_dsor_exp(clk, rate);
741 return clk->parent->rate / (1 << dsor_exp);
744 if(clk->round_rate != 0)
745 return clk->round_rate(rate);
749 EXPORT_SYMBOL(clk_round_rate);
752 static void propagate_rate(struct clk * clk)
756 for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
757 if (likely((*clkp)->parent != clk)) continue;
758 if (likely((*clkp)->recalc))
759 (*clkp)->recalc(*clkp);
764 static int select_table_rate(unsigned long rate)
766 /* Find the highest supported frequency <= rate and switch to it */
767 struct mpu_rate * ptr;
769 for (ptr = rate_table; ptr->rate; ptr++) {
770 if (ptr->xtal != ck_ref.rate)
773 /* DPLL1 cannot be reprogrammed without risking system crash */
774 if (likely(ck_dpll1.rate!=0) && ptr->pll_rate != ck_dpll1.rate)
777 /* Can check only after xtal frequency check */
778 if (ptr->rate <= rate)
785 if (unlikely(ck_dpll1.rate == 0)) {
786 omap_writew(ptr->dpllctl_val, DPLL_CTL);
787 ck_dpll1.rate = ptr->pll_rate;
789 omap_writew(ptr->ckctl_val, ARM_CKCTL);
790 propagate_rate(&ck_dpll1);
795 static long round_to_table_rate(unsigned long rate)
797 /* Find the highest supported frequency <= rate */
798 struct mpu_rate * ptr;
801 highest_rate = -EINVAL;
803 for (ptr = rate_table; ptr->rate; ptr++) {
804 if (ptr->xtal != ck_ref.rate)
807 highest_rate = ptr->rate;
809 /* Can check only after xtal frequency check */
810 if (ptr->rate <= rate)
818 int clk_set_rate(struct clk *clk, unsigned long rate)
825 if (clk->flags & RATE_CKCTL) {
826 dsor_exp = calc_dsor_exp(clk, rate);
832 spin_lock_irqsave(&clockfw_lock, flags);
833 regval = omap_readw(ARM_CKCTL);
834 regval &= ~(3 << clk->rate_offset);
835 regval |= dsor_exp << clk->rate_offset;
836 regval = verify_ckctl_value(regval);
837 omap_writew(regval, ARM_CKCTL);
838 clk->rate = clk->parent->rate / (1 << dsor_exp);
839 spin_unlock_irqrestore(&clockfw_lock, flags);
841 } else if(clk->set_rate != 0) {
842 spin_lock_irqsave(&clockfw_lock, flags);
843 ret = clk->set_rate(rate);
844 spin_unlock_irqrestore(&clockfw_lock, flags);
847 if (unlikely(ret == 0 && (clk->flags & RATE_PROPAGATES)))
852 EXPORT_SYMBOL(clk_set_rate);
855 int clk_register(struct clk *clk)
858 list_add(&clk->node, &clocks);
862 EXPORT_SYMBOL(clk_register);
864 void clk_unregister(struct clk *clk)
867 list_del(&clk->node);
870 EXPORT_SYMBOL(clk_unregister);
874 int __init clk_init(void)
877 const struct omap_clock_config *info;
878 int crystal_type = 0; /* Default 12 MHz */
880 for (clkp = onchip_clks; clkp < onchip_clks+ARRAY_SIZE(onchip_clks); clkp++) {
881 if (((*clkp)->flags &CLOCK_IN_OMAP1510) && cpu_is_omap1510()) {
886 if (((*clkp)->flags &CLOCK_IN_OMAP16XX) && cpu_is_omap16xx()) {
892 info = omap_get_config(OMAP_TAG_CLOCK, struct omap_clock_config);
894 if (!cpu_is_omap1510())
895 crystal_type = info->system_clock_type;
898 #if defined(CONFIG_ARCH_OMAP730)
899 ck_ref.rate = 13000000;
900 #elif defined(CONFIG_ARCH_OMAP16XX)
901 if (crystal_type == 2)
902 ck_ref.rate = 19200000;
905 /* We want to be in syncronous scalable mode */
906 omap_writew(0x1000, ARM_SYSST);
908 /* Find the highest supported frequency and enable it */
909 if (select_table_rate(~0)) {
910 printk(KERN_ERR "System frequencies not set. Check your config.\n");
911 /* Guess sane values (60MHz) */
912 omap_writew(0x2290, DPLL_CTL);
913 omap_writew(0x1005, ARM_CKCTL);
914 ck_dpll1.rate = 60000000;
915 propagate_rate(&ck_dpll1);
916 printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): %ld/%ld/%ld\n",
917 ck_ref.rate, ck_dpll1.rate, arm_ck.rate);
920 /* Cache rates for clocks connected to ck_ref (not dpll1) */
921 propagate_rate(&ck_ref);
923 #ifdef CONFIG_MACH_OMAP_PERSEUS2
924 /* Select slicer output as OMAP input clock */
925 omap_writew(omap_readw(OMAP730_PCC_UPLD_CTRL) & ~0x1, OMAP730_PCC_UPLD_CTRL);
928 /* Turn off DSP and ARM_TIMXO. Make sure ARM_INTHCK is not divided */
929 omap_writew(omap_readw(ARM_CKCTL) & 0x0fff, ARM_CKCTL);
931 /* Put DSP/MPUI into reset until needed */
932 omap_writew(0, ARM_RSTCT1);
933 omap_writew(1, ARM_RSTCT2);
934 omap_writew(0x400, ARM_IDLECT1);
937 * According to OMAP5910 Erratum SYS_DMA_1, bit DMACK_REQ (bit 8)
938 * of the ARM_IDLECT2 register must be set to zero. The power-on
939 * default value of this bit is one.
941 omap_writew(0x0000, ARM_IDLECT2); /* Turn LCD clock off also */
944 * Only enable those clocks we will need, let the drivers
945 * enable other clocks as necessary
951 if (cpu_is_omap1510())
952 clk_enable(&arm_gpio_ck);