summaryrefslogtreecommitdiff
path: root/arch/arm/mach-s3c2443
diff options
context:
space:
mode:
authorBen Dooks <ben-linux@fluff.org>2008-07-07 21:12:39 +0400
committerBen Dooks <ben-linux@fluff.org>2008-07-07 21:13:02 +0400
commitba7622a19fabb853b8bbb918a5d76557f88e4274 (patch)
treeb3cb710091eef5ea6a1d74a4cd49bfbc619568c5 /arch/arm/mach-s3c2443
parent29a7bcfd144a577b5cdb3b735c58e20d0489b30e (diff)
downloadlinux-ba7622a19fabb853b8bbb918a5d76557f88e4274.tar.xz
[ARM] S3C2443: Add armdiv and arm clocks
Add the armdiv and arm clocks to the S3C2443 clock framework and ensure they are correctly setup. Signed-off-by: Ben Dooks <ben-linux@fluff.org>
Diffstat (limited to 'arch/arm/mach-s3c2443')
-rw-r--r--arch/arm/mach-s3c2443/clock.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
index 24da92417a16..d34f3d32eba5 100644
--- a/arch/arm/mach-s3c2443/clock.c
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -221,7 +221,6 @@ static struct clk clk_mdivclk = {
.get_rate = s3c2443_getrate_mdivclk,
};
-
static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent)
{
unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
@@ -249,6 +248,46 @@ static struct clk clk_msysclk = {
.set_parent = s3c2443_setparent_msysclk,
};
+/* armdiv
+ *
+ * this clock is sourced from msysclk and can have a number of
+ * divider values applied to it to then be fed into armclk.
+*/
+
+static struct clk clk_armdiv = {
+ .name = "armdiv",
+ .id = -1,
+ .parent = &clk_msysclk,
+};
+
+/* armclk
+ *
+ * this is the clock fed into the ARM core itself, either from
+ * armdiv or from hclk.
+ */
+
+static int s3c2443_setparent_armclk(struct clk *clk, struct clk *parent)
+{
+ unsigned long clkdiv0;
+
+ clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+
+ if (parent == &clk_armdiv)
+ clkdiv0 &= ~S3C2443_CLKDIV0_DVS;
+ else if (parent == &clk_h)
+ clkdiv0 |= S3C2443_CLKDIV0_DVS;
+ else
+ return -EINVAL;
+
+ __raw_writel(clkdiv0, S3C2443_CLKDIV0);
+ return 0;
+}
+
+static struct clk clk_arm = {
+ .name = "armclk",
+ .id = -1,
+ .set_parent = s3c2443_setparent_armclk,
+};
/* esysclk
*
@@ -887,6 +926,15 @@ static void __init s3c2443_clk_initparents(void)
}
clk_init_set_parent(&clk_msysclk, parent);
+
+ /* arm */
+
+ if (__raw_readl(S3C2443_CLKDIV0) & S3C2443_CLKDIV0_DVS)
+ parent = &clk_h;
+ else
+ parent = &clk_armdiv;
+
+ clk_init_set_parent(&clk_arm, parent);
}
/* armdiv divisor table */
@@ -936,6 +984,8 @@ static struct clk *clks[] __initdata = {
&clk_hsspi,
&clk_hsmmc_div,
&clk_hsmmc,
+ &clk_armdiv,
+ &clk_arm,
};
void __init s3c2443_init_clocks(int xtal)
@@ -958,6 +1008,8 @@ void __init s3c2443_init_clocks(int xtal)
hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1);
pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
+ clk_armdiv.rate = fclk;
+
s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",