1 /* SPDX-License-Identifier: GPL-2.0+ */
3 * Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
5 * (C) Copyright 2009 Freescale Semiconductor, Inc.
9 #include <asm/arch/imx-regs.h>
10 #include <generated/asm-offsets.h>
11 #include <linux/linkage.h>
13 .section ".text.init", "x"
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
23 * L2CC Cache setup/invalidation/disable
26 /* explicitly disable L2 cache */
27 mrc 15, 0, r0, c1, c0, 1
29 mcr 15, 0, r0, c1, c0, 1
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 */
38 #if defined(CONFIG_MX51)
39 ldr r3, [r4, #ROM_SI_REV]
42 /* disable write combine for TO 2 and lower revs */
43 orrls r0, r0, #1 << 25
46 mcr 15, 1, r0, c9, c0, 2
49 mrc 15, 0, r0, c1, c0, 1
51 mcr 15, 0, r0, c1, c0, 1
55 /* AIPS setup - Only setup MPROTx registers.
56 * The PACR default values are good.*/
59 * Set all MPROTx to be non-bufferable, trusted for R/W,
60 * not forced to user-mode.
62 ldr r0, =AIPS1_BASE_ADDR
66 ldr r0, =AIPS2_BASE_ADDR
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
79 /* VPU and IPU given higher priority (0x4)
80 * IPU accesses with ID=0x1 given highest priority (=0xA)
82 ldr r0, =M4IF_BASE_ADDR
98 .macro setup_pll pll, freq
110 str r1, [r0, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */
112 str r1, [r0, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
114 ldr r1, [r2, #W_DP_OP]
115 str r1, [r0, #PLL_DP_OP]
116 str r1, [r0, #PLL_DP_HFS_OP]
118 ldr r1, [r2, #W_DP_MFD]
119 str r1, [r0, #PLL_DP_MFD]
120 str r1, [r0, #PLL_DP_HFS_MFD]
122 ldr r1, [r2, #W_DP_MFN]
123 str r1, [r0, #PLL_DP_MFN]
124 str r1, [r0, #PLL_DP_HFS_MFN]
127 str r1, [r0, #PLL_DP_CTL]
128 1: ldr r1, [r0, #PLL_DP_CTL]
132 /* r10 saved upper lr */
135 .macro setup_pll_errata pll, freq
137 str r4, [r2, #PLL_DP_CONFIG] /* Disable auto-restart AREN bit */
139 str r1, [r2, #PLL_DP_CTL] /* Restart PLL with PLM=1 */
140 1: ldr r1, [r2, #PLL_DP_CTL] /* Wait for lock */
145 str r5, [r2, #PLL_DP_MFN] /* Modify MFN value */
146 str r5, [r2, #PLL_DP_HFS_MFN]
149 str r1, [r2, #PLL_DP_CONFIG] /* Reload MFN value */
151 2: ldr r1, [r2, #PLL_DP_CONFIG]
155 ldr r1, =100 /* Wait at least 4 us */
160 str r1, [r2, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
164 #if defined (CONFIG_MX51)
165 ldr r0, =CCM_BASE_ADDR
167 /* Gate of clocks to the peripherals first */
169 str r1, [r0, #CLKCTL_CCGR0]
170 str r4, [r0, #CLKCTL_CCGR1]
171 str r4, [r0, #CLKCTL_CCGR2]
172 str r4, [r0, #CLKCTL_CCGR3]
175 str r1, [r0, #CLKCTL_CCGR4]
177 str r1, [r0, #CLKCTL_CCGR5]
179 str r1, [r0, #CLKCTL_CCGR6]
181 /* Disable IPU and HSC dividers */
183 str r1, [r0, #CLKCTL_CCDR]
185 /* Make sure to switch the DDR away from PLL 1 */
187 str r1, [r0, #CLKCTL_CBCDR]
188 /* make sure divider effective */
189 1: ldr r1, [r0, #CLKCTL_CDHIPR]
193 /* Switch ARM to step clock */
195 str r1, [r0, #CLKCTL_CCSR]
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
201 setup_pll PLL1_BASE_ADDR, 800
204 setup_pll PLL3_BASE_ADDR, 665
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]
211 str r1, [r0, #CLKCTL_CBCDR]
212 setup_pll PLL2_BASE_ADDR, 665
214 /* Switch peripheral to PLL2 */
215 ldr r0, =CCM_BASE_ADDR
217 str r1, [r0, #CLKCTL_CBCDR]
218 ldr r1, =0x000020C0 | CONFIG_SYS_DDR_CLKSEL
219 str r1, [r0, #CLKCTL_CBCMR]
221 setup_pll PLL3_BASE_ADDR, 216
223 /* Set the platform clock dividers */
224 ldr r0, =ARM_BASE_ADDR
228 ldr r0, =CCM_BASE_ADDR
230 /* Run 3.0 at Full speed, for other TO's wait till we increase VDDGP */
231 ldr r3, [r4, #ROM_SI_REV]
236 str r1, [r0, #CLKCTL_CACRR]
238 /* Switch ARM back to PLL 1 */
239 str r4, [r0, #CLKCTL_CCSR]
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]
249 /* Restore the default values in the Gate registers */
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]
259 /* Use PLL 2 for UART's, get 66.5MHz from it */
261 str r1, [r0, #CLKCTL_CSCMR1]
263 str r1, [r0, #CLKCTL_CSCDR1]
264 /* make sure divider effective */
265 1: ldr r1, [r0, #CLKCTL_CDHIPR]
269 str r4, [r0, #CLKCTL_CCDR]
271 /* for cko - for ARM div by 8 */
273 add r1, r1, #0x00000F0
274 str r1, [r0, #CLKCTL_CCOSR]
275 #else /* CONFIG_MX53 */
276 ldr r0, =CCM_BASE_ADDR
278 /* Gate of clocks to the peripherals first */
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]
286 str r1, [r0, #CLKCTL_CCGR4]
288 str r1, [r0, #CLKCTL_CCGR5]
290 str r1, [r0, #CLKCTL_CCGR6]
292 /* Switch ARM to step clock */
294 str r1, [r0, #CLKCTL_CCSR]
296 setup_pll PLL1_BASE_ADDR, 800
298 setup_pll PLL3_BASE_ADDR, 400
300 /* Switch peripheral to PLL3 */
301 ldr r0, =CCM_BASE_ADDR
303 str r1, [r0, #CLKCTL_CBCMR]
305 str r1, [r0, #CLKCTL_CBCDR]
306 /* make sure change is effective */
307 1: ldr r1, [r0, #CLKCTL_CDHIPR]
311 setup_pll PLL2_BASE_ADDR, 400
313 /* Switch peripheral to PLL2 */
314 ldr r0, =CCM_BASE_ADDR
316 str r1, [r0, #CLKCTL_CBCDR]
319 str r1, [r0, #CLKCTL_CBCMR]
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]
327 /* make sure change is effective */
328 1: ldr r1, [r0, #CLKCTL_CDHIPR]
332 setup_pll PLL3_BASE_ADDR, 216
334 setup_pll PLL4_BASE_ADDR, 455
336 /* Set the platform clock dividers */
337 ldr r0, =ARM_BASE_ADDR
341 ldr r0, =CCM_BASE_ADDR
343 str r1, [r0, #CLKCTL_CACRR]
345 /* Switch ARM back to PLL 1. */
347 str r1, [r0, #CLKCTL_CCSR]
349 /* make uart div=6 */
350 ldr r1, [r0, #CLKCTL_CSCDR1]
351 and r1, r1, #0xffffffc0
353 str r1, [r0, #CLKCTL_CSCDR1]
355 /* Restore the default values in the Gate registers */
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]
367 str r1, [r0, #CLKCTL_CCDR]
369 /* for cko - for ARM div by 8 */
371 add r1, r1, #0x00000F0
372 str r1, [r0, #CLKCTL_CCOSR]
374 #endif /* CONFIG_MX53 */
379 mov r4, #0 /* Fix R4 to 0 */
381 #if defined(CONFIG_SYS_MAIN_PWR_ON)
382 ldr r0, =GPIO1_BASE_ADDR
402 ENDPROC(lowlevel_init)
404 /* Board level setting value */
405 #if defined(CONFIG_MX51_PLL_ERRATA)
406 W_DP_864: .word DP_OP_864
409 W_DP_MFN_800_DIT: .word DP_MFN_800_DIT
411 W_DP_800: .word DP_OP_800
415 #if defined(CONFIG_MX51)
416 W_DP_665: .word DP_OP_665
420 W_DP_216: .word DP_OP_216
423 W_DP_400: .word DP_OP_400
426 W_DP_455: .word DP_OP_455