Merge branch 'upstream' of git://lost.foo-projects.org/~ahkok/git/netdev-2.6 into...
[pandora-kernel.git] / arch / arm / mach-omap2 / clock.c
index 5407b95..d1b648a 100644 (file)
@@ -15,7 +15,6 @@
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  */
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/device.h>
 
 #include <asm/arch/clock.h>
 #include <asm/arch/sram.h>
-#include <asm/arch/prcm.h>
 
+#include "prcm-regs.h"
+#include "memory.h"
 #include "clock.h"
 
 //#define DOWN_VARIABLE_DPLL 1                 /* Experimental */
 
 static struct prcm_config *curr_prcm_set;
-static struct memory_timings mem_timings;
 static u32 curr_perf_level = PRCM_FULL_SPEED;
 
 /*-------------------------------------------------------------------------
@@ -54,11 +53,13 @@ static void omap2_sys_clk_recalc(struct clk * clk)
 
 static u32 omap2_get_dpll_rate(struct clk * tclk)
 {
-       int dpll_clk, dpll_mult, dpll_div, amult;
+       long long dpll_clk;
+       int dpll_mult, dpll_div, amult;
 
        dpll_mult = (CM_CLKSEL1_PLL >> 12) & 0x03ff;    /* 10 bits */
        dpll_div = (CM_CLKSEL1_PLL >> 8) & 0x0f;        /* 4 bits */
-       dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1);
+       dpll_clk = (long long)tclk->parent->rate * dpll_mult;
+       do_div(dpll_clk, dpll_div + 1);
        amult = CM_CLKSEL2_PLL & 0x3;
        dpll_clk *= amult;
 
@@ -111,7 +112,7 @@ static void omap2_clk_fixed_enable(struct clk *clk)
 /* Enables clock without considering parent dependencies or use count
  * REVISIT: Maybe change this to use clk->enable like on omap1?
  */
-static int omap2_clk_enable(struct clk * clk)
+static int _omap2_clk_enable(struct clk * clk)
 {
        u32 regval32;
 
@@ -150,7 +151,7 @@ static void omap2_clk_fixed_disable(struct clk *clk)
 }
 
 /* Disables clock without considering parent dependencies or use count */
-static void omap2_clk_disable(struct clk *clk)
+static void _omap2_clk_disable(struct clk *clk)
 {
        u32 regval32;
 
@@ -167,23 +168,23 @@ static void omap2_clk_disable(struct clk *clk)
        __raw_writel(regval32, clk->enable_reg);
 }
 
-static int omap2_clk_use(struct clk *clk)
+static int omap2_clk_enable(struct clk *clk)
 {
        int ret = 0;
 
        if (clk->usecount++ == 0) {
                if (likely((u32)clk->parent))
-                       ret = omap2_clk_use(clk->parent);
+                       ret = omap2_clk_enable(clk->parent);
 
                if (unlikely(ret != 0)) {
                        clk->usecount--;
                        return ret;
                }
 
-               ret = omap2_clk_enable(clk);
+               ret = _omap2_clk_enable(clk);
 
                if (unlikely(ret != 0) && clk->parent) {
-                       omap2_clk_unuse(clk->parent);
+                       omap2_clk_disable(clk->parent);
                        clk->usecount--;
                }
        }
@@ -191,12 +192,12 @@ static int omap2_clk_use(struct clk *clk)
        return ret;
 }
 
-static void omap2_clk_unuse(struct clk *clk)
+static void omap2_clk_disable(struct clk *clk)
 {
        if (clk->usecount > 0 && !(--clk->usecount)) {
-               omap2_clk_disable(clk);
+               _omap2_clk_disable(clk);
                if (likely((u32)clk->parent))
-                       omap2_clk_unuse(clk->parent);
+                       omap2_clk_disable(clk->parent);
        }
 }
 
@@ -385,75 +386,23 @@ static u32 omap2_dll_force_needed(void)
                return 0;
 }
 
-static void omap2_init_memory_params(u32 force_lock_to_unlock_mode)
-{
-       unsigned long dll_cnt;
-       u32 fast_dll = 0;
-
-       mem_timings.m_type = !((SDRC_MR_0 & 0x3) == 0x1); /* DDR = 1, SDR = 0 */
-
-       /* 2422 es2.05 and beyond has a single SIP DDR instead of 2 like others.
-        * In the case of 2422, its ok to use CS1 instead of CS0.
-        */
-
-#if 0  /* FIXME: Enable after 24xx cpu detection works */
-       ctype = get_cpu_type();
-       if (cpu_is_omap2422())
-               mem_timings.base_cs = 1;
-       else
-#endif
-               mem_timings.base_cs = 0;
-
-       if (mem_timings.m_type != M_DDR)
-               return;
-
-       /* With DDR we need to determine the low frequency DLL value */
-       if (((mem_timings.fast_dll_ctrl & (1 << 2)) == M_LOCK_CTRL))
-               mem_timings.dll_mode = M_UNLOCK;
-       else
-               mem_timings.dll_mode = M_LOCK;
-
-       if (mem_timings.base_cs == 0) {
-               fast_dll = SDRC_DLLA_CTRL;
-               dll_cnt = SDRC_DLLA_STATUS & 0xff00;
-       } else {
-               fast_dll = SDRC_DLLB_CTRL;
-               dll_cnt = SDRC_DLLB_STATUS & 0xff00;
-       }
-       if (force_lock_to_unlock_mode) {
-               fast_dll &= ~0xff00;
-               fast_dll |= dll_cnt;            /* Current lock mode */
-       }
-       mem_timings.fast_dll_ctrl = fast_dll;
-
-       /* No disruptions, DDR will be offline & C-ABI not followed */
-       omap2_sram_ddr_init(&mem_timings.slow_dll_ctrl,
-                           mem_timings.fast_dll_ctrl,
-                           mem_timings.base_cs,
-                           force_lock_to_unlock_mode);
-       mem_timings.slow_dll_ctrl &= 0xff00;    /* Keep lock value */
-
-       /* Turn status into unlock ctrl */
-       mem_timings.slow_dll_ctrl |=
-               ((mem_timings.fast_dll_ctrl & 0xF) | (1 << 2));
-
-       /* 90 degree phase for anything below 133Mhz */
-       mem_timings.slow_dll_ctrl |= (1 << 1);
-}
-
 static u32 omap2_reprogram_sdrc(u32 level, u32 force)
 {
+       u32 slow_dll_ctrl, fast_dll_ctrl, m_type;
        u32 prev = curr_perf_level, flags;
 
        if ((curr_perf_level == level) && !force)
                return prev;
 
+       m_type = omap2_memory_get_type();
+       slow_dll_ctrl = omap2_memory_get_slow_dll_ctrl();
+       fast_dll_ctrl = omap2_memory_get_fast_dll_ctrl();
+
        if (level == PRCM_HALF_SPEED) {
                local_irq_save(flags);
                PRCM_VOLTSETUP = 0xffff;
                omap2_sram_reprogram_sdrc(PRCM_HALF_SPEED,
-                                         mem_timings.slow_dll_ctrl,
-                                         mem_timings.m_type);
+                                         slow_dll_ctrl, m_type);
                curr_perf_level = PRCM_HALF_SPEED;
                local_irq_restore(flags);
        }
@@ -461,8 +410,7 @@ static u32 omap2_reprogram_sdrc(u32 level, u32 force)
                local_irq_save(flags);
                PRCM_VOLTSETUP = 0xffff;
                omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED,
-                                         mem_timings.fast_dll_ctrl,
-                                         mem_timings.m_type);
+                                         fast_dll_ctrl, m_type);
                curr_perf_level = PRCM_FULL_SPEED;
                local_irq_restore(flags);
        }
@@ -650,7 +598,7 @@ static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask,
                case 13:                                /* dss2 */
                        mask = 0x1; break;
                case 25:                                /* usb */
-                       mask = 0xf; break;
+                       mask = 0x7; break;
                }
        }
 
@@ -711,26 +659,35 @@ static int omap2_clk_set_rate(struct clk *clk, unsigned long rate)
 
                /* Isolate control register */
                div_sel = (SRC_RATE_SEL_MASK & clk->flags);
-               div_off = clk->src_offset;
+               div_off = clk->rate_offset;
 
                validrate = omap2_clksel_round_rate(clk, rate, &new_div);
-               if(validrate != rate)
+               if (validrate != rate)
                        return(ret);
 
                field_val = omap2_get_clksel(&div_sel, &field_mask, clk);
                if (div_sel == 0)
                        return ret;
 
-               if(clk->flags & CM_SYSCLKOUT_SEL1){
-                       switch(new_div){
-                       case 16: field_val = 4; break;
-                       case 8:  field_val = 3; break;
-                       case 4:  field_val = 2; break;
-                       case 2:  field_val = 1; break;
-                       case 1:  field_val = 0; break;
+               if (clk->flags & CM_SYSCLKOUT_SEL1) {
+                       switch (new_div) {
+                       case 16:
+                               field_val = 4;
+                               break;
+                       case 8:
+                               field_val = 3;
+                               break;
+                       case 4:
+                               field_val = 2;
+                               break;
+                       case 2:
+                               field_val = 1;
+                               break;
+                       case 1:
+                               field_val = 0;
+                               break;
                        }
-               }
-               else
+               } else
                        field_val = new_div;
 
                reg = (void __iomem *)div_sel;
@@ -795,7 +752,7 @@ static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset,
                        val = 0x2;
                break;
        case CM_WKUP_SEL1:
-               src_reg_addr = (u32)&CM_CLKSEL2_CORE;
+               src_reg_addr = (u32)&CM_CLKSEL_WKUP;
                mask = 0x3;
                if (src_clk == &func_32k_ck)
                        val = 0x0;
@@ -835,9 +792,9 @@ static u32 omap2_get_src_field(u32 *type_to_addr, u32 reg_offset,
                        val = 0;
                if (src_clk == &sys_ck)
                        val = 1;
-               if (src_clk == &func_54m_ck)
-                       val = 2;
                if (src_clk == &func_96m_ck)
+                       val = 2;
+               if (src_clk == &func_54m_ck)
                        val = 3;
                break;
        }
@@ -873,7 +830,7 @@ static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
                reg = (void __iomem *)src_sel;
 
                if (clk->usecount > 0)
-                       omap2_clk_disable(clk);
+                       _omap2_clk_disable(clk);
 
                /* Set new source value (previous dividers if any in effect) */
                reg_val = __raw_readl(reg) & ~(field_mask << src_off);
@@ -884,7 +841,7 @@ static int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)
                        __raw_writel(0x1, (void __iomem *)&PRCM_CLKCFG_CTRL);
 
                if (clk->usecount > 0)
-                       omap2_clk_enable(clk);
+                       _omap2_clk_enable(clk);
 
                clk->parent = new_parent;
 
@@ -999,8 +956,6 @@ static int omap2_select_table_rate(struct clk * clk, unsigned long rate)
 static struct clk_functions omap2_clk_functions = {
        .clk_enable             = omap2_clk_enable,
        .clk_disable            = omap2_clk_disable,
-       .clk_use                = omap2_clk_use,
-       .clk_unuse              = omap2_clk_unuse,
        .clk_round_rate         = omap2_clk_round_rate,
        .clk_set_rate           = omap2_clk_set_rate,
        .clk_set_parent         = omap2_clk_set_parent,
@@ -1045,7 +1000,7 @@ static void __init omap2_disable_unused_clocks(void)
                        continue;
 
                printk(KERN_INFO "Disabling unused clock \"%s\"\n", ck->name);
-               omap2_clk_disable(ck);
+               _omap2_clk_disable(ck);
        }
 }
 late_initcall(omap2_disable_unused_clocks);
@@ -1120,10 +1075,10 @@ int __init omap2_clk_init(void)
         * Only enable those clocks we will need, let the drivers
         * enable other clocks as necessary
         */
-       clk_use(&sync_32k_ick);
-       clk_use(&omapctrl_ick);
+       clk_enable(&sync_32k_ick);
+       clk_enable(&omapctrl_ick);
        if (cpu_is_omap2430())
-               clk_use(&sdrc_ick);
+               clk_enable(&sdrc_ick);
 
        return 0;
 }