GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / linux / linux-2.6.36 / arch / arm / mach-omap2 / clkt2xxx_dpllcore.c
blob995208b836eacf3bafbba93203ecfe591e80f26e
2 #undef DEBUG
4 #include <linux/kernel.h>
5 #include <linux/errno.h>
6 #include <linux/clk.h>
7 #include <linux/io.h>
9 #include <plat/clock.h>
10 #include <plat/sram.h>
11 #include <plat/sdrc.h>
13 #include "clock.h"
14 #include "clock2xxx.h"
15 #include "opp2xxx.h"
16 #include "cm.h"
17 #include "cm-regbits-24xx.h"
19 /* #define DOWN_VARIABLE_DPLL 1 */ /* Experimental */
21 /**
22 * omap2xxx_clk_get_core_rate - return the CORE_CLK rate
23 * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck")
25 * Returns the CORE_CLK rate. CORE_CLK can have one of three rate
26 * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz
27 * (the latter is unusual). This currently should be called with
28 * struct clk *dpll_ck, which is a composite clock of dpll_ck and
29 * core_ck.
31 unsigned long omap2xxx_clk_get_core_rate(struct clk *clk)
33 long long core_clk;
34 u32 v;
36 core_clk = omap2_get_dpll_rate(clk);
38 v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
39 v &= OMAP24XX_CORE_CLK_SRC_MASK;
41 if (v == CORE_CLK_SRC_32K)
42 core_clk = 32768;
43 else
44 core_clk *= v;
46 return core_clk;
50 * Uses the current prcm set to tell if a rate is valid.
51 * You can go slower, but not faster within a given rate set.
53 static long omap2_dpllcore_round_rate(unsigned long target_rate)
55 u32 high, low, core_clk_src;
57 core_clk_src = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
58 core_clk_src &= OMAP24XX_CORE_CLK_SRC_MASK;
60 if (core_clk_src == CORE_CLK_SRC_DPLL) { /* DPLL clockout */
61 high = curr_prcm_set->dpll_speed * 2;
62 low = curr_prcm_set->dpll_speed;
63 } else { /* DPLL clockout x 2 */
64 high = curr_prcm_set->dpll_speed;
65 low = curr_prcm_set->dpll_speed / 2;
68 #ifdef DOWN_VARIABLE_DPLL
69 if (target_rate > high)
70 return high;
71 else
72 return target_rate;
73 #else
74 if (target_rate > low)
75 return high;
76 else
77 return low;
78 #endif
82 unsigned long omap2_dpllcore_recalc(struct clk *clk)
84 return omap2xxx_clk_get_core_rate(clk);
87 int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate)
89 u32 cur_rate, low, mult, div, valid_rate, done_rate;
90 u32 bypass = 0;
91 struct prcm_config tmpset;
92 const struct dpll_data *dd;
94 cur_rate = omap2xxx_clk_get_core_rate(dclk);
95 mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
96 mult &= OMAP24XX_CORE_CLK_SRC_MASK;
98 if ((rate == (cur_rate / 2)) && (mult == 2)) {
99 omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1);
100 } else if ((rate == (cur_rate * 2)) && (mult == 1)) {
101 omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
102 } else if (rate != cur_rate) {
103 valid_rate = omap2_dpllcore_round_rate(rate);
104 if (valid_rate != rate)
105 return -EINVAL;
107 if (mult == 1)
108 low = curr_prcm_set->dpll_speed;
109 else
110 low = curr_prcm_set->dpll_speed / 2;
112 dd = clk->dpll_data;
113 if (!dd)
114 return -EINVAL;
116 tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg);
117 tmpset.cm_clksel1_pll &= ~(dd->mult_mask |
118 dd->div1_mask);
119 div = ((curr_prcm_set->xtal_speed / 1000000) - 1);
120 tmpset.cm_clksel2_pll = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2);
121 tmpset.cm_clksel2_pll &= ~OMAP24XX_CORE_CLK_SRC_MASK;
122 if (rate > low) {
123 tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL_X2;
124 mult = ((rate / 2) / 1000000);
125 done_rate = CORE_CLK_SRC_DPLL_X2;
126 } else {
127 tmpset.cm_clksel2_pll |= CORE_CLK_SRC_DPLL;
128 mult = (rate / 1000000);
129 done_rate = CORE_CLK_SRC_DPLL;
131 tmpset.cm_clksel1_pll |= (div << __ffs(dd->mult_mask));
132 tmpset.cm_clksel1_pll |= (mult << __ffs(dd->div1_mask));
134 /* Worst case */
135 tmpset.base_sdrc_rfr = SDRC_RFR_CTRL_BYPASS;
137 if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */
138 bypass = 1;
140 /* For omap2xxx_sdrc_init_params() */
141 omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1);
143 /* Force dll lock mode */
144 omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr,
145 bypass);
147 /* Errata: ret dll entry state */
148 omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked());
149 omap2xxx_sdrc_reprogram(done_rate, 0);
152 return 0;