aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-s3c2412
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2008-01-28 07:01:18 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2008-01-28 08:20:50 -0500
commitbdbea34ddd2e52dc73f03e7ef7197d4c0da400d6 (patch)
tree655dbe87607c90150d11923b18bd0401c0793c87 /arch/arm/mach-s3c2412
parent57c1b0f8dbfffaa00a242b171429e56489caef15 (diff)
[ARM] 4778/1: S3C2412: Add armclk and init from DVS state
Add armclk to the S3C2412 to indicate the current clock connected to the ARM core. Signed-off-by: Ben Dooks <ben-linux@fluff.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-s3c2412')
-rw-r--r--arch/arm/mach-s3c2412/clock.c50
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
237static 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
269static 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
635int __init s3c2412_baseclk_add(void) 675int __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)) {