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