]> git.ipfire.org Git - thirdparty/u-boot.git/blob - arch/arm/cpu/armv7/omap3/clock.c
Merge branch 'u-boot/master' into 'u-boot-arm/master'
[thirdparty/u-boot.git] / arch / arm / cpu / armv7 / omap3 / clock.c
1 /*
2 * (C) Copyright 2008
3 * Texas Instruments, <www.ti.com>
4 *
5 * Author :
6 * Manikandan Pillai <mani.pillai@ti.com>
7 *
8 * Derived from Beagle Board and OMAP3 SDP code by
9 * Richard Woodruff <r-woodruff2@ti.com>
10 * Syed Mohammed Khasim <khasim@ti.com>
11 *
12 * SPDX-License-Identifier: GPL-2.0+
13 */
14
15 #include <common.h>
16 #include <asm/io.h>
17 #include <asm/arch/clock.h>
18 #include <asm/arch/clocks_omap3.h>
19 #include <asm/arch/mem.h>
20 #include <asm/arch/sys_proto.h>
21 #include <environment.h>
22 #include <command.h>
23
24 /******************************************************************************
25 * get_sys_clk_speed() - determine reference oscillator speed
26 * based on known 32kHz clock and gptimer.
27 *****************************************************************************/
28 u32 get_osc_clk_speed(void)
29 {
30 u32 start, cstart, cend, cdiff, cdiv, val;
31 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
32 struct prm *prm_base = (struct prm *)PRM_BASE;
33 struct gptimer *gpt1_base = (struct gptimer *)OMAP34XX_GPT1;
34 struct s32ktimer *s32k_base = (struct s32ktimer *)SYNC_32KTIMER_BASE;
35
36 val = readl(&prm_base->clksrc_ctrl);
37
38 if (val & SYSCLKDIV_2)
39 cdiv = 2;
40 else
41 cdiv = 1;
42
43 /* enable timer2 */
44 val = readl(&prcm_base->clksel_wkup) | CLKSEL_GPT1;
45
46 /* select sys_clk for GPT1 */
47 writel(val, &prcm_base->clksel_wkup);
48
49 /* Enable I and F Clocks for GPT1 */
50 val = readl(&prcm_base->iclken_wkup) | EN_GPT1 | EN_32KSYNC;
51 writel(val, &prcm_base->iclken_wkup);
52
53 val = readl(&prcm_base->fclken_wkup) | EN_GPT1;
54 writel(val, &prcm_base->fclken_wkup);
55
56 writel(0, &gpt1_base->tldr); /* start counting at 0 */
57 writel(GPT_EN, &gpt1_base->tclr); /* enable clock */
58
59 /* enable 32kHz source, determine sys_clk via gauging */
60
61 /* start time in 20 cycles */
62 start = 20 + readl(&s32k_base->s32k_cr);
63
64 /* dead loop till start time */
65 while (readl(&s32k_base->s32k_cr) < start);
66
67 /* get start sys_clk count */
68 cstart = readl(&gpt1_base->tcrr);
69
70 /* wait for 40 cycles */
71 while (readl(&s32k_base->s32k_cr) < (start + 20)) ;
72 cend = readl(&gpt1_base->tcrr); /* get end sys_clk count */
73 cdiff = cend - cstart; /* get elapsed ticks */
74 cdiff *= cdiv;
75
76 /* based on number of ticks assign speed */
77 if (cdiff > 19000)
78 return S38_4M;
79 else if (cdiff > 15200)
80 return S26M;
81 else if (cdiff > 13000)
82 return S24M;
83 else if (cdiff > 9000)
84 return S19_2M;
85 else if (cdiff > 7600)
86 return S13M;
87 else
88 return S12M;
89 }
90
91 /******************************************************************************
92 * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on
93 * input oscillator clock frequency.
94 *****************************************************************************/
95 void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)
96 {
97 switch(osc_clk) {
98 case S38_4M:
99 *sys_clkin_sel = 4;
100 break;
101 case S26M:
102 *sys_clkin_sel = 3;
103 break;
104 case S19_2M:
105 *sys_clkin_sel = 2;
106 break;
107 case S13M:
108 *sys_clkin_sel = 1;
109 break;
110 case S12M:
111 default:
112 *sys_clkin_sel = 0;
113 }
114 }
115
116 /*
117 * OMAP34XX/35XX specific functions
118 */
119
120 static void dpll3_init_34xx(u32 sil_index, u32 clk_index)
121 {
122 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
123 dpll_param *ptr = (dpll_param *) get_core_dpll_param();
124 void (*f_lock_pll) (u32, u32, u32, u32);
125 int xip_safe, p0, p1, p2, p3;
126
127 xip_safe = is_running_in_sram();
128
129 /* Moving to the right sysclk and ES rev base */
130 ptr = ptr + (3 * clk_index) + sil_index;
131
132 if (xip_safe) {
133 /*
134 * CORE DPLL
135 * sr32(CM_CLKSEL2_EMU) set override to work when asleep
136 */
137 sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS);
138 wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
139 LDELAY);
140
141 /*
142 * For OMAP3 ES1.0 Errata 1.50, default value directly doesn't
143 * work. write another value and then default value.
144 */
145
146 /* CM_CLKSEL1_EMU[DIV_DPLL3] */
147 sr32(&prcm_base->clksel1_emu, 16, 5, (CORE_M3X2 + 1)) ;
148 sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2);
149
150 /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
151 sr32(&prcm_base->clksel1_pll, 27, 5, ptr->m2);
152
153 /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
154 sr32(&prcm_base->clksel1_pll, 16, 11, ptr->m);
155
156 /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
157 sr32(&prcm_base->clksel1_pll, 8, 7, ptr->n);
158
159 /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
160 sr32(&prcm_base->clksel1_pll, 6, 1, 0);
161
162 /* SSI */
163 sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV);
164 /* FSUSB */
165 sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV);
166 /* L4 */
167 sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV);
168 /* L3 */
169 sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV);
170 /* GFX */
171 sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV);
172 /* RESET MGR */
173 sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM);
174 /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
175 sr32(&prcm_base->clken_pll, 4, 4, ptr->fsel);
176 /* LOCK MODE */
177 sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK);
178
179 wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
180 LDELAY);
181 } else if (is_running_in_flash()) {
182 /*
183 * if running from flash, jump to small relocated code
184 * area in SRAM.
185 */
186 f_lock_pll = (void *) (SRAM_CLK_CODE);
187
188 p0 = readl(&prcm_base->clken_pll);
189 sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
190 /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
191 sr32(&p0, 4, 4, ptr->fsel);
192
193 p1 = readl(&prcm_base->clksel1_pll);
194 /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
195 sr32(&p1, 27, 5, ptr->m2);
196 /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
197 sr32(&p1, 16, 11, ptr->m);
198 /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
199 sr32(&p1, 8, 7, ptr->n);
200 /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
201 sr32(&p1, 6, 1, 0);
202
203 p2 = readl(&prcm_base->clksel_core);
204 /* SSI */
205 sr32(&p2, 8, 4, CORE_SSI_DIV);
206 /* FSUSB */
207 sr32(&p2, 4, 2, CORE_FUSB_DIV);
208 /* L4 */
209 sr32(&p2, 2, 2, CORE_L4_DIV);
210 /* L3 */
211 sr32(&p2, 0, 2, CORE_L3_DIV);
212
213 p3 = (u32)&prcm_base->idlest_ckgen;
214
215 (*f_lock_pll) (p0, p1, p2, p3);
216 }
217 }
218
219 static void dpll4_init_34xx(u32 sil_index, u32 clk_index)
220 {
221 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
222 dpll_param *ptr = (dpll_param *) get_per_dpll_param();
223
224 /* Moving it to the right sysclk base */
225 ptr = ptr + clk_index;
226
227 /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
228 sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
229 wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
230
231 /*
232 * Errata 1.50 Workaround for OMAP3 ES1.0 only
233 * If using default divisors, write default divisor + 1
234 * and then the actual divisor value
235 */
236 /* M6 */
237 sr32(&prcm_base->clksel1_emu, 24, 5, (PER_M6X2 + 1));
238 sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2);
239 /* M5 */
240 sr32(&prcm_base->clksel_cam, 0, 5, (PER_M5X2 + 1));
241 sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2);
242 /* M4 */
243 sr32(&prcm_base->clksel_dss, 0, 5, (PER_M4X2 + 1));
244 sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2);
245 /* M3 */
246 sr32(&prcm_base->clksel_dss, 8, 5, (PER_M3X2 + 1));
247 sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2);
248 /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
249 sr32(&prcm_base->clksel3_pll, 0, 5, (ptr->m2 + 1));
250 sr32(&prcm_base->clksel3_pll, 0, 5, ptr->m2);
251 /* Workaround end */
252
253 /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */
254 sr32(&prcm_base->clksel2_pll, 8, 11, ptr->m);
255
256 /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
257 sr32(&prcm_base->clksel2_pll, 0, 7, ptr->n);
258
259 /* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */
260 sr32(&prcm_base->clken_pll, 20, 4, ptr->fsel);
261
262 /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
263 sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK);
264 wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
265 }
266
267 static void dpll5_init_34xx(u32 sil_index, u32 clk_index)
268 {
269 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
270 dpll_param *ptr = (dpll_param *) get_per2_dpll_param();
271
272 /* Moving it to the right sysclk base */
273 ptr = ptr + clk_index;
274
275 /* PER2 DPLL (DPLL5) */
276 sr32(&prcm_base->clken2_pll, 0, 3, PLL_STOP);
277 wait_on_value(1, 0, &prcm_base->idlest2_ckgen, LDELAY);
278 sr32(&prcm_base->clksel5_pll, 0, 5, ptr->m2); /* set M2 (usbtll_fck) */
279 sr32(&prcm_base->clksel4_pll, 8, 11, ptr->m); /* set m (11-bit multiplier) */
280 sr32(&prcm_base->clksel4_pll, 0, 7, ptr->n); /* set n (7-bit divider)*/
281 sr32(&prcm_base->clken_pll, 4, 4, ptr->fsel); /* FREQSEL */
282 sr32(&prcm_base->clken2_pll, 0, 3, PLL_LOCK); /* lock mode */
283 wait_on_value(1, 1, &prcm_base->idlest2_ckgen, LDELAY);
284 }
285
286 static void mpu_init_34xx(u32 sil_index, u32 clk_index)
287 {
288 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
289 dpll_param *ptr = (dpll_param *) get_mpu_dpll_param();
290
291 /* Moving to the right sysclk and ES rev base */
292 ptr = ptr + (3 * clk_index) + sil_index;
293
294 /* MPU DPLL (unlocked already) */
295
296 /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
297 sr32(&prcm_base->clksel2_pll_mpu, 0, 5, ptr->m2);
298
299 /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
300 sr32(&prcm_base->clksel1_pll_mpu, 8, 11, ptr->m);
301
302 /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
303 sr32(&prcm_base->clksel1_pll_mpu, 0, 7, ptr->n);
304
305 /* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */
306 sr32(&prcm_base->clken_pll_mpu, 4, 4, ptr->fsel);
307 }
308
309 static void iva_init_34xx(u32 sil_index, u32 clk_index)
310 {
311 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
312 dpll_param *ptr = (dpll_param *) get_iva_dpll_param();
313
314 /* Moving to the right sysclk and ES rev base */
315 ptr = ptr + (3 * clk_index) + sil_index;
316
317 /* IVA DPLL */
318 /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
319 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);
320 wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
321
322 /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
323 sr32(&prcm_base->clksel2_pll_iva2, 0, 5, ptr->m2);
324
325 /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
326 sr32(&prcm_base->clksel1_pll_iva2, 8, 11, ptr->m);
327
328 /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
329 sr32(&prcm_base->clksel1_pll_iva2, 0, 7, ptr->n);
330
331 /* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */
332 sr32(&prcm_base->clken_pll_iva2, 4, 4, ptr->fsel);
333
334 /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
335 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK);
336
337 wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
338 }
339
340 /*
341 * OMAP3630 specific functions
342 */
343
344 static void dpll3_init_36xx(u32 sil_index, u32 clk_index)
345 {
346 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
347 dpll_param *ptr = (dpll_param *) get_36x_core_dpll_param();
348 void (*f_lock_pll) (u32, u32, u32, u32);
349 int xip_safe, p0, p1, p2, p3;
350
351 xip_safe = is_running_in_sram();
352
353 /* Moving it to the right sysclk base */
354 ptr += clk_index;
355
356 if (xip_safe) {
357 /* CORE DPLL */
358
359 /* Select relock bypass: CM_CLKEN_PLL[0:2] */
360 sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS);
361 wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
362 LDELAY);
363
364 /* CM_CLKSEL1_EMU[DIV_DPLL3] */
365 sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2);
366
367 /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
368 sr32(&prcm_base->clksel1_pll, 27, 5, ptr->m2);
369
370 /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
371 sr32(&prcm_base->clksel1_pll, 16, 11, ptr->m);
372
373 /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
374 sr32(&prcm_base->clksel1_pll, 8, 7, ptr->n);
375
376 /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
377 sr32(&prcm_base->clksel1_pll, 6, 1, 0);
378
379 /* SSI */
380 sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV);
381 /* FSUSB */
382 sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV);
383 /* L4 */
384 sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV);
385 /* L3 */
386 sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV);
387 /* GFX */
388 sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV_36X);
389 /* RESET MGR */
390 sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM);
391 /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
392 sr32(&prcm_base->clken_pll, 4, 4, ptr->fsel);
393 /* LOCK MODE */
394 sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK);
395
396 wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
397 LDELAY);
398 } else if (is_running_in_flash()) {
399 /*
400 * if running from flash, jump to small relocated code
401 * area in SRAM.
402 */
403 f_lock_pll = (void *) (SRAM_CLK_CODE);
404
405 p0 = readl(&prcm_base->clken_pll);
406 sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
407 /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
408 sr32(&p0, 4, 4, ptr->fsel);
409
410 p1 = readl(&prcm_base->clksel1_pll);
411 /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
412 sr32(&p1, 27, 5, ptr->m2);
413 /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
414 sr32(&p1, 16, 11, ptr->m);
415 /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
416 sr32(&p1, 8, 7, ptr->n);
417 /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
418 sr32(&p1, 6, 1, 0);
419
420 p2 = readl(&prcm_base->clksel_core);
421 /* SSI */
422 sr32(&p2, 8, 4, CORE_SSI_DIV);
423 /* FSUSB */
424 sr32(&p2, 4, 2, CORE_FUSB_DIV);
425 /* L4 */
426 sr32(&p2, 2, 2, CORE_L4_DIV);
427 /* L3 */
428 sr32(&p2, 0, 2, CORE_L3_DIV);
429
430 p3 = (u32)&prcm_base->idlest_ckgen;
431
432 (*f_lock_pll) (p0, p1, p2, p3);
433 }
434 }
435
436 static void dpll4_init_36xx(u32 sil_index, u32 clk_index)
437 {
438 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
439 struct dpll_per_36x_param *ptr;
440
441 ptr = (struct dpll_per_36x_param *)get_36x_per_dpll_param();
442
443 /* Moving it to the right sysclk base */
444 ptr += clk_index;
445
446 /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
447 sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
448 wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
449
450 /* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */
451 sr32(&prcm_base->clksel1_emu, 24, 6, ptr->m6);
452
453 /* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */
454 sr32(&prcm_base->clksel_cam, 0, 6, ptr->m5);
455
456 /* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */
457 sr32(&prcm_base->clksel_dss, 0, 6, ptr->m4);
458
459 /* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */
460 sr32(&prcm_base->clksel_dss, 8, 6, ptr->m3);
461
462 /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
463 sr32(&prcm_base->clksel3_pll, 0, 5, ptr->m2);
464
465 /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */
466 sr32(&prcm_base->clksel2_pll, 8, 12, ptr->m);
467
468 /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
469 sr32(&prcm_base->clksel2_pll, 0, 7, ptr->n);
470
471 /* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */
472 sr32(&prcm_base->clksel_core, 12, 2, ptr->m2div);
473
474 /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
475 sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK);
476 wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
477 }
478
479 static void dpll5_init_36xx(u32 sil_index, u32 clk_index)
480 {
481 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
482 dpll_param *ptr = (dpll_param *) get_36x_per2_dpll_param();
483
484 /* Moving it to the right sysclk base */
485 ptr = ptr + clk_index;
486
487 /* PER2 DPLL (DPLL5) */
488 sr32(&prcm_base->clken2_pll, 0, 3, PLL_STOP);
489 wait_on_value(1, 0, &prcm_base->idlest2_ckgen, LDELAY);
490 sr32(&prcm_base->clksel5_pll, 0, 5, ptr->m2); /* set M2 (usbtll_fck) */
491 sr32(&prcm_base->clksel4_pll, 8, 11, ptr->m); /* set m (11-bit multiplier) */
492 sr32(&prcm_base->clksel4_pll, 0, 7, ptr->n); /* set n (7-bit divider)*/
493 sr32(&prcm_base->clken2_pll, 0, 3, PLL_LOCK); /* lock mode */
494 wait_on_value(1, 1, &prcm_base->idlest2_ckgen, LDELAY);
495 }
496
497 static void mpu_init_36xx(u32 sil_index, u32 clk_index)
498 {
499 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
500 dpll_param *ptr = (dpll_param *) get_36x_mpu_dpll_param();
501
502 /* Moving to the right sysclk */
503 ptr += clk_index;
504
505 /* MPU DPLL (unlocked already */
506
507 /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
508 sr32(&prcm_base->clksel2_pll_mpu, 0, 5, ptr->m2);
509
510 /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
511 sr32(&prcm_base->clksel1_pll_mpu, 8, 11, ptr->m);
512
513 /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
514 sr32(&prcm_base->clksel1_pll_mpu, 0, 7, ptr->n);
515 }
516
517 static void iva_init_36xx(u32 sil_index, u32 clk_index)
518 {
519 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
520 dpll_param *ptr = (dpll_param *)get_36x_iva_dpll_param();
521
522 /* Moving to the right sysclk */
523 ptr += clk_index;
524
525 /* IVA DPLL */
526 /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
527 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);
528 wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
529
530 /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
531 sr32(&prcm_base->clksel2_pll_iva2, 0, 5, ptr->m2);
532
533 /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
534 sr32(&prcm_base->clksel1_pll_iva2, 8, 11, ptr->m);
535
536 /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
537 sr32(&prcm_base->clksel1_pll_iva2, 0, 7, ptr->n);
538
539 /* LOCK (MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
540 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK);
541
542 wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
543 }
544
545 /******************************************************************************
546 * prcm_init() - inits clocks for PRCM as defined in clocks.h
547 * called from SRAM, or Flash (using temp SRAM stack).
548 *****************************************************************************/
549 void prcm_init(void)
550 {
551 u32 osc_clk = 0, sys_clkin_sel;
552 u32 clk_index, sil_index = 0;
553 struct prm *prm_base = (struct prm *)PRM_BASE;
554 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
555
556 /*
557 * Gauge the input clock speed and find out the sys_clkin_sel
558 * value corresponding to the input clock.
559 */
560 osc_clk = get_osc_clk_speed();
561 get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
562
563 /* set input crystal speed */
564 sr32(&prm_base->clksel, 0, 3, sys_clkin_sel);
565
566 /* If the input clock is greater than 19.2M always divide/2 */
567 if (sys_clkin_sel > 2) {
568 /* input clock divider */
569 sr32(&prm_base->clksrc_ctrl, 6, 2, 2);
570 clk_index = sys_clkin_sel / 2;
571 } else {
572 /* input clock divider */
573 sr32(&prm_base->clksrc_ctrl, 6, 2, 1);
574 clk_index = sys_clkin_sel;
575 }
576
577 if (get_cpu_family() == CPU_OMAP36XX) {
578 /*
579 * In warm reset conditions on OMAP36xx/AM/DM37xx
580 * the rom code incorrectly sets the DPLL4 clock
581 * input divider to /6.5. Section 3.5.3.3.3.2.1 of
582 * the AM/DM37x TRM explains that the /6.5 divider
583 * is used only when the input clock is 13MHz.
584 *
585 * If the part is in this cpu family *and* the input
586 * clock *is not* 13 MHz, then reset the DPLL4 clock
587 * input divider to /1 as it should never set to /6.5
588 * in this case.
589 */
590 if (sys_clkin_sel != 1) /* 13 MHz */
591 /* Bit 8: DPLL4_CLKINP_DIV */
592 sr32(&prm_base->clksrc_ctrl, 8, 1, 0);
593
594 /* Unlock MPU DPLL (slows things down, and needed later) */
595 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS);
596 wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,
597 LDELAY);
598
599 dpll3_init_36xx(0, clk_index);
600 dpll4_init_36xx(0, clk_index);
601 dpll5_init_36xx(0, clk_index);
602 iva_init_36xx(0, clk_index);
603 mpu_init_36xx(0, clk_index);
604
605 /* Lock MPU DPLL to set frequency */
606 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK);
607 wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu,
608 LDELAY);
609 } else {
610 /*
611 * The DPLL tables are defined according to sysclk value and
612 * silicon revision. The clk_index value will be used to get
613 * the values for that input sysclk from the DPLL param table
614 * and sil_index will get the values for that SysClk for the
615 * appropriate silicon rev.
616 */
617 if (((get_cpu_family() == CPU_OMAP34XX)
618 && (get_cpu_rev() >= CPU_3XX_ES20)) ||
619 (get_cpu_family() == CPU_AM35XX))
620 sil_index = 1;
621
622 /* Unlock MPU DPLL (slows things down, and needed later) */
623 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS);
624 wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,
625 LDELAY);
626
627 dpll3_init_34xx(sil_index, clk_index);
628 dpll4_init_34xx(sil_index, clk_index);
629 dpll5_init_34xx(sil_index, clk_index);
630 if (get_cpu_family() != CPU_AM35XX)
631 iva_init_34xx(sil_index, clk_index);
632
633 mpu_init_34xx(sil_index, clk_index);
634
635 /* Lock MPU DPLL to set frequency */
636 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK);
637 wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu,
638 LDELAY);
639 }
640
641 /* Set up GPTimers to sys_clk source only */
642 sr32(&prcm_base->clksel_per, 0, 8, 0xff);
643 sr32(&prcm_base->clksel_wkup, 0, 1, 1);
644
645 sdelay(5000);
646 }
647
648 /*
649 * Enable usb ehci uhh, tll clocks
650 */
651 void ehci_clocks_enable(void)
652 {
653 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
654
655 /* Enable USBHOST_L3_ICLK (USBHOST_MICLK) */
656 sr32(&prcm_base->iclken_usbhost, 0, 1, 1);
657 /*
658 * Enable USBHOST_48M_FCLK (USBHOST_FCLK1)
659 * and USBHOST_120M_FCLK (USBHOST_FCLK2)
660 */
661 sr32(&prcm_base->fclken_usbhost, 0, 2, 3);
662 /* Enable USBTTL_ICLK */
663 sr32(&prcm_base->iclken3_core, 2, 1, 1);
664 /* Enable USBTTL_FCLK */
665 sr32(&prcm_base->fclken3_core, 2, 1, 1);
666 }
667
668 /******************************************************************************
669 * peripheral_enable() - Enable the clks & power for perifs (GPT2, UART1,...)
670 *****************************************************************************/
671 void per_clocks_enable(void)
672 {
673 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
674
675 /* Enable GP2 timer. */
676 sr32(&prcm_base->clksel_per, 0, 1, 0x1); /* GPT2 = sys clk */
677 sr32(&prcm_base->iclken_per, 3, 1, 0x1); /* ICKen GPT2 */
678 sr32(&prcm_base->fclken_per, 3, 1, 0x1); /* FCKen GPT2 */
679
680 #ifdef CONFIG_SYS_NS16550
681 /* Enable UART1 clocks */
682 sr32(&prcm_base->fclken1_core, 13, 1, 0x1);
683 sr32(&prcm_base->iclken1_core, 13, 1, 0x1);
684
685 /* UART 3 Clocks */
686 sr32(&prcm_base->fclken_per, 11, 1, 0x1);
687 sr32(&prcm_base->iclken_per, 11, 1, 0x1);
688 #endif
689
690 #ifdef CONFIG_OMAP3_GPIO_2
691 sr32(&prcm_base->fclken_per, 13, 1, 1);
692 sr32(&prcm_base->iclken_per, 13, 1, 1);
693 #endif
694 #ifdef CONFIG_OMAP3_GPIO_3
695 sr32(&prcm_base->fclken_per, 14, 1, 1);
696 sr32(&prcm_base->iclken_per, 14, 1, 1);
697 #endif
698 #ifdef CONFIG_OMAP3_GPIO_4
699 sr32(&prcm_base->fclken_per, 15, 1, 1);
700 sr32(&prcm_base->iclken_per, 15, 1, 1);
701 #endif
702 #ifdef CONFIG_OMAP3_GPIO_5
703 sr32(&prcm_base->fclken_per, 16, 1, 1);
704 sr32(&prcm_base->iclken_per, 16, 1, 1);
705 #endif
706 #ifdef CONFIG_OMAP3_GPIO_6
707 sr32(&prcm_base->fclken_per, 17, 1, 1);
708 sr32(&prcm_base->iclken_per, 17, 1, 1);
709 #endif
710
711 #ifdef CONFIG_SYS_I2C_OMAP34XX
712 /* Turn on all 3 I2C clocks */
713 sr32(&prcm_base->fclken1_core, 15, 3, 0x7);
714 sr32(&prcm_base->iclken1_core, 15, 3, 0x7); /* I2C1,2,3 = on */
715 #endif
716 /* Enable the ICLK for 32K Sync Timer as its used in udelay */
717 sr32(&prcm_base->iclken_wkup, 2, 1, 0x1);
718
719 if (get_cpu_family() != CPU_AM35XX)
720 sr32(&prcm_base->fclken_iva2, 0, 32, FCK_IVA2_ON);
721
722 sr32(&prcm_base->fclken1_core, 0, 32, FCK_CORE1_ON);
723 sr32(&prcm_base->iclken1_core, 0, 32, ICK_CORE1_ON);
724 sr32(&prcm_base->iclken2_core, 0, 32, ICK_CORE2_ON);
725 sr32(&prcm_base->fclken_wkup, 0, 32, FCK_WKUP_ON);
726 sr32(&prcm_base->iclken_wkup, 0, 32, ICK_WKUP_ON);
727 sr32(&prcm_base->fclken_dss, 0, 32, FCK_DSS_ON);
728 sr32(&prcm_base->iclken_dss, 0, 32, ICK_DSS_ON);
729 if (get_cpu_family() != CPU_AM35XX) {
730 sr32(&prcm_base->fclken_cam, 0, 32, FCK_CAM_ON);
731 sr32(&prcm_base->iclken_cam, 0, 32, ICK_CAM_ON);
732 }
733
734 sdelay(1000);
735 }