]>
Commit | Line | Data |
---|---|---|
3776801d A |
1 | /* |
2 | * | |
3 | * Clock initialization for OMAP4 | |
4 | * | |
5 | * (C) Copyright 2010 | |
6 | * Texas Instruments, <www.ti.com> | |
7 | * | |
8 | * Aneesh V <[email protected]> | |
9 | * | |
10 | * Based on previous work by: | |
11 | * Santosh Shilimkar <[email protected]> | |
12 | * Rajendra Nayak <[email protected]> | |
13 | * | |
14 | * See file CREDITS for list of people who contributed to this | |
15 | * project. | |
16 | * | |
17 | * This program is free software; you can redistribute it and/or | |
18 | * modify it under the terms of the GNU General Public License as | |
19 | * published by the Free Software Foundation; either version 2 of | |
20 | * the License, or (at your option) any later version. | |
21 | * | |
22 | * This program is distributed in the hope that it will be useful, | |
23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
25 | * GNU General Public License for more details. | |
26 | * | |
27 | * You should have received a copy of the GNU General Public License | |
28 | * along with this program; if not, write to the Free Software | |
29 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | |
30 | * MA 02111-1307 USA | |
31 | */ | |
32 | #include <common.h> | |
33 | #include <asm/omap_common.h> | |
3b690ebb | 34 | #include <asm/gpio.h> |
3776801d A |
35 | #include <asm/arch/clocks.h> |
36 | #include <asm/arch/sys_proto.h> | |
37 | #include <asm/utils.h> | |
d506719f | 38 | #include <asm/omap_gpio.h> |
3776801d A |
39 | |
40 | #ifndef CONFIG_SPL_BUILD | |
41 | /* | |
42 | * printing to console doesn't work unless | |
43 | * this code is executed from SPL | |
44 | */ | |
45 | #define printf(fmt, args...) | |
46 | #define puts(s) | |
47 | #endif | |
48 | ||
49 | #define abs(x) (((x) < 0) ? ((x)*-1) : (x)) | |
50 | ||
51 | struct omap4_prcm_regs *const prcm = (struct omap4_prcm_regs *)0x4A004100; | |
52 | ||
53 | static const u32 sys_clk_array[8] = { | |
54 | 12000000, /* 12 MHz */ | |
55 | 13000000, /* 13 MHz */ | |
56 | 16800000, /* 16.8 MHz */ | |
57 | 19200000, /* 19.2 MHz */ | |
58 | 26000000, /* 26 MHz */ | |
59 | 27000000, /* 27 MHz */ | |
60 | 38400000, /* 38.4 MHz */ | |
61 | }; | |
62 | ||
63 | /* | |
64 | * The M & N values in the following tables are created using the | |
65 | * following tool: | |
66 | * tools/omap/clocks_get_m_n.c | |
67 | * Please use this tool for creating the table for any new frequency. | |
68 | */ | |
69 | ||
b4dc6442 A |
70 | /* dpll locked at 1840 MHz MPU clk at 920 MHz(OPP Turbo 4460) - DCC OFF */ |
71 | static const struct dpll_params mpu_dpll_params_1840mhz[NUM_SYS_CLKS] = { | |
72 | {230, 2, 1, -1, -1, -1, -1, -1}, /* 12 MHz */ | |
73 | {920, 12, 1, -1, -1, -1, -1, -1}, /* 13 MHz */ | |
74 | {219, 3, 1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ | |
75 | {575, 11, 1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ | |
76 | {460, 12, 1, -1, -1, -1, -1, -1}, /* 26 MHz */ | |
77 | {920, 26, 1, -1, -1, -1, -1, -1}, /* 27 MHz */ | |
78 | {575, 23, 1, -1, -1, -1, -1, -1} /* 38.4 MHz */ | |
79 | }; | |
80 | ||
81 | /* dpll locked at 1584 MHz - MPU clk at 792 MHz(OPP Turbo 4430) */ | |
3776801d A |
82 | static const struct dpll_params mpu_dpll_params_1584mhz[NUM_SYS_CLKS] = { |
83 | {66, 0, 1, -1, -1, -1, -1, -1}, /* 12 MHz */ | |
84 | {792, 12, 1, -1, -1, -1, -1, -1}, /* 13 MHz */ | |
85 | {330, 6, 1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ | |
86 | {165, 3, 1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ | |
87 | {396, 12, 1, -1, -1, -1, -1, -1}, /* 26 MHz */ | |
88 | {88, 2, 1, -1, -1, -1, -1, -1}, /* 27 MHz */ | |
89 | {165, 7, 1, -1, -1, -1, -1, -1} /* 38.4 MHz */ | |
90 | }; | |
91 | ||
92 | /* dpll locked at 1200 MHz - MPU clk at 600 MHz */ | |
93 | static const struct dpll_params mpu_dpll_params_1200mhz[NUM_SYS_CLKS] = { | |
94 | {50, 0, 1, -1, -1, -1, -1, -1}, /* 12 MHz */ | |
95 | {600, 12, 1, -1, -1, -1, -1, -1}, /* 13 MHz */ | |
96 | {250, 6, 1, -1, -1, -1, -1, -1}, /* 16.8 MHz */ | |
97 | {125, 3, 1, -1, -1, -1, -1, -1}, /* 19.2 MHz */ | |
98 | {300, 12, 1, -1, -1, -1, -1, -1}, /* 26 MHz */ | |
99 | {200, 8, 1, -1, -1, -1, -1, -1}, /* 27 MHz */ | |
100 | {125, 7, 1, -1, -1, -1, -1, -1} /* 38.4 MHz */ | |
101 | }; | |
102 | ||
103 | static const struct dpll_params core_dpll_params_1600mhz[NUM_SYS_CLKS] = { | |
104 | {200, 2, 1, 5, 8, 4, 6, 5}, /* 12 MHz */ | |
105 | {800, 12, 1, 5, 8, 4, 6, 5}, /* 13 MHz */ | |
106 | {619, 12, 1, 5, 8, 4, 6, 5}, /* 16.8 MHz */ | |
107 | {125, 2, 1, 5, 8, 4, 6, 5}, /* 19.2 MHz */ | |
108 | {400, 12, 1, 5, 8, 4, 6, 5}, /* 26 MHz */ | |
109 | {800, 26, 1, 5, 8, 4, 6, 5}, /* 27 MHz */ | |
110 | {125, 5, 1, 5, 8, 4, 6, 5} /* 38.4 MHz */ | |
111 | }; | |
112 | ||
113 | static const struct dpll_params core_dpll_params_es1_1524mhz[NUM_SYS_CLKS] = { | |
114 | {127, 1, 1, 5, 8, 4, 6, 5}, /* 12 MHz */ | |
115 | {762, 12, 1, 5, 8, 4, 6, 5}, /* 13 MHz */ | |
116 | {635, 13, 1, 5, 8, 4, 6, 5}, /* 16.8 MHz */ | |
117 | {635, 15, 1, 5, 8, 4, 6, 5}, /* 19.2 MHz */ | |
118 | {381, 12, 1, 5, 8, 4, 6, 5}, /* 26 MHz */ | |
119 | {254, 8, 1, 5, 8, 4, 6, 5}, /* 27 MHz */ | |
120 | {496, 24, 1, 5, 8, 4, 6, 5} /* 38.4 MHz */ | |
121 | }; | |
122 | ||
123 | static const struct dpll_params | |
124 | core_dpll_params_es2_1600mhz_ddr200mhz[NUM_SYS_CLKS] = { | |
125 | {200, 2, 2, 5, 8, 4, 6, 5}, /* 12 MHz */ | |
126 | {800, 12, 2, 5, 8, 4, 6, 5}, /* 13 MHz */ | |
127 | {619, 12, 2, 5, 8, 4, 6, 5}, /* 16.8 MHz */ | |
128 | {125, 2, 2, 5, 8, 4, 6, 5}, /* 19.2 MHz */ | |
129 | {400, 12, 2, 5, 8, 4, 6, 5}, /* 26 MHz */ | |
130 | {800, 26, 2, 5, 8, 4, 6, 5}, /* 27 MHz */ | |
131 | {125, 5, 2, 5, 8, 4, 6, 5} /* 38.4 MHz */ | |
132 | }; | |
133 | ||
134 | static const struct dpll_params per_dpll_params_1536mhz[NUM_SYS_CLKS] = { | |
135 | {64, 0, 8, 6, 12, 9, 4, 5}, /* 12 MHz */ | |
136 | {768, 12, 8, 6, 12, 9, 4, 5}, /* 13 MHz */ | |
137 | {320, 6, 8, 6, 12, 9, 4, 5}, /* 16.8 MHz */ | |
138 | {40, 0, 8, 6, 12, 9, 4, 5}, /* 19.2 MHz */ | |
139 | {384, 12, 8, 6, 12, 9, 4, 5}, /* 26 MHz */ | |
140 | {256, 8, 8, 6, 12, 9, 4, 5}, /* 27 MHz */ | |
141 | {20, 0, 8, 6, 12, 9, 4, 5} /* 38.4 MHz */ | |
142 | }; | |
143 | ||
144 | static const struct dpll_params iva_dpll_params_1862mhz[NUM_SYS_CLKS] = { | |
145 | {931, 11, -1, -1, 4, 7, -1, -1}, /* 12 MHz */ | |
146 | {931, 12, -1, -1, 4, 7, -1, -1}, /* 13 MHz */ | |
147 | {665, 11, -1, -1, 4, 7, -1, -1}, /* 16.8 MHz */ | |
148 | {727, 14, -1, -1, 4, 7, -1, -1}, /* 19.2 MHz */ | |
149 | {931, 25, -1, -1, 4, 7, -1, -1}, /* 26 MHz */ | |
150 | {931, 26, -1, -1, 4, 7, -1, -1}, /* 27 MHz */ | |
151 | {412, 16, -1, -1, 4, 7, -1, -1} /* 38.4 MHz */ | |
152 | }; | |
153 | ||
154 | /* ABE M & N values with sys_clk as source */ | |
155 | static const struct dpll_params | |
156 | abe_dpll_params_sysclk_196608khz[NUM_SYS_CLKS] = { | |
157 | {49, 5, 1, 1, -1, -1, -1, -1}, /* 12 MHz */ | |
158 | {68, 8, 1, 1, -1, -1, -1, -1}, /* 13 MHz */ | |
159 | {35, 5, 1, 1, -1, -1, -1, -1}, /* 16.8 MHz */ | |
160 | {46, 8, 1, 1, -1, -1, -1, -1}, /* 19.2 MHz */ | |
161 | {34, 8, 1, 1, -1, -1, -1, -1}, /* 26 MHz */ | |
162 | {29, 7, 1, 1, -1, -1, -1, -1}, /* 27 MHz */ | |
163 | {64, 24, 1, 1, -1, -1, -1, -1} /* 38.4 MHz */ | |
164 | }; | |
165 | ||
166 | /* ABE M & N values with 32K clock as source */ | |
167 | static const struct dpll_params abe_dpll_params_32k_196608khz = { | |
168 | 750, 0, 1, 1, -1, -1, -1, -1 | |
169 | }; | |
170 | ||
171 | ||
172 | static const struct dpll_params usb_dpll_params_1920mhz[NUM_SYS_CLKS] = { | |
173 | {80, 0, 2, -1, -1, -1, -1, -1}, /* 12 MHz */ | |
174 | {960, 12, 2, -1, -1, -1, -1, -1}, /* 13 MHz */ | |
175 | {400, 6, 2, -1, -1, -1, -1, -1}, /* 16.8 MHz */ | |
176 | {50, 0, 2, -1, -1, -1, -1, -1}, /* 19.2 MHz */ | |
177 | {480, 12, 2, -1, -1, -1, -1, -1}, /* 26 MHz */ | |
178 | {320, 8, 2, -1, -1, -1, -1, -1}, /* 27 MHz */ | |
179 | {25, 0, 2, -1, -1, -1, -1, -1} /* 38.4 MHz */ | |
180 | }; | |
181 | ||
182 | static inline u32 __get_sys_clk_index(void) | |
183 | { | |
184 | u32 ind; | |
185 | /* | |
186 | * For ES1 the ROM code calibration of sys clock is not reliable | |
187 | * due to hw issue. So, use hard-coded value. If this value is not | |
188 | * correct for any board over-ride this function in board file | |
189 | * From ES2.0 onwards you will get this information from | |
190 | * CM_SYS_CLKSEL | |
191 | */ | |
192 | if (omap_revision() == OMAP4430_ES1_0) | |
193 | ind = OMAP_SYS_CLK_IND_38_4_MHZ; | |
194 | else { | |
195 | /* SYS_CLKSEL - 1 to match the dpll param array indices */ | |
196 | ind = (readl(&prcm->cm_sys_clksel) & | |
197 | CM_SYS_CLKSEL_SYS_CLKSEL_MASK) - 1; | |
198 | } | |
199 | return ind; | |
200 | } | |
201 | ||
202 | u32 get_sys_clk_index(void) | |
203 | __attribute__ ((weak, alias("__get_sys_clk_index"))); | |
204 | ||
205 | u32 get_sys_clk_freq(void) | |
206 | { | |
207 | u8 index = get_sys_clk_index(); | |
208 | return sys_clk_array[index]; | |
209 | } | |
210 | ||
211 | static inline void do_bypass_dpll(u32 *const base) | |
212 | { | |
213 | struct dpll_regs *dpll_regs = (struct dpll_regs *)base; | |
214 | ||
215 | clrsetbits_le32(&dpll_regs->cm_clkmode_dpll, | |
216 | CM_CLKMODE_DPLL_DPLL_EN_MASK, | |
217 | DPLL_EN_FAST_RELOCK_BYPASS << | |
218 | CM_CLKMODE_DPLL_EN_SHIFT); | |
219 | } | |
220 | ||
221 | static inline void wait_for_bypass(u32 *const base) | |
222 | { | |
223 | struct dpll_regs *const dpll_regs = (struct dpll_regs *)base; | |
224 | ||
225 | if (!wait_on_value(ST_DPLL_CLK_MASK, 0, &dpll_regs->cm_idlest_dpll, | |
226 | LDELAY)) { | |
227 | printf("Bypassing DPLL failed %p\n", base); | |
228 | } | |
229 | } | |
230 | ||
231 | static inline void do_lock_dpll(u32 *const base) | |
232 | { | |
233 | struct dpll_regs *const dpll_regs = (struct dpll_regs *)base; | |
234 | ||
235 | clrsetbits_le32(&dpll_regs->cm_clkmode_dpll, | |
236 | CM_CLKMODE_DPLL_DPLL_EN_MASK, | |
237 | DPLL_EN_LOCK << CM_CLKMODE_DPLL_EN_SHIFT); | |
238 | } | |
239 | ||
240 | static inline void wait_for_lock(u32 *const base) | |
241 | { | |
242 | struct dpll_regs *const dpll_regs = (struct dpll_regs *)base; | |
243 | ||
244 | if (!wait_on_value(ST_DPLL_CLK_MASK, ST_DPLL_CLK_MASK, | |
245 | &dpll_regs->cm_idlest_dpll, LDELAY)) { | |
246 | printf("DPLL locking failed for %p\n", base); | |
247 | hang(); | |
248 | } | |
249 | } | |
250 | ||
251 | static void do_setup_dpll(u32 *const base, const struct dpll_params *params, | |
252 | u8 lock) | |
253 | { | |
254 | u32 temp; | |
255 | struct dpll_regs *const dpll_regs = (struct dpll_regs *)base; | |
256 | ||
257 | bypass_dpll(base); | |
258 | ||
259 | /* Set M & N */ | |
260 | temp = readl(&dpll_regs->cm_clksel_dpll); | |
261 | ||
262 | temp &= ~CM_CLKSEL_DPLL_M_MASK; | |
263 | temp |= (params->m << CM_CLKSEL_DPLL_M_SHIFT) & CM_CLKSEL_DPLL_M_MASK; | |
264 | ||
265 | temp &= ~CM_CLKSEL_DPLL_N_MASK; | |
266 | temp |= (params->n << CM_CLKSEL_DPLL_N_SHIFT) & CM_CLKSEL_DPLL_N_MASK; | |
267 | ||
268 | writel(temp, &dpll_regs->cm_clksel_dpll); | |
269 | ||
270 | /* Lock */ | |
271 | if (lock) | |
272 | do_lock_dpll(base); | |
273 | ||
274 | /* Setup post-dividers */ | |
275 | if (params->m2 >= 0) | |
276 | writel(params->m2, &dpll_regs->cm_div_m2_dpll); | |
277 | if (params->m3 >= 0) | |
278 | writel(params->m3, &dpll_regs->cm_div_m3_dpll); | |
279 | if (params->m4 >= 0) | |
280 | writel(params->m4, &dpll_regs->cm_div_m4_dpll); | |
281 | if (params->m5 >= 0) | |
282 | writel(params->m5, &dpll_regs->cm_div_m5_dpll); | |
283 | if (params->m6 >= 0) | |
284 | writel(params->m6, &dpll_regs->cm_div_m6_dpll); | |
285 | if (params->m7 >= 0) | |
286 | writel(params->m7, &dpll_regs->cm_div_m7_dpll); | |
287 | ||
288 | /* Wait till the DPLL locks */ | |
289 | if (lock) | |
290 | wait_for_lock(base); | |
291 | } | |
292 | ||
293 | const struct dpll_params *get_core_dpll_params(void) | |
294 | { | |
295 | u32 sysclk_ind = get_sys_clk_index(); | |
296 | ||
297 | switch (omap_revision()) { | |
298 | case OMAP4430_ES1_0: | |
299 | return &core_dpll_params_es1_1524mhz[sysclk_ind]; | |
300 | case OMAP4430_ES2_0: | |
301 | case OMAP4430_SILICON_ID_INVALID: | |
302 | /* safest */ | |
303 | return &core_dpll_params_es2_1600mhz_ddr200mhz[sysclk_ind]; | |
304 | default: | |
305 | return &core_dpll_params_1600mhz[sysclk_ind]; | |
306 | } | |
307 | } | |
308 | ||
309 | u32 omap4_ddr_clk(void) | |
310 | { | |
311 | u32 ddr_clk, sys_clk_khz; | |
312 | const struct dpll_params *core_dpll_params; | |
313 | ||
314 | sys_clk_khz = get_sys_clk_freq() / 1000; | |
315 | ||
316 | core_dpll_params = get_core_dpll_params(); | |
317 | ||
318 | debug("sys_clk %d\n ", sys_clk_khz * 1000); | |
319 | ||
320 | /* Find Core DPLL locked frequency first */ | |
321 | ddr_clk = sys_clk_khz * 2 * core_dpll_params->m / | |
322 | (core_dpll_params->n + 1); | |
323 | /* | |
324 | * DDR frequency is PHY_ROOT_CLK/2 | |
325 | * PHY_ROOT_CLK = Fdpll/2/M2 | |
326 | */ | |
327 | ddr_clk = ddr_clk / 4 / core_dpll_params->m2; | |
328 | ||
329 | ddr_clk *= 1000; /* convert to Hz */ | |
330 | debug("ddr_clk %d\n ", ddr_clk); | |
331 | ||
332 | return ddr_clk; | |
333 | } | |
334 | ||
b4dc6442 A |
335 | /* |
336 | * Lock MPU dpll | |
337 | * | |
338 | * Resulting MPU frequencies: | |
339 | * 4430 ES1.0 : 600 MHz | |
340 | * 4430 ES2.x : 792 MHz (OPP Turbo) | |
341 | * 4460 : 920 MHz (OPP Turbo) - DCC disabled | |
342 | */ | |
343 | void configure_mpu_dpll(void) | |
344 | { | |
345 | const struct dpll_params *params; | |
346 | struct dpll_regs *mpu_dpll_regs; | |
347 | u32 omap4_rev, sysclk_ind; | |
348 | ||
349 | omap4_rev = omap_revision(); | |
350 | sysclk_ind = get_sys_clk_index(); | |
351 | ||
352 | if (omap4_rev == OMAP4430_ES1_0) | |
353 | params = &mpu_dpll_params_1200mhz[sysclk_ind]; | |
354 | else if (omap4_rev < OMAP4460_ES1_0) | |
355 | params = &mpu_dpll_params_1584mhz[sysclk_ind]; | |
356 | else | |
357 | params = &mpu_dpll_params_1840mhz[sysclk_ind]; | |
358 | ||
359 | /* DCC and clock divider settings for 4460 */ | |
360 | if (omap4_rev >= OMAP4460_ES1_0) { | |
361 | mpu_dpll_regs = | |
362 | (struct dpll_regs *)&prcm->cm_clkmode_dpll_mpu; | |
363 | bypass_dpll(&prcm->cm_clkmode_dpll_mpu); | |
364 | clrbits_le32(&prcm->cm_mpu_mpu_clkctrl, | |
365 | MPU_CLKCTRL_CLKSEL_EMIF_DIV_MODE_MASK); | |
366 | setbits_le32(&prcm->cm_mpu_mpu_clkctrl, | |
367 | MPU_CLKCTRL_CLKSEL_ABE_DIV_MODE_MASK); | |
368 | clrbits_le32(&mpu_dpll_regs->cm_clksel_dpll, | |
369 | CM_CLKSEL_DCC_EN_MASK); | |
370 | } | |
371 | ||
372 | do_setup_dpll(&prcm->cm_clkmode_dpll_mpu, params, DPLL_LOCK); | |
373 | debug("MPU DPLL locked\n"); | |
374 | } | |
375 | ||
3776801d A |
376 | static void setup_dplls(void) |
377 | { | |
378 | u32 sysclk_ind, temp; | |
379 | const struct dpll_params *params; | |
380 | debug("setup_dplls\n"); | |
381 | ||
382 | sysclk_ind = get_sys_clk_index(); | |
383 | ||
384 | /* CORE dpll */ | |
385 | params = get_core_dpll_params(); /* default - safest */ | |
386 | /* | |
387 | * Do not lock the core DPLL now. Just set it up. | |
388 | * Core DPLL will be locked after setting up EMIF | |
389 | * using the FREQ_UPDATE method(freq_update_core()) | |
390 | */ | |
391 | do_setup_dpll(&prcm->cm_clkmode_dpll_core, params, DPLL_NO_LOCK); | |
392 | /* Set the ratios for CORE_CLK, L3_CLK, L4_CLK */ | |
393 | temp = (CLKSEL_CORE_X2_DIV_1 << CLKSEL_CORE_SHIFT) | | |
394 | (CLKSEL_L3_CORE_DIV_2 << CLKSEL_L3_SHIFT) | | |
395 | (CLKSEL_L4_L3_DIV_2 << CLKSEL_L4_SHIFT); | |
396 | writel(temp, &prcm->cm_clksel_core); | |
397 | debug("Core DPLL configured\n"); | |
398 | ||
399 | /* lock PER dpll */ | |
400 | do_setup_dpll(&prcm->cm_clkmode_dpll_per, | |
401 | &per_dpll_params_1536mhz[sysclk_ind], DPLL_LOCK); | |
402 | debug("PER DPLL locked\n"); | |
403 | ||
404 | /* MPU dpll */ | |
b4dc6442 | 405 | configure_mpu_dpll(); |
3776801d A |
406 | } |
407 | ||
408 | static void setup_non_essential_dplls(void) | |
409 | { | |
410 | u32 sys_clk_khz, abe_ref_clk; | |
411 | u32 sysclk_ind, sd_div, num, den; | |
412 | const struct dpll_params *params; | |
413 | ||
414 | sysclk_ind = get_sys_clk_index(); | |
415 | sys_clk_khz = get_sys_clk_freq() / 1000; | |
416 | ||
417 | /* IVA */ | |
418 | clrsetbits_le32(&prcm->cm_bypclk_dpll_iva, | |
419 | CM_BYPCLK_DPLL_IVA_CLKSEL_MASK, DPLL_IVA_CLKSEL_CORE_X2_DIV_2); | |
420 | ||
421 | do_setup_dpll(&prcm->cm_clkmode_dpll_iva, | |
422 | &iva_dpll_params_1862mhz[sysclk_ind], DPLL_LOCK); | |
423 | ||
424 | /* | |
425 | * USB: | |
426 | * USB dpll is J-type. Need to set DPLL_SD_DIV for jitter correction | |
427 | * DPLL_SD_DIV = CEILING ([DPLL_MULT/(DPLL_DIV+1)]* CLKINP / 250) | |
428 | * - where CLKINP is sys_clk in MHz | |
429 | * Use CLKINP in KHz and adjust the denominator accordingly so | |
430 | * that we have enough accuracy and at the same time no overflow | |
431 | */ | |
432 | params = &usb_dpll_params_1920mhz[sysclk_ind]; | |
433 | num = params->m * sys_clk_khz; | |
434 | den = (params->n + 1) * 250 * 1000; | |
435 | num += den - 1; | |
436 | sd_div = num / den; | |
437 | clrsetbits_le32(&prcm->cm_clksel_dpll_usb, | |
438 | CM_CLKSEL_DPLL_DPLL_SD_DIV_MASK, | |
439 | sd_div << CM_CLKSEL_DPLL_DPLL_SD_DIV_SHIFT); | |
440 | ||
441 | /* Now setup the dpll with the regular function */ | |
442 | do_setup_dpll(&prcm->cm_clkmode_dpll_usb, params, DPLL_LOCK); | |
443 | ||
444 | #ifdef CONFIG_SYS_OMAP4_ABE_SYSCK | |
445 | params = &abe_dpll_params_sysclk_196608khz[sysclk_ind]; | |
446 | abe_ref_clk = CM_ABE_PLL_REF_CLKSEL_CLKSEL_SYSCLK; | |
447 | #else | |
448 | params = &abe_dpll_params_32k_196608khz; | |
449 | abe_ref_clk = CM_ABE_PLL_REF_CLKSEL_CLKSEL_32KCLK; | |
450 | /* | |
451 | * We need to enable some additional options to achieve | |
452 | * 196.608MHz from 32768 Hz | |
453 | */ | |
454 | setbits_le32(&prcm->cm_clkmode_dpll_abe, | |
455 | CM_CLKMODE_DPLL_DRIFTGUARD_EN_MASK| | |
456 | CM_CLKMODE_DPLL_RELOCK_RAMP_EN_MASK| | |
457 | CM_CLKMODE_DPLL_LPMODE_EN_MASK| | |
458 | CM_CLKMODE_DPLL_REGM4XEN_MASK); | |
459 | /* Spend 4 REFCLK cycles at each stage */ | |
460 | clrsetbits_le32(&prcm->cm_clkmode_dpll_abe, | |
461 | CM_CLKMODE_DPLL_RAMP_RATE_MASK, | |
462 | 1 << CM_CLKMODE_DPLL_RAMP_RATE_SHIFT); | |
463 | #endif | |
464 | ||
465 | /* Select the right reference clk */ | |
466 | clrsetbits_le32(&prcm->cm_abe_pll_ref_clksel, | |
467 | CM_ABE_PLL_REF_CLKSEL_CLKSEL_MASK, | |
468 | abe_ref_clk << CM_ABE_PLL_REF_CLKSEL_CLKSEL_SHIFT); | |
469 | /* Lock the dpll */ | |
470 | do_setup_dpll(&prcm->cm_clkmode_dpll_abe, params, DPLL_LOCK); | |
471 | } | |
472 | ||
d506719f A |
473 | static void do_scale_tps62361(u32 reg, u32 volt_mv) |
474 | { | |
475 | u32 temp, step; | |
476 | ||
477 | step = volt_mv - TPS62361_BASE_VOLT_MV; | |
478 | step /= 10; | |
479 | ||
480 | /* | |
481 | * Select SET1 in TPS62361: | |
482 | * VSEL1 is grounded on board. So the following selects | |
483 | * VSEL1 = 0 and VSEL0 = 1 | |
484 | */ | |
3b690ebb SP |
485 | gpio_direction_output(TPS62361_VSEL0_GPIO, 0); |
486 | gpio_set_value(TPS62361_VSEL0_GPIO, 1); | |
d506719f A |
487 | |
488 | temp = TPS62361_I2C_SLAVE_ADDR | | |
489 | (reg << PRM_VC_VAL_BYPASS_REGADDR_SHIFT) | | |
490 | (step << PRM_VC_VAL_BYPASS_DATA_SHIFT) | | |
491 | PRM_VC_VAL_BYPASS_VALID_BIT; | |
492 | debug("do_scale_tps62361: volt - %d step - 0x%x\n", volt_mv, step); | |
493 | ||
494 | writel(temp, &prcm->prm_vc_val_bypass); | |
495 | if (!wait_on_value(PRM_VC_VAL_BYPASS_VALID_BIT, 0, | |
496 | &prcm->prm_vc_val_bypass, LDELAY)) { | |
497 | puts("Scaling voltage failed for vdd_mpu from TPS\n"); | |
498 | } | |
499 | } | |
500 | ||
3776801d A |
501 | static void do_scale_vcore(u32 vcore_reg, u32 volt_mv) |
502 | { | |
503 | u32 temp, offset_code; | |
504 | u32 step = 12660; /* 12.66 mV represented in uV */ | |
505 | u32 offset = volt_mv; | |
506 | ||
507 | /* convert to uV for better accuracy in the calculations */ | |
508 | offset *= 1000; | |
509 | ||
510 | if (omap_revision() == OMAP4430_ES1_0) | |
511 | offset -= PHOENIX_SMPS_BASE_VOLT_STD_MODE_UV; | |
512 | else | |
513 | offset -= PHOENIX_SMPS_BASE_VOLT_STD_MODE_WITH_OFFSET_UV; | |
514 | ||
515 | offset_code = (offset + step - 1) / step; | |
516 | /* The code starts at 1 not 0 */ | |
517 | offset_code++; | |
518 | ||
519 | debug("do_scale_vcore: volt - %d offset_code - 0x%x\n", volt_mv, | |
520 | offset_code); | |
521 | ||
522 | temp = SMPS_I2C_SLAVE_ADDR | | |
523 | (vcore_reg << PRM_VC_VAL_BYPASS_REGADDR_SHIFT) | | |
524 | (offset_code << PRM_VC_VAL_BYPASS_DATA_SHIFT) | | |
525 | PRM_VC_VAL_BYPASS_VALID_BIT; | |
526 | writel(temp, &prcm->prm_vc_val_bypass); | |
527 | if (!wait_on_value(PRM_VC_VAL_BYPASS_VALID_BIT, 0, | |
528 | &prcm->prm_vc_val_bypass, LDELAY)) { | |
529 | printf("Scaling voltage failed for 0x%x\n", vcore_reg); | |
530 | } | |
531 | } | |
532 | ||
533 | /* | |
534 | * Setup the voltages for vdd_mpu, vdd_core, and vdd_iva | |
535 | * We set the maximum voltages allowed here because Smart-Reflex is not | |
536 | * enabled in bootloader. Voltage initialization in the kernel will set | |
537 | * these to the nominal values after enabling Smart-Reflex | |
538 | */ | |
539 | static void scale_vcores(void) | |
540 | { | |
d506719f | 541 | u32 volt, sys_clk_khz, cycles_hi, cycles_low, temp, omap4_rev; |
3776801d A |
542 | |
543 | sys_clk_khz = get_sys_clk_freq() / 1000; | |
544 | ||
545 | /* | |
546 | * Setup the dedicated I2C controller for Voltage Control | |
547 | * I2C clk - high period 40% low period 60% | |
548 | */ | |
549 | cycles_hi = sys_clk_khz * 4 / PRM_VC_I2C_CHANNEL_FREQ_KHZ / 10; | |
550 | cycles_low = sys_clk_khz * 6 / PRM_VC_I2C_CHANNEL_FREQ_KHZ / 10; | |
551 | /* values to be set in register - less by 5 & 7 respectively */ | |
552 | cycles_hi -= 5; | |
553 | cycles_low -= 7; | |
554 | temp = (cycles_hi << PRM_VC_CFG_I2C_CLK_SCLH_SHIFT) | | |
555 | (cycles_low << PRM_VC_CFG_I2C_CLK_SCLL_SHIFT); | |
556 | writel(temp, &prcm->prm_vc_cfg_i2c_clk); | |
557 | ||
558 | /* Disable high speed mode and all advanced features */ | |
559 | writel(0x0, &prcm->prm_vc_cfg_i2c_mode); | |
560 | ||
d506719f A |
561 | omap4_rev = omap_revision(); |
562 | /* TPS - supplies vdd_mpu on 4460 */ | |
563 | if (omap4_rev >= OMAP4460_ES1_0) { | |
564 | volt = 1430; | |
565 | do_scale_tps62361(TPS62361_REG_ADDR_SET1, volt); | |
566 | } | |
567 | ||
3776801d | 568 | /* |
d506719f A |
569 | * VCORE 1 |
570 | * | |
571 | * 4430 : supplies vdd_mpu | |
3776801d A |
572 | * Setting a high voltage for Nitro mode as smart reflex is not enabled. |
573 | * We use the maximum possible value in the AVS range because the next | |
574 | * higher voltage in the discrete range (code >= 0b111010) is way too | |
575 | * high | |
d506719f A |
576 | * |
577 | * 4460 : supplies vdd_core | |
3776801d | 578 | */ |
d506719f A |
579 | if (omap4_rev < OMAP4460_ES1_0) { |
580 | volt = 1417; | |
581 | do_scale_vcore(SMPS_REG_ADDR_VCORE1, volt); | |
582 | } else { | |
583 | volt = 1200; | |
584 | do_scale_vcore(SMPS_REG_ADDR_VCORE1, volt); | |
585 | } | |
3776801d A |
586 | |
587 | /* VCORE 2 - supplies vdd_iva */ | |
588 | volt = 1200; | |
589 | do_scale_vcore(SMPS_REG_ADDR_VCORE2, volt); | |
590 | ||
d506719f A |
591 | /* |
592 | * VCORE 3 | |
593 | * 4430 : supplies vdd_core | |
594 | * 4460 : not connected | |
595 | */ | |
596 | if (omap4_rev < OMAP4460_ES1_0) { | |
597 | volt = 1200; | |
598 | do_scale_vcore(SMPS_REG_ADDR_VCORE3, volt); | |
599 | } | |
3776801d A |
600 | } |
601 | ||
602 | static inline void enable_clock_domain(u32 *const clkctrl_reg, u32 enable_mode) | |
603 | { | |
604 | clrsetbits_le32(clkctrl_reg, CD_CLKCTRL_CLKTRCTRL_MASK, | |
605 | enable_mode << CD_CLKCTRL_CLKTRCTRL_SHIFT); | |
606 | debug("Enable clock domain - 0x%08x\n", clkctrl_reg); | |
607 | } | |
608 | ||
609 | static inline void wait_for_clk_enable(u32 *clkctrl_addr) | |
610 | { | |
611 | u32 clkctrl, idlest = MODULE_CLKCTRL_IDLEST_DISABLED; | |
612 | u32 bound = LDELAY; | |
613 | ||
614 | while ((idlest == MODULE_CLKCTRL_IDLEST_DISABLED) || | |
615 | (idlest == MODULE_CLKCTRL_IDLEST_TRANSITIONING)) { | |
616 | ||
617 | clkctrl = readl(clkctrl_addr); | |
618 | idlest = (clkctrl & MODULE_CLKCTRL_IDLEST_MASK) >> | |
619 | MODULE_CLKCTRL_IDLEST_SHIFT; | |
620 | if (--bound == 0) { | |
621 | printf("Clock enable failed for 0x%p idlest 0x%x\n", | |
622 | clkctrl_addr, clkctrl); | |
623 | return; | |
624 | } | |
625 | } | |
626 | } | |
627 | ||
628 | static inline void enable_clock_module(u32 *const clkctrl_addr, u32 enable_mode, | |
629 | u32 wait_for_enable) | |
630 | { | |
631 | clrsetbits_le32(clkctrl_addr, MODULE_CLKCTRL_MODULEMODE_MASK, | |
632 | enable_mode << MODULE_CLKCTRL_MODULEMODE_SHIFT); | |
633 | debug("Enable clock module - 0x%08x\n", clkctrl_addr); | |
634 | if (wait_for_enable) | |
635 | wait_for_clk_enable(clkctrl_addr); | |
636 | } | |
637 | ||
638 | /* | |
639 | * Enable essential clock domains, modules and | |
640 | * do some additional special settings needed | |
641 | */ | |
642 | static void enable_basic_clocks(void) | |
643 | { | |
644 | u32 i, max = 100, wait_for_enable = 1; | |
645 | u32 *const clk_domains_essential[] = { | |
646 | &prcm->cm_l4per_clkstctrl, | |
647 | &prcm->cm_l3init_clkstctrl, | |
648 | &prcm->cm_memif_clkstctrl, | |
649 | &prcm->cm_l4cfg_clkstctrl, | |
650 | 0 | |
651 | }; | |
652 | ||
653 | u32 *const clk_modules_hw_auto_essential[] = { | |
654 | &prcm->cm_wkup_gpio1_clkctrl, | |
655 | &prcm->cm_l4per_gpio2_clkctrl, | |
656 | &prcm->cm_l4per_gpio3_clkctrl, | |
657 | &prcm->cm_l4per_gpio4_clkctrl, | |
658 | &prcm->cm_l4per_gpio5_clkctrl, | |
659 | &prcm->cm_l4per_gpio6_clkctrl, | |
660 | &prcm->cm_memif_emif_1_clkctrl, | |
661 | &prcm->cm_memif_emif_2_clkctrl, | |
662 | &prcm->cm_l3init_hsusbotg_clkctrl, | |
663 | &prcm->cm_l3init_usbphy_clkctrl, | |
664 | &prcm->cm_l4cfg_l4_cfg_clkctrl, | |
665 | 0 | |
666 | }; | |
667 | ||
668 | u32 *const clk_modules_explicit_en_essential[] = { | |
669 | &prcm->cm_l4per_gptimer2_clkctrl, | |
670 | &prcm->cm_l3init_hsmmc1_clkctrl, | |
671 | &prcm->cm_l3init_hsmmc2_clkctrl, | |
672 | &prcm->cm_l4per_mcspi1_clkctrl, | |
673 | &prcm->cm_wkup_gptimer1_clkctrl, | |
674 | &prcm->cm_l4per_i2c1_clkctrl, | |
675 | &prcm->cm_l4per_i2c2_clkctrl, | |
676 | &prcm->cm_l4per_i2c3_clkctrl, | |
677 | &prcm->cm_l4per_i2c4_clkctrl, | |
678 | &prcm->cm_wkup_wdtimer2_clkctrl, | |
679 | &prcm->cm_l4per_uart3_clkctrl, | |
680 | 0 | |
681 | }; | |
682 | ||
683 | /* Enable optional additional functional clock for GPIO4 */ | |
684 | setbits_le32(&prcm->cm_l4per_gpio4_clkctrl, | |
685 | GPIO4_CLKCTRL_OPTFCLKEN_MASK); | |
686 | ||
687 | /* Enable 96 MHz clock for MMC1 & MMC2 */ | |
688 | setbits_le32(&prcm->cm_l3init_hsmmc1_clkctrl, | |
689 | HSMMC_CLKCTRL_CLKSEL_MASK); | |
690 | setbits_le32(&prcm->cm_l3init_hsmmc2_clkctrl, | |
691 | HSMMC_CLKCTRL_CLKSEL_MASK); | |
692 | ||
693 | /* Select 32KHz clock as the source of GPTIMER1 */ | |
694 | setbits_le32(&prcm->cm_wkup_gptimer1_clkctrl, | |
695 | GPTIMER1_CLKCTRL_CLKSEL_MASK); | |
696 | ||
697 | /* Enable optional 48M functional clock for USB PHY */ | |
698 | setbits_le32(&prcm->cm_l3init_usbphy_clkctrl, | |
699 | USBPHY_CLKCTRL_OPTFCLKEN_PHY_48M_MASK); | |
700 | ||
701 | /* Put the clock domains in SW_WKUP mode */ | |
702 | for (i = 0; (i < max) && clk_domains_essential[i]; i++) { | |
703 | enable_clock_domain(clk_domains_essential[i], | |
704 | CD_CLKCTRL_CLKTRCTRL_SW_WKUP); | |
705 | } | |
706 | ||
707 | /* Clock modules that need to be put in HW_AUTO */ | |
708 | for (i = 0; (i < max) && clk_modules_hw_auto_essential[i]; i++) { | |
709 | enable_clock_module(clk_modules_hw_auto_essential[i], | |
710 | MODULE_CLKCTRL_MODULEMODE_HW_AUTO, | |
711 | wait_for_enable); | |
712 | }; | |
713 | ||
714 | /* Clock modules that need to be put in SW_EXPLICIT_EN mode */ | |
715 | for (i = 0; (i < max) && clk_modules_explicit_en_essential[i]; i++) { | |
716 | enable_clock_module(clk_modules_explicit_en_essential[i], | |
717 | MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN, | |
718 | wait_for_enable); | |
719 | }; | |
720 | ||
721 | /* Put the clock domains in HW_AUTO mode now */ | |
722 | for (i = 0; (i < max) && clk_domains_essential[i]; i++) { | |
723 | enable_clock_domain(clk_domains_essential[i], | |
724 | CD_CLKCTRL_CLKTRCTRL_HW_AUTO); | |
725 | } | |
726 | } | |
727 | ||
728 | /* | |
729 | * Enable non-essential clock domains, modules and | |
730 | * do some additional special settings needed | |
731 | */ | |
732 | static void enable_non_essential_clocks(void) | |
733 | { | |
734 | u32 i, max = 100, wait_for_enable = 0; | |
735 | u32 *const clk_domains_non_essential[] = { | |
736 | &prcm->cm_mpu_m3_clkstctrl, | |
737 | &prcm->cm_ivahd_clkstctrl, | |
738 | &prcm->cm_dsp_clkstctrl, | |
739 | &prcm->cm_dss_clkstctrl, | |
740 | &prcm->cm_sgx_clkstctrl, | |
741 | &prcm->cm1_abe_clkstctrl, | |
742 | &prcm->cm_c2c_clkstctrl, | |
743 | &prcm->cm_cam_clkstctrl, | |
744 | &prcm->cm_dss_clkstctrl, | |
745 | &prcm->cm_sdma_clkstctrl, | |
746 | 0 | |
747 | }; | |
748 | ||
749 | u32 *const clk_modules_hw_auto_non_essential[] = { | |
750 | &prcm->cm_mpu_m3_mpu_m3_clkctrl, | |
751 | &prcm->cm_ivahd_ivahd_clkctrl, | |
752 | &prcm->cm_ivahd_sl2_clkctrl, | |
753 | &prcm->cm_dsp_dsp_clkctrl, | |
754 | &prcm->cm_l3_2_gpmc_clkctrl, | |
755 | &prcm->cm_l3instr_l3_3_clkctrl, | |
756 | &prcm->cm_l3instr_l3_instr_clkctrl, | |
757 | &prcm->cm_l3instr_intrconn_wp1_clkctrl, | |
758 | &prcm->cm_l3init_hsi_clkctrl, | |
759 | &prcm->cm_l3init_hsusbtll_clkctrl, | |
760 | 0 | |
761 | }; | |
762 | ||
763 | u32 *const clk_modules_explicit_en_non_essential[] = { | |
764 | &prcm->cm1_abe_aess_clkctrl, | |
765 | &prcm->cm1_abe_pdm_clkctrl, | |
766 | &prcm->cm1_abe_dmic_clkctrl, | |
767 | &prcm->cm1_abe_mcasp_clkctrl, | |
768 | &prcm->cm1_abe_mcbsp1_clkctrl, | |
769 | &prcm->cm1_abe_mcbsp2_clkctrl, | |
770 | &prcm->cm1_abe_mcbsp3_clkctrl, | |
771 | &prcm->cm1_abe_slimbus_clkctrl, | |
772 | &prcm->cm1_abe_timer5_clkctrl, | |
773 | &prcm->cm1_abe_timer6_clkctrl, | |
774 | &prcm->cm1_abe_timer7_clkctrl, | |
775 | &prcm->cm1_abe_timer8_clkctrl, | |
776 | &prcm->cm1_abe_wdt3_clkctrl, | |
777 | &prcm->cm_l4per_gptimer9_clkctrl, | |
778 | &prcm->cm_l4per_gptimer10_clkctrl, | |
779 | &prcm->cm_l4per_gptimer11_clkctrl, | |
780 | &prcm->cm_l4per_gptimer3_clkctrl, | |
781 | &prcm->cm_l4per_gptimer4_clkctrl, | |
782 | &prcm->cm_l4per_hdq1w_clkctrl, | |
783 | &prcm->cm_l4per_mcbsp4_clkctrl, | |
784 | &prcm->cm_l4per_mcspi2_clkctrl, | |
785 | &prcm->cm_l4per_mcspi3_clkctrl, | |
786 | &prcm->cm_l4per_mcspi4_clkctrl, | |
787 | &prcm->cm_l4per_mmcsd3_clkctrl, | |
788 | &prcm->cm_l4per_mmcsd4_clkctrl, | |
789 | &prcm->cm_l4per_mmcsd5_clkctrl, | |
790 | &prcm->cm_l4per_uart1_clkctrl, | |
791 | &prcm->cm_l4per_uart2_clkctrl, | |
792 | &prcm->cm_l4per_uart4_clkctrl, | |
793 | &prcm->cm_wkup_keyboard_clkctrl, | |
794 | &prcm->cm_wkup_wdtimer2_clkctrl, | |
795 | &prcm->cm_cam_iss_clkctrl, | |
796 | &prcm->cm_cam_fdif_clkctrl, | |
797 | &prcm->cm_dss_dss_clkctrl, | |
798 | &prcm->cm_sgx_sgx_clkctrl, | |
799 | &prcm->cm_l3init_hsusbhost_clkctrl, | |
800 | &prcm->cm_l3init_fsusb_clkctrl, | |
801 | 0 | |
802 | }; | |
803 | ||
804 | /* Enable optional functional clock for ISS */ | |
805 | setbits_le32(&prcm->cm_cam_iss_clkctrl, ISS_CLKCTRL_OPTFCLKEN_MASK); | |
806 | ||
807 | /* Enable all optional functional clocks of DSS */ | |
808 | setbits_le32(&prcm->cm_dss_dss_clkctrl, DSS_CLKCTRL_OPTFCLKEN_MASK); | |
809 | ||
810 | ||
811 | /* Put the clock domains in SW_WKUP mode */ | |
812 | for (i = 0; (i < max) && clk_domains_non_essential[i]; i++) { | |
813 | enable_clock_domain(clk_domains_non_essential[i], | |
814 | CD_CLKCTRL_CLKTRCTRL_SW_WKUP); | |
815 | } | |
816 | ||
817 | /* Clock modules that need to be put in HW_AUTO */ | |
818 | for (i = 0; (i < max) && clk_modules_hw_auto_non_essential[i]; i++) { | |
819 | enable_clock_module(clk_modules_hw_auto_non_essential[i], | |
820 | MODULE_CLKCTRL_MODULEMODE_HW_AUTO, | |
821 | wait_for_enable); | |
822 | }; | |
823 | ||
824 | /* Clock modules that need to be put in SW_EXPLICIT_EN mode */ | |
825 | for (i = 0; (i < max) && clk_modules_explicit_en_non_essential[i]; | |
826 | i++) { | |
827 | enable_clock_module(clk_modules_explicit_en_non_essential[i], | |
828 | MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN, | |
829 | wait_for_enable); | |
830 | }; | |
831 | ||
832 | /* Put the clock domains in HW_AUTO mode now */ | |
833 | for (i = 0; (i < max) && clk_domains_non_essential[i]; i++) { | |
834 | enable_clock_domain(clk_domains_non_essential[i], | |
835 | CD_CLKCTRL_CLKTRCTRL_HW_AUTO); | |
836 | } | |
837 | ||
838 | /* Put camera module in no sleep mode */ | |
839 | clrsetbits_le32(&prcm->cm_cam_clkstctrl, MODULE_CLKCTRL_MODULEMODE_MASK, | |
840 | CD_CLKCTRL_CLKTRCTRL_NO_SLEEP << | |
841 | MODULE_CLKCTRL_MODULEMODE_SHIFT); | |
842 | } | |
843 | ||
844 | ||
845 | void freq_update_core(void) | |
846 | { | |
847 | u32 freq_config1 = 0; | |
848 | const struct dpll_params *core_dpll_params; | |
849 | ||
850 | core_dpll_params = get_core_dpll_params(); | |
851 | /* Put EMIF clock domain in sw wakeup mode */ | |
852 | enable_clock_domain(&prcm->cm_memif_clkstctrl, | |
853 | CD_CLKCTRL_CLKTRCTRL_SW_WKUP); | |
854 | wait_for_clk_enable(&prcm->cm_memif_emif_1_clkctrl); | |
855 | wait_for_clk_enable(&prcm->cm_memif_emif_2_clkctrl); | |
856 | ||
857 | freq_config1 = SHADOW_FREQ_CONFIG1_FREQ_UPDATE_MASK | | |
858 | SHADOW_FREQ_CONFIG1_DLL_RESET_MASK; | |
859 | ||
860 | freq_config1 |= (DPLL_EN_LOCK << SHADOW_FREQ_CONFIG1_DPLL_EN_SHIFT) & | |
861 | SHADOW_FREQ_CONFIG1_DPLL_EN_MASK; | |
862 | ||
863 | freq_config1 |= (core_dpll_params->m2 << | |
864 | SHADOW_FREQ_CONFIG1_M2_DIV_SHIFT) & | |
865 | SHADOW_FREQ_CONFIG1_M2_DIV_MASK; | |
866 | ||
867 | writel(freq_config1, &prcm->cm_shadow_freq_config1); | |
868 | if (!wait_on_value(SHADOW_FREQ_CONFIG1_FREQ_UPDATE_MASK, 0, | |
869 | &prcm->cm_shadow_freq_config1, LDELAY)) { | |
870 | puts("FREQ UPDATE procedure failed!!"); | |
871 | hang(); | |
872 | } | |
873 | ||
874 | /* Put EMIF clock domain back in hw auto mode */ | |
875 | enable_clock_domain(&prcm->cm_memif_clkstctrl, | |
876 | CD_CLKCTRL_CLKTRCTRL_HW_AUTO); | |
877 | wait_for_clk_enable(&prcm->cm_memif_emif_1_clkctrl); | |
878 | wait_for_clk_enable(&prcm->cm_memif_emif_2_clkctrl); | |
879 | } | |
880 | ||
881 | void bypass_dpll(u32 *const base) | |
882 | { | |
883 | do_bypass_dpll(base); | |
884 | wait_for_bypass(base); | |
885 | } | |
886 | ||
887 | void lock_dpll(u32 *const base) | |
888 | { | |
889 | do_lock_dpll(base); | |
890 | wait_for_lock(base); | |
891 | } | |
892 | ||
bcae7211 A |
893 | void setup_clocks_for_console(void) |
894 | { | |
895 | /* Do not add any spl_debug prints in this function */ | |
896 | clrsetbits_le32(&prcm->cm_l4per_clkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, | |
897 | CD_CLKCTRL_CLKTRCTRL_SW_WKUP << | |
898 | CD_CLKCTRL_CLKTRCTRL_SHIFT); | |
899 | ||
900 | /* Enable all UARTs - console will be on one of them */ | |
901 | clrsetbits_le32(&prcm->cm_l4per_uart1_clkctrl, | |
902 | MODULE_CLKCTRL_MODULEMODE_MASK, | |
903 | MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << | |
904 | MODULE_CLKCTRL_MODULEMODE_SHIFT); | |
905 | ||
906 | clrsetbits_le32(&prcm->cm_l4per_uart2_clkctrl, | |
907 | MODULE_CLKCTRL_MODULEMODE_MASK, | |
908 | MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << | |
909 | MODULE_CLKCTRL_MODULEMODE_SHIFT); | |
910 | ||
911 | clrsetbits_le32(&prcm->cm_l4per_uart3_clkctrl, | |
912 | MODULE_CLKCTRL_MODULEMODE_MASK, | |
913 | MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << | |
914 | MODULE_CLKCTRL_MODULEMODE_SHIFT); | |
915 | ||
916 | clrsetbits_le32(&prcm->cm_l4per_uart3_clkctrl, | |
917 | MODULE_CLKCTRL_MODULEMODE_MASK, | |
918 | MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << | |
919 | MODULE_CLKCTRL_MODULEMODE_SHIFT); | |
920 | ||
921 | clrsetbits_le32(&prcm->cm_l4per_clkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, | |
922 | CD_CLKCTRL_CLKTRCTRL_HW_AUTO << | |
923 | CD_CLKCTRL_CLKTRCTRL_SHIFT); | |
924 | } | |
925 | ||
3776801d A |
926 | void prcm_init(void) |
927 | { | |
928 | switch (omap4_hw_init_context()) { | |
929 | case OMAP_INIT_CONTEXT_SPL: | |
930 | case OMAP_INIT_CONTEXT_UBOOT_FROM_NOR: | |
931 | case OMAP_INIT_CONTEXT_UBOOT_AFTER_CH: | |
25223a68 | 932 | enable_basic_clocks(); |
3776801d A |
933 | scale_vcores(); |
934 | setup_dplls(); | |
3776801d A |
935 | setup_non_essential_dplls(); |
936 | enable_non_essential_clocks(); | |
937 | break; | |
938 | default: | |
939 | break; | |
940 | } | |
941 | } |