Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/sage/ceph...
[pandora-kernel.git] / arch / arm / mach-mxs / clock-mx28.c
index 5e489a2..5dcc59d 100644 (file)
@@ -295,11 +295,11 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)           \
        unsigned long diff, parent_rate, calc_rate;                     \
        int i;                                                          \
                                                                        \
-       parent_rate = clk_get_rate(clk->parent);                        \
        div_max = BM_CLKCTRL_##dr##_DIV >> BP_CLKCTRL_##dr##_DIV;       \
        bm_busy = BM_CLKCTRL_##dr##_BUSY;                               \
                                                                        \
        if (clk->parent == &ref_xtal_clk) {                             \
+               parent_rate = clk_get_rate(clk->parent);                \
                div = DIV_ROUND_UP(parent_rate, rate);                  \
                if (clk == &cpu_clk) {                                  \
                        div_max = BM_CLKCTRL_CPU_DIV_XTAL >>            \
@@ -309,6 +309,11 @@ static int name##_set_rate(struct clk *clk, unsigned long rate)            \
                if (div == 0 || div > div_max)                          \
                        return -EINVAL;                                 \
        } else {                                                        \
+               /*                                                      \
+                * hack alert: this block modifies clk->parent, too,    \
+                * so the base to use it the grand parent.              \
+                */                                                     \
+               parent_rate = clk_get_rate(clk->parent->parent);        \
                rate >>= PARENT_RATE_SHIFT;                             \
                parent_rate >>= PARENT_RATE_SHIFT;                      \
                diff = parent_rate;                                     \
@@ -618,6 +623,8 @@ static struct clk_lookup lookups[] = {
        _REGISTER_CLOCK("pll2", NULL, pll2_clk)
        _REGISTER_CLOCK("mxs-dma-apbh", NULL, hbus_clk)
        _REGISTER_CLOCK("mxs-dma-apbx", NULL, xbus_clk)
+       _REGISTER_CLOCK("mxs-mmc.0", NULL, ssp0_clk)
+       _REGISTER_CLOCK("mxs-mmc.1", NULL, ssp1_clk)
        _REGISTER_CLOCK("flexcan.0", NULL, can0_clk)
        _REGISTER_CLOCK("flexcan.1", NULL, can1_clk)
        _REGISTER_CLOCK(NULL, "usb0", usb0_clk)
@@ -737,6 +744,15 @@ static int clk_misc_init(void)
        reg |= BM_CLKCTRL_ENET_CLK_OUT_EN;
        __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_ENET);
 
+       /*
+        * 480 MHz seems too high to be ssp clock source directly,
+        * so set frac0 to get a 288 MHz ref_io0.
+        */
+       reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+       reg &= ~BM_CLKCTRL_FRAC0_IO0FRAC;
+       reg |= 30 << BP_CLKCTRL_FRAC0_IO0FRAC;
+       __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC0);
+
        return 0;
 }
 
@@ -744,6 +760,13 @@ int __init mx28_clocks_init(void)
 {
        clk_misc_init();
 
+       /*
+        * source ssp clock from ref_io0 than ref_xtal,
+        * as ref_xtal only provides 24 MHz as maximum.
+        */
+       clk_set_parent(&ssp0_clk, &ref_io0_clk);
+       clk_set_parent(&ssp1_clk, &ref_io0_clk);
+
        clk_enable(&cpu_clk);
        clk_enable(&hbus_clk);
        clk_enable(&xbus_clk);