1/*
2 * Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
3 *
4 * (C) Copyright 2009 Freescale Semiconductor, Inc.
5 *
6 * SPDX-License-Identifier:	GPL-2.0+
7 */
8
9#include <config.h>
10#include <asm/arch/imx-regs.h>
11#include <generated/asm-offsets.h>
12#include <linux/linkage.h>
13
14.section ".text.init", "x"
15
16.macro init_arm_erratum
17	/* ARM erratum ID #468414 */
18	mrc 15, 0, r1, c1, c0, 1
19	orr r1, r1, #(1 << 5)    /* enable L1NEON bit */
20	mcr 15, 0, r1, c1, c0, 1
21.endm
22
23/*
24 * L2CC Cache setup/invalidation/disable
25 */
26.macro init_l2cc
27	/* explicitly disable L2 cache */
28	mrc 15, 0, r0, c1, c0, 1
29	bic r0, r0, #0x2
30	mcr 15, 0, r0, c1, c0, 1
31
32	/* reconfigure L2 cache aux control reg */
33	ldr r0, =0xC0 |			/* tag RAM */ \
34		 0x4 |			/* data RAM */ \
35		 1 << 24 |		/* disable write allocate delay */ \
36		 1 << 23 |		/* disable write allocate combine */ \
37		 1 << 22		/* disable write allocate */
38
39#if defined(CONFIG_MX51)
40	ldr r3, [r4, #ROM_SI_REV]
41	cmp r3, #0x10
42
43	/* disable write combine for TO 2 and lower revs */
44	orrls r0, r0, #1 << 25
45#endif
46
47	mcr 15, 1, r0, c9, c0, 2
48
49	/* enable L2 cache */
50	mrc 15, 0, r0, c1, c0, 1
51	orr r0, r0, #2
52	mcr 15, 0, r0, c1, c0, 1
53
54.endm /* init_l2cc */
55
56/* AIPS setup - Only setup MPROTx registers.
57 * The PACR default values are good.*/
58.macro init_aips
59	/*
60	 * Set all MPROTx to be non-bufferable, trusted for R/W,
61	 * not forced to user-mode.
62	 */
63	ldr r0, =AIPS1_BASE_ADDR
64	ldr r1, =0x77777777
65	str r1, [r0, #0x0]
66	str r1, [r0, #0x4]
67	ldr r0, =AIPS2_BASE_ADDR
68	str r1, [r0, #0x0]
69	str r1, [r0, #0x4]
70	/*
71	 * Clear the on and off peripheral modules Supervisor Protect bit
72	 * for SDMA to access them. Did not change the AIPS control registers
73	 * (offset 0x20) access type
74	 */
75.endm /* init_aips */
76
77/* M4IF setup */
78.macro init_m4if
79#ifdef CONFIG_MX51
80	/* VPU and IPU given higher priority (0x4)
81	 * IPU accesses with ID=0x1 given highest priority (=0xA)
82	 */
83	ldr r0, =M4IF_BASE_ADDR
84
85	ldr r1, =0x00000203
86	str r1, [r0, #0x40]
87
88	str r4, [r0, #0x44]
89
90	ldr r1, =0x00120125
91	str r1, [r0, #0x9C]
92
93	ldr r1, =0x001901A3
94	str r1, [r0, #0x48]
95
96#endif
97.endm /* init_m4if */
98
99.macro setup_pll pll, freq
100	ldr r0, =\pll
101	adr r2, W_DP_\freq
102	bl setup_pll_func
103.endm
104
105#define W_DP_OP		0
106#define W_DP_MFD	4
107#define W_DP_MFN	8
108
109setup_pll_func:
110	ldr r1, =0x00001232
111	str r1, [r0, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */
112	mov r1, #0x2
113	str r1, [r0, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
114
115	ldr r1, [r2, #W_DP_OP]
116	str r1, [r0, #PLL_DP_OP]
117	str r1, [r0, #PLL_DP_HFS_OP]
118
119	ldr r1, [r2, #W_DP_MFD]
120	str r1, [r0, #PLL_DP_MFD]
121	str r1, [r0, #PLL_DP_HFS_MFD]
122
123	ldr r1, [r2, #W_DP_MFN]
124	str r1, [r0, #PLL_DP_MFN]
125	str r1, [r0, #PLL_DP_HFS_MFN]
126
127	ldr r1, =0x00001232
128	str r1, [r0, #PLL_DP_CTL]
1291:	ldr r1, [r0, #PLL_DP_CTL]
130	ands r1, r1, #0x1
131	beq 1b
132
133	/* r10 saved upper lr */
134	mov pc, lr
135
136.macro setup_pll_errata pll, freq
137	ldr r2, =\pll
138	str r4, [r2, #PLL_DP_CONFIG] /* Disable auto-restart AREN bit */
139	ldr r1, =0x00001236
140	str r1, [r2, #PLL_DP_CTL]    /* Restart PLL with PLM=1 */
1411:	ldr r1, [r2, #PLL_DP_CTL]    /* Wait for lock */
142	ands r1, r1, #0x1
143	beq 1b
144
145	ldr r5, \freq
146	str r5, [r2, #PLL_DP_MFN]    /* Modify MFN value */
147	str r5, [r2, #PLL_DP_HFS_MFN]
148
149	mov r1, #0x1
150	str r1, [r2, #PLL_DP_CONFIG] /* Reload MFN value */
151
1522:	ldr r1, [r2, #PLL_DP_CONFIG]
153	tst r1, #1
154	bne 2b
155
156	ldr r1, =100		     /* Wait at least 4 us */
1573:	subs r1, r1, #1
158	bge 3b
159
160	mov r1, #0x2
161	str r1, [r2, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
162.endm
163
164.macro init_clock
165#if defined (CONFIG_MX51)
166	ldr r0, =CCM_BASE_ADDR
167
168	/* Gate of clocks to the peripherals first */
169	ldr r1, =0x3FFFFFFF
170	str r1, [r0, #CLKCTL_CCGR0]
171	str r4, [r0, #CLKCTL_CCGR1]
172	str r4, [r0, #CLKCTL_CCGR2]
173	str r4, [r0, #CLKCTL_CCGR3]
174
175	ldr r1, =0x00030000
176	str r1, [r0, #CLKCTL_CCGR4]
177	ldr r1, =0x00FFF030
178	str r1, [r0, #CLKCTL_CCGR5]
179	ldr r1, =0x00000300
180	str r1, [r0, #CLKCTL_CCGR6]
181
182	/* Disable IPU and HSC dividers */
183	mov r1, #0x60000
184	str r1, [r0, #CLKCTL_CCDR]
185
186	/* Make sure to switch the DDR away from PLL 1 */
187	ldr r1, =0x19239145
188	str r1, [r0, #CLKCTL_CBCDR]
189	/* make sure divider effective */
1901:	ldr r1, [r0, #CLKCTL_CDHIPR]
191	cmp r1, #0x0
192	bne 1b
193
194	/* Switch ARM to step clock */
195	mov r1, #0x4
196	str r1, [r0, #CLKCTL_CCSR]
197
198#if defined(CONFIG_MX51_PLL_ERRATA)
199	setup_pll PLL1_BASE_ADDR, 864
200	setup_pll_errata PLL1_BASE_ADDR, W_DP_MFN_800_DIT
201#else
202	setup_pll PLL1_BASE_ADDR, 800
203#endif
204
205	setup_pll PLL3_BASE_ADDR, 665
206
207	/* Switch peripheral to PLL 3 */
208	ldr r0, =CCM_BASE_ADDR
209	ldr r1, =0x000010C0 | CONFIG_SYS_DDR_CLKSEL
210	str r1, [r0, #CLKCTL_CBCMR]
211	ldr r1, =0x13239145
212	str r1, [r0, #CLKCTL_CBCDR]
213	setup_pll PLL2_BASE_ADDR, 665
214
215	/* Switch peripheral to PLL2 */
216	ldr r0, =CCM_BASE_ADDR
217	ldr r1, =0x19239145
218	str r1, [r0, #CLKCTL_CBCDR]
219	ldr r1, =0x000020C0 | CONFIG_SYS_DDR_CLKSEL
220	str r1, [r0, #CLKCTL_CBCMR]
221
222	setup_pll PLL3_BASE_ADDR, 216
223
224	/* Set the platform clock dividers */
225	ldr r0, =ARM_BASE_ADDR
226	ldr r1, =0x00000725
227	str r1, [r0, #0x14]
228
229	ldr r0, =CCM_BASE_ADDR
230
231	/* Run 3.0 at Full speed, for other TO's wait till we increase VDDGP */
232	ldr r3, [r4, #ROM_SI_REV]
233	cmp r3, #0x10
234	movls r1, #0x1
235	movhi r1, #0
236
237	str r1, [r0, #CLKCTL_CACRR]
238
239	/* Switch ARM back to PLL 1 */
240	str r4, [r0, #CLKCTL_CCSR]
241
242	/* setup the rest */
243	/* Use lp_apm (24MHz) source for perclk */
244	ldr r1, =0x000020C2 | CONFIG_SYS_DDR_CLKSEL
245	str r1, [r0, #CLKCTL_CBCMR]
246	/* ddr clock from PLL 1, all perclk dividers are 1 since using 24MHz */
247	ldr r1, =CONFIG_SYS_CLKTL_CBCDR
248	str r1, [r0, #CLKCTL_CBCDR]
249
250	/* Restore the default values in the Gate registers */
251	ldr r1, =0xFFFFFFFF
252	str r1, [r0, #CLKCTL_CCGR0]
253	str r1, [r0, #CLKCTL_CCGR1]
254	str r1, [r0, #CLKCTL_CCGR2]
255	str r1, [r0, #CLKCTL_CCGR3]
256	str r1, [r0, #CLKCTL_CCGR4]
257	str r1, [r0, #CLKCTL_CCGR5]
258	str r1, [r0, #CLKCTL_CCGR6]
259
260	/* Use PLL 2 for UART's, get 66.5MHz from it */
261	ldr r1, =0xA5A2A020
262	str r1, [r0, #CLKCTL_CSCMR1]
263	ldr r1, =0x00C30321
264	str r1, [r0, #CLKCTL_CSCDR1]
265	/* make sure divider effective */
2661:	ldr r1, [r0, #CLKCTL_CDHIPR]
267	cmp r1, #0x0
268	bne 1b
269
270	str r4, [r0, #CLKCTL_CCDR]
271
272	/* for cko - for ARM div by 8 */
273	mov r1, #0x000A0000
274	add r1, r1, #0x00000F0
275	str r1, [r0, #CLKCTL_CCOSR]
276#else	/* CONFIG_MX53 */
277	ldr r0, =CCM_BASE_ADDR
278
279	/* Gate of clocks to the peripherals first */
280	ldr r1, =0x3FFFFFFF
281	str r1, [r0, #CLKCTL_CCGR0]
282	str r4, [r0, #CLKCTL_CCGR1]
283	str r4, [r0, #CLKCTL_CCGR2]
284	str r4, [r0, #CLKCTL_CCGR3]
285	str r4, [r0, #CLKCTL_CCGR7]
286	ldr r1, =0x00030000
287	str r1, [r0, #CLKCTL_CCGR4]
288	ldr r1, =0x00FFF030
289	str r1, [r0, #CLKCTL_CCGR5]
290	ldr r1, =0x0F00030F
291	str r1, [r0, #CLKCTL_CCGR6]
292
293	/* Switch ARM to step clock */
294	mov r1, #0x4
295	str r1, [r0, #CLKCTL_CCSR]
296
297	setup_pll PLL1_BASE_ADDR, 800
298
299	setup_pll PLL3_BASE_ADDR, 400
300
301	/* Switch peripheral to PLL3 */
302	ldr r0, =CCM_BASE_ADDR
303	ldr r1, =0x00015154
304	str r1, [r0, #CLKCTL_CBCMR]
305	ldr r1, =0x02898945
306	str r1, [r0, #CLKCTL_CBCDR]
307	/* make sure change is effective */
3081:      ldr r1, [r0, #CLKCTL_CDHIPR]
309	cmp r1, #0x0
310	bne 1b
311
312	setup_pll PLL2_BASE_ADDR, 400
313
314	/* Switch peripheral to PLL2 */
315	ldr r0, =CCM_BASE_ADDR
316	ldr r1, =0x00888945
317	str r1, [r0, #CLKCTL_CBCDR]
318
319	ldr r1, =0x00016154
320	str r1, [r0, #CLKCTL_CBCMR]
321
322	/*change uart clk parent to pll2*/
323	ldr r1, [r0, #CLKCTL_CSCMR1]
324	and r1, r1, #0xfcffffff
325	orr r1, r1, #0x01000000
326	str r1, [r0, #CLKCTL_CSCMR1]
327
328	/* make sure change is effective */
3291:      ldr r1, [r0, #CLKCTL_CDHIPR]
330	cmp r1, #0x0
331	bne 1b
332
333	setup_pll PLL3_BASE_ADDR, 216
334
335	setup_pll PLL4_BASE_ADDR, 455
336
337	/* Set the platform clock dividers */
338	ldr r0, =ARM_BASE_ADDR
339	ldr r1, =0x00000124
340	str r1, [r0, #0x14]
341
342	ldr r0, =CCM_BASE_ADDR
343	mov r1, #0
344	str r1, [r0, #CLKCTL_CACRR]
345
346	/* Switch ARM back to PLL 1. */
347	mov r1, #0x0
348	str r1, [r0, #CLKCTL_CCSR]
349
350	/* make uart div=6 */
351	ldr r1, [r0, #CLKCTL_CSCDR1]
352	and r1, r1, #0xffffffc0
353	orr r1, r1, #0x0a
354	str r1, [r0, #CLKCTL_CSCDR1]
355
356	/* Restore the default values in the Gate registers */
357	ldr r1, =0xFFFFFFFF
358	str r1, [r0, #CLKCTL_CCGR0]
359	str r1, [r0, #CLKCTL_CCGR1]
360	str r1, [r0, #CLKCTL_CCGR2]
361	str r1, [r0, #CLKCTL_CCGR3]
362	str r1, [r0, #CLKCTL_CCGR4]
363	str r1, [r0, #CLKCTL_CCGR5]
364	str r1, [r0, #CLKCTL_CCGR6]
365	str r1, [r0, #CLKCTL_CCGR7]
366
367	mov r1, #0x00000
368	str r1, [r0, #CLKCTL_CCDR]
369
370	/* for cko - for ARM div by 8 */
371	mov r1, #0x000A0000
372	add r1, r1, #0x00000F0
373	str r1, [r0, #CLKCTL_CCOSR]
374
375#endif	/* CONFIG_MX53 */
376.endm
377
378ENTRY(lowlevel_init)
379	mov r10, lr
380	mov r4, #0	/* Fix R4 to 0 */
381
382#if defined(CONFIG_SYS_MAIN_PWR_ON)
383	ldr r0, =GPIO1_BASE_ADDR
384	ldr r1, [r0, #0x0]
385	orr r1, r1, #1 << 23
386	str r1, [r0, #0x0]
387	ldr r1, [r0, #0x4]
388	orr r1, r1, #1 << 23
389	str r1, [r0, #0x4]
390#endif
391
392	init_arm_erratum
393
394	init_l2cc
395
396	init_aips
397
398	init_m4if
399
400	init_clock
401
402	mov pc, r10
403ENDPROC(lowlevel_init)
404
405/* Board level setting value */
406#if defined(CONFIG_MX51_PLL_ERRATA)
407W_DP_864:		.word DP_OP_864
408			.word DP_MFD_864
409			.word DP_MFN_864
410W_DP_MFN_800_DIT:	.word DP_MFN_800_DIT
411#else
412W_DP_800:		.word DP_OP_800
413			.word DP_MFD_800
414			.word DP_MFN_800
415#endif
416#if defined(CONFIG_MX51)
417W_DP_665:		.word DP_OP_665
418			.word DP_MFD_665
419			.word DP_MFN_665
420#endif
421W_DP_216:		.word DP_OP_216
422			.word DP_MFD_216
423			.word DP_MFN_216
424W_DP_400:               .word DP_OP_400
425			.word DP_MFD_400
426			.word DP_MFN_400
427W_DP_455:               .word DP_OP_455
428			.word DP_MFD_455
429			.word DP_MFN_455
430