]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/arm/mach-omap1/clock.c
OMAP clock: support "dry run" rate and parent changes
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap1 / clock.c
index ae2b304d3f29a89487c97c784cebdc019a7df9cf..f3cf6f8156b7162aa82e0b0f76bc3d4b0b8ac6c0 100644 (file)
@@ -34,27 +34,50 @@ __u32 arm_idlect1_mask;
  * Omap1 specific clock functions
  *-------------------------------------------------------------------------*/
 
-static void omap1_watchdog_recalc(struct clk * clk)
+static void omap1_watchdog_recalc(struct clk *clk, unsigned long parent_rate,
+                                 u8 rate_storage)
 {
-       clk->rate = clk->parent->rate / 14;
+       unsigned long new_rate;
+
+       new_rate = parent_rate / 14;
+
+       if (rate_storage == CURRENT_RATE)
+               clk->rate = new_rate;
+       else if (rate_storage == TEMP_RATE)
+               clk->temp_rate = new_rate;
 }
 
-static void omap1_uart_recalc(struct clk * clk)
+static void omap1_uart_recalc(struct clk *clk, unsigned long parent_rate,
+                             u8 rate_storage)
 {
+       unsigned long new_rate;
        unsigned int val = __raw_readl(clk->enable_reg);
+
        if (val & clk->enable_bit)
-               clk->rate = 48000000;
+               new_rate = 48000000;
        else
-               clk->rate = 12000000;
+               new_rate = 12000000;
+
+       if (rate_storage == CURRENT_RATE)
+               clk->rate = new_rate;
+       else if (rate_storage == TEMP_RATE)
+               clk->temp_rate = new_rate;
 }
 
-static void omap1_sossi_recalc(struct clk *clk)
+static void omap1_sossi_recalc(struct clk *clk, unsigned long parent_rate,
+                              u8 rate_storage)
 {
+       unsigned long new_rate;
        u32 div = omap_readl(MOD_CONF_CTRL_1);
 
        div = (div >> 17) & 0x7;
        div++;
-       clk->rate = clk->parent->rate / div;
+       new_rate = clk->parent->rate / div;
+
+       if (rate_storage == CURRENT_RATE)
+               clk->rate = new_rate;
+       else if (rate_storage == TEMP_RATE)
+               clk->temp_rate = new_rate;
 }
 
 static int omap1_clk_enable_dsp_domain(struct clk *clk)
@@ -215,21 +238,32 @@ static int calc_dsor_exp(struct clk *clk, unsigned long rate)
        return dsor_exp;
 }
 
-static void omap1_ckctl_recalc(struct clk * clk)
+static void omap1_ckctl_recalc(struct clk *clk, unsigned long parent_rate,
+                              u8 rate_storage)
 {
        int dsor;
+       unsigned long new_rate;
 
        /* Calculate divisor encoded as 2-bit exponent */
        dsor = 1 << (3 & (omap_readw(ARM_CKCTL) >> clk->rate_offset));
 
-       if (unlikely(clk->rate == clk->parent->rate / dsor))
+       new_rate = parent_rate / dsor;
+
+       if (unlikely(clk->rate == new_rate))
                return; /* No change, quick exit */
-       clk->rate = clk->parent->rate / dsor;
+
+       if (rate_storage == CURRENT_RATE)
+               clk->rate = new_rate;
+       else if (rate_storage == TEMP_RATE)
+               clk->temp_rate = new_rate;
 }
 
-static void omap1_ckctl_recalc_dsp_domain(struct clk * clk)
+static void omap1_ckctl_recalc_dsp_domain(struct clk *clk,
+                                         unsigned long parent_rate,
+                                         u8 rate_storage)
 {
        int dsor;
+       unsigned long new_rate;
 
        /* Calculate divisor encoded as 2-bit exponent
         *
@@ -242,9 +276,15 @@ static void omap1_ckctl_recalc_dsp_domain(struct clk * clk)
        dsor = 1 << (3 & (__raw_readw(DSP_CKCTL) >> clk->rate_offset));
        omap1_clk_disable(&api_ck.clk);
 
-       if (unlikely(clk->rate == clk->parent->rate / dsor))
+       new_rate = parent_rate / dsor;
+
+       if (unlikely(clk->rate == new_rate))
                return; /* No change, quick exit */
-       clk->rate = clk->parent->rate / dsor;
+
+       if (rate_storage == CURRENT_RATE)
+               clk->rate = new_rate;
+       else if (rate_storage == TEMP_RATE)
+               clk->temp_rate = new_rate;
 }
 
 /* MPU virtual clock functions */
@@ -283,7 +323,7 @@ static int omap1_select_table_rate(struct clk * clk, unsigned long rate)
                omap_sram_reprogram_clock(ptr->dpllctl_val, ptr->ckctl_val);
 
        ck_dpll1.rate = ptr->pll_rate;
-       propagate_rate(&ck_dpll1);
+       propagate_rate(&ck_dpll1, CURRENT_RATE);
        return 0;
 }
 
@@ -724,7 +764,7 @@ int __init omap1_clk_init(void)
                        }
                }
        }
-       propagate_rate(&ck_dpll1);
+       propagate_rate(&ck_dpll1, CURRENT_RATE);
 #else
        /* Find the highest supported frequency and enable it */
        if (omap1_select_table_rate(&virtual_ck_mpu, ~0)) {
@@ -733,11 +773,11 @@ int __init omap1_clk_init(void)
                omap_writew(0x2290, DPLL_CTL);
                omap_writew(cpu_is_omap730() ? 0x3005 : 0x1005, ARM_CKCTL);
                ck_dpll1.rate = 60000000;
-               propagate_rate(&ck_dpll1);
+               propagate_rate(&ck_dpll1, CURRENT_RATE);
        }
 #endif
        /* Cache rates for clocks connected to ck_ref (not dpll1) */
-       propagate_rate(&ck_ref);
+       propagate_rate(&ck_ref, CURRENT_RATE);
        printk(KERN_INFO "Clocking rate (xtal/DPLL1/MPU): "
                "%ld.%01ld/%ld.%01ld/%ld.%01ld MHz\n",
               ck_ref.rate / 1000000, (ck_ref.rate / 100000) % 10,