blob: 3acbc9c864cf379e9a69a102fcc9b1a69b3c2dc6 [file] [log] [blame]
Dirk Behme595d37b2008-12-14 09:47:14 +01001/*
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 *
Wolfgang Denkd79de1d2013-07-08 09:37:19 +020012 * SPDX-License-Identifier: GPL-2.0+
Dirk Behme595d37b2008-12-14 09:47:14 +010013 */
14
15#include <common.h>
16#include <asm/io.h>
Lokesh Vutla61c517f2013-05-30 02:54:32 +000017#include <asm/arch/clock.h>
Dirk Behme595d37b2008-12-14 09:47:14 +010018#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 *****************************************************************************/
28u32 get_osc_clk_speed(void)
29{
Sanjeev Premief7bd712010-02-08 11:33:25 -050030 u32 start, cstart, cend, cdiff, cdiv, val;
Dirk Behmedc7af202009-08-08 09:30:21 +020031 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;
Dirk Behme595d37b2008-12-14 09:47:14 +010035
36 val = readl(&prm_base->clksrc_ctrl);
37
Sanjeev Premief7bd712010-02-08 11:33:25 -050038 if (val & SYSCLKDIV_2)
39 cdiv = 2;
Sanjeev Premief7bd712010-02-08 11:33:25 -050040 else
Sanjeev Premief7bd712010-02-08 11:33:25 -050041 cdiv = 1;
Dirk Behme595d37b2008-12-14 09:47:14 +010042
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);
Sanjeev Premief7bd712010-02-08 11:33:25 -050052
Dirk Behme595d37b2008-12-14 09:47:14 +010053 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 */
Steve Sakoman24e81c12010-08-18 07:34:09 -070074 cdiff *= cdiv;
Sanjeev Premief7bd712010-02-08 11:33:25 -050075
Dirk Behme595d37b2008-12-14 09:47:14 +010076 /* 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 *****************************************************************************/
95void 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
Steve Sakoman24e81c12010-08-18 07:34:09 -0700116/*
117 * OMAP34XX/35XX specific functions
118 */
119
120static void dpll3_init_34xx(u32 sil_index, u32 clk_index)
Dirk Behme595d37b2008-12-14 09:47:14 +0100121{
Steve Sakoman24e81c12010-08-18 07:34:09 -0700122 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
123 dpll_param *ptr = (dpll_param *) get_core_dpll_param();
Dirk Behme595d37b2008-12-14 09:47:14 +0100124 void (*f_lock_pll) (u32, u32, u32, u32);
125 int xip_safe, p0, p1, p2, p3;
Dirk Behme595d37b2008-12-14 09:47:14 +0100126
127 xip_safe = is_running_in_sram();
128
Steve Sakoman24e81c12010-08-18 07:34:09 -0700129 /* Moving to the right sysclk and ES rev base */
130 ptr = ptr + (3 * clk_index) + sil_index;
Dirk Behme595d37b2008-12-14 09:47:14 +0100131
Dirk Behme595d37b2008-12-14 09:47:14 +0100132 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
Steve Sakoman24e81c12010-08-18 07:34:09 -0700146 /* CM_CLKSEL1_EMU[DIV_DPLL3] */
147 sr32(&prcm_base->clksel1_emu, 16, 5, (CORE_M3X2 + 1)) ;
Dirk Behme595d37b2008-12-14 09:47:14 +0100148 sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700149
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] */
Dirk Behme595d37b2008-12-14 09:47:14 +0100160 sr32(&prcm_base->clksel1_pll, 6, 1, 0);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700161
162 /* SSI */
Dirk Behme595d37b2008-12-14 09:47:14 +0100163 sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700164 /* FSUSB */
Dirk Behme595d37b2008-12-14 09:47:14 +0100165 sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700166 /* L4 */
Dirk Behme595d37b2008-12-14 09:47:14 +0100167 sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700168 /* L3 */
Dirk Behme595d37b2008-12-14 09:47:14 +0100169 sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700170 /* GFX */
171 sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV);
172 /* RESET MGR */
Dirk Behme595d37b2008-12-14 09:47:14 +0100173 sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700174 /* 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);
Dirk Behme595d37b2008-12-14 09:47:14 +0100178
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 */
Steve Sakoman24e81c12010-08-18 07:34:09 -0700186 f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
187 SRAM_VECT_CODE);
188
Dirk Behme595d37b2008-12-14 09:47:14 +0100189 p0 = readl(&prcm_base->clken_pll);
190 sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700191 /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
192 sr32(&p0, 4, 4, ptr->fsel);
Dirk Behme595d37b2008-12-14 09:47:14 +0100193
194 p1 = readl(&prcm_base->clksel1_pll);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700195 /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
196 sr32(&p1, 27, 5, ptr->m2);
197 /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
198 sr32(&p1, 16, 11, ptr->m);
199 /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
200 sr32(&p1, 8, 7, ptr->n);
201 /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
202 sr32(&p1, 6, 1, 0);
Dirk Behme595d37b2008-12-14 09:47:14 +0100203
204 p2 = readl(&prcm_base->clksel_core);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700205 /* SSI */
206 sr32(&p2, 8, 4, CORE_SSI_DIV);
207 /* FSUSB */
208 sr32(&p2, 4, 2, CORE_FUSB_DIV);
209 /* L4 */
210 sr32(&p2, 2, 2, CORE_L4_DIV);
211 /* L3 */
212 sr32(&p2, 0, 2, CORE_L3_DIV);
Dirk Behme595d37b2008-12-14 09:47:14 +0100213
214 p3 = (u32)&prcm_base->idlest_ckgen;
215
216 (*f_lock_pll) (p0, p1, p2, p3);
217 }
Steve Sakoman24e81c12010-08-18 07:34:09 -0700218}
Dirk Behme595d37b2008-12-14 09:47:14 +0100219
Steve Sakoman24e81c12010-08-18 07:34:09 -0700220static void dpll4_init_34xx(u32 sil_index, u32 clk_index)
221{
222 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
223 dpll_param *ptr = (dpll_param *) get_per_dpll_param();
Dirk Behme595d37b2008-12-14 09:47:14 +0100224
225 /* Moving it to the right sysclk base */
Steve Sakoman24e81c12010-08-18 07:34:09 -0700226 ptr = ptr + clk_index;
227
228 /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
229 sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
230 wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
Dirk Behme595d37b2008-12-14 09:47:14 +0100231
232 /*
233 * Errata 1.50 Workaround for OMAP3 ES1.0 only
234 * If using default divisors, write default divisor + 1
235 * and then the actual divisor value
236 */
Steve Sakoman24e81c12010-08-18 07:34:09 -0700237 /* M6 */
238 sr32(&prcm_base->clksel1_emu, 24, 5, (PER_M6X2 + 1));
239 sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2);
240 /* M5 */
241 sr32(&prcm_base->clksel_cam, 0, 5, (PER_M5X2 + 1));
242 sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2);
243 /* M4 */
244 sr32(&prcm_base->clksel_dss, 0, 5, (PER_M4X2 + 1));
245 sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2);
246 /* M3 */
247 sr32(&prcm_base->clksel_dss, 8, 5, (PER_M3X2 + 1));
248 sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2);
249 /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
250 sr32(&prcm_base->clksel3_pll, 0, 5, (ptr->m2 + 1));
251 sr32(&prcm_base->clksel3_pll, 0, 5, ptr->m2);
Dirk Behme595d37b2008-12-14 09:47:14 +0100252 /* Workaround end */
253
Steve Sakoman24e81c12010-08-18 07:34:09 -0700254 /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */
255 sr32(&prcm_base->clksel2_pll, 8, 11, ptr->m);
256
257 /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
258 sr32(&prcm_base->clksel2_pll, 0, 7, ptr->n);
259
260 /* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */
261 sr32(&prcm_base->clken_pll, 20, 4, ptr->fsel);
262
263 /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
264 sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK);
Dirk Behme595d37b2008-12-14 09:47:14 +0100265 wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700266}
Dirk Behme595d37b2008-12-14 09:47:14 +0100267
Alexander Holler96b549e2011-04-19 09:27:55 -0400268static void dpll5_init_34xx(u32 sil_index, u32 clk_index)
269{
270 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
271 dpll_param *ptr = (dpll_param *) get_per2_dpll_param();
272
273 /* Moving it to the right sysclk base */
274 ptr = ptr + clk_index;
275
276 /* PER2 DPLL (DPLL5) */
277 sr32(&prcm_base->clken2_pll, 0, 3, PLL_STOP);
278 wait_on_value(1, 0, &prcm_base->idlest2_ckgen, LDELAY);
279 sr32(&prcm_base->clksel5_pll, 0, 5, ptr->m2); /* set M2 (usbtll_fck) */
280 sr32(&prcm_base->clksel4_pll, 8, 11, ptr->m); /* set m (11-bit multiplier) */
281 sr32(&prcm_base->clksel4_pll, 0, 7, ptr->n); /* set n (7-bit divider)*/
282 sr32(&prcm_base->clken_pll, 4, 4, ptr->fsel); /* FREQSEL */
283 sr32(&prcm_base->clken2_pll, 0, 3, PLL_LOCK); /* lock mode */
284 wait_on_value(1, 1, &prcm_base->idlest2_ckgen, LDELAY);
285}
286
Steve Sakoman24e81c12010-08-18 07:34:09 -0700287static void mpu_init_34xx(u32 sil_index, u32 clk_index)
288{
289 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
290 dpll_param *ptr = (dpll_param *) get_mpu_dpll_param();
Dirk Behme595d37b2008-12-14 09:47:14 +0100291
Steve Sakoman24e81c12010-08-18 07:34:09 -0700292 /* Moving to the right sysclk and ES rev base */
293 ptr = ptr + (3 * clk_index) + sil_index;
Dirk Behme595d37b2008-12-14 09:47:14 +0100294
295 /* MPU DPLL (unlocked already) */
296
Steve Sakoman24e81c12010-08-18 07:34:09 -0700297 /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
298 sr32(&prcm_base->clksel2_pll_mpu, 0, 5, ptr->m2);
299
300 /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
301 sr32(&prcm_base->clksel1_pll_mpu, 8, 11, ptr->m);
302
303 /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
304 sr32(&prcm_base->clksel1_pll_mpu, 0, 7, ptr->n);
305
306 /* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */
307 sr32(&prcm_base->clken_pll_mpu, 4, 4, ptr->fsel);
308}
309
310static void iva_init_34xx(u32 sil_index, u32 clk_index)
311{
312 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
313 dpll_param *ptr = (dpll_param *) get_iva_dpll_param();
314
315 /* Moving to the right sysclk and ES rev base */
316 ptr = ptr + (3 * clk_index) + sil_index;
317
318 /* IVA DPLL */
319 /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
320 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);
321 wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
322
323 /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
324 sr32(&prcm_base->clksel2_pll_iva2, 0, 5, ptr->m2);
325
326 /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
327 sr32(&prcm_base->clksel1_pll_iva2, 8, 11, ptr->m);
328
329 /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
330 sr32(&prcm_base->clksel1_pll_iva2, 0, 7, ptr->n);
331
332 /* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */
333 sr32(&prcm_base->clken_pll_iva2, 4, 4, ptr->fsel);
334
335 /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
336 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK);
337
338 wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
339}
340
341/*
342 * OMAP3630 specific functions
343 */
344
345static void dpll3_init_36xx(u32 sil_index, u32 clk_index)
346{
347 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
348 dpll_param *ptr = (dpll_param *) get_36x_core_dpll_param();
349 void (*f_lock_pll) (u32, u32, u32, u32);
350 int xip_safe, p0, p1, p2, p3;
351
352 xip_safe = is_running_in_sram();
353
354 /* Moving it to the right sysclk base */
355 ptr += clk_index;
356
357 if (xip_safe) {
358 /* CORE DPLL */
359
360 /* Select relock bypass: CM_CLKEN_PLL[0:2] */
361 sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS);
362 wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
363 LDELAY);
364
365 /* CM_CLKSEL1_EMU[DIV_DPLL3] */
366 sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2);
367
368 /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
369 sr32(&prcm_base->clksel1_pll, 27, 5, ptr->m2);
370
371 /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
372 sr32(&prcm_base->clksel1_pll, 16, 11, ptr->m);
373
374 /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
375 sr32(&prcm_base->clksel1_pll, 8, 7, ptr->n);
376
377 /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
378 sr32(&prcm_base->clksel1_pll, 6, 1, 0);
379
380 /* SSI */
381 sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV);
382 /* FSUSB */
383 sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV);
384 /* L4 */
385 sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV);
386 /* L3 */
387 sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV);
388 /* GFX */
Vaibhav Hiremath7bddeac2011-09-03 21:29:59 -0400389 sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV_36X);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700390 /* RESET MGR */
391 sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM);
392 /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
393 sr32(&prcm_base->clken_pll, 4, 4, ptr->fsel);
394 /* LOCK MODE */
395 sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK);
396
397 wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
398 LDELAY);
399 } else if (is_running_in_flash()) {
400 /*
401 * if running from flash, jump to small relocated code
402 * area in SRAM.
403 */
404 f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
405 SRAM_VECT_CODE);
406
407 p0 = readl(&prcm_base->clken_pll);
408 sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
409 /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
410 sr32(&p0, 4, 4, ptr->fsel);
411
412 p1 = readl(&prcm_base->clksel1_pll);
413 /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
414 sr32(&p1, 27, 5, ptr->m2);
415 /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
416 sr32(&p1, 16, 11, ptr->m);
417 /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
418 sr32(&p1, 8, 7, ptr->n);
419 /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
420 sr32(&p1, 6, 1, 0);
421
422 p2 = readl(&prcm_base->clksel_core);
423 /* SSI */
424 sr32(&p2, 8, 4, CORE_SSI_DIV);
425 /* FSUSB */
426 sr32(&p2, 4, 2, CORE_FUSB_DIV);
427 /* L4 */
428 sr32(&p2, 2, 2, CORE_L4_DIV);
429 /* L3 */
430 sr32(&p2, 0, 2, CORE_L3_DIV);
431
432 p3 = (u32)&prcm_base->idlest_ckgen;
433
434 (*f_lock_pll) (p0, p1, p2, p3);
435 }
436}
437
438static void dpll4_init_36xx(u32 sil_index, u32 clk_index)
439{
440 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
441 struct dpll_per_36x_param *ptr;
442
443 ptr = (struct dpll_per_36x_param *)get_36x_per_dpll_param();
444
445 /* Moving it to the right sysclk base */
446 ptr += clk_index;
447
448 /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
449 sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
450 wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
451
452 /* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */
453 sr32(&prcm_base->clksel1_emu, 24, 6, ptr->m6);
454
455 /* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */
456 sr32(&prcm_base->clksel_cam, 0, 6, ptr->m5);
457
458 /* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */
459 sr32(&prcm_base->clksel_dss, 0, 6, ptr->m4);
460
461 /* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */
462 sr32(&prcm_base->clksel_dss, 8, 6, ptr->m3);
463
464 /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
465 sr32(&prcm_base->clksel3_pll, 0, 5, ptr->m2);
466
467 /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */
468 sr32(&prcm_base->clksel2_pll, 8, 12, ptr->m);
469
470 /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
471 sr32(&prcm_base->clksel2_pll, 0, 7, ptr->n);
472
473 /* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */
474 sr32(&prcm_base->clksel_core, 12, 2, ptr->m2div);
475
476 /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
477 sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK);
478 wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
479}
480
481static void mpu_init_36xx(u32 sil_index, u32 clk_index)
482{
483 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
484 dpll_param *ptr = (dpll_param *) get_36x_mpu_dpll_param();
485
486 /* Moving to the right sysclk */
487 ptr += clk_index;
488
489 /* MPU DPLL (unlocked already */
490
491 /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
492 sr32(&prcm_base->clksel2_pll_mpu, 0, 5, ptr->m2);
493
494 /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
495 sr32(&prcm_base->clksel1_pll_mpu, 8, 11, ptr->m);
496
497 /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
498 sr32(&prcm_base->clksel1_pll_mpu, 0, 7, ptr->n);
499}
Dirk Behme595d37b2008-12-14 09:47:14 +0100500
Steve Sakoman24e81c12010-08-18 07:34:09 -0700501static void iva_init_36xx(u32 sil_index, u32 clk_index)
502{
503 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
504 dpll_param *ptr = (dpll_param *)get_36x_iva_dpll_param();
Dirk Behme595d37b2008-12-14 09:47:14 +0100505
Steve Sakoman24e81c12010-08-18 07:34:09 -0700506 /* Moving to the right sysclk */
507 ptr += clk_index;
Dirk Behme595d37b2008-12-14 09:47:14 +0100508
Steve Sakoman24e81c12010-08-18 07:34:09 -0700509 /* IVA DPLL */
510 /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
Dirk Behme595d37b2008-12-14 09:47:14 +0100511 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);
512 wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700513
514 /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
515 sr32(&prcm_base->clksel2_pll_iva2, 0, 5, ptr->m2);
516
517 /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
518 sr32(&prcm_base->clksel1_pll_iva2, 8, 11, ptr->m);
519
520 /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
521 sr32(&prcm_base->clksel1_pll_iva2, 0, 7, ptr->n);
522
523 /* LOCK (MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
Dirk Behme595d37b2008-12-14 09:47:14 +0100524 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700525
Dirk Behme595d37b2008-12-14 09:47:14 +0100526 wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700527}
528
529/******************************************************************************
530 * prcm_init() - inits clocks for PRCM as defined in clocks.h
531 * called from SRAM, or Flash (using temp SRAM stack).
532 *****************************************************************************/
533void prcm_init(void)
534{
535 u32 osc_clk = 0, sys_clkin_sel;
536 u32 clk_index, sil_index = 0;
537 struct prm *prm_base = (struct prm *)PRM_BASE;
538 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
539
540 /*
541 * Gauge the input clock speed and find out the sys_clkin_sel
542 * value corresponding to the input clock.
543 */
544 osc_clk = get_osc_clk_speed();
545 get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
546
547 /* set input crystal speed */
548 sr32(&prm_base->clksel, 0, 3, sys_clkin_sel);
549
550 /* If the input clock is greater than 19.2M always divide/2 */
551 if (sys_clkin_sel > 2) {
552 /* input clock divider */
553 sr32(&prm_base->clksrc_ctrl, 6, 2, 2);
554 clk_index = sys_clkin_sel / 2;
555 } else {
556 /* input clock divider */
557 sr32(&prm_base->clksrc_ctrl, 6, 2, 1);
558 clk_index = sys_clkin_sel;
559 }
560
561 if (get_cpu_family() == CPU_OMAP36XX) {
Matt Porterede13a42012-05-07 16:49:21 +0000562 /*
563 * In warm reset conditions on OMAP36xx/AM/DM37xx
564 * the rom code incorrectly sets the DPLL4 clock
565 * input divider to /6.5. Section 3.5.3.3.3.2.1 of
566 * the AM/DM37x TRM explains that the /6.5 divider
567 * is used only when the input clock is 13MHz.
568 *
569 * If the part is in this cpu family *and* the input
570 * clock *is not* 13 MHz, then reset the DPLL4 clock
571 * input divider to /1 as it should never set to /6.5
572 * in this case.
573 */
574 if (sys_clkin_sel != 1) /* 13 MHz */
575 /* Bit 8: DPLL4_CLKINP_DIV */
576 sr32(&prm_base->clksrc_ctrl, 8, 1, 0);
577
Steve Sakoman24e81c12010-08-18 07:34:09 -0700578 /* Unlock MPU DPLL (slows things down, and needed later) */
579 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS);
580 wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,
581 LDELAY);
582
583 dpll3_init_36xx(0, clk_index);
584 dpll4_init_36xx(0, clk_index);
Eric Benard565f6372011-06-10 12:21:52 +0000585 dpll5_init_34xx(0, clk_index);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700586 iva_init_36xx(0, clk_index);
587 mpu_init_36xx(0, clk_index);
588
589 /* Lock MPU DPLL to set frequency */
590 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK);
591 wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu,
592 LDELAY);
593 } else {
594 /*
595 * The DPLL tables are defined according to sysclk value and
596 * silicon revision. The clk_index value will be used to get
597 * the values for that input sysclk from the DPLL param table
598 * and sil_index will get the values for that SysClk for the
599 * appropriate silicon rev.
600 */
601 if (((get_cpu_family() == CPU_OMAP34XX)
602 && (get_cpu_rev() >= CPU_3XX_ES20)) ||
603 (get_cpu_family() == CPU_AM35XX))
604 sil_index = 1;
605
606 /* Unlock MPU DPLL (slows things down, and needed later) */
607 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS);
608 wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,
609 LDELAY);
610
611 dpll3_init_34xx(sil_index, clk_index);
612 dpll4_init_34xx(sil_index, clk_index);
Alexander Holler96b549e2011-04-19 09:27:55 -0400613 dpll5_init_34xx(sil_index, clk_index);
Vaibhav Hiremath8f612c32011-09-03 21:35:31 -0400614 if (get_cpu_family() != CPU_AM35XX)
615 iva_init_34xx(sil_index, clk_index);
616
Steve Sakoman24e81c12010-08-18 07:34:09 -0700617 mpu_init_34xx(sil_index, clk_index);
618
619 /* Lock MPU DPLL to set frequency */
620 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK);
621 wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu,
622 LDELAY);
623 }
Dirk Behme595d37b2008-12-14 09:47:14 +0100624
625 /* Set up GPTimers to sys_clk source only */
626 sr32(&prcm_base->clksel_per, 0, 8, 0xff);
627 sr32(&prcm_base->clksel_wkup, 0, 1, 1);
628
629 sdelay(5000);
630}
631
Govindraj.R3968a6a2012-02-06 03:55:35 +0000632/*
633 * Enable usb ehci uhh, tll clocks
634 */
635void ehci_clocks_enable(void)
636{
637 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
638
639 /* Enable USBHOST_L3_ICLK (USBHOST_MICLK) */
640 sr32(&prcm_base->iclken_usbhost, 0, 1, 1);
641 /*
642 * Enable USBHOST_48M_FCLK (USBHOST_FCLK1)
643 * and USBHOST_120M_FCLK (USBHOST_FCLK2)
644 */
645 sr32(&prcm_base->fclken_usbhost, 0, 2, 3);
646 /* Enable USBTTL_ICLK */
647 sr32(&prcm_base->iclken3_core, 2, 1, 1);
648 /* Enable USBTTL_FCLK */
649 sr32(&prcm_base->fclken3_core, 2, 1, 1);
650}
651
Dirk Behme595d37b2008-12-14 09:47:14 +0100652/******************************************************************************
653 * peripheral_enable() - Enable the clks & power for perifs (GPT2, UART1,...)
654 *****************************************************************************/
655void per_clocks_enable(void)
656{
Dirk Behmedc7af202009-08-08 09:30:21 +0200657 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
Dirk Behme595d37b2008-12-14 09:47:14 +0100658
659 /* Enable GP2 timer. */
660 sr32(&prcm_base->clksel_per, 0, 1, 0x1); /* GPT2 = sys clk */
661 sr32(&prcm_base->iclken_per, 3, 1, 0x1); /* ICKen GPT2 */
662 sr32(&prcm_base->fclken_per, 3, 1, 0x1); /* FCKen GPT2 */
663
664#ifdef CONFIG_SYS_NS16550
665 /* Enable UART1 clocks */
666 sr32(&prcm_base->fclken1_core, 13, 1, 0x1);
667 sr32(&prcm_base->iclken1_core, 13, 1, 0x1);
668
669 /* UART 3 Clocks */
670 sr32(&prcm_base->fclken_per, 11, 1, 0x1);
671 sr32(&prcm_base->iclken_per, 11, 1, 0x1);
672#endif
Tom Rixde8ab062009-05-29 18:57:31 -0500673
674#ifdef CONFIG_OMAP3_GPIO_2
675 sr32(&prcm_base->fclken_per, 13, 1, 1);
676 sr32(&prcm_base->iclken_per, 13, 1, 1);
677#endif
678#ifdef CONFIG_OMAP3_GPIO_3
679 sr32(&prcm_base->fclken_per, 14, 1, 1);
680 sr32(&prcm_base->iclken_per, 14, 1, 1);
681#endif
682#ifdef CONFIG_OMAP3_GPIO_4
683 sr32(&prcm_base->fclken_per, 15, 1, 1);
684 sr32(&prcm_base->iclken_per, 15, 1, 1);
685#endif
686#ifdef CONFIG_OMAP3_GPIO_5
687 sr32(&prcm_base->fclken_per, 16, 1, 1);
688 sr32(&prcm_base->iclken_per, 16, 1, 1);
689#endif
690#ifdef CONFIG_OMAP3_GPIO_6
691 sr32(&prcm_base->fclken_per, 17, 1, 1);
692 sr32(&prcm_base->iclken_per, 17, 1, 1);
693#endif
694
Dirk Behme595d37b2008-12-14 09:47:14 +0100695#ifdef CONFIG_DRIVER_OMAP34XX_I2C
696 /* Turn on all 3 I2C clocks */
697 sr32(&prcm_base->fclken1_core, 15, 3, 0x7);
698 sr32(&prcm_base->iclken1_core, 15, 3, 0x7); /* I2C1,2,3 = on */
699#endif
700 /* Enable the ICLK for 32K Sync Timer as its used in udelay */
701 sr32(&prcm_base->iclken_wkup, 2, 1, 0x1);
702
Vaibhav Hiremath8f612c32011-09-03 21:35:31 -0400703 if (get_cpu_family() != CPU_AM35XX)
704 sr32(&prcm_base->fclken_iva2, 0, 32, FCK_IVA2_ON);
705
Dirk Behme595d37b2008-12-14 09:47:14 +0100706 sr32(&prcm_base->fclken1_core, 0, 32, FCK_CORE1_ON);
707 sr32(&prcm_base->iclken1_core, 0, 32, ICK_CORE1_ON);
708 sr32(&prcm_base->iclken2_core, 0, 32, ICK_CORE2_ON);
709 sr32(&prcm_base->fclken_wkup, 0, 32, FCK_WKUP_ON);
710 sr32(&prcm_base->iclken_wkup, 0, 32, ICK_WKUP_ON);
711 sr32(&prcm_base->fclken_dss, 0, 32, FCK_DSS_ON);
712 sr32(&prcm_base->iclken_dss, 0, 32, ICK_DSS_ON);
Vaibhav Hiremath8f612c32011-09-03 21:35:31 -0400713 if (get_cpu_family() != CPU_AM35XX) {
714 sr32(&prcm_base->fclken_cam, 0, 32, FCK_CAM_ON);
715 sr32(&prcm_base->iclken_cam, 0, 32, ICK_CAM_ON);
716 }
Dirk Behme595d37b2008-12-14 09:47:14 +0100717 sr32(&prcm_base->fclken_per, 0, 32, FCK_PER_ON);
718 sr32(&prcm_base->iclken_per, 0, 32, ICK_PER_ON);
719
720 sdelay(1000);
721}