]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/mach-s3c2443/clock.c
[ARM] S3C2443: Add armdiv and arm clocks
[linux-2.6-omap-h63xx.git] / arch / arm / mach-s3c2443 / clock.c
index dd2272fb1131c53e99b2ba75a85369ecafd7ffd8..d34f3d32eba57696d5e4515e2f17bfcd985adb39 100644 (file)
@@ -81,7 +81,7 @@ static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
        else
                clkcon &= ~clocks;
 
-       __raw_writel(clkcon, S3C2443_HCLKCON);
+       __raw_writel(clkcon, S3C2443_PCLKCON);
 
        return 0;
 }
@@ -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
  *
@@ -394,7 +433,7 @@ static int s3c2443_setrate_usbhost(struct clk *clk, unsigned long rate)
        return 0;
 }
 
-struct clk clk_usb_bus_host = {
+static struct clk clk_usb_bus_host = {
        .name           = "usb-bus-host-parent",
        .id             = -1,
        .parent         = &clk_esysclk,
@@ -746,6 +785,24 @@ static struct clk init_clocks[] = {
                .parent         = &clk_h,
                .enable         = s3c2443_clkcon_enable_h,
                .ctrlbit        = S3C2443_HCLKCON_USBD,
+       }, {
+               .name           = "hsmmc",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_HSMMC,
+       }, {
+               .name           = "cfc",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_CFC,
+       }, {
+               .name           = "ssmc",
+               .id             = -1,
+               .parent         = &clk_h,
+               .enable         = s3c2443_clkcon_enable_h,
+               .ctrlbit        = S3C2443_HCLKCON_SSMC,
        }, {
                .name           = "timers",
                .id             = -1,
@@ -791,6 +848,11 @@ static struct clk init_clocks[] = {
                .name           = "usb-bus-host",
                .id             = -1,
                .parent         = &clk_usb_bus_host,
+       }, {
+               .name           = "ac97",
+               .id             = -1,
+               .parent         = &clk_p,
+               .ctrlbit        = S3C2443_PCLKCON_AC97,
        }
 };
 
@@ -864,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 */
@@ -913,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)
@@ -935,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",
@@ -982,7 +1057,7 @@ void __init s3c2443_init_clocks(int xtal)
        }
 
        /* We must be careful disabling the clocks we are not intending to
-        * be using at boot time, as subsytems such as the LCD which do
+        * be using at boot time, as subsystems such as the LCD which do
         * their own DMA requests to the bus can cause the system to lockup
         * if they where in the middle of requesting bus access.
         *