linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / arm / mach-omap2 / clock.c
index 72eb4bf..180f675 100644 (file)
 
 #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,13 +54,11 @@ static void omap2_sys_clk_recalc(struct clk * clk)
 
 static u32 omap2_get_dpll_rate(struct clk * tclk)
 {
-       long long dpll_clk;
-       int dpll_mult, dpll_div, amult;
+       int dpll_clk, 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 = (long long)tclk->parent->rate * dpll_mult;
-       do_div(dpll_clk, dpll_div + 1);
+       dpll_clk = (tclk->parent->rate * dpll_mult) / (dpll_div + 1);
        amult = CM_CLKSEL2_PLL & 0x3;
        dpll_clk *= amult;
 
@@ -387,23 +385,75 @@ 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,
-                                         slow_dll_ctrl, m_type);
+                                         mem_timings.slow_dll_ctrl,
+                                         mem_timings.m_type);
                curr_perf_level = PRCM_HALF_SPEED;
                local_irq_restore(flags);
        }
@@ -411,7 +461,8 @@ static u32 omap2_reprogram_sdrc(u32 level, u32 force)
                local_irq_save(flags);
                PRCM_VOLTSETUP = 0xffff;
                omap2_sram_reprogram_sdrc(PRCM_FULL_SPEED,
-                                         fast_dll_ctrl, m_type);
+                                         mem_timings.fast_dll_ctrl,
+                                         mem_timings.m_type);
                curr_perf_level = PRCM_FULL_SPEED;
                local_irq_restore(flags);
        }
@@ -599,7 +650,7 @@ static u32 omap2_get_clksel(u32 *div_sel, u32 *field_mask,
                case 13:                                /* dss2 */
                        mask = 0x1; break;
                case 25:                                /* usb */
-                       mask = 0x7; break;
+                       mask = 0xf; break;
                }
        }