diff options
Diffstat (limited to 'arch/arm/mach-omap2/clock24xx.c')
-rw-r--r-- | arch/arm/mach-omap2/clock24xx.c | 377 |
1 files changed, 306 insertions, 71 deletions
diff --git a/arch/arm/mach-omap2/clock24xx.c b/arch/arm/mach-omap2/clock24xx.c index d382eb0184ac..1e839c5a28c5 100644 --- a/arch/arm/mach-omap2/clock24xx.c +++ b/arch/arm/mach-omap2/clock24xx.c | |||
@@ -31,15 +31,192 @@ | |||
31 | #include <mach/clock.h> | 31 | #include <mach/clock.h> |
32 | #include <mach/sram.h> | 32 | #include <mach/sram.h> |
33 | #include <asm/div64.h> | 33 | #include <asm/div64.h> |
34 | #include <asm/clkdev.h> | ||
34 | 35 | ||
35 | #include "memory.h" | 36 | #include <mach/sdrc.h> |
36 | #include "clock.h" | 37 | #include "clock.h" |
37 | #include "clock24xx.h" | ||
38 | #include "prm.h" | 38 | #include "prm.h" |
39 | #include "prm-regbits-24xx.h" | 39 | #include "prm-regbits-24xx.h" |
40 | #include "cm.h" | 40 | #include "cm.h" |
41 | #include "cm-regbits-24xx.h" | 41 | #include "cm-regbits-24xx.h" |
42 | 42 | ||
43 | static const struct clkops clkops_oscck; | ||
44 | static const struct clkops clkops_fixed; | ||
45 | |||
46 | #include "clock24xx.h" | ||
47 | |||
48 | struct omap_clk { | ||
49 | u32 cpu; | ||
50 | struct clk_lookup lk; | ||
51 | }; | ||
52 | |||
53 | #define CLK(dev, con, ck, cp) \ | ||
54 | { \ | ||
55 | .cpu = cp, \ | ||
56 | .lk = { \ | ||
57 | .dev_id = dev, \ | ||
58 | .con_id = con, \ | ||
59 | .clk = ck, \ | ||
60 | }, \ | ||
61 | } | ||
62 | |||
63 | #define CK_243X (1 << 0) | ||
64 | #define CK_242X (1 << 1) | ||
65 | |||
66 | static struct omap_clk omap24xx_clks[] = { | ||
67 | /* external root sources */ | ||
68 | CLK(NULL, "func_32k_ck", &func_32k_ck, CK_243X | CK_242X), | ||
69 | CLK(NULL, "osc_ck", &osc_ck, CK_243X | CK_242X), | ||
70 | CLK(NULL, "sys_ck", &sys_ck, CK_243X | CK_242X), | ||
71 | CLK(NULL, "alt_ck", &alt_ck, CK_243X | CK_242X), | ||
72 | /* internal analog sources */ | ||
73 | CLK(NULL, "dpll_ck", &dpll_ck, CK_243X | CK_242X), | ||
74 | CLK(NULL, "apll96_ck", &apll96_ck, CK_243X | CK_242X), | ||
75 | CLK(NULL, "apll54_ck", &apll54_ck, CK_243X | CK_242X), | ||
76 | /* internal prcm root sources */ | ||
77 | CLK(NULL, "func_54m_ck", &func_54m_ck, CK_243X | CK_242X), | ||
78 | CLK(NULL, "core_ck", &core_ck, CK_243X | CK_242X), | ||
79 | CLK(NULL, "func_96m_ck", &func_96m_ck, CK_243X | CK_242X), | ||
80 | CLK(NULL, "func_48m_ck", &func_48m_ck, CK_243X | CK_242X), | ||
81 | CLK(NULL, "func_12m_ck", &func_12m_ck, CK_243X | CK_242X), | ||
82 | CLK(NULL, "ck_wdt1_osc", &wdt1_osc_ck, CK_243X | CK_242X), | ||
83 | CLK(NULL, "sys_clkout_src", &sys_clkout_src, CK_243X | CK_242X), | ||
84 | CLK(NULL, "sys_clkout", &sys_clkout, CK_243X | CK_242X), | ||
85 | CLK(NULL, "sys_clkout2_src", &sys_clkout2_src, CK_242X), | ||
86 | CLK(NULL, "sys_clkout2", &sys_clkout2, CK_242X), | ||
87 | CLK(NULL, "emul_ck", &emul_ck, CK_242X), | ||
88 | /* mpu domain clocks */ | ||
89 | CLK(NULL, "mpu_ck", &mpu_ck, CK_243X | CK_242X), | ||
90 | /* dsp domain clocks */ | ||
91 | CLK(NULL, "dsp_fck", &dsp_fck, CK_243X | CK_242X), | ||
92 | CLK(NULL, "dsp_irate_ick", &dsp_irate_ick, CK_243X | CK_242X), | ||
93 | CLK(NULL, "dsp_ick", &dsp_ick, CK_242X), | ||
94 | CLK(NULL, "iva2_1_ick", &iva2_1_ick, CK_243X), | ||
95 | CLK(NULL, "iva1_ifck", &iva1_ifck, CK_242X), | ||
96 | CLK(NULL, "iva1_mpu_int_ifck", &iva1_mpu_int_ifck, CK_242X), | ||
97 | /* GFX domain clocks */ | ||
98 | CLK(NULL, "gfx_3d_fck", &gfx_3d_fck, CK_243X | CK_242X), | ||
99 | CLK(NULL, "gfx_2d_fck", &gfx_2d_fck, CK_243X | CK_242X), | ||
100 | CLK(NULL, "gfx_ick", &gfx_ick, CK_243X | CK_242X), | ||
101 | /* Modem domain clocks */ | ||
102 | CLK(NULL, "mdm_ick", &mdm_ick, CK_243X), | ||
103 | CLK(NULL, "mdm_osc_ck", &mdm_osc_ck, CK_243X), | ||
104 | /* DSS domain clocks */ | ||
105 | CLK(NULL, "dss_ick", &dss_ick, CK_243X | CK_242X), | ||
106 | CLK(NULL, "dss1_fck", &dss1_fck, CK_243X | CK_242X), | ||
107 | CLK(NULL, "dss2_fck", &dss2_fck, CK_243X | CK_242X), | ||
108 | CLK(NULL, "dss_54m_fck", &dss_54m_fck, CK_243X | CK_242X), | ||
109 | /* L3 domain clocks */ | ||
110 | CLK(NULL, "core_l3_ck", &core_l3_ck, CK_243X | CK_242X), | ||
111 | CLK(NULL, "ssi_fck", &ssi_ssr_sst_fck, CK_243X | CK_242X), | ||
112 | CLK(NULL, "usb_l4_ick", &usb_l4_ick, CK_243X | CK_242X), | ||
113 | /* L4 domain clocks */ | ||
114 | CLK(NULL, "l4_ck", &l4_ck, CK_243X | CK_242X), | ||
115 | CLK(NULL, "ssi_l4_ick", &ssi_l4_ick, CK_243X | CK_242X), | ||
116 | /* virtual meta-group clock */ | ||
117 | CLK(NULL, "virt_prcm_set", &virt_prcm_set, CK_243X | CK_242X), | ||
118 | /* general l4 interface ck, multi-parent functional clk */ | ||
119 | CLK(NULL, "gpt1_ick", &gpt1_ick, CK_243X | CK_242X), | ||
120 | CLK(NULL, "gpt1_fck", &gpt1_fck, CK_243X | CK_242X), | ||
121 | CLK(NULL, "gpt2_ick", &gpt2_ick, CK_243X | CK_242X), | ||
122 | CLK(NULL, "gpt2_fck", &gpt2_fck, CK_243X | CK_242X), | ||
123 | CLK(NULL, "gpt3_ick", &gpt3_ick, CK_243X | CK_242X), | ||
124 | CLK(NULL, "gpt3_fck", &gpt3_fck, CK_243X | CK_242X), | ||
125 | CLK(NULL, "gpt4_ick", &gpt4_ick, CK_243X | CK_242X), | ||
126 | CLK(NULL, "gpt4_fck", &gpt4_fck, CK_243X | CK_242X), | ||
127 | CLK(NULL, "gpt5_ick", &gpt5_ick, CK_243X | CK_242X), | ||
128 | CLK(NULL, "gpt5_fck", &gpt5_fck, CK_243X | CK_242X), | ||
129 | CLK(NULL, "gpt6_ick", &gpt6_ick, CK_243X | CK_242X), | ||
130 | CLK(NULL, "gpt6_fck", &gpt6_fck, CK_243X | CK_242X), | ||
131 | CLK(NULL, "gpt7_ick", &gpt7_ick, CK_243X | CK_242X), | ||
132 | CLK(NULL, "gpt7_fck", &gpt7_fck, CK_243X | CK_242X), | ||
133 | CLK(NULL, "gpt8_ick", &gpt8_ick, CK_243X | CK_242X), | ||
134 | CLK(NULL, "gpt8_fck", &gpt8_fck, CK_243X | CK_242X), | ||
135 | CLK(NULL, "gpt9_ick", &gpt9_ick, CK_243X | CK_242X), | ||
136 | CLK(NULL, "gpt9_fck", &gpt9_fck, CK_243X | CK_242X), | ||
137 | CLK(NULL, "gpt10_ick", &gpt10_ick, CK_243X | CK_242X), | ||
138 | CLK(NULL, "gpt10_fck", &gpt10_fck, CK_243X | CK_242X), | ||
139 | CLK(NULL, "gpt11_ick", &gpt11_ick, CK_243X | CK_242X), | ||
140 | CLK(NULL, "gpt11_fck", &gpt11_fck, CK_243X | CK_242X), | ||
141 | CLK(NULL, "gpt12_ick", &gpt12_ick, CK_243X | CK_242X), | ||
142 | CLK(NULL, "gpt12_fck", &gpt12_fck, CK_243X | CK_242X), | ||
143 | CLK("omap-mcbsp.1", "ick", &mcbsp1_ick, CK_243X | CK_242X), | ||
144 | CLK("omap-mcbsp.1", "fck", &mcbsp1_fck, CK_243X | CK_242X), | ||
145 | CLK("omap-mcbsp.2", "ick", &mcbsp2_ick, CK_243X | CK_242X), | ||
146 | CLK("omap-mcbsp.2", "fck", &mcbsp2_fck, CK_243X | CK_242X), | ||
147 | CLK("omap-mcbsp.3", "ick", &mcbsp3_ick, CK_243X), | ||
148 | CLK("omap-mcbsp.3", "fck", &mcbsp3_fck, CK_243X), | ||
149 | CLK("omap-mcbsp.4", "ick", &mcbsp4_ick, CK_243X), | ||
150 | CLK("omap-mcbsp.4", "fck", &mcbsp4_fck, CK_243X), | ||
151 | CLK("omap-mcbsp.5", "ick", &mcbsp5_ick, CK_243X), | ||
152 | CLK("omap-mcbsp.5", "fck", &mcbsp5_fck, CK_243X), | ||
153 | CLK("omap2_mcspi.1", "ick", &mcspi1_ick, CK_243X | CK_242X), | ||
154 | CLK("omap2_mcspi.1", "fck", &mcspi1_fck, CK_243X | CK_242X), | ||
155 | CLK("omap2_mcspi.2", "ick", &mcspi2_ick, CK_243X | CK_242X), | ||
156 | CLK("omap2_mcspi.2", "fck", &mcspi2_fck, CK_243X | CK_242X), | ||
157 | CLK("omap2_mcspi.3", "ick", &mcspi3_ick, CK_243X), | ||
158 | CLK("omap2_mcspi.3", "fck", &mcspi3_fck, CK_243X), | ||
159 | CLK(NULL, "uart1_ick", &uart1_ick, CK_243X | CK_242X), | ||
160 | CLK(NULL, "uart1_fck", &uart1_fck, CK_243X | CK_242X), | ||
161 | CLK(NULL, "uart2_ick", &uart2_ick, CK_243X | CK_242X), | ||
162 | CLK(NULL, "uart2_fck", &uart2_fck, CK_243X | CK_242X), | ||
163 | CLK(NULL, "uart3_ick", &uart3_ick, CK_243X | CK_242X), | ||
164 | CLK(NULL, "uart3_fck", &uart3_fck, CK_243X | CK_242X), | ||
165 | CLK(NULL, "gpios_ick", &gpios_ick, CK_243X | CK_242X), | ||
166 | CLK(NULL, "gpios_fck", &gpios_fck, CK_243X | CK_242X), | ||
167 | CLK("omap_wdt", "ick", &mpu_wdt_ick, CK_243X | CK_242X), | ||
168 | CLK("omap_wdt", "fck", &mpu_wdt_fck, CK_243X | CK_242X), | ||
169 | CLK(NULL, "sync_32k_ick", &sync_32k_ick, CK_243X | CK_242X), | ||
170 | CLK(NULL, "wdt1_ick", &wdt1_ick, CK_243X | CK_242X), | ||
171 | CLK(NULL, "omapctrl_ick", &omapctrl_ick, CK_243X | CK_242X), | ||
172 | CLK(NULL, "icr_ick", &icr_ick, CK_243X), | ||
173 | CLK("omap24xxcam", "fck", &cam_fck, CK_243X | CK_242X), | ||
174 | CLK("omap24xxcam", "ick", &cam_ick, CK_243X | CK_242X), | ||
175 | CLK(NULL, "mailboxes_ick", &mailboxes_ick, CK_243X | CK_242X), | ||
176 | CLK(NULL, "wdt4_ick", &wdt4_ick, CK_243X | CK_242X), | ||
177 | CLK(NULL, "wdt4_fck", &wdt4_fck, CK_243X | CK_242X), | ||
178 | CLK(NULL, "wdt3_ick", &wdt3_ick, CK_242X), | ||
179 | CLK(NULL, "wdt3_fck", &wdt3_fck, CK_242X), | ||
180 | CLK(NULL, "mspro_ick", &mspro_ick, CK_243X | CK_242X), | ||
181 | CLK(NULL, "mspro_fck", &mspro_fck, CK_243X | CK_242X), | ||
182 | CLK("mmci-omap.0", "ick", &mmc_ick, CK_242X), | ||
183 | CLK("mmci-omap.0", "fck", &mmc_fck, CK_242X), | ||
184 | CLK(NULL, "fac_ick", &fac_ick, CK_243X | CK_242X), | ||
185 | CLK(NULL, "fac_fck", &fac_fck, CK_243X | CK_242X), | ||
186 | CLK(NULL, "eac_ick", &eac_ick, CK_242X), | ||
187 | CLK(NULL, "eac_fck", &eac_fck, CK_242X), | ||
188 | CLK("omap_hdq.0", "ick", &hdq_ick, CK_243X | CK_242X), | ||
189 | CLK("omap_hdq.1", "fck", &hdq_fck, CK_243X | CK_242X), | ||
190 | CLK("i2c_omap.1", "ick", &i2c1_ick, CK_243X | CK_242X), | ||
191 | CLK("i2c_omap.1", "fck", &i2c1_fck, CK_242X), | ||
192 | CLK("i2c_omap.1", "fck", &i2chs1_fck, CK_243X), | ||
193 | CLK("i2c_omap.2", "ick", &i2c2_ick, CK_243X | CK_242X), | ||
194 | CLK("i2c_omap.2", "fck", &i2c2_fck, CK_242X), | ||
195 | CLK("i2c_omap.2", "fck", &i2chs2_fck, CK_243X), | ||
196 | CLK(NULL, "gpmc_fck", &gpmc_fck, CK_243X | CK_242X), | ||
197 | CLK(NULL, "sdma_fck", &sdma_fck, CK_243X | CK_242X), | ||
198 | CLK(NULL, "sdma_ick", &sdma_ick, CK_243X | CK_242X), | ||
199 | CLK(NULL, "vlynq_ick", &vlynq_ick, CK_242X), | ||
200 | CLK(NULL, "vlynq_fck", &vlynq_fck, CK_242X), | ||
201 | CLK(NULL, "sdrc_ick", &sdrc_ick, CK_243X), | ||
202 | CLK(NULL, "des_ick", &des_ick, CK_243X | CK_242X), | ||
203 | CLK(NULL, "sha_ick", &sha_ick, CK_243X | CK_242X), | ||
204 | CLK("omap_rng", "ick", &rng_ick, CK_243X | CK_242X), | ||
205 | CLK(NULL, "aes_ick", &aes_ick, CK_243X | CK_242X), | ||
206 | CLK(NULL, "pka_ick", &pka_ick, CK_243X | CK_242X), | ||
207 | CLK(NULL, "usb_fck", &usb_fck, CK_243X | CK_242X), | ||
208 | CLK(NULL, "usbhs_ick", &usbhs_ick, CK_243X), | ||
209 | CLK("mmci-omap-hs.0", "ick", &mmchs1_ick, CK_243X), | ||
210 | CLK("mmci-omap-hs.0", "fck", &mmchs1_fck, CK_243X), | ||
211 | CLK("mmci-omap-hs.1", "ick", &mmchs2_ick, CK_243X), | ||
212 | CLK("mmci-omap-hs.1", "fck", &mmchs2_fck, CK_243X), | ||
213 | CLK(NULL, "gpio5_ick", &gpio5_ick, CK_243X), | ||
214 | CLK(NULL, "gpio5_fck", &gpio5_fck, CK_243X), | ||
215 | CLK(NULL, "mdm_intc_ick", &mdm_intc_ick, CK_243X), | ||
216 | CLK("mmci-omap-hs.0", "mmchsdb_fck", &mmchsdb1_fck, CK_243X), | ||
217 | CLK("mmci-omap-hs.1", "mmchsdb_fck", &mmchsdb2_fck, CK_243X), | ||
218 | }; | ||
219 | |||
43 | /* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */ | 220 | /* CM_CLKEN_PLL.EN_{54,96}M_PLL options (24XX) */ |
44 | #define EN_APLL_STOPPED 0 | 221 | #define EN_APLL_STOPPED 0 |
45 | #define EN_APLL_LOCKED 3 | 222 | #define EN_APLL_LOCKED 3 |
@@ -59,19 +236,32 @@ static struct clk *sclk; | |||
59 | * Omap24xx specific clock functions | 236 | * Omap24xx specific clock functions |
60 | *-------------------------------------------------------------------------*/ | 237 | *-------------------------------------------------------------------------*/ |
61 | 238 | ||
62 | /* This actually returns the rate of core_ck, not dpll_ck. */ | 239 | /** |
63 | static u32 omap2_get_dpll_rate_24xx(struct clk *tclk) | 240 | * omap2xxx_clk_get_core_rate - return the CORE_CLK rate |
241 | * @clk: pointer to the combined dpll_ck + core_ck (currently "dpll_ck") | ||
242 | * | ||
243 | * Returns the CORE_CLK rate. CORE_CLK can have one of three rate | ||
244 | * sources on OMAP2xxx: the DPLL CLKOUT rate, DPLL CLKOUTX2, or 32KHz | ||
245 | * (the latter is unusual). This currently should be called with | ||
246 | * struct clk *dpll_ck, which is a composite clock of dpll_ck and | ||
247 | * core_ck. | ||
248 | */ | ||
249 | static unsigned long omap2xxx_clk_get_core_rate(struct clk *clk) | ||
64 | { | 250 | { |
65 | long long dpll_clk; | 251 | long long core_clk; |
66 | u8 amult; | 252 | u32 v; |
253 | |||
254 | core_clk = omap2_get_dpll_rate(clk); | ||
67 | 255 | ||
68 | dpll_clk = omap2_get_dpll_rate(tclk); | 256 | v = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); |
257 | v &= OMAP24XX_CORE_CLK_SRC_MASK; | ||
69 | 258 | ||
70 | amult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); | 259 | if (v == CORE_CLK_SRC_32K) |
71 | amult &= OMAP24XX_CORE_CLK_SRC_MASK; | 260 | core_clk = 32768; |
72 | dpll_clk *= amult; | 261 | else |
262 | core_clk *= v; | ||
73 | 263 | ||
74 | return dpll_clk; | 264 | return core_clk; |
75 | } | 265 | } |
76 | 266 | ||
77 | static int omap2_enable_osc_ck(struct clk *clk) | 267 | static int omap2_enable_osc_ck(struct clk *clk) |
@@ -96,6 +286,11 @@ static void omap2_disable_osc_ck(struct clk *clk) | |||
96 | OMAP24XX_PRCM_CLKSRC_CTRL); | 286 | OMAP24XX_PRCM_CLKSRC_CTRL); |
97 | } | 287 | } |
98 | 288 | ||
289 | static const struct clkops clkops_oscck = { | ||
290 | .enable = &omap2_enable_osc_ck, | ||
291 | .disable = &omap2_disable_osc_ck, | ||
292 | }; | ||
293 | |||
99 | #ifdef OLD_CK | 294 | #ifdef OLD_CK |
100 | /* Recalculate SYST_CLK */ | 295 | /* Recalculate SYST_CLK */ |
101 | static void omap2_sys_clk_recalc(struct clk * clk) | 296 | static void omap2_sys_clk_recalc(struct clk * clk) |
@@ -149,11 +344,16 @@ static void omap2_clk_fixed_disable(struct clk *clk) | |||
149 | cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN); | 344 | cm_write_mod_reg(cval, PLL_MOD, CM_CLKEN); |
150 | } | 345 | } |
151 | 346 | ||
347 | static const struct clkops clkops_fixed = { | ||
348 | .enable = &omap2_clk_fixed_enable, | ||
349 | .disable = &omap2_clk_fixed_disable, | ||
350 | }; | ||
351 | |||
152 | /* | 352 | /* |
153 | * Uses the current prcm set to tell if a rate is valid. | 353 | * Uses the current prcm set to tell if a rate is valid. |
154 | * You can go slower, but not faster within a given rate set. | 354 | * You can go slower, but not faster within a given rate set. |
155 | */ | 355 | */ |
156 | long omap2_dpllcore_round_rate(unsigned long target_rate) | 356 | static long omap2_dpllcore_round_rate(unsigned long target_rate) |
157 | { | 357 | { |
158 | u32 high, low, core_clk_src; | 358 | u32 high, low, core_clk_src; |
159 | 359 | ||
@@ -182,11 +382,9 @@ long omap2_dpllcore_round_rate(unsigned long target_rate) | |||
182 | 382 | ||
183 | } | 383 | } |
184 | 384 | ||
185 | static void omap2_dpllcore_recalc(struct clk *clk) | 385 | static unsigned long omap2_dpllcore_recalc(struct clk *clk) |
186 | { | 386 | { |
187 | clk->rate = omap2_get_dpll_rate_24xx(clk); | 387 | return omap2xxx_clk_get_core_rate(clk); |
188 | |||
189 | propagate_rate(clk); | ||
190 | } | 388 | } |
191 | 389 | ||
192 | static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) | 390 | static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) |
@@ -195,22 +393,19 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) | |||
195 | u32 bypass = 0; | 393 | u32 bypass = 0; |
196 | struct prcm_config tmpset; | 394 | struct prcm_config tmpset; |
197 | const struct dpll_data *dd; | 395 | const struct dpll_data *dd; |
198 | unsigned long flags; | ||
199 | int ret = -EINVAL; | ||
200 | 396 | ||
201 | local_irq_save(flags); | 397 | cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck); |
202 | cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck); | ||
203 | mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); | 398 | mult = cm_read_mod_reg(PLL_MOD, CM_CLKSEL2); |
204 | mult &= OMAP24XX_CORE_CLK_SRC_MASK; | 399 | mult &= OMAP24XX_CORE_CLK_SRC_MASK; |
205 | 400 | ||
206 | if ((rate == (cur_rate / 2)) && (mult == 2)) { | 401 | if ((rate == (cur_rate / 2)) && (mult == 2)) { |
207 | omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL, 1); | 402 | omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1); |
208 | } else if ((rate == (cur_rate * 2)) && (mult == 1)) { | 403 | } else if ((rate == (cur_rate * 2)) && (mult == 1)) { |
209 | omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); | 404 | omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1); |
210 | } else if (rate != cur_rate) { | 405 | } else if (rate != cur_rate) { |
211 | valid_rate = omap2_dpllcore_round_rate(rate); | 406 | valid_rate = omap2_dpllcore_round_rate(rate); |
212 | if (valid_rate != rate) | 407 | if (valid_rate != rate) |
213 | goto dpll_exit; | 408 | return -EINVAL; |
214 | 409 | ||
215 | if (mult == 1) | 410 | if (mult == 1) |
216 | low = curr_prcm_set->dpll_speed; | 411 | low = curr_prcm_set->dpll_speed; |
@@ -219,7 +414,7 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) | |||
219 | 414 | ||
220 | dd = clk->dpll_data; | 415 | dd = clk->dpll_data; |
221 | if (!dd) | 416 | if (!dd) |
222 | goto dpll_exit; | 417 | return -EINVAL; |
223 | 418 | ||
224 | tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg); | 419 | tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg); |
225 | tmpset.cm_clksel1_pll &= ~(dd->mult_mask | | 420 | tmpset.cm_clksel1_pll &= ~(dd->mult_mask | |
@@ -245,22 +440,19 @@ static int omap2_reprogram_dpllcore(struct clk *clk, unsigned long rate) | |||
245 | if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */ | 440 | if (rate == curr_prcm_set->xtal_speed) /* If asking for 1-1 */ |
246 | bypass = 1; | 441 | bypass = 1; |
247 | 442 | ||
248 | omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); /* For init_mem */ | 443 | /* For omap2xxx_sdrc_init_params() */ |
444 | omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1); | ||
249 | 445 | ||
250 | /* Force dll lock mode */ | 446 | /* Force dll lock mode */ |
251 | omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr, | 447 | omap2_set_prcm(tmpset.cm_clksel1_pll, tmpset.base_sdrc_rfr, |
252 | bypass); | 448 | bypass); |
253 | 449 | ||
254 | /* Errata: ret dll entry state */ | 450 | /* Errata: ret dll entry state */ |
255 | omap2_init_memory_params(omap2_dll_force_needed()); | 451 | omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked()); |
256 | omap2_reprogram_sdrc(done_rate, 0); | 452 | omap2xxx_sdrc_reprogram(done_rate, 0); |
257 | } | 453 | } |
258 | omap2_dpllcore_recalc(&dpll_ck); | ||
259 | ret = 0; | ||
260 | 454 | ||
261 | dpll_exit: | 455 | return 0; |
262 | local_irq_restore(flags); | ||
263 | return(ret); | ||
264 | } | 456 | } |
265 | 457 | ||
266 | /** | 458 | /** |
@@ -269,9 +461,9 @@ dpll_exit: | |||
269 | * | 461 | * |
270 | * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set. | 462 | * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set. |
271 | */ | 463 | */ |
272 | static void omap2_table_mpu_recalc(struct clk *clk) | 464 | static unsigned long omap2_table_mpu_recalc(struct clk *clk) |
273 | { | 465 | { |
274 | clk->rate = curr_prcm_set->mpu_speed; | 466 | return curr_prcm_set->mpu_speed; |
275 | } | 467 | } |
276 | 468 | ||
277 | /* | 469 | /* |
@@ -337,12 +529,12 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate) | |||
337 | } | 529 | } |
338 | 530 | ||
339 | curr_prcm_set = prcm; | 531 | curr_prcm_set = prcm; |
340 | cur_rate = omap2_get_dpll_rate_24xx(&dpll_ck); | 532 | cur_rate = omap2xxx_clk_get_core_rate(&dpll_ck); |
341 | 533 | ||
342 | if (prcm->dpll_speed == cur_rate / 2) { | 534 | if (prcm->dpll_speed == cur_rate / 2) { |
343 | omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL, 1); | 535 | omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL, 1); |
344 | } else if (prcm->dpll_speed == cur_rate * 2) { | 536 | } else if (prcm->dpll_speed == cur_rate * 2) { |
345 | omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); | 537 | omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1); |
346 | } else if (prcm->dpll_speed != cur_rate) { | 538 | } else if (prcm->dpll_speed != cur_rate) { |
347 | local_irq_save(flags); | 539 | local_irq_save(flags); |
348 | 540 | ||
@@ -366,27 +558,67 @@ static int omap2_select_table_rate(struct clk *clk, unsigned long rate) | |||
366 | 558 | ||
367 | /* Major subsystem dividers */ | 559 | /* Major subsystem dividers */ |
368 | tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK; | 560 | tmp = cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & OMAP24XX_CLKSEL_DSS2_MASK; |
369 | cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD, CM_CLKSEL1); | 561 | cm_write_mod_reg(prcm->cm_clksel1_core | tmp, CORE_MOD, |
562 | CM_CLKSEL1); | ||
563 | |||
370 | if (cpu_is_omap2430()) | 564 | if (cpu_is_omap2430()) |
371 | cm_write_mod_reg(prcm->cm_clksel_mdm, | 565 | cm_write_mod_reg(prcm->cm_clksel_mdm, |
372 | OMAP2430_MDM_MOD, CM_CLKSEL); | 566 | OMAP2430_MDM_MOD, CM_CLKSEL); |
373 | 567 | ||
374 | /* x2 to enter init_mem */ | 568 | /* x2 to enter omap2xxx_sdrc_init_params() */ |
375 | omap2_reprogram_sdrc(CORE_CLK_SRC_DPLL_X2, 1); | 569 | omap2xxx_sdrc_reprogram(CORE_CLK_SRC_DPLL_X2, 1); |
376 | 570 | ||
377 | omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr, | 571 | omap2_set_prcm(prcm->cm_clksel1_pll, prcm->base_sdrc_rfr, |
378 | bypass); | 572 | bypass); |
379 | 573 | ||
380 | omap2_init_memory_params(omap2_dll_force_needed()); | 574 | omap2xxx_sdrc_init_params(omap2xxx_sdrc_dll_is_unlocked()); |
381 | omap2_reprogram_sdrc(done_rate, 0); | 575 | omap2xxx_sdrc_reprogram(done_rate, 0); |
382 | 576 | ||
383 | local_irq_restore(flags); | 577 | local_irq_restore(flags); |
384 | } | 578 | } |
385 | omap2_dpllcore_recalc(&dpll_ck); | ||
386 | 579 | ||
387 | return 0; | 580 | return 0; |
388 | } | 581 | } |
389 | 582 | ||
583 | #ifdef CONFIG_CPU_FREQ | ||
584 | /* | ||
585 | * Walk PRCM rate table and fillout cpufreq freq_table | ||
586 | */ | ||
587 | static struct cpufreq_frequency_table freq_table[ARRAY_SIZE(rate_table)]; | ||
588 | |||
589 | void omap2_clk_init_cpufreq_table(struct cpufreq_frequency_table **table) | ||
590 | { | ||
591 | struct prcm_config *prcm; | ||
592 | int i = 0; | ||
593 | |||
594 | for (prcm = rate_table; prcm->mpu_speed; prcm++) { | ||
595 | if (!(prcm->flags & cpu_mask)) | ||
596 | continue; | ||
597 | if (prcm->xtal_speed != sys_ck.rate) | ||
598 | continue; | ||
599 | |||
600 | /* don't put bypass rates in table */ | ||
601 | if (prcm->dpll_speed == prcm->xtal_speed) | ||
602 | continue; | ||
603 | |||
604 | freq_table[i].index = i; | ||
605 | freq_table[i].frequency = prcm->mpu_speed / 1000; | ||
606 | i++; | ||
607 | } | ||
608 | |||
609 | if (i == 0) { | ||
610 | printk(KERN_WARNING "%s: failed to initialize frequency " | ||
611 | "table\n", __func__); | ||
612 | return; | ||
613 | } | ||
614 | |||
615 | freq_table[i].index = i; | ||
616 | freq_table[i].frequency = CPUFREQ_TABLE_END; | ||
617 | |||
618 | *table = &freq_table[0]; | ||
619 | } | ||
620 | #endif | ||
621 | |||
390 | static struct clk_functions omap2_clk_functions = { | 622 | static struct clk_functions omap2_clk_functions = { |
391 | .clk_enable = omap2_clk_enable, | 623 | .clk_enable = omap2_clk_enable, |
392 | .clk_disable = omap2_clk_disable, | 624 | .clk_disable = omap2_clk_disable, |
@@ -394,24 +626,27 @@ static struct clk_functions omap2_clk_functions = { | |||
394 | .clk_set_rate = omap2_clk_set_rate, | 626 | .clk_set_rate = omap2_clk_set_rate, |
395 | .clk_set_parent = omap2_clk_set_parent, | 627 | .clk_set_parent = omap2_clk_set_parent, |
396 | .clk_disable_unused = omap2_clk_disable_unused, | 628 | .clk_disable_unused = omap2_clk_disable_unused, |
629 | #ifdef CONFIG_CPU_FREQ | ||
630 | .clk_init_cpufreq_table = omap2_clk_init_cpufreq_table, | ||
631 | #endif | ||
397 | }; | 632 | }; |
398 | 633 | ||
399 | static u32 omap2_get_apll_clkin(void) | 634 | static u32 omap2_get_apll_clkin(void) |
400 | { | 635 | { |
401 | u32 aplls, sclk = 0; | 636 | u32 aplls, srate = 0; |
402 | 637 | ||
403 | aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1); | 638 | aplls = cm_read_mod_reg(PLL_MOD, CM_CLKSEL1); |
404 | aplls &= OMAP24XX_APLLS_CLKIN_MASK; | 639 | aplls &= OMAP24XX_APLLS_CLKIN_MASK; |
405 | aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT; | 640 | aplls >>= OMAP24XX_APLLS_CLKIN_SHIFT; |
406 | 641 | ||
407 | if (aplls == APLLS_CLKIN_19_2MHZ) | 642 | if (aplls == APLLS_CLKIN_19_2MHZ) |
408 | sclk = 19200000; | 643 | srate = 19200000; |
409 | else if (aplls == APLLS_CLKIN_13MHZ) | 644 | else if (aplls == APLLS_CLKIN_13MHZ) |
410 | sclk = 13000000; | 645 | srate = 13000000; |
411 | else if (aplls == APLLS_CLKIN_12MHZ) | 646 | else if (aplls == APLLS_CLKIN_12MHZ) |
412 | sclk = 12000000; | 647 | srate = 12000000; |
413 | 648 | ||
414 | return sclk; | 649 | return srate; |
415 | } | 650 | } |
416 | 651 | ||
417 | static u32 omap2_get_sysclkdiv(void) | 652 | static u32 omap2_get_sysclkdiv(void) |
@@ -425,16 +660,14 @@ static u32 omap2_get_sysclkdiv(void) | |||
425 | return div; | 660 | return div; |
426 | } | 661 | } |
427 | 662 | ||
428 | static void omap2_osc_clk_recalc(struct clk *clk) | 663 | static unsigned long omap2_osc_clk_recalc(struct clk *clk) |
429 | { | 664 | { |
430 | clk->rate = omap2_get_apll_clkin() * omap2_get_sysclkdiv(); | 665 | return omap2_get_apll_clkin() * omap2_get_sysclkdiv(); |
431 | propagate_rate(clk); | ||
432 | } | 666 | } |
433 | 667 | ||
434 | static void omap2_sys_clk_recalc(struct clk *clk) | 668 | static unsigned long omap2_sys_clk_recalc(struct clk *clk) |
435 | { | 669 | { |
436 | clk->rate = clk->parent->rate / omap2_get_sysclkdiv(); | 670 | return clk->parent->rate / omap2_get_sysclkdiv(); |
437 | propagate_rate(clk); | ||
438 | } | 671 | } |
439 | 672 | ||
440 | /* | 673 | /* |
@@ -460,7 +693,7 @@ static int __init omap2_clk_arch_init(void) | |||
460 | if (!mpurate) | 693 | if (!mpurate) |
461 | return -EINVAL; | 694 | return -EINVAL; |
462 | 695 | ||
463 | if (omap2_select_table_rate(&virt_prcm_set, mpurate)) | 696 | if (clk_set_rate(&virt_prcm_set, mpurate)) |
464 | printk(KERN_ERR "Could not find matching MPU rate\n"); | 697 | printk(KERN_ERR "Could not find matching MPU rate\n"); |
465 | 698 | ||
466 | recalculate_root_clocks(); | 699 | recalculate_root_clocks(); |
@@ -477,8 +710,8 @@ arch_initcall(omap2_clk_arch_init); | |||
477 | int __init omap2_clk_init(void) | 710 | int __init omap2_clk_init(void) |
478 | { | 711 | { |
479 | struct prcm_config *prcm; | 712 | struct prcm_config *prcm; |
480 | struct clk **clkp; | 713 | struct omap_clk *c; |
481 | u32 clkrate; | 714 | u32 clkrate, cpu_mask; |
482 | 715 | ||
483 | if (cpu_is_omap242x()) | 716 | if (cpu_is_omap242x()) |
484 | cpu_mask = RATE_IN_242X; | 717 | cpu_mask = RATE_IN_242X; |
@@ -487,26 +720,28 @@ int __init omap2_clk_init(void) | |||
487 | 720 | ||
488 | clk_init(&omap2_clk_functions); | 721 | clk_init(&omap2_clk_functions); |
489 | 722 | ||
490 | omap2_osc_clk_recalc(&osc_ck); | 723 | osc_ck.rate = omap2_osc_clk_recalc(&osc_ck); |
491 | omap2_sys_clk_recalc(&sys_ck); | 724 | propagate_rate(&osc_ck); |
725 | sys_ck.rate = omap2_sys_clk_recalc(&sys_ck); | ||
726 | propagate_rate(&sys_ck); | ||
492 | 727 | ||
493 | for (clkp = onchip_24xx_clks; | 728 | for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++) |
494 | clkp < onchip_24xx_clks + ARRAY_SIZE(onchip_24xx_clks); | 729 | clk_init_one(c->lk.clk); |
495 | clkp++) { | ||
496 | 730 | ||
497 | if ((*clkp)->flags & CLOCK_IN_OMAP242X && cpu_is_omap2420()) { | 731 | cpu_mask = 0; |
498 | clk_register(*clkp); | 732 | if (cpu_is_omap2420()) |
499 | continue; | 733 | cpu_mask |= CK_242X; |
500 | } | 734 | if (cpu_is_omap2430()) |
735 | cpu_mask |= CK_243X; | ||
501 | 736 | ||
502 | if ((*clkp)->flags & CLOCK_IN_OMAP243X && cpu_is_omap2430()) { | 737 | for (c = omap24xx_clks; c < omap24xx_clks + ARRAY_SIZE(omap24xx_clks); c++) |
503 | clk_register(*clkp); | 738 | if (c->cpu & cpu_mask) { |
504 | continue; | 739 | clkdev_add(&c->lk); |
740 | clk_register(c->lk.clk); | ||
505 | } | 741 | } |
506 | } | ||
507 | 742 | ||
508 | /* Check the MPU rate set by bootloader */ | 743 | /* Check the MPU rate set by bootloader */ |
509 | clkrate = omap2_get_dpll_rate_24xx(&dpll_ck); | 744 | clkrate = omap2xxx_clk_get_core_rate(&dpll_ck); |
510 | for (prcm = rate_table; prcm->mpu_speed; prcm++) { | 745 | for (prcm = rate_table; prcm->mpu_speed; prcm++) { |
511 | if (!(prcm->flags & cpu_mask)) | 746 | if (!(prcm->flags & cpu_mask)) |
512 | continue; | 747 | continue; |