xref: /rk3399_rockchip-uboot/arch/arm/mach-omap2/omap3/clock.c (revision b24065c4ef21687787a74eef22dfa9232096f965)
1983e3700STom Rini /*
2983e3700STom Rini  * (C) Copyright 2008
3983e3700STom Rini  * Texas Instruments, <www.ti.com>
4983e3700STom Rini  *
5983e3700STom Rini  * Author :
6983e3700STom Rini  *      Manikandan Pillai <mani.pillai@ti.com>
7983e3700STom Rini  *
8983e3700STom Rini  * Derived from Beagle Board and OMAP3 SDP code by
9983e3700STom Rini  *      Richard Woodruff <r-woodruff2@ti.com>
10983e3700STom Rini  *      Syed Mohammed Khasim <khasim@ti.com>
11983e3700STom Rini  *
12983e3700STom Rini  * SPDX-License-Identifier:	GPL-2.0+
13983e3700STom Rini  */
14983e3700STom Rini 
15983e3700STom Rini #include <common.h>
16983e3700STom Rini #include <asm/io.h>
17983e3700STom Rini #include <asm/arch/clock.h>
18983e3700STom Rini #include <asm/arch/clocks_omap3.h>
19983e3700STom Rini #include <asm/arch/mem.h>
20983e3700STom Rini #include <asm/arch/sys_proto.h>
21983e3700STom Rini #include <environment.h>
22983e3700STom Rini #include <command.h>
23983e3700STom Rini 
24983e3700STom Rini /******************************************************************************
25983e3700STom Rini  * get_sys_clk_speed() - determine reference oscillator speed
26983e3700STom Rini  *                       based on known 32kHz clock and gptimer.
27983e3700STom Rini  *****************************************************************************/
get_osc_clk_speed(void)28983e3700STom Rini u32 get_osc_clk_speed(void)
29983e3700STom Rini {
30983e3700STom Rini 	u32 start, cstart, cend, cdiff, cdiv, val;
31983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
32983e3700STom Rini 	struct prm *prm_base = (struct prm *)PRM_BASE;
33983e3700STom Rini 	struct gptimer *gpt1_base = (struct gptimer *)OMAP34XX_GPT1;
34983e3700STom Rini 	struct s32ktimer *s32k_base = (struct s32ktimer *)SYNC_32KTIMER_BASE;
35983e3700STom Rini 
36983e3700STom Rini 	val = readl(&prm_base->clksrc_ctrl);
37983e3700STom Rini 
38983e3700STom Rini 	if (val & SYSCLKDIV_2)
39983e3700STom Rini 		cdiv = 2;
40983e3700STom Rini 	else
41983e3700STom Rini 		cdiv = 1;
42983e3700STom Rini 
43983e3700STom Rini 	/* enable timer2 */
44983e3700STom Rini 	val = readl(&prcm_base->clksel_wkup) | CLKSEL_GPT1;
45983e3700STom Rini 
46983e3700STom Rini 	/* select sys_clk for GPT1 */
47983e3700STom Rini 	writel(val, &prcm_base->clksel_wkup);
48983e3700STom Rini 
49983e3700STom Rini 	/* Enable I and F Clocks for GPT1 */
50983e3700STom Rini 	val = readl(&prcm_base->iclken_wkup) | EN_GPT1 | EN_32KSYNC;
51983e3700STom Rini 	writel(val, &prcm_base->iclken_wkup);
52983e3700STom Rini 
53983e3700STom Rini 	val = readl(&prcm_base->fclken_wkup) | EN_GPT1;
54983e3700STom Rini 	writel(val, &prcm_base->fclken_wkup);
55983e3700STom Rini 
56983e3700STom Rini 	writel(0, &gpt1_base->tldr);		/* start counting at 0 */
57983e3700STom Rini 	writel(GPT_EN, &gpt1_base->tclr);	/* enable clock */
58983e3700STom Rini 
59983e3700STom Rini 	/* enable 32kHz source, determine sys_clk via gauging */
60983e3700STom Rini 
61983e3700STom Rini 	/* start time in 20 cycles */
62983e3700STom Rini 	start = 20 + readl(&s32k_base->s32k_cr);
63983e3700STom Rini 
64983e3700STom Rini 	/* dead loop till start time */
65983e3700STom Rini 	while (readl(&s32k_base->s32k_cr) < start);
66983e3700STom Rini 
67983e3700STom Rini 	/* get start sys_clk count */
68983e3700STom Rini 	cstart = readl(&gpt1_base->tcrr);
69983e3700STom Rini 
70983e3700STom Rini 	/* wait for 40 cycles */
71983e3700STom Rini 	while (readl(&s32k_base->s32k_cr) < (start + 20)) ;
72983e3700STom Rini 	cend = readl(&gpt1_base->tcrr);		/* get end sys_clk count */
73983e3700STom Rini 	cdiff = cend - cstart;			/* get elapsed ticks */
74983e3700STom Rini 	cdiff *= cdiv;
75983e3700STom Rini 
76983e3700STom Rini 	/* based on number of ticks assign speed */
77983e3700STom Rini 	if (cdiff > 19000)
78983e3700STom Rini 		return S38_4M;
79983e3700STom Rini 	else if (cdiff > 15200)
80983e3700STom Rini 		return S26M;
81983e3700STom Rini 	else if (cdiff > 13000)
82983e3700STom Rini 		return S24M;
83983e3700STom Rini 	else if (cdiff > 9000)
84983e3700STom Rini 		return S19_2M;
85983e3700STom Rini 	else if (cdiff > 7600)
86983e3700STom Rini 		return S13M;
87983e3700STom Rini 	else
88983e3700STom Rini 		return S12M;
89983e3700STom Rini }
90983e3700STom Rini 
91983e3700STom Rini /******************************************************************************
92983e3700STom Rini  * get_sys_clkin_sel() - returns the sys_clkin_sel field value based on
93983e3700STom Rini  *                       input oscillator clock frequency.
94983e3700STom Rini  *****************************************************************************/
get_sys_clkin_sel(u32 osc_clk,u32 * sys_clkin_sel)95983e3700STom Rini void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)
96983e3700STom Rini {
97983e3700STom Rini 	switch(osc_clk) {
98983e3700STom Rini 	case S38_4M:
99983e3700STom Rini 		*sys_clkin_sel = 4;
100983e3700STom Rini 		break;
101983e3700STom Rini 	case S26M:
102983e3700STom Rini 		*sys_clkin_sel = 3;
103983e3700STom Rini 		break;
104983e3700STom Rini 	case S19_2M:
105983e3700STom Rini 		*sys_clkin_sel = 2;
106983e3700STom Rini 		break;
107983e3700STom Rini 	case S13M:
108983e3700STom Rini 		*sys_clkin_sel = 1;
109983e3700STom Rini 		break;
110983e3700STom Rini 	case S12M:
111983e3700STom Rini 	default:
112983e3700STom Rini 		*sys_clkin_sel = 0;
113983e3700STom Rini 	}
114983e3700STom Rini }
115983e3700STom Rini 
116983e3700STom Rini /*
117983e3700STom Rini  * OMAP34XX/35XX specific functions
118983e3700STom Rini  */
119983e3700STom Rini 
dpll3_init_34xx(u32 sil_index,u32 clk_index)120983e3700STom Rini static void dpll3_init_34xx(u32 sil_index, u32 clk_index)
121983e3700STom Rini {
122983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
123983e3700STom Rini 	dpll_param *ptr = (dpll_param *) get_core_dpll_param();
124983e3700STom Rini 	void (*f_lock_pll) (u32, u32, u32, u32);
125983e3700STom Rini 	int xip_safe, p0, p1, p2, p3;
126983e3700STom Rini 
127983e3700STom Rini 	xip_safe = is_running_in_sram();
128983e3700STom Rini 
129983e3700STom Rini 	/* Moving to the right sysclk and ES rev base */
130983e3700STom Rini 	ptr = ptr + (3 * clk_index) + sil_index;
131983e3700STom Rini 
132983e3700STom Rini 	if (xip_safe) {
133983e3700STom Rini 		/*
134983e3700STom Rini 		 * CORE DPLL
135983e3700STom Rini 		 */
136983e3700STom Rini 		clrsetbits_le32(&prcm_base->clken_pll,
137983e3700STom Rini 				0x00000007, PLL_FAST_RELOCK_BYPASS);
138983e3700STom Rini 		wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
139983e3700STom Rini 				LDELAY);
140983e3700STom Rini 
141983e3700STom Rini 		/*
142983e3700STom Rini 		 * For OMAP3 ES1.0 Errata 1.50, default value directly doesn't
143983e3700STom Rini 		 * work. write another value and then default value.
144983e3700STom Rini 		 */
145983e3700STom Rini 
146983e3700STom Rini 		/* CM_CLKSEL1_EMU[DIV_DPLL3] */
147983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel1_emu,
148983e3700STom Rini 				0x001F0000, (CORE_M3X2 + 1) << 16) ;
149983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel1_emu,
150983e3700STom Rini 				0x001F0000, CORE_M3X2 << 16);
151983e3700STom Rini 
152983e3700STom Rini 		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
153983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel1_pll,
154983e3700STom Rini 				0xF8000000, ptr->m2 << 27);
155983e3700STom Rini 
156983e3700STom Rini 		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
157983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel1_pll,
158983e3700STom Rini 				0x07FF0000, ptr->m << 16);
159983e3700STom Rini 
160983e3700STom Rini 		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
161983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel1_pll,
162983e3700STom Rini 				0x00007F00, ptr->n << 8);
163983e3700STom Rini 
164983e3700STom Rini 		/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
165983e3700STom Rini 		clrbits_le32(&prcm_base->clksel1_pll, 0x00000040);
166983e3700STom Rini 
167983e3700STom Rini 		/* SSI */
168983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel_core,
169983e3700STom Rini 				0x00000F00, CORE_SSI_DIV << 8);
170983e3700STom Rini 		/* FSUSB */
171983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel_core,
172983e3700STom Rini 				0x00000030, CORE_FUSB_DIV << 4);
173983e3700STom Rini 		/* L4 */
174983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel_core,
175983e3700STom Rini 				0x0000000C, CORE_L4_DIV << 2);
176983e3700STom Rini 		/* L3 */
177983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel_core,
178983e3700STom Rini 				0x00000003, CORE_L3_DIV);
179983e3700STom Rini 		/* GFX */
180983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel_gfx,
181983e3700STom Rini 				0x00000007, GFX_DIV);
182983e3700STom Rini 		/* RESET MGR */
183983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel_wkup,
184983e3700STom Rini 				0x00000006, WKUP_RSM << 1);
185983e3700STom Rini 		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
186983e3700STom Rini 		clrsetbits_le32(&prcm_base->clken_pll,
187983e3700STom Rini 				0x000000F0, ptr->fsel << 4);
188983e3700STom Rini 		/* LOCK MODE */
189983e3700STom Rini 		clrsetbits_le32(&prcm_base->clken_pll,
190983e3700STom Rini 				0x00000007, PLL_LOCK);
191983e3700STom Rini 
192983e3700STom Rini 		wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
193983e3700STom Rini 				LDELAY);
194983e3700STom Rini 	} else if (is_running_in_flash()) {
195983e3700STom Rini 		/*
196983e3700STom Rini 		 * if running from flash, jump to small relocated code
197983e3700STom Rini 		 * area in SRAM.
198983e3700STom Rini 		 */
199983e3700STom Rini 		f_lock_pll = (void *) (SRAM_CLK_CODE);
200983e3700STom Rini 
201983e3700STom Rini 		p0 = readl(&prcm_base->clken_pll);
202983e3700STom Rini 		clrsetbits_le32(&p0, 0x00000007, PLL_FAST_RELOCK_BYPASS);
203983e3700STom Rini 		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
204983e3700STom Rini 		clrsetbits_le32(&p0, 0x000000F0, ptr->fsel << 4);
205983e3700STom Rini 
206983e3700STom Rini 		p1 = readl(&prcm_base->clksel1_pll);
207983e3700STom Rini 		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
208983e3700STom Rini 		clrsetbits_le32(&p1, 0xF8000000, ptr->m2 << 27);
209983e3700STom Rini 		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
210983e3700STom Rini 		clrsetbits_le32(&p1, 0x07FF0000, ptr->m << 16);
211983e3700STom Rini 		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
212983e3700STom Rini 		clrsetbits_le32(&p1, 0x00007F00, ptr->n << 8);
213983e3700STom Rini 		/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
214983e3700STom Rini 		clrbits_le32(&p1, 0x00000040);
215983e3700STom Rini 
216983e3700STom Rini 		p2 = readl(&prcm_base->clksel_core);
217983e3700STom Rini 		/* SSI */
218983e3700STom Rini 		clrsetbits_le32(&p2, 0x00000F00, CORE_SSI_DIV << 8);
219983e3700STom Rini 		/* FSUSB */
220983e3700STom Rini 		clrsetbits_le32(&p2, 0x00000030, CORE_FUSB_DIV << 4);
221983e3700STom Rini 		/* L4 */
222983e3700STom Rini 		clrsetbits_le32(&p2, 0x0000000C, CORE_L4_DIV << 2);
223983e3700STom Rini 		/* L3 */
224983e3700STom Rini 		clrsetbits_le32(&p2, 0x00000003, CORE_L3_DIV);
225983e3700STom Rini 
226983e3700STom Rini 		p3 = (u32)&prcm_base->idlest_ckgen;
227983e3700STom Rini 
228983e3700STom Rini 		(*f_lock_pll) (p0, p1, p2, p3);
229983e3700STom Rini 	}
230983e3700STom Rini }
231983e3700STom Rini 
dpll4_init_34xx(u32 sil_index,u32 clk_index)232983e3700STom Rini static void dpll4_init_34xx(u32 sil_index, u32 clk_index)
233983e3700STom Rini {
234983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
235983e3700STom Rini 	dpll_param *ptr = (dpll_param *) get_per_dpll_param();
236983e3700STom Rini 
237983e3700STom Rini 	/* Moving it to the right sysclk base */
238983e3700STom Rini 	ptr = ptr + clk_index;
239983e3700STom Rini 
240983e3700STom Rini 	/* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
241983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken_pll, 0x00070000, PLL_STOP << 16);
242983e3700STom Rini 	wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
243983e3700STom Rini 
244983e3700STom Rini 	/*
245983e3700STom Rini 	 * Errata 1.50 Workaround for OMAP3 ES1.0 only
246983e3700STom Rini 	 * If using default divisors, write default divisor + 1
247983e3700STom Rini 	 * and then the actual divisor value
248983e3700STom Rini 	 */
249983e3700STom Rini 	/* M6 */
250983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel1_emu,
251983e3700STom Rini 			0x1F000000, (PER_M6X2 + 1) << 24);
252983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel1_emu,
253983e3700STom Rini 			0x1F000000, PER_M6X2 << 24);
254983e3700STom Rini 	/* M5 */
255983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel_cam, 0x0000001F, (PER_M5X2 + 1));
256983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel_cam, 0x0000001F, PER_M5X2);
257983e3700STom Rini 	/* M4 */
258983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel_dss, 0x0000001F, (PER_M4X2 + 1));
259983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel_dss, 0x0000001F, PER_M4X2);
260983e3700STom Rini 	/* M3 */
261983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel_dss,
262983e3700STom Rini 			0x00001F00, (PER_M3X2 + 1) << 8);
263983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel_dss,
264983e3700STom Rini 			0x00001F00, PER_M3X2 << 8);
265983e3700STom Rini 	/* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
266983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel3_pll, 0x0000001F, (ptr->m2 + 1));
267983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel3_pll, 0x0000001F, ptr->m2);
268983e3700STom Rini 	/* Workaround end */
269983e3700STom Rini 
270983e3700STom Rini 	/* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */
271983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel2_pll,
272983e3700STom Rini 			0x0007FF00, ptr->m << 8);
273983e3700STom Rini 
274983e3700STom Rini 	/* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
275983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel2_pll, 0x0000007F, ptr->n);
276983e3700STom Rini 
277983e3700STom Rini 	/* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */
278983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken_pll, 0x00F00000, ptr->fsel << 20);
279983e3700STom Rini 
280983e3700STom Rini 	/* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
281983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken_pll, 0x00070000, PLL_LOCK << 16);
282983e3700STom Rini 	wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
283983e3700STom Rini }
284983e3700STom Rini 
dpll5_init_34xx(u32 sil_index,u32 clk_index)285983e3700STom Rini static void dpll5_init_34xx(u32 sil_index, u32 clk_index)
286983e3700STom Rini {
287983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
288983e3700STom Rini 	dpll_param *ptr = (dpll_param *) get_per2_dpll_param();
289983e3700STom Rini 
290983e3700STom Rini 	/* Moving it to the right sysclk base */
291983e3700STom Rini 	ptr = ptr + clk_index;
292983e3700STom Rini 
293983e3700STom Rini 	/* PER2 DPLL (DPLL5) */
294983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken2_pll, 0x00000007, PLL_STOP);
295983e3700STom Rini 	wait_on_value(1, 0, &prcm_base->idlest2_ckgen, LDELAY);
296983e3700STom Rini 	/* set M2 (usbtll_fck) */
297983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel5_pll, 0x0000001F, ptr->m2);
298983e3700STom Rini 	/* set m (11-bit multiplier) */
299983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel4_pll, 0x0007FF00, ptr->m << 8);
300983e3700STom Rini 	/* set n (7-bit divider)*/
301983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel4_pll, 0x0000007F, ptr->n);
302983e3700STom Rini 	/* FREQSEL */
303983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken_pll, 0x000000F0, ptr->fsel << 4);
304983e3700STom Rini 	/* lock mode */
305983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken2_pll, 0x00000007, PLL_LOCK);
306983e3700STom Rini 	wait_on_value(1, 1, &prcm_base->idlest2_ckgen, LDELAY);
307983e3700STom Rini }
308983e3700STom Rini 
mpu_init_34xx(u32 sil_index,u32 clk_index)309983e3700STom Rini static void mpu_init_34xx(u32 sil_index, u32 clk_index)
310983e3700STom Rini {
311983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
312983e3700STom Rini 	dpll_param *ptr = (dpll_param *) get_mpu_dpll_param();
313983e3700STom Rini 
314983e3700STom Rini 	/* Moving to the right sysclk and ES rev base */
315983e3700STom Rini 	ptr = ptr + (3 * clk_index) + sil_index;
316983e3700STom Rini 
317983e3700STom Rini 	/* MPU DPLL (unlocked already) */
318983e3700STom Rini 
319983e3700STom Rini 	/* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
320983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel2_pll_mpu,
321983e3700STom Rini 			0x0000001F, ptr->m2);
322983e3700STom Rini 
323983e3700STom Rini 	/* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
324983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel1_pll_mpu,
325983e3700STom Rini 			0x0007FF00, ptr->m << 8);
326983e3700STom Rini 
327983e3700STom Rini 	/* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
328983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel1_pll_mpu,
329983e3700STom Rini 			0x0000007F, ptr->n);
330983e3700STom Rini 
331983e3700STom Rini 	/* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */
332983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken_pll_mpu,
333983e3700STom Rini 			0x000000F0, ptr->fsel << 4);
334983e3700STom Rini }
335983e3700STom Rini 
iva_init_34xx(u32 sil_index,u32 clk_index)336983e3700STom Rini static void iva_init_34xx(u32 sil_index, u32 clk_index)
337983e3700STom Rini {
338983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
339983e3700STom Rini 	dpll_param *ptr = (dpll_param *) get_iva_dpll_param();
340983e3700STom Rini 
341983e3700STom Rini 	/* Moving to the right sysclk and ES rev base */
342983e3700STom Rini 	ptr = ptr + (3 * clk_index) + sil_index;
343983e3700STom Rini 
344983e3700STom Rini 	/* IVA DPLL */
345983e3700STom Rini 	/* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
346983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken_pll_iva2,
347983e3700STom Rini 			0x00000007, PLL_STOP);
348983e3700STom Rini 	wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
349983e3700STom Rini 
350983e3700STom Rini 	/* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
351983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel2_pll_iva2,
352983e3700STom Rini 			0x0000001F, ptr->m2);
353983e3700STom Rini 
354983e3700STom Rini 	/* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
355983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel1_pll_iva2,
356983e3700STom Rini 			0x0007FF00, ptr->m << 8);
357983e3700STom Rini 
358983e3700STom Rini 	/* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
359983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel1_pll_iva2,
360983e3700STom Rini 			0x0000007F, ptr->n);
361983e3700STom Rini 
362983e3700STom Rini 	/* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */
363983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken_pll_iva2,
364983e3700STom Rini 			0x000000F0, ptr->fsel << 4);
365983e3700STom Rini 
366983e3700STom Rini 	/* LOCK MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
367983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken_pll_iva2,
368983e3700STom Rini 			0x00000007, PLL_LOCK);
369983e3700STom Rini 
370983e3700STom Rini 	wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
371983e3700STom Rini }
372983e3700STom Rini 
373983e3700STom Rini /*
374983e3700STom Rini  * OMAP3630 specific functions
375983e3700STom Rini  */
376983e3700STom Rini 
dpll3_init_36xx(u32 sil_index,u32 clk_index)377983e3700STom Rini static void dpll3_init_36xx(u32 sil_index, u32 clk_index)
378983e3700STom Rini {
379983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
380983e3700STom Rini 	dpll_param *ptr = (dpll_param *) get_36x_core_dpll_param();
381983e3700STom Rini 	void (*f_lock_pll) (u32, u32, u32, u32);
382983e3700STom Rini 	int xip_safe, p0, p1, p2, p3;
383983e3700STom Rini 
384983e3700STom Rini 	xip_safe = is_running_in_sram();
385983e3700STom Rini 
386983e3700STom Rini 	/* Moving it to the right sysclk base */
387983e3700STom Rini 	ptr += clk_index;
388983e3700STom Rini 
389983e3700STom Rini 	if (xip_safe) {
390983e3700STom Rini 		/* CORE DPLL */
391983e3700STom Rini 
392983e3700STom Rini 		/* Select relock bypass: CM_CLKEN_PLL[0:2] */
393983e3700STom Rini 		clrsetbits_le32(&prcm_base->clken_pll,
394983e3700STom Rini 				0x00000007, PLL_FAST_RELOCK_BYPASS);
395983e3700STom Rini 		wait_on_value(ST_CORE_CLK, 0, &prcm_base->idlest_ckgen,
396983e3700STom Rini 				LDELAY);
397983e3700STom Rini 
398983e3700STom Rini 		/* CM_CLKSEL1_EMU[DIV_DPLL3] */
399983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel1_emu,
400983e3700STom Rini 				0x001F0000, CORE_M3X2 << 16);
401983e3700STom Rini 
402983e3700STom Rini 		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
403983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel1_pll,
404983e3700STom Rini 				0xF8000000, ptr->m2 << 27);
405983e3700STom Rini 
406983e3700STom Rini 		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
407983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel1_pll,
408983e3700STom Rini 				0x07FF0000, ptr->m << 16);
409983e3700STom Rini 
410983e3700STom Rini 		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
411983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel1_pll,
412983e3700STom Rini 				0x00007F00, ptr->n << 8);
413983e3700STom Rini 
414983e3700STom Rini 		/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
415983e3700STom Rini 		clrbits_le32(&prcm_base->clksel1_pll, 0x00000040);
416983e3700STom Rini 
417983e3700STom Rini 		/* SSI */
418983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel_core,
419983e3700STom Rini 				0x00000F00, CORE_SSI_DIV << 8);
420983e3700STom Rini 		/* FSUSB */
421983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel_core,
422983e3700STom Rini 				0x00000030, CORE_FUSB_DIV << 4);
423983e3700STom Rini 		/* L4 */
424983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel_core,
425983e3700STom Rini 				0x0000000C, CORE_L4_DIV << 2);
426983e3700STom Rini 		/* L3 */
427983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel_core,
428983e3700STom Rini 				0x00000003, CORE_L3_DIV);
429983e3700STom Rini 		/* GFX */
430983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel_gfx,
431983e3700STom Rini 				0x00000007, GFX_DIV_36X);
432983e3700STom Rini 		/* RESET MGR */
433983e3700STom Rini 		clrsetbits_le32(&prcm_base->clksel_wkup,
434983e3700STom Rini 				0x00000006, WKUP_RSM << 1);
435983e3700STom Rini 		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
436983e3700STom Rini 		clrsetbits_le32(&prcm_base->clken_pll,
437983e3700STom Rini 				0x000000F0, ptr->fsel << 4);
438983e3700STom Rini 		/* LOCK MODE */
439983e3700STom Rini 		clrsetbits_le32(&prcm_base->clken_pll,
440983e3700STom Rini 				0x00000007, PLL_LOCK);
441983e3700STom Rini 
442983e3700STom Rini 		wait_on_value(ST_CORE_CLK, 1, &prcm_base->idlest_ckgen,
443983e3700STom Rini 				LDELAY);
444983e3700STom Rini 	} else if (is_running_in_flash()) {
445983e3700STom Rini 		/*
446983e3700STom Rini 		 * if running from flash, jump to small relocated code
447983e3700STom Rini 		 * area in SRAM.
448983e3700STom Rini 		 */
449983e3700STom Rini 		f_lock_pll = (void *) (SRAM_CLK_CODE);
450983e3700STom Rini 
451983e3700STom Rini 		p0 = readl(&prcm_base->clken_pll);
452983e3700STom Rini 		clrsetbits_le32(&p0, 0x00000007, PLL_FAST_RELOCK_BYPASS);
453983e3700STom Rini 		/* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
454983e3700STom Rini 		clrsetbits_le32(&p0, 0x000000F0, ptr->fsel << 4);
455983e3700STom Rini 
456983e3700STom Rini 		p1 = readl(&prcm_base->clksel1_pll);
457983e3700STom Rini 		/* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
458983e3700STom Rini 		clrsetbits_le32(&p1, 0xF8000000, ptr->m2 << 27);
459983e3700STom Rini 		/* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
460983e3700STom Rini 		clrsetbits_le32(&p1, 0x07FF0000, ptr->m << 16);
461983e3700STom Rini 		/* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
462983e3700STom Rini 		clrsetbits_le32(&p1, 0x00007F00, ptr->n << 8);
463983e3700STom Rini 		/* Source is the CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
464983e3700STom Rini 		clrbits_le32(&p1, 0x00000040);
465983e3700STom Rini 
466983e3700STom Rini 		p2 = readl(&prcm_base->clksel_core);
467983e3700STom Rini 		/* SSI */
468983e3700STom Rini 		clrsetbits_le32(&p2, 0x00000F00, CORE_SSI_DIV << 8);
469983e3700STom Rini 		/* FSUSB */
470983e3700STom Rini 		clrsetbits_le32(&p2, 0x00000030, CORE_FUSB_DIV << 4);
471983e3700STom Rini 		/* L4 */
472983e3700STom Rini 		clrsetbits_le32(&p2, 0x0000000C, CORE_L4_DIV << 2);
473983e3700STom Rini 		/* L3 */
474983e3700STom Rini 		clrsetbits_le32(&p2, 0x00000003, CORE_L3_DIV);
475983e3700STom Rini 
476983e3700STom Rini 		p3 = (u32)&prcm_base->idlest_ckgen;
477983e3700STom Rini 
478983e3700STom Rini 		(*f_lock_pll) (p0, p1, p2, p3);
479983e3700STom Rini 	}
480983e3700STom Rini }
481983e3700STom Rini 
dpll4_init_36xx(u32 sil_index,u32 clk_index)482983e3700STom Rini static void dpll4_init_36xx(u32 sil_index, u32 clk_index)
483983e3700STom Rini {
484983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
485983e3700STom Rini 	struct dpll_per_36x_param *ptr;
486983e3700STom Rini 
487983e3700STom Rini 	ptr = (struct dpll_per_36x_param *)get_36x_per_dpll_param();
488983e3700STom Rini 
489983e3700STom Rini 	/* Moving it to the right sysclk base */
490983e3700STom Rini 	ptr += clk_index;
491983e3700STom Rini 
492983e3700STom Rini 	/* EN_PERIPH_DPLL: CM_CLKEN_PLL[16:18] */
493983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken_pll, 0x00070000, PLL_STOP << 16);
494983e3700STom Rini 	wait_on_value(ST_PERIPH_CLK, 0, &prcm_base->idlest_ckgen, LDELAY);
495983e3700STom Rini 
496983e3700STom Rini 	/* M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */
497983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel1_emu, 0x3F000000, ptr->m6 << 24);
498983e3700STom Rini 
499983e3700STom Rini 	/* M5 (CLKSEL_CAM): CM_CLKSEL1_EMU[0:5] */
500983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel_cam, 0x0000003F, ptr->m5);
501983e3700STom Rini 
502983e3700STom Rini 	/* M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */
503983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel_dss, 0x0000003F, ptr->m4);
504983e3700STom Rini 
505983e3700STom Rini 	/* M3 (CLKSEL_DSS1): CM_CLKSEL_DSS[8:13] */
506983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel_dss, 0x00003F00, ptr->m3 << 8);
507983e3700STom Rini 
508983e3700STom Rini 	/* M2 (DIV_96M): CM_CLKSEL3_PLL[0:4] */
509983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel3_pll, 0x0000001F, ptr->m2);
510983e3700STom Rini 
511983e3700STom Rini 	/* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */
512983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel2_pll, 0x000FFF00, ptr->m << 8);
513983e3700STom Rini 
514983e3700STom Rini 	/* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
515983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel2_pll, 0x0000007F, ptr->n);
516983e3700STom Rini 
517983e3700STom Rini 	/* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */
518983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel_core, 0x00003000, ptr->m2div << 12);
519983e3700STom Rini 
520983e3700STom Rini 	/* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
521983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken_pll, 0x00070000, PLL_LOCK << 16);
522983e3700STom Rini 	wait_on_value(ST_PERIPH_CLK, 2, &prcm_base->idlest_ckgen, LDELAY);
523983e3700STom Rini }
524983e3700STom Rini 
dpll5_init_36xx(u32 sil_index,u32 clk_index)525983e3700STom Rini static void dpll5_init_36xx(u32 sil_index, u32 clk_index)
526983e3700STom Rini {
527983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
528983e3700STom Rini 	dpll_param *ptr = (dpll_param *) get_36x_per2_dpll_param();
529983e3700STom Rini 
530983e3700STom Rini 	/* Moving it to the right sysclk base */
531983e3700STom Rini 	ptr = ptr + clk_index;
532983e3700STom Rini 
533983e3700STom Rini 	/* PER2 DPLL (DPLL5) */
534983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken2_pll, 0x00000007, PLL_STOP);
535983e3700STom Rini 	wait_on_value(1, 0, &prcm_base->idlest2_ckgen, LDELAY);
536983e3700STom Rini 	/* set M2 (usbtll_fck) */
537983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel5_pll, 0x0000001F, ptr->m2);
538983e3700STom Rini 	/* set m (11-bit multiplier) */
539983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel4_pll, 0x0007FF00, ptr->m << 8);
540983e3700STom Rini 	/* set n (7-bit divider)*/
541983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel4_pll, 0x0000007F, ptr->n);
542983e3700STom Rini 	/* lock mode */
543983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken2_pll, 0x00000007, PLL_LOCK);
544983e3700STom Rini 	wait_on_value(1, 1, &prcm_base->idlest2_ckgen, LDELAY);
545983e3700STom Rini }
546983e3700STom Rini 
mpu_init_36xx(u32 sil_index,u32 clk_index)547983e3700STom Rini static void mpu_init_36xx(u32 sil_index, u32 clk_index)
548983e3700STom Rini {
549983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
550983e3700STom Rini 	dpll_param *ptr = (dpll_param *) get_36x_mpu_dpll_param();
551983e3700STom Rini 
552983e3700STom Rini 	/* Moving to the right sysclk */
553983e3700STom Rini 	ptr += clk_index;
554983e3700STom Rini 
555983e3700STom Rini 	/* MPU DPLL (unlocked already */
556983e3700STom Rini 
557983e3700STom Rini 	/* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
558983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel2_pll_mpu, 0x0000001F, ptr->m2);
559983e3700STom Rini 
560983e3700STom Rini 	/* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
561983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel1_pll_mpu, 0x0007FF00, ptr->m << 8);
562983e3700STom Rini 
563983e3700STom Rini 	/* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
564983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel1_pll_mpu, 0x0000007F, ptr->n);
565983e3700STom Rini }
566983e3700STom Rini 
iva_init_36xx(u32 sil_index,u32 clk_index)567983e3700STom Rini static void iva_init_36xx(u32 sil_index, u32 clk_index)
568983e3700STom Rini {
569983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
570983e3700STom Rini 	dpll_param *ptr = (dpll_param *)get_36x_iva_dpll_param();
571983e3700STom Rini 
572983e3700STom Rini 	/* Moving to the right sysclk */
573983e3700STom Rini 	ptr += clk_index;
574983e3700STom Rini 
575983e3700STom Rini 	/* IVA DPLL */
576983e3700STom Rini 	/* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
577983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken_pll_iva2, 0x00000007, PLL_STOP);
578983e3700STom Rini 	wait_on_value(ST_IVA2_CLK, 0, &prcm_base->idlest_pll_iva2, LDELAY);
579983e3700STom Rini 
580983e3700STom Rini 	/* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
581983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel2_pll_iva2, 0x0000001F, ptr->m2);
582983e3700STom Rini 
583983e3700STom Rini 	/* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
584983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel1_pll_iva2, 0x0007FF00, ptr->m << 8);
585983e3700STom Rini 
586983e3700STom Rini 	/* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
587983e3700STom Rini 	clrsetbits_le32(&prcm_base->clksel1_pll_iva2, 0x0000007F, ptr->n);
588983e3700STom Rini 
589983e3700STom Rini 	/* LOCK (MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
590983e3700STom Rini 	clrsetbits_le32(&prcm_base->clken_pll_iva2, 0x00000007, PLL_LOCK);
591983e3700STom Rini 
592983e3700STom Rini 	wait_on_value(ST_IVA2_CLK, 1, &prcm_base->idlest_pll_iva2, LDELAY);
593983e3700STom Rini }
594983e3700STom Rini 
595983e3700STom Rini /******************************************************************************
596983e3700STom Rini  * prcm_init() - inits clocks for PRCM as defined in clocks.h
597983e3700STom Rini  *               called from SRAM, or Flash (using temp SRAM stack).
598983e3700STom Rini  *****************************************************************************/
prcm_init(void)599983e3700STom Rini void prcm_init(void)
600983e3700STom Rini {
601983e3700STom Rini 	u32 osc_clk = 0, sys_clkin_sel;
602983e3700STom Rini 	u32 clk_index, sil_index = 0;
603983e3700STom Rini 	struct prm *prm_base = (struct prm *)PRM_BASE;
604983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
605983e3700STom Rini 
606983e3700STom Rini 	/*
607983e3700STom Rini 	 * Gauge the input clock speed and find out the sys_clkin_sel
608983e3700STom Rini 	 * value corresponding to the input clock.
609983e3700STom Rini 	 */
610983e3700STom Rini 	osc_clk = get_osc_clk_speed();
611983e3700STom Rini 	get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
612983e3700STom Rini 
613983e3700STom Rini 	/* set input crystal speed */
614983e3700STom Rini 	clrsetbits_le32(&prm_base->clksel, 0x00000007, sys_clkin_sel);
615983e3700STom Rini 
616983e3700STom Rini 	/* If the input clock is greater than 19.2M always divide/2 */
617983e3700STom Rini 	if (sys_clkin_sel > 2) {
618983e3700STom Rini 		/* input clock divider */
619983e3700STom Rini 		clrsetbits_le32(&prm_base->clksrc_ctrl, 0x000000C0, 2 << 6);
620983e3700STom Rini 		clk_index = sys_clkin_sel / 2;
621983e3700STom Rini 	} else {
622983e3700STom Rini 		/* input clock divider */
623983e3700STom Rini 		clrsetbits_le32(&prm_base->clksrc_ctrl, 0x000000C0, 1 << 6);
624983e3700STom Rini 		clk_index = sys_clkin_sel;
625983e3700STom Rini 	}
626983e3700STom Rini 
627983e3700STom Rini 	if (get_cpu_family() == CPU_OMAP36XX) {
628983e3700STom Rini 		/*
629983e3700STom Rini 		 * In warm reset conditions on OMAP36xx/AM/DM37xx
630983e3700STom Rini 		 * the rom code incorrectly sets the DPLL4 clock
631983e3700STom Rini 		 * input divider to /6.5. Section 3.5.3.3.3.2.1 of
632983e3700STom Rini 		 * the AM/DM37x TRM explains that the /6.5 divider
633983e3700STom Rini 		 * is used only when the input clock is 13MHz.
634983e3700STom Rini 		 *
635983e3700STom Rini 		 * If the part is in this cpu family *and* the input
636983e3700STom Rini 		 * clock *is not* 13 MHz, then reset the DPLL4 clock
637983e3700STom Rini 		 * input divider to /1 as it should never set to /6.5
638983e3700STom Rini 		 * in this case.
639983e3700STom Rini 		 */
640983e3700STom Rini 		if (sys_clkin_sel != 1) {	/* 13 MHz */
641983e3700STom Rini 			/* Bit 8: DPLL4_CLKINP_DIV */
642983e3700STom Rini 			clrbits_le32(&prm_base->clksrc_ctrl, 0x00000100);
643983e3700STom Rini 		}
644983e3700STom Rini 
645983e3700STom Rini 		/* Unlock MPU DPLL (slows things down, and needed later) */
646983e3700STom Rini 		clrsetbits_le32(&prcm_base->clken_pll_mpu,
647983e3700STom Rini 				0x00000007, PLL_LOW_POWER_BYPASS);
648983e3700STom Rini 		wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,
649983e3700STom Rini 				LDELAY);
650983e3700STom Rini 
651983e3700STom Rini 		dpll3_init_36xx(0, clk_index);
652983e3700STom Rini 		dpll4_init_36xx(0, clk_index);
653983e3700STom Rini 		dpll5_init_36xx(0, clk_index);
654983e3700STom Rini 		iva_init_36xx(0, clk_index);
655983e3700STom Rini 		mpu_init_36xx(0, clk_index);
656983e3700STom Rini 
657983e3700STom Rini 		/* Lock MPU DPLL to set frequency */
658983e3700STom Rini 		clrsetbits_le32(&prcm_base->clken_pll_mpu,
659983e3700STom Rini 				0x00000007, PLL_LOCK);
660983e3700STom Rini 		wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu,
661983e3700STom Rini 				LDELAY);
662983e3700STom Rini 	} else {
663983e3700STom Rini 		/*
664983e3700STom Rini 		 * The DPLL tables are defined according to sysclk value and
665983e3700STom Rini 		 * silicon revision. The clk_index value will be used to get
666983e3700STom Rini 		 * the values for that input sysclk from the DPLL param table
667983e3700STom Rini 		 * and sil_index will get the values for that SysClk for the
668983e3700STom Rini 		 * appropriate silicon rev.
669983e3700STom Rini 		 */
670983e3700STom Rini 		if (((get_cpu_family() == CPU_OMAP34XX)
671983e3700STom Rini 				&& (get_cpu_rev() >= CPU_3XX_ES20)) ||
672983e3700STom Rini 			(get_cpu_family() == CPU_AM35XX))
673983e3700STom Rini 			sil_index = 1;
674983e3700STom Rini 
675983e3700STom Rini 		/* Unlock MPU DPLL (slows things down, and needed later) */
676983e3700STom Rini 		clrsetbits_le32(&prcm_base->clken_pll_mpu,
677983e3700STom Rini 				0x00000007, PLL_LOW_POWER_BYPASS);
678983e3700STom Rini 		wait_on_value(ST_MPU_CLK, 0, &prcm_base->idlest_pll_mpu,
679983e3700STom Rini 				LDELAY);
680983e3700STom Rini 
681983e3700STom Rini 		dpll3_init_34xx(sil_index, clk_index);
682983e3700STom Rini 		dpll4_init_34xx(sil_index, clk_index);
683983e3700STom Rini 		dpll5_init_34xx(sil_index, clk_index);
684983e3700STom Rini 		if (get_cpu_family() != CPU_AM35XX)
685983e3700STom Rini 			iva_init_34xx(sil_index, clk_index);
686983e3700STom Rini 
687983e3700STom Rini 		mpu_init_34xx(sil_index, clk_index);
688983e3700STom Rini 
689983e3700STom Rini 		/* Lock MPU DPLL to set frequency */
690983e3700STom Rini 		clrsetbits_le32(&prcm_base->clken_pll_mpu,
691983e3700STom Rini 				0x00000007, PLL_LOCK);
692983e3700STom Rini 		wait_on_value(ST_MPU_CLK, 1, &prcm_base->idlest_pll_mpu,
693983e3700STom Rini 				LDELAY);
694983e3700STom Rini 	}
695983e3700STom Rini 
696983e3700STom Rini 	/* Set up GPTimers to sys_clk source only */
697983e3700STom Rini 	setbits_le32(&prcm_base->clksel_per, 0x000000FF);
698983e3700STom Rini 	setbits_le32(&prcm_base->clksel_wkup, 1);
699983e3700STom Rini 
700983e3700STom Rini 	sdelay(5000);
701983e3700STom Rini }
702983e3700STom Rini 
703983e3700STom Rini /*
704983e3700STom Rini  * Enable usb ehci uhh, tll clocks
705983e3700STom Rini  */
ehci_clocks_enable(void)706983e3700STom Rini void ehci_clocks_enable(void)
707983e3700STom Rini {
708983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
709983e3700STom Rini 
710983e3700STom Rini 	/* Enable USBHOST_L3_ICLK (USBHOST_MICLK) */
711983e3700STom Rini 	setbits_le32(&prcm_base->iclken_usbhost, 1);
712983e3700STom Rini 	/*
713983e3700STom Rini 	 * Enable USBHOST_48M_FCLK (USBHOST_FCLK1)
714983e3700STom Rini 	 * and USBHOST_120M_FCLK (USBHOST_FCLK2)
715983e3700STom Rini 	 */
716983e3700STom Rini 	setbits_le32(&prcm_base->fclken_usbhost, 0x00000003);
717983e3700STom Rini 	/* Enable USBTTL_ICLK */
718983e3700STom Rini 	setbits_le32(&prcm_base->iclken3_core, 0x00000004);
719983e3700STom Rini 	/* Enable USBTTL_FCLK */
720983e3700STom Rini 	setbits_le32(&prcm_base->fclken3_core, 0x00000004);
721983e3700STom Rini }
722983e3700STom Rini 
723983e3700STom Rini /******************************************************************************
724983e3700STom Rini  * peripheral_enable() - Enable the clks & power for perifs (GPT2, UART1,...)
725983e3700STom Rini  *****************************************************************************/
per_clocks_enable(void)726983e3700STom Rini void per_clocks_enable(void)
727983e3700STom Rini {
728983e3700STom Rini 	struct prcm *prcm_base = (struct prcm *)PRCM_BASE;
729983e3700STom Rini 
730983e3700STom Rini 	/* Enable GP2 timer. */
731983e3700STom Rini 	setbits_le32(&prcm_base->clksel_per, 0x01);	/* GPT2 = sys clk */
732983e3700STom Rini 	setbits_le32(&prcm_base->iclken_per, 0x08);	/* ICKen GPT2 */
733983e3700STom Rini 	setbits_le32(&prcm_base->fclken_per, 0x08);	/* FCKen GPT2 */
734983e3700STom Rini 
735983e3700STom Rini 	/* Enable GP9 timer. */
736983e3700STom Rini 	setbits_le32(&prcm_base->clksel_per, 0x80);	/* GPT9 = 32kHz clk */
737983e3700STom Rini 	setbits_le32(&prcm_base->iclken_per, 0x400);	/* ICKen GPT9 */
738983e3700STom Rini 	setbits_le32(&prcm_base->fclken_per, 0x400);	/* FCKen GPT9 */
739983e3700STom Rini 
740983e3700STom Rini #ifdef CONFIG_SYS_NS16550
741983e3700STom Rini 	/* Enable UART1 clocks */
742983e3700STom Rini 	setbits_le32(&prcm_base->fclken1_core, 0x00002000);
743983e3700STom Rini 	setbits_le32(&prcm_base->iclken1_core, 0x00002000);
744983e3700STom Rini 
745983e3700STom Rini 	/* Enable UART2 clocks */
746983e3700STom Rini 	setbits_le32(&prcm_base->fclken1_core, 0x00004000);
747983e3700STom Rini 	setbits_le32(&prcm_base->iclken1_core, 0x00004000);
748983e3700STom Rini 
749983e3700STom Rini 	/* UART 3 Clocks */
750983e3700STom Rini 	setbits_le32(&prcm_base->fclken_per, 0x00000800);
751983e3700STom Rini 	setbits_le32(&prcm_base->iclken_per, 0x00000800);
752983e3700STom Rini #endif
753983e3700STom Rini 
754983e3700STom Rini #ifdef CONFIG_OMAP3_GPIO_2
755983e3700STom Rini 	setbits_le32(&prcm_base->fclken_per, 0x00002000);
756983e3700STom Rini 	setbits_le32(&prcm_base->iclken_per, 0x00002000);
757983e3700STom Rini #endif
758983e3700STom Rini #ifdef CONFIG_OMAP3_GPIO_3
759983e3700STom Rini 	setbits_le32(&prcm_base->fclken_per, 0x00004000);
760983e3700STom Rini 	setbits_le32(&prcm_base->iclken_per, 0x00004000);
761983e3700STom Rini #endif
762983e3700STom Rini #ifdef CONFIG_OMAP3_GPIO_4
763983e3700STom Rini 	setbits_le32(&prcm_base->fclken_per, 0x00008000);
764983e3700STom Rini 	setbits_le32(&prcm_base->iclken_per, 0x00008000);
765983e3700STom Rini #endif
766983e3700STom Rini #ifdef CONFIG_OMAP3_GPIO_5
767983e3700STom Rini 	setbits_le32(&prcm_base->fclken_per, 0x00010000);
768983e3700STom Rini 	setbits_le32(&prcm_base->iclken_per, 0x00010000);
769983e3700STom Rini #endif
770983e3700STom Rini #ifdef CONFIG_OMAP3_GPIO_6
771983e3700STom Rini 	setbits_le32(&prcm_base->fclken_per, 0x00020000);
772983e3700STom Rini 	setbits_le32(&prcm_base->iclken_per, 0x00020000);
773983e3700STom Rini #endif
774983e3700STom Rini 
775*94d50bedSAdam Ford #ifdef CONFIG_SYS_I2C_OMAP24XX
776983e3700STom Rini 	/* Turn on all 3 I2C clocks */
777983e3700STom Rini 	setbits_le32(&prcm_base->fclken1_core, 0x00038000);
778983e3700STom Rini 	setbits_le32(&prcm_base->iclken1_core, 0x00038000); /* I2C1,2,3 = on */
779983e3700STom Rini #endif
780983e3700STom Rini 	/* Enable the ICLK for 32K Sync Timer as its used in udelay */
781983e3700STom Rini 	setbits_le32(&prcm_base->iclken_wkup, 0x00000004);
782983e3700STom Rini 
783983e3700STom Rini 	if (get_cpu_family() != CPU_AM35XX)
784983e3700STom Rini 		out_le32(&prcm_base->fclken_iva2, FCK_IVA2_ON);
785983e3700STom Rini 
786983e3700STom Rini 	out_le32(&prcm_base->fclken1_core, FCK_CORE1_ON);
787983e3700STom Rini 	out_le32(&prcm_base->iclken1_core, ICK_CORE1_ON);
788983e3700STom Rini 	out_le32(&prcm_base->iclken2_core, ICK_CORE2_ON);
789983e3700STom Rini 	out_le32(&prcm_base->fclken_wkup, FCK_WKUP_ON);
790983e3700STom Rini 	out_le32(&prcm_base->iclken_wkup, ICK_WKUP_ON);
791983e3700STom Rini 	out_le32(&prcm_base->fclken_dss, FCK_DSS_ON);
792983e3700STom Rini 	out_le32(&prcm_base->iclken_dss, ICK_DSS_ON);
793983e3700STom Rini 	if (get_cpu_family() != CPU_AM35XX) {
794983e3700STom Rini 		out_le32(&prcm_base->fclken_cam, FCK_CAM_ON);
795983e3700STom Rini 		out_le32(&prcm_base->iclken_cam, ICK_CAM_ON);
796983e3700STom Rini 	}
797983e3700STom Rini 
798983e3700STom Rini 	sdelay(1000);
799983e3700STom Rini }
800