diff options
| -rw-r--r-- | arch/arm/mach-s3c2412/clock.c | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/arch/arm/mach-s3c2412/clock.c b/arch/arm/mach-s3c2412/clock.c index 458993601897..42ccb5eb6042 100644 --- a/arch/arm/mach-s3c2412/clock.c +++ b/arch/arm/mach-s3c2412/clock.c | |||
| @@ -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; |
| @@ -655,6 +696,15 @@ int __init s3c2412_baseclk_add(void) | |||
| 655 | } | 696 | } |
| 656 | } | 697 | } |
| 657 | 698 | ||
| 699 | /* set the dvs state according to what we got at boot time */ | ||
| 700 | |||
| 701 | dvs = __raw_readl(S3C2410_CLKDIVN) & S3C2412_CLKDIVN_DVSEN; | ||
| 702 | |||
| 703 | if (dvs) | ||
| 704 | clk_armclk.parent = &clk_h; | ||
| 705 | |||
| 706 | printk(KERN_INFO "S3C2412: DVS is %s\n", dvs ? "on" : "off"); | ||
| 707 | |||
| 658 | /* ensure usb bus clock is within correct rate of 48MHz */ | 708 | /* ensure usb bus clock is within correct rate of 48MHz */ |
| 659 | 709 | ||
| 660 | if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) { | 710 | if (clk_get_rate(&clk_usb_bus) != (48 * 1000 * 1000)) { |
