[ARM] S3C2443: Add prediv clk and fix setting of h and p clocks
authorBen Dooks <ben-linux@fluff.org>
Mon, 7 Jul 2008 17:12:40 +0000 (18:12 +0100)
committerBen Dooks <ben-linux@fluff.org>
Mon, 7 Jul 2008 17:13:02 +0000 (18:13 +0100)
Update the S3C2443 clock support to add the prediv clock
that is sourced via a divider from msysclk. Also fix the
setting of p and h clocks from this prediv clock.

Signed-off-by: Ben Dooks <ben-linux@fluff.org>
arch/arm/mach-s3c2443/clock.c

index d34f3d32eba57696d5e4515e2f17bfcd985adb39..17f064fabdaf72dd6f4c50964f5933e3fb8e6a1b 100644 (file)
@@ -678,6 +678,29 @@ static struct clk clk_display = {
        .round_rate     = s3c2443_roundrate_clksrc256,
 };
 
+/* prediv
+ *
+ * this divides the msysclk down to pass to h/p/etc.
+ */
+
+static unsigned long s3c2443_prediv_getrate(struct clk *clk)
+{
+       unsigned long rate = clk_get_rate(clk->parent);
+       unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
+
+       clkdiv0 &= S3C2443_CLKDIV0_PREDIV_MASK;
+       clkdiv0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
+
+       return rate / (clkdiv0 + 1);
+}
+
+static struct clk clk_prediv = {
+       .name           = "prediv",
+       .id             = -1,
+       .parent         = &clk_msysclk,
+       .get_rate       = s3c2443_prediv_getrate,
+};
+
 /* standard clock definitions */
 
 static struct clk init_clocks_disable[] = {
@@ -957,10 +980,9 @@ static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
        return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
 }
 
-static inline unsigned long s3c2443_get_prediv(unsigned long clkcon0)
+static inline unsigned long s3c2443_get_hdiv(unsigned long clkcon0)
 {
-       clkcon0 &= S3C2443_CLKDIV0_PREDIV_MASK;
-       clkcon0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
+       clkcon0 &= S3C2443_CLKDIV0_HCLKDIV_MASK;
 
        return clkcon0 + 1;
 }
@@ -986,6 +1008,7 @@ static struct clk *clks[] __initdata = {
        &clk_hsmmc,
        &clk_armdiv,
        &clk_arm,
+       &clk_prediv,
 };
 
 void __init s3c2443_init_clocks(int xtal)
@@ -1001,15 +1024,19 @@ void __init s3c2443_init_clocks(int xtal)
        int ret;
        int ptr;
 
+       /* s3c2443 parents h and p clocks from prediv */
+       clk_h.parent = &clk_prediv;
+       clk_p.parent = &clk_prediv;
+
        pll = s3c2443_get_mpll(mpllcon, xtal);
+       clk_msysclk.rate = pll;
 
        fclk = pll / s3c2443_fclk_div(clkdiv0);
-       hclk = fclk / s3c2443_get_prediv(clkdiv0);
+       hclk = s3c2443_prediv_getrate(&clk_prediv);
+       hclk = hclk / s3c2443_get_hdiv(clkdiv0);
        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",