]> git.ipfire.org Git - people/ms/u-boot.git/blame - arch/arm/cpu/arm_cortexa8/omap3/clock.c
arm: Move cpu/$CPU to arch/arm/cpu/$CPU
[people/ms/u-boot.git] / arch / arm / cpu / arm_cortexa8 / omap3 / clock.c
CommitLineData
5ed3e865
DB
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 * 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{
b74064a0 43 u32 start, cstart, cend, cdiff, cdiv, val;
97a099ea
DB
44 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;
5ed3e865
DB
48
49 val = readl(&prm_base->clksrc_ctrl);
50
b74064a0
SP
51 if (val & SYSCLKDIV_2)
52 cdiv = 2;
53 else if (val & SYSCLKDIV_1)
54 cdiv = 1;
55 else
56 /*
57 * Should never reach here! (Assume divider as 1)
58 */
59 cdiv = 1;
5ed3e865
DB
60
61 /* enable timer2 */
62 val = readl(&prcm_base->clksel_wkup) | CLKSEL_GPT1;
63
64 /* select sys_clk for GPT1 */
65 writel(val, &prcm_base->clksel_wkup);
66
67 /* Enable I and F Clocks for GPT1 */
68 val = readl(&prcm_base->iclken_wkup) | EN_GPT1 | EN_32KSYNC;
69 writel(val, &prcm_base->iclken_wkup);
b74064a0 70
5ed3e865
DB
71 val = readl(&prcm_base->fclken_wkup) | EN_GPT1;
72 writel(val, &prcm_base->fclken_wkup);
73
74 writel(0, &gpt1_base->tldr); /* start counting at 0 */
75 writel(GPT_EN, &gpt1_base->tclr); /* enable clock */
76
77 /* enable 32kHz source, determine sys_clk via gauging */
78
79 /* start time in 20 cycles */
80 start = 20 + readl(&s32k_base->s32k_cr);
81
82 /* dead loop till start time */
83 while (readl(&s32k_base->s32k_cr) < start);
84
85 /* get start sys_clk count */
86 cstart = readl(&gpt1_base->tcrr);
87
88 /* wait for 40 cycles */
89 while (readl(&s32k_base->s32k_cr) < (start + 20)) ;
90 cend = readl(&gpt1_base->tcrr); /* get end sys_clk count */
91 cdiff = cend - cstart; /* get elapsed ticks */
92
b74064a0
SP
93 if (cdiv == 2)
94 {
95 cdiff *= 2;
96 }
97
5ed3e865
DB
98 /* based on number of ticks assign speed */
99 if (cdiff > 19000)
100 return S38_4M;
101 else if (cdiff > 15200)
102 return S26M;
103 else if (cdiff > 13000)
104 return S24M;
105 else if (cdiff > 9000)
106 return S19_2M;
107 else if (cdiff > 7600)
108 return S13M;
109 else
110 return S12M;
111}
112
113/******************************************************************************
114 * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on
115 * input oscillator clock frequency.
116 *****************************************************************************/
117void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)
118{
119 switch(osc_clk) {
120 case S38_4M:
121 *sys_clkin_sel = 4;
122 break;
123 case S26M:
124 *sys_clkin_sel = 3;
125 break;
126 case S19_2M:
127 *sys_clkin_sel = 2;
128 break;
129 case S13M:
130 *sys_clkin_sel = 1;
131 break;
132 case S12M:
133 default:
134 *sys_clkin_sel = 0;
135 }
136}
137
138/******************************************************************************
139 * prcm_init() - inits clocks for PRCM as defined in clocks.h
140 * called from SRAM, or Flash (using temp SRAM stack).
141 *****************************************************************************/
142void prcm_init(void)
143{
144 void (*f_lock_pll) (u32, u32, u32, u32);
145 int xip_safe, p0, p1, p2, p3;
146 u32 osc_clk = 0, sys_clkin_sel;
cba0b778 147 u32 clk_index, sil_index = 0;
97a099ea
DB
148 struct prm *prm_base = (struct prm *)PRM_BASE;
149 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
5ed3e865
DB
150 dpll_param *dpll_param_p;
151
152 f_lock_pll = (void *) ((u32) &_end_vect - (u32) &_start +
153 SRAM_VECT_CODE);
154
155 xip_safe = is_running_in_sram();
156
157 /*
158 * Gauge the input clock speed and find out the sys_clkin_sel
159 * value corresponding to the input clock.
160 */
161 osc_clk = get_osc_clk_speed();
162 get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
163
164 /* set input crystal speed */
165 sr32(&prm_base->clksel, 0, 3, sys_clkin_sel);
166
167 /* If the input clock is greater than 19.2M always divide/2 */
168 if (sys_clkin_sel > 2) {
169 /* input clock divider */
170 sr32(&prm_base->clksrc_ctrl, 6, 2, 2);
171 clk_index = sys_clkin_sel / 2;
172 } else {
173 /* input clock divider */
174 sr32(&prm_base->clksrc_ctrl, 6, 2, 1);
175 clk_index = sys_clkin_sel;
176 }
177
178 /*
179 * The DPLL tables are defined according to sysclk value and
180 * silicon revision. The clk_index value will be used to get
181 * the values for that input sysclk from the DPLL param table
182 * and sil_index will get the values for that SysClk for the
183 * appropriate silicon rev.
184 */
cba0b778
SP
185 if (get_cpu_rev())
186 sil_index = 1;
5ed3e865
DB
187
188 /* Unlock MPU DPLL (slows things down, and needed later) */
189 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOW_POWER_BYPASS);
190 wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu, LDELAY);
191
192 /* Getting the base address of Core DPLL param table */
193 dpll_param_p = (dpll_param *) get_core_dpll_param();
194
195 /* Moving it to the right sysclk and ES rev base */
196 dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
197 if (xip_safe) {
198 /*
199 * CORE DPLL
200 * sr32(CM_CLKSEL2_EMU) set override to work when asleep
201 */
202 sr32(&prcm_base->clken_pll, 0, 3, PLL_FAST_RELOCK_BYPASS);
203 wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
204 LDELAY);
205
206 /*
207 * For OMAP3 ES1.0 Errata 1.50, default value directly doesn't
208 * work. write another value and then default value.
209 */
210
211 /* m3x2 */
212 sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2 + 1);
213 /* m3x2 */
214 sr32(&prcm_base->clksel1_emu, 16, 5, CORE_M3X2);
215 /* Set M2 */
216 sr32(&prcm_base->clksel1_pll, 27, 2, dpll_param_p->m2);
217 /* Set M */
218 sr32(&prcm_base->clksel1_pll, 16, 11, dpll_param_p->m);
219 /* Set N */
220 sr32(&prcm_base->clksel1_pll, 8, 7, dpll_param_p->n);
221 /* 96M Src */
222 sr32(&prcm_base->clksel1_pll, 6, 1, 0);
223 /* ssi */
224 sr32(&prcm_base->clksel_core, 8, 4, CORE_SSI_DIV);
225 /* fsusb */
226 sr32(&prcm_base->clksel_core, 4, 2, CORE_FUSB_DIV);
227 /* l4 */
228 sr32(&prcm_base->clksel_core, 2, 2, CORE_L4_DIV);
229 /* l3 */
230 sr32(&prcm_base->clksel_core, 0, 2, CORE_L3_DIV);
231 /* gfx */
232 sr32(&prcm_base->clksel_gfx, 0, 3, GFX_DIV);
233 /* reset mgr */
234 sr32(&prcm_base->clksel_wkup, 1, 2, WKUP_RSM);
235 /* FREQSEL */
236 sr32(&prcm_base->clken_pll, 4, 4, dpll_param_p->fsel);
237 /* lock mode */
238 sr32(&prcm_base->clken_pll, 0, 3, PLL_LOCK);
239
240 wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
241 LDELAY);
242 } else if (is_running_in_flash()) {
243 /*
244 * if running from flash, jump to small relocated code
245 * area in SRAM.
246 */
247 p0 = readl(&prcm_base->clken_pll);
248 sr32(&p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
249 sr32(&p0, 4, 4, dpll_param_p->fsel); /* FREQSEL */
250
251 p1 = readl(&prcm_base->clksel1_pll);
252 sr32(&p1, 27, 2, dpll_param_p->m2); /* Set M2 */
253 sr32(&p1, 16, 11, dpll_param_p->m); /* Set M */
254 sr32(&p1, 8, 7, dpll_param_p->n); /* Set N */
255 sr32(&p1, 6, 1, 0); /* set source for 96M */
256
257 p2 = readl(&prcm_base->clksel_core);
258 sr32(&p2, 8, 4, CORE_SSI_DIV); /* ssi */
259 sr32(&p2, 4, 2, CORE_FUSB_DIV); /* fsusb */
260 sr32(&p2, 2, 2, CORE_L4_DIV); /* l4 */
261 sr32(&p2, 0, 2, CORE_L3_DIV); /* l3 */
262
263 p3 = (u32)&prcm_base->idlest_ckgen;
264
265 (*f_lock_pll) (p0, p1, p2, p3);
266 }
267
268 /* PER DPLL */
269 sr32(&prcm_base->clken_pll, 16, 3, PLL_STOP);
270 wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
271
272 /* Getting the base address to PER DPLL param table */
273
274 /* Set N */
275 dpll_param_p = (dpll_param *) get_per_dpll_param();
276
277 /* Moving it to the right sysclk base */
278 dpll_param_p = dpll_param_p + clk_index;
279
280 /*
281 * Errata 1.50 Workaround for OMAP3 ES1.0 only
282 * If using default divisors, write default divisor + 1
283 * and then the actual divisor value
284 */
285 sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2 + 1); /* set M6 */
286 sr32(&prcm_base->clksel1_emu, 24, 5, PER_M6X2); /* set M6 */
287 sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2 + 1); /* set M5 */
288 sr32(&prcm_base->clksel_cam, 0, 5, PER_M5X2); /* set M5 */
289 sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2 + 1); /* set M4 */
290 sr32(&prcm_base->clksel_dss, 0, 5, PER_M4X2); /* set M4 */
291 sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2 + 1); /* set M3 */
292 sr32(&prcm_base->clksel_dss, 8, 5, PER_M3X2); /* set M3 */
293 sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2 + 1); /* set M2 */
294 sr32(&prcm_base->clksel3_pll, 0, 5, dpll_param_p->m2); /* set M2 */
295 /* Workaround end */
296
297 sr32(&prcm_base->clksel2_pll, 8, 11, dpll_param_p->m); /* set m */
298 sr32(&prcm_base->clksel2_pll, 0, 7, dpll_param_p->n); /* set n */
299 sr32(&prcm_base->clken_pll, 20, 4, dpll_param_p->fsel); /* FREQSEL */
300 sr32(&prcm_base->clken_pll, 16, 3, PLL_LOCK); /* lock mode */
301 wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
302
303 /* Getting the base address to MPU DPLL param table */
304 dpll_param_p = (dpll_param *) get_mpu_dpll_param();
305
306 /* Moving it to the right sysclk and ES rev base */
307 dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
308
309 /* MPU DPLL (unlocked already) */
310
311 /* Set M2 */
312 sr32(&prcm_base->clksel2_pll_mpu, 0, 5, dpll_param_p->m2);
313 /* Set M */
314 sr32(&prcm_base->clksel1_pll_mpu, 8, 11, dpll_param_p->m);
315 /* Set N */
316 sr32(&prcm_base->clksel1_pll_mpu, 0, 7, dpll_param_p->n);
317 /* FREQSEL */
318 sr32(&prcm_base->clken_pll_mpu, 4, 4, dpll_param_p->fsel);
319 /* lock mode */
320 sr32(&prcm_base->clken_pll_mpu, 0, 3, PLL_LOCK);
321 wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu, LDELAY);
322
323 /* Getting the base address to IVA DPLL param table */
324 dpll_param_p = (dpll_param *) get_iva_dpll_param();
325
326 /* Moving it to the right sysclk and ES rev base */
327 dpll_param_p = dpll_param_p + 3 * clk_index + sil_index;
328
329 /* IVA DPLL (set to 12*20=240MHz) */
330 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_STOP);
331 wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
332 /* set M2 */
333 sr32(&prcm_base->clksel2_pll_iva2, 0, 5, dpll_param_p->m2);
334 /* set M */
335 sr32(&prcm_base->clksel1_pll_iva2, 8, 11, dpll_param_p->m);
336 /* set N */
337 sr32(&prcm_base->clksel1_pll_iva2, 0, 7, dpll_param_p->n);
338 /* FREQSEL */
339 sr32(&prcm_base->clken_pll_iva2, 4, 4, dpll_param_p->fsel);
340 /* lock mode */
341 sr32(&prcm_base->clken_pll_iva2, 0, 3, PLL_LOCK);
342 wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
343
344 /* Set up GPTimers to sys_clk source only */
345 sr32(&prcm_base->clksel_per, 0, 8, 0xff);
346 sr32(&prcm_base->clksel_wkup, 0, 1, 1);
347
348 sdelay(5000);
349}
350
351/******************************************************************************
352 * peripheral_enable() - Enable the clks & power for perifs (GPT2, UART1,...)
353 *****************************************************************************/
354void per_clocks_enable(void)
355{
97a099ea 356 struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
5ed3e865
DB
357
358 /* Enable GP2 timer. */
359 sr32(&prcm_base->clksel_per, 0, 1, 0x1); /* GPT2 = sys clk */
360 sr32(&prcm_base->iclken_per, 3, 1, 0x1); /* ICKen GPT2 */
361 sr32(&prcm_base->fclken_per, 3, 1, 0x1); /* FCKen GPT2 */
362
363#ifdef CONFIG_SYS_NS16550
364 /* Enable UART1 clocks */
365 sr32(&prcm_base->fclken1_core, 13, 1, 0x1);
366 sr32(&prcm_base->iclken1_core, 13, 1, 0x1);
367
368 /* UART 3 Clocks */
369 sr32(&prcm_base->fclken_per, 11, 1, 0x1);
370 sr32(&prcm_base->iclken_per, 11, 1, 0x1);
371#endif
708cfb74
TR
372
373#ifdef CONFIG_OMAP3_GPIO_2
374 sr32(&prcm_base->fclken_per, 13, 1, 1);
375 sr32(&prcm_base->iclken_per, 13, 1, 1);
376#endif
377#ifdef CONFIG_OMAP3_GPIO_3
378 sr32(&prcm_base->fclken_per, 14, 1, 1);
379 sr32(&prcm_base->iclken_per, 14, 1, 1);
380#endif
381#ifdef CONFIG_OMAP3_GPIO_4
382 sr32(&prcm_base->fclken_per, 15, 1, 1);
383 sr32(&prcm_base->iclken_per, 15, 1, 1);
384#endif
385#ifdef CONFIG_OMAP3_GPIO_5
386 sr32(&prcm_base->fclken_per, 16, 1, 1);
387 sr32(&prcm_base->iclken_per, 16, 1, 1);
388#endif
389#ifdef CONFIG_OMAP3_GPIO_6
390 sr32(&prcm_base->fclken_per, 17, 1, 1);
391 sr32(&prcm_base->iclken_per, 17, 1, 1);
392#endif
393
5ed3e865
DB
394#ifdef CONFIG_DRIVER_OMAP34XX_I2C
395 /* Turn on all 3 I2C clocks */
396 sr32(&prcm_base->fclken1_core, 15, 3, 0x7);
397 sr32(&prcm_base->iclken1_core, 15, 3, 0x7); /* I2C1,2,3 = on */
398#endif
399 /* Enable the ICLK for 32K Sync Timer as its used in udelay */
400 sr32(&prcm_base->iclken_wkup, 2, 1, 0x1);
401
402 sr32(&prcm_base->fclken_iva2, 0, 32, FCK_IVA2_ON);
403 sr32(&prcm_base->fclken1_core, 0, 32, FCK_CORE1_ON);
404 sr32(&prcm_base->iclken1_core, 0, 32, ICK_CORE1_ON);
405 sr32(&prcm_base->iclken2_core, 0, 32, ICK_CORE2_ON);
406 sr32(&prcm_base->fclken_wkup, 0, 32, FCK_WKUP_ON);
407 sr32(&prcm_base->iclken_wkup, 0, 32, ICK_WKUP_ON);
408 sr32(&prcm_base->fclken_dss, 0, 32, FCK_DSS_ON);
409 sr32(&prcm_base->iclken_dss, 0, 32, ICK_DSS_ON);
410 sr32(&prcm_base->fclken_cam, 0, 32, FCK_CAM_ON);
411 sr32(&prcm_base->iclken_cam, 0, 32, ICK_CAM_ON);
412 sr32(&prcm_base->fclken_per, 0, 32, FCK_PER_ON);
413 sr32(&prcm_base->iclken_per, 0, 32, ICK_PER_ON);
414
415 sdelay(1000);
416}