blob: 2238c52e3bec7c23d0c97546cba293788d2db7de [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 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License as
14 * published by the Free Software Foundation; either version 2 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
25 * MA 02111-1307 USA
26 */
27
28#include <common.h>
29#include <asm/io.h>
30#include <asm/arch/clocks.h>
31#include <asm/arch/clocks_omap3.h>
32#include <asm/arch/mem.h>
33#include <asm/arch/sys_proto.h>
34#include <environment.h>
35#include <command.h>
36
37/******************************************************************************
38 * get_sys_clk_speed() - determine reference oscillator speed
39 * based on known 32kHz clock and gptimer.
40 *****************************************************************************/
41u32 get_osc_clk_speed(void)
42{
Sanjeev Premief7bd712010-02-08 11:33:25 -050043 u32 start, cstart, cend, cdiff, cdiv, val;
Dirk Behmedc7af202009-08-08 09:30:21 +020044 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
45 struct prm *prm_base = (struct prm *)PRM_BASE;
46 struct gptimer *gpt1_base = (struct gptimer *)OMAP34XX_GPT1;
47 struct s32ktimer *s32k_base = (struct s32ktimer *)SYNC_32KTIMER_BASE;
Dirk Behme595d37b2008-12-14 09:47:14 +010048
49 val = readl(&prm_base->clksrc_ctrl);
50
Sanjeev Premief7bd712010-02-08 11:33:25 -050051 if (val & SYSCLKDIV_2)
52 cdiv = 2;
Sanjeev Premief7bd712010-02-08 11:33:25 -050053 else
Sanjeev Premief7bd712010-02-08 11:33:25 -050054 cdiv = 1;
Dirk Behme595d37b2008-12-14 09:47:14 +010055
56 /* enable timer2 */
57 val = readl(&prcm_base->clksel_wkup) | CLKSEL_GPT1;
58
59 /* select sys_clk for GPT1 */
60 writel(val, &prcm_base->clksel_wkup);
61
62 /* Enable I and F Clocks for GPT1 */
63 val = readl(&prcm_base->iclken_wkup) | EN_GPT1 | EN_32KSYNC;
64 writel(val, &prcm_base->iclken_wkup);
Sanjeev Premief7bd712010-02-08 11:33:25 -050065
Dirk Behme595d37b2008-12-14 09:47:14 +010066 val = readl(&prcm_base->fclken_wkup) | EN_GPT1;
67 writel(val, &prcm_base->fclken_wkup);
68
69 writel(0, &gpt1_base->tldr); /* start counting at 0 */
70 writel(GPT_EN, &gpt1_base->tclr); /* enable clock */
71
72 /* enable 32kHz source, determine sys_clk via gauging */
73
74 /* start time in 20 cycles */
75 start = 20 + readl(&s32k_base->s32k_cr);
76
77 /* dead loop till start time */
78 while (readl(&s32k_base->s32k_cr) < start);
79
80 /* get start sys_clk count */
81 cstart = readl(&gpt1_base->tcrr);
82
83 /* wait for 40 cycles */
84 while (readl(&s32k_base->s32k_cr) < (start + 20)) ;
85 cend = readl(&gpt1_base->tcrr); /* get end sys_clk count */
86 cdiff = cend - cstart; /* get elapsed ticks */
Steve Sakoman24e81c12010-08-18 07:34:09 -070087 cdiff *= cdiv;
Sanjeev Premief7bd712010-02-08 11:33:25 -050088
Dirk Behme595d37b2008-12-14 09:47:14 +010089 /* based on number of ticks assign speed */
90 if (cdiff > 19000)
91 return S38_4M;
92 else if (cdiff > 15200)
93 return S26M;
94 else if (cdiff > 13000)
95 return S24M;
96 else if (cdiff > 9000)
97 return S19_2M;
98 else if (cdiff > 7600)
99 return S13M;
100 else
101 return S12M;
102}
103
104/******************************************************************************
105 * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on
106 * input oscillator clock frequency.
107 *****************************************************************************/
108void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)
109{
110 switch(osc_clk) {
111 case S38_4M:
112 *sys_clkin_sel = 4;
113 break;
114 case S26M:
115 *sys_clkin_sel = 3;
116 break;
117 case S19_2M:
118 *sys_clkin_sel = 2;
119 break;
120 case S13M:
121 *sys_clkin_sel = 1;
122 break;
123 case S12M:
124 default:
125 *sys_clkin_sel = 0;
126 }
127}
128
Steve Sakoman24e81c12010-08-18 07:34:09 -0700129/*
130 * OMAP34XX/35XX specific functions
131 */
132
133static void dpll3_init_34xx(u32 sil_index, u32 clk_index)
Dirk Behme595d37b2008-12-14 09:47:14 +0100134{
Steve Sakoman24e81c12010-08-18 07:34:09 -0700135 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
136 dpll_param *ptr = (dpll_param *) get_core_dpll_param();
Dirk Behme595d37b2008-12-14 09:47:14 +0100137 void (*f_lock_pll) (u32, u32, u32, u32);
138 int xip_safe, p0, p1, p2, p3;
Dirk Behme595d37b2008-12-14 09:47:14 +0100139
140 xip_safe = is_running_in_sram();
141
Steve Sakoman24e81c12010-08-18 07:34:09 -0700142 /* Moving to the right sysclk and ES rev base */
143 ptr = ptr + (3 * clk_index) + sil_index;
Dirk Behme595d37b2008-12-14 09:47:14 +0100144
Dirk Behme595d37b2008-12-14 09:47:14 +0100145 if (xip_safe) {
146 /*
147 * CORE DPLL
148 * sr32(CM_CLKSEL2_EMU) set override to work when asleep
149 */
150 sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS);
151 wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
152 LDELAY);
153
154 /*
155 * For OMAP3 ES1.0 Errata 1.50, default value directly doesn't
156 * work. write another value and then default value.
157 */
158
Steve Sakoman24e81c12010-08-18 07:34:09 -0700159 /* CM_CLKSEL1_EMU[DIV_DPLL3] */
160 sr32(&prcm_base->clksel1_emu, 16, 5, (CORE_M3X2 + 1)) ;
Dirk Behme595d37b2008-12-14 09:47:14 +0100161 sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700162
163 /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
164 sr32(&prcm_base->clksel1_pll, 27, 5, ptr->m2);
165
166 /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
167 sr32(&prcm_base->clksel1_pll, 16, 11, ptr->m);
168
169 /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
170 sr32(&prcm_base->clksel1_pll, 8, 7, ptr->n);
171
172 /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
Dirk Behme595d37b2008-12-14 09:47:14 +0100173 sr32(&prcm_base->clksel1_pll, 6, 1, 0);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700174
175 /* SSI */
Dirk Behme595d37b2008-12-14 09:47:14 +0100176 sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700177 /* FSUSB */
Dirk Behme595d37b2008-12-14 09:47:14 +0100178 sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700179 /* L4 */
Dirk Behme595d37b2008-12-14 09:47:14 +0100180 sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700181 /* L3 */
Dirk Behme595d37b2008-12-14 09:47:14 +0100182 sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700183 /* GFX */
184 sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV);
185 /* RESET MGR */
Dirk Behme595d37b2008-12-14 09:47:14 +0100186 sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700187 /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
188 sr32(&prcm_base->clken_pll, 4, 4, ptr->fsel);
189 /* LOCK MODE */
190 sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK);
Dirk Behme595d37b2008-12-14 09:47:14 +0100191
192 wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
193 LDELAY);
194 } else if (is_running_in_flash()) {
195 /*
196 * if running from flash, jump to small relocated code
197 * area in SRAM.
198 */
Steve Sakoman24e81c12010-08-18 07:34:09 -0700199 f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
200 SRAM_VECT_CODE);
201
Dirk Behme595d37b2008-12-14 09:47:14 +0100202 p0 = readl(&prcm_base->clken_pll);
203 sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700204 /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
205 sr32(&p0, 4, 4, ptr->fsel);
Dirk Behme595d37b2008-12-14 09:47:14 +0100206
207 p1 = readl(&prcm_base->clksel1_pll);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700208 /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
209 sr32(&p1, 27, 5, ptr->m2);
210 /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
211 sr32(&p1, 16, 11, ptr->m);
212 /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
213 sr32(&p1, 8, 7, ptr->n);
214 /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
215 sr32(&p1, 6, 1, 0);
Dirk Behme595d37b2008-12-14 09:47:14 +0100216
217 p2 = readl(&prcm_base->clksel_core);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700218 /* SSI */
219 sr32(&p2, 8, 4, CORE_SSI_DIV);
220 /* FSUSB */
221 sr32(&p2, 4, 2, CORE_FUSB_DIV);
222 /* L4 */
223 sr32(&p2, 2, 2, CORE_L4_DIV);
224 /* L3 */
225 sr32(&p2, 0, 2, CORE_L3_DIV);
Dirk Behme595d37b2008-12-14 09:47:14 +0100226
227 p3 = (u32)&prcm_base->idlest_ckgen;
228
229 (*f_lock_pll) (p0, p1, p2, p3);
230 }
Steve Sakoman24e81c12010-08-18 07:34:09 -0700231}
Dirk Behme595d37b2008-12-14 09:47:14 +0100232
Steve Sakoman24e81c12010-08-18 07:34:09 -0700233static void dpll4_init_34xx(u32 sil_index, u32 clk_index)
234{
235 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
236 dpll_param *ptr = (dpll_param *) get_per_dpll_param();
Dirk Behme595d37b2008-12-14 09:47:14 +0100237
238 /* Moving it to the right sysclk base */
Steve Sakoman24e81c12010-08-18 07:34:09 -0700239 ptr = ptr + clk_index;
240
241 /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
242 sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
243 wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
Dirk Behme595d37b2008-12-14 09:47:14 +0100244
245 /*
246 * Errata 1.50 Workaround for OMAP3 ES1.0 only
247 * If using default divisors, write default divisor + 1
248 * and then the actual divisor value
249 */
Steve Sakoman24e81c12010-08-18 07:34:09 -0700250 /* M6 */
251 sr32(&prcm_base->clksel1_emu, 24, 5, (PER_M6X2 + 1));
252 sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2);
253 /* M5 */
254 sr32(&prcm_base->clksel_cam, 0, 5, (PER_M5X2 + 1));
255 sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2);
256 /* M4 */
257 sr32(&prcm_base->clksel_dss, 0, 5, (PER_M4X2 + 1));
258 sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2);
259 /* M3 */
260 sr32(&prcm_base->clksel_dss, 8, 5, (PER_M3X2 + 1));
261 sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2);
262 /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
263 sr32(&prcm_base->clksel3_pll, 0, 5, (ptr->m2 + 1));
264 sr32(&prcm_base->clksel3_pll, 0, 5, ptr->m2);
Dirk Behme595d37b2008-12-14 09:47:14 +0100265 /* Workaround end */
266
Steve Sakoman24e81c12010-08-18 07:34:09 -0700267 /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */
268 sr32(&prcm_base->clksel2_pll, 8, 11, ptr->m);
269
270 /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
271 sr32(&prcm_base->clksel2_pll, 0, 7, ptr->n);
272
273 /* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */
274 sr32(&prcm_base->clken_pll, 20, 4, ptr->fsel);
275
276 /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
277 sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK);
Dirk Behme595d37b2008-12-14 09:47:14 +0100278 wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700279}
Dirk Behme595d37b2008-12-14 09:47:14 +0100280
Steve Sakoman24e81c12010-08-18 07:34:09 -0700281static void mpu_init_34xx(u32 sil_index, u32 clk_index)
282{
283 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
284 dpll_param *ptr = (dpll_param *) get_mpu_dpll_param();
Dirk Behme595d37b2008-12-14 09:47:14 +0100285
Steve Sakoman24e81c12010-08-18 07:34:09 -0700286 /* Moving to the right sysclk and ES rev base */
287 ptr = ptr + (3 * clk_index) + sil_index;
Dirk Behme595d37b2008-12-14 09:47:14 +0100288
289 /* MPU DPLL (unlocked already) */
290
Steve Sakoman24e81c12010-08-18 07:34:09 -0700291 /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
292 sr32(&prcm_base->clksel2_pll_mpu, 0, 5, ptr->m2);
293
294 /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
295 sr32(&prcm_base->clksel1_pll_mpu, 8, 11, ptr->m);
296
297 /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
298 sr32(&prcm_base->clksel1_pll_mpu, 0, 7, ptr->n);
299
300 /* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */
301 sr32(&prcm_base->clken_pll_mpu, 4, 4, ptr->fsel);
302}
303
304static void iva_init_34xx(u32 sil_index, u32 clk_index)
305{
306 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
307 dpll_param *ptr = (dpll_param *) get_iva_dpll_param();
308
309 /* Moving to the right sysclk and ES rev base */
310 ptr = ptr + (3 * clk_index) + sil_index;
311
312 /* IVA DPLL */
313 /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
314 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);
315 wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
316
317 /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
318 sr32(&prcm_base->clksel2_pll_iva2, 0, 5, ptr->m2);
319
320 /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
321 sr32(&prcm_base->clksel1_pll_iva2, 8, 11, ptr->m);
322
323 /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
324 sr32(&prcm_base->clksel1_pll_iva2, 0, 7, ptr->n);
325
326 /* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */
327 sr32(&prcm_base->clken_pll_iva2, 4, 4, ptr->fsel);
328
329 /* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
330 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK);
331
332 wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
333}
334
335/*
336 * OMAP3630 specific functions
337 */
338
339static void dpll3_init_36xx(u32 sil_index, u32 clk_index)
340{
341 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
342 dpll_param *ptr = (dpll_param *) get_36x_core_dpll_param();
343 void (*f_lock_pll) (u32, u32, u32, u32);
344 int xip_safe, p0, p1, p2, p3;
345
346 xip_safe = is_running_in_sram();
347
348 /* Moving it to the right sysclk base */
349 ptr += clk_index;
350
351 if (xip_safe) {
352 /* CORE DPLL */
353
354 /* Select relock bypass: CM_CLKEN_PLL[0:2] */
355 sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS);
356 wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
357 LDELAY);
358
359 /* CM_CLKSEL1_EMU[DIV_DPLL3] */
360 sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2);
361
362 /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
363 sr32(&prcm_base->clksel1_pll, 27, 5, ptr->m2);
364
365 /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
366 sr32(&prcm_base->clksel1_pll, 16, 11, ptr->m);
367
368 /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
369 sr32(&prcm_base->clksel1_pll, 8, 7, ptr->n);
370
371 /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
372 sr32(&prcm_base->clksel1_pll, 6, 1, 0);
373
374 /* SSI */
375 sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV);
376 /* FSUSB */
377 sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV);
378 /* L4 */
379 sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV);
380 /* L3 */
381 sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV);
382 /* GFX */
383 sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV);
384 /* RESET MGR */
385 sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM);
386 /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
387 sr32(&prcm_base->clken_pll, 4, 4, ptr->fsel);
388 /* LOCK MODE */
389 sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK);
390
391 wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
392 LDELAY);
393 } else if (is_running_in_flash()) {
394 /*
395 * if running from flash, jump to small relocated code
396 * area in SRAM.
397 */
398 f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
399 SRAM_VECT_CODE);
400
401 p0 = readl(&prcm_base->clken_pll);
402 sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
403 /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
404 sr32(&p0, 4, 4, ptr->fsel);
405
406 p1 = readl(&prcm_base->clksel1_pll);
407 /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
408 sr32(&p1, 27, 5, ptr->m2);
409 /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
410 sr32(&p1, 16, 11, ptr->m);
411 /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
412 sr32(&p1, 8, 7, ptr->n);
413 /* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
414 sr32(&p1, 6, 1, 0);
415
416 p2 = readl(&prcm_base->clksel_core);
417 /* SSI */
418 sr32(&p2, 8, 4, CORE_SSI_DIV);
419 /* FSUSB */
420 sr32(&p2, 4, 2, CORE_FUSB_DIV);
421 /* L4 */
422 sr32(&p2, 2, 2, CORE_L4_DIV);
423 /* L3 */
424 sr32(&p2, 0, 2, CORE_L3_DIV);
425
426 p3 = (u32)&prcm_base->idlest_ckgen;
427
428 (*f_lock_pll) (p0, p1, p2, p3);
429 }
430}
431
432static void dpll4_init_36xx(u32 sil_index, u32 clk_index)
433{
434 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
435 struct dpll_per_36x_param *ptr;
436
437 ptr = (struct dpll_per_36x_param *)get_36x_per_dpll_param();
438
439 /* Moving it to the right sysclk base */
440 ptr += clk_index;
441
442 /* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
443 sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
444 wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
445
446 /* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */
447 sr32(&prcm_base->clksel1_emu, 24, 6, ptr->m6);
448
449 /* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */
450 sr32(&prcm_base->clksel_cam, 0, 6, ptr->m5);
451
452 /* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */
453 sr32(&prcm_base->clksel_dss, 0, 6, ptr->m4);
454
455 /* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */
456 sr32(&prcm_base->clksel_dss, 8, 6, ptr->m3);
457
458 /* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
459 sr32(&prcm_base->clksel3_pll, 0, 5, ptr->m2);
460
461 /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */
462 sr32(&prcm_base->clksel2_pll, 8, 12, ptr->m);
463
464 /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
465 sr32(&prcm_base->clksel2_pll, 0, 7, ptr->n);
466
467 /* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */
468 sr32(&prcm_base->clksel_core, 12, 2, ptr->m2div);
469
470 /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
471 sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK);
472 wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
473}
474
475static void mpu_init_36xx(u32 sil_index, u32 clk_index)
476{
477 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
478 dpll_param *ptr = (dpll_param *) get_36x_mpu_dpll_param();
479
480 /* Moving to the right sysclk */
481 ptr += clk_index;
482
483 /* MPU DPLL (unlocked already */
484
485 /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
486 sr32(&prcm_base->clksel2_pll_mpu, 0, 5, ptr->m2);
487
488 /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
489 sr32(&prcm_base->clksel1_pll_mpu, 8, 11, ptr->m);
490
491 /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
492 sr32(&prcm_base->clksel1_pll_mpu, 0, 7, ptr->n);
493}
Dirk Behme595d37b2008-12-14 09:47:14 +0100494
Steve Sakoman24e81c12010-08-18 07:34:09 -0700495static void iva_init_36xx(u32 sil_index, u32 clk_index)
496{
497 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
498 dpll_param *ptr = (dpll_param *)get_36x_iva_dpll_param();
Dirk Behme595d37b2008-12-14 09:47:14 +0100499
Steve Sakoman24e81c12010-08-18 07:34:09 -0700500 /* Moving to the right sysclk */
501 ptr += clk_index;
Dirk Behme595d37b2008-12-14 09:47:14 +0100502
Steve Sakoman24e81c12010-08-18 07:34:09 -0700503 /* IVA DPLL */
504 /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
Dirk Behme595d37b2008-12-14 09:47:14 +0100505 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);
506 wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700507
508 /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
509 sr32(&prcm_base->clksel2_pll_iva2, 0, 5, ptr->m2);
510
511 /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
512 sr32(&prcm_base->clksel1_pll_iva2, 8, 11, ptr->m);
513
514 /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
515 sr32(&prcm_base->clksel1_pll_iva2, 0, 7, ptr->n);
516
517 /* LOCK (MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
Dirk Behme595d37b2008-12-14 09:47:14 +0100518 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700519
Dirk Behme595d37b2008-12-14 09:47:14 +0100520 wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
Steve Sakoman24e81c12010-08-18 07:34:09 -0700521}
522
523/******************************************************************************
524 * prcm_init() - inits clocks for PRCM as defined in clocks.h
525 * called from SRAM, or Flash (using temp SRAM stack).
526 *****************************************************************************/
527void prcm_init(void)
528{
529 u32 osc_clk = 0, sys_clkin_sel;
530 u32 clk_index, sil_index = 0;
531 struct prm *prm_base = (struct prm *)PRM_BASE;
532 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
533
534 /*
535 * Gauge the input clock speed and find out the sys_clkin_sel
536 * value corresponding to the input clock.
537 */
538 osc_clk = get_osc_clk_speed();
539 get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
540
541 /* set input crystal speed */
542 sr32(&prm_base->clksel, 0, 3, sys_clkin_sel);
543
544 /* If the input clock is greater than 19.2M always divide/2 */
545 if (sys_clkin_sel > 2) {
546 /* input clock divider */
547 sr32(&prm_base->clksrc_ctrl, 6, 2, 2);
548 clk_index = sys_clkin_sel / 2;
549 } else {
550 /* input clock divider */
551 sr32(&prm_base->clksrc_ctrl, 6, 2, 1);
552 clk_index = sys_clkin_sel;
553 }
554
555 if (get_cpu_family() == CPU_OMAP36XX) {
556 /* Unlock MPU DPLL (slows things down, and needed later) */
557 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS);
558 wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,
559 LDELAY);
560
561 dpll3_init_36xx(0, clk_index);
562 dpll4_init_36xx(0, clk_index);
563 iva_init_36xx(0, clk_index);
564 mpu_init_36xx(0, clk_index);
565
566 /* Lock MPU DPLL to set frequency */
567 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK);
568 wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu,
569 LDELAY);
570 } else {
571 /*
572 * The DPLL tables are defined according to sysclk value and
573 * silicon revision. The clk_index value will be used to get
574 * the values for that input sysclk from the DPLL param table
575 * and sil_index will get the values for that SysClk for the
576 * appropriate silicon rev.
577 */
578 if (((get_cpu_family() == CPU_OMAP34XX)
579 && (get_cpu_rev() >= CPU_3XX_ES20)) ||
580 (get_cpu_family() == CPU_AM35XX))
581 sil_index = 1;
582
583 /* Unlock MPU DPLL (slows things down, and needed later) */
584 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS);
585 wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,
586 LDELAY);
587
588 dpll3_init_34xx(sil_index, clk_index);
589 dpll4_init_34xx(sil_index, clk_index);
590 iva_init_34xx(sil_index, clk_index);
591 mpu_init_34xx(sil_index, clk_index);
592
593 /* Lock MPU DPLL to set frequency */
594 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK);
595 wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu,
596 LDELAY);
597 }
Dirk Behme595d37b2008-12-14 09:47:14 +0100598
599 /* Set up GPTimers to sys_clk source only */
600 sr32(&prcm_base->clksel_per, 0, 8, 0xff);
601 sr32(&prcm_base->clksel_wkup, 0, 1, 1);
602
603 sdelay(5000);
604}
605
606/******************************************************************************
607 * peripheral_enable() - Enable the clks & power for perifs (GPT2, UART1,...)
608 *****************************************************************************/
609void per_clocks_enable(void)
610{
Dirk Behmedc7af202009-08-08 09:30:21 +0200611 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
Dirk Behme595d37b2008-12-14 09:47:14 +0100612
613 /* Enable GP2 timer. */
614 sr32(&prcm_base->clksel_per, 0, 1, 0x1); /* GPT2 = sys clk */
615 sr32(&prcm_base->iclken_per, 3, 1, 0x1); /* ICKen GPT2 */
616 sr32(&prcm_base->fclken_per, 3, 1, 0x1); /* FCKen GPT2 */
617
618#ifdef CONFIG_SYS_NS16550
619 /* Enable UART1 clocks */
620 sr32(&prcm_base->fclken1_core, 13, 1, 0x1);
621 sr32(&prcm_base->iclken1_core, 13, 1, 0x1);
622
623 /* UART 3 Clocks */
624 sr32(&prcm_base->fclken_per, 11, 1, 0x1);
625 sr32(&prcm_base->iclken_per, 11, 1, 0x1);
626#endif
Tom Rixde8ab062009-05-29 18:57:31 -0500627
628#ifdef CONFIG_OMAP3_GPIO_2
629 sr32(&prcm_base->fclken_per, 13, 1, 1);
630 sr32(&prcm_base->iclken_per, 13, 1, 1);
631#endif
632#ifdef CONFIG_OMAP3_GPIO_3
633 sr32(&prcm_base->fclken_per, 14, 1, 1);
634 sr32(&prcm_base->iclken_per, 14, 1, 1);
635#endif
636#ifdef CONFIG_OMAP3_GPIO_4
637 sr32(&prcm_base->fclken_per, 15, 1, 1);
638 sr32(&prcm_base->iclken_per, 15, 1, 1);
639#endif
640#ifdef CONFIG_OMAP3_GPIO_5
641 sr32(&prcm_base->fclken_per, 16, 1, 1);
642 sr32(&prcm_base->iclken_per, 16, 1, 1);
643#endif
644#ifdef CONFIG_OMAP3_GPIO_6
645 sr32(&prcm_base->fclken_per, 17, 1, 1);
646 sr32(&prcm_base->iclken_per, 17, 1, 1);
647#endif
648
Dirk Behme595d37b2008-12-14 09:47:14 +0100649#ifdef CONFIG_DRIVER_OMAP34XX_I2C
650 /* Turn on all 3 I2C clocks */
651 sr32(&prcm_base->fclken1_core, 15, 3, 0x7);
652 sr32(&prcm_base->iclken1_core, 15, 3, 0x7); /* I2C1,2,3 = on */
653#endif
654 /* Enable the ICLK for 32K Sync Timer as its used in udelay */
655 sr32(&prcm_base->iclken_wkup, 2, 1, 0x1);
656
657 sr32(&prcm_base->fclken_iva2, 0, 32, FCK_IVA2_ON);
658 sr32(&prcm_base->fclken1_core, 0, 32, FCK_CORE1_ON);
659 sr32(&prcm_base->iclken1_core, 0, 32, ICK_CORE1_ON);
660 sr32(&prcm_base->iclken2_core, 0, 32, ICK_CORE2_ON);
661 sr32(&prcm_base->fclken_wkup, 0, 32, FCK_WKUP_ON);
662 sr32(&prcm_base->iclken_wkup, 0, 32, ICK_WKUP_ON);
663 sr32(&prcm_base->fclken_dss, 0, 32, FCK_DSS_ON);
664 sr32(&prcm_base->iclken_dss, 0, 32, ICK_DSS_ON);
665 sr32(&prcm_base->fclken_cam, 0, 32, FCK_CAM_ON);
666 sr32(&prcm_base->iclken_cam, 0, 32, ICK_CAM_ON);
667 sr32(&prcm_base->fclken_per, 0, 32, FCK_PER_ON);
668 sr32(&prcm_base->iclken_per, 0, 32, ICK_PER_ON);
669
670 sdelay(1000);
671}