diff options
author | Paul Mackerras <paulus@samba.org> | 2008-01-30 19:25:51 -0500 |
---|---|---|
committer | Paul Mackerras <paulus@samba.org> | 2008-01-30 19:25:51 -0500 |
commit | bd45ac0c5daae35e7c71138172e63df5cf644cf6 (patch) | |
tree | 5eb5a599bf6a9d7a8a34e802db932aa9e9555de4 /arch/arm/mach-s3c2412/clock.c | |
parent | 4eece4ccf997c0e6d8fdad3d842e37b16b8d705f (diff) | |
parent | 5bdeae46be6dfe9efa44a548bd622af325f4bdb4 (diff) |
Merge branch 'linux-2.6'
Diffstat (limited to 'arch/arm/mach-s3c2412/clock.c')
-rw-r--r-- | arch/arm/mach-s3c2412/clock.c | 54 |
1 files changed, 53 insertions, 1 deletions
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c index 458993601897..2697a65ba727 100644 --- a/arch/arm/mach-s3c2412/clock.c +++ b/arch/arm/mach-s3c2412/clock.c | |||
@@ -217,7 +217,7 @@ static int s3c2412_setparent_msysclk(struct clk *clk, struct clk *parent) | |||
217 | 217 | ||
218 | if (parent == &clk_mdivclk) | 218 | if (parent == &clk_mdivclk) |
219 | clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL; | 219 | clksrc &= ~S3C2412_CLKSRC_MSYSCLK_MPLL; |
220 | else if (parent == &clk_upll) | 220 | else if (parent == &clk_mpll) |
221 | clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL; | 221 | clksrc |= S3C2412_CLKSRC_MSYSCLK_MPLL; |
222 | else | 222 | else |
223 | return -EINVAL; | 223 | return -EINVAL; |
@@ -234,6 +234,45 @@ static struct clk clk_msysclk = { | |||
234 | .set_parent = s3c2412_setparent_msysclk, | 234 | .set_parent = s3c2412_setparent_msysclk, |
235 | }; | 235 | }; |
236 | 236 | ||
237 | static int s3c2412_setparent_armclk(struct clk *clk, struct clk *parent) | ||
238 | { | ||
239 | unsigned long flags; | ||
240 | unsigned long clkdiv; | ||
241 | unsigned long dvs; | ||
242 | |||
243 | /* Note, we current equate fclk andf msysclk for S3C2412 */ | ||
244 | |||
245 | if (parent == &clk_msysclk || parent == &clk_f) | ||
246 | dvs = 0; | ||
247 | else if (parent == &clk_h) | ||
248 | dvs = S3C2412_CLKDIVN_DVSEN; | ||
249 | else | ||
250 | return -EINVAL; | ||
251 | |||
252 | clk->parent = parent; | ||
253 | |||
254 | /* update this under irq lockdown, clkdivn is not protected | ||
255 | * by the clock system. */ | ||
256 | |||
257 | local_irq_save(flags); | ||
258 | |||
259 | clkdiv = __raw_readl(S3C2410_CLKDIVN); | ||
260 | clkdiv &= ~S3C2412_CLKDIVN_DVSEN; | ||
261 | clkdiv |= dvs; | ||
262 | __raw_writel(clkdiv, S3C2410_CLKDIVN); | ||
263 | |||
264 | local_irq_restore(flags); | ||
265 | |||
266 | return 0; | ||
267 | } | ||
268 | |||
269 | static struct clk clk_armclk = { | ||
270 | .name = "armclk", | ||
271 | .id = -1, | ||
272 | .parent = &clk_msysclk, | ||
273 | .set_parent = s3c2412_setparent_armclk, | ||
274 | }; | ||
275 | |||
237 | /* these next clocks have an divider immediately after them, | 276 | /* these next clocks have an divider immediately after them, |
238 | * so we can register them with their divider and leave out the | 277 | * so we can register them with their divider and leave out the |
239 | * intermediate clock stage | 278 | * intermediate clock stage |
@@ -630,11 +669,13 @@ static struct clk *clks[] __initdata = { | |||
630 | &clk_erefclk, | 669 | &clk_erefclk, |
631 | &clk_urefclk, | 670 | &clk_urefclk, |
632 | &clk_mrefclk, | 671 | &clk_mrefclk, |
672 | &clk_armclk, | ||
633 | }; | 673 | }; |
634 | 674 | ||
635 | int __init s3c2412_baseclk_add(void) | 675 | int __init s3c2412_baseclk_add(void) |
636 | { | 676 | { |
637 | unsigned long clkcon = __raw_readl(S3C2410_CLKCON); | 677 | unsigned long clkcon = __raw_readl(S3C2410_CLKCON); |
678 | unsigned int dvs; | ||
638 | struct clk *clkp; | 679 | struct clk *clkp; |
639 | int ret; | 680 | int ret; |
640 | int ptr; | 681 | int ptr; |
@@ -643,6 +684,8 @@ int __init s3c2412_baseclk_add(void) | |||
643 | clk_usb_bus.parent = &clk_usbsrc; | 684 | clk_usb_bus.parent = &clk_usbsrc; |
644 | clk_usb_bus.rate = 0x0; | 685 | clk_usb_bus.rate = 0x0; |
645 | 686 | ||
687 | clk_f.parent = &clk_msysclk; | ||
688 | |||
646 | s3c2412_clk_initparents(); | 689 | s3c2412_clk_initparents(); |
647 | 690 | ||
648 | for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) { | 691 | for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) { |
@@ -655,6 +698,15 @@ int __init s3c2412_baseclk_add(void) | |||
655 | } | 698 | } |
656 | } | 699 | } |
657 | 700 | ||
701 | /* set the dvs state according to what we got at boot time */ | ||
702 | |||
703 | dvs = __raw_readl(S3C2410_CLKDIVN) & S3C2412_CLKDIVN_DVSEN; | ||
704 | |||
705 | if (dvs) | ||
706 | clk_armclk.parent = &clk_h; | ||
707 | |||
708 | printk(KERN_INFO "S3C2412: DVS is %s\n", dvs ? "on" : "off"); | ||
709 | |||
658 | /* ensure usb bus clock is within correct rate of 48MHz */ | 710 | /* ensure usb bus clock is within correct rate of 48MHz */ |
659 | 711 | ||
660 | if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) { | 712 | if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) { |