1/*
2 * Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
3 *
4 * (C) Copyright 2009 Freescale Semiconductor, Inc.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; either version 2 of
9 * the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
19 * MA 02111-1307 USA
20 */
21
22#include <config.h>
23#include <asm/arch/imx-regs.h>
24#include <asm/arch/asm-offsets.h>
25
26/*
27 * L2CC Cache setup/invalidation/disable
28 */
29.macro init_l2cc
30	/* explicitly disable L2 cache */
31	mrc 15, 0, r0, c1, c0, 1
32	bic r0, r0, #0x2
33	mcr 15, 0, r0, c1, c0, 1
34
35	/* reconfigure L2 cache aux control reg */
36	mov r0, #0xC0			/* tag RAM */
37	add r0, r0, #0x4		/* data RAM */
38	orr r0, r0, #(1 << 24)		/* disable write allocate delay */
39	orr r0, r0, #(1 << 23)		/* disable write allocate combine */
40	orr r0, r0, #(1 << 22)		/* disable write allocate */
41
42	cmp r3, #0x10    /* r3 contains the silicon rev */
43
44	/* disable write combine for TO 2 and lower revs */
45	orrls r0, r0, #(1 << 25)
46
47	mcr 15, 1, r0, c9, c0, 2
48.endm /* init_l2cc */
49
50/* AIPS setup - Only setup MPROTx registers.
51 * The PACR default values are good.*/
52.macro init_aips
53	/*
54	 * Set all MPROTx to be non-bufferable, trusted for R/W,
55	 * not forced to user-mode.
56	 */
57	ldr r0, =AIPS1_BASE_ADDR
58	ldr r1, =0x77777777
59	str r1, [r0, #0x0]
60	str r1, [r0, #0x4]
61	ldr r0, =AIPS2_BASE_ADDR
62	str r1, [r0, #0x0]
63	str r1, [r0, #0x4]
64	/*
65	 * Clear the on and off peripheral modules Supervisor Protect bit
66	 * for SDMA to access them. Did not change the AIPS control registers
67	 * (offset 0x20) access type
68	 */
69.endm /* init_aips */
70
71/* M4IF setup */
72.macro init_m4if
73	/* VPU and IPU given higher priority (0x4)
74	 * IPU accesses with ID=0x1 given highest priority (=0xA)
75	 */
76	ldr r0, =M4IF_BASE_ADDR
77
78	ldr r1, =0x00000203
79	str r1, [r0, #0x40]
80
81	ldr r1, =0x0
82	str r1, [r0, #0x44]
83
84	ldr r1, =0x00120125
85	str r1, [r0, #0x9C]
86
87	ldr r1, =0x001901A3
88	str r1, [r0, #0x48]
89
90.endm /* init_m4if */
91
92.macro setup_pll pll, freq
93	ldr r2, =\pll
94	ldr r1, =0x00001232
95	str r1, [r2, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */
96	mov r1, #0x2
97	str r1, [r2, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */
98
99	str r3, [r2, #PLL_DP_OP]
100	str r3, [r2, #PLL_DP_HFS_OP]
101
102	str r4, [r2, #PLL_DP_MFD]
103	str r4, [r2, #PLL_DP_HFS_MFD]
104
105	str r5, [r2, #PLL_DP_MFN]
106	str r5, [r2, #PLL_DP_HFS_MFN]
107
108	ldr r1, =0x00001232
109	str r1, [r2, #PLL_DP_CTL]
1101:	ldr r1, [r2, #PLL_DP_CTL]
111	ands r1, r1, #0x1
112	beq 1b
113.endm
114
115.macro init_clock
116	ldr r0, =CCM_BASE_ADDR
117
118	/* Gate of clocks to the peripherals first */
119	ldr r1, =0x3FFFFFFF
120	str r1, [r0, #CLKCTL_CCGR0]
121	ldr r1, =0x0
122	str r1, [r0, #CLKCTL_CCGR1]
123	str r1, [r0, #CLKCTL_CCGR2]
124	str r1, [r0, #CLKCTL_CCGR3]
125
126	ldr r1, =0x00030000
127	str r1, [r0, #CLKCTL_CCGR4]
128	ldr r1, =0x00FFF030
129	str r1, [r0, #CLKCTL_CCGR5]
130	ldr r1, =0x00000300
131	str r1, [r0, #CLKCTL_CCGR6]
132
133	/* Disable IPU and HSC dividers */
134	mov r1, #0x60000
135	str r1, [r0, #CLKCTL_CCDR]
136
137	/* Make sure to switch the DDR away from PLL 1 */
138	ldr r1, =0x19239145
139	str r1, [r0, #CLKCTL_CBCDR]
140	/* make sure divider effective */
1411:	ldr r1, [r0, #CLKCTL_CDHIPR]
142	cmp r1, #0x0
143	bne 1b
144
145	/* Switch ARM to step clock */
146	mov r1, #0x4
147	str r1, [r0, #CLKCTL_CCSR]
148	mov r3, #DP_OP_800
149	mov r4, #DP_MFD_800
150	mov r5, #DP_MFN_800
151	setup_pll PLL1_BASE_ADDR
152
153	mov r3, #DP_OP_665
154	mov r4, #DP_MFD_665
155	mov r5, #DP_MFN_665
156	setup_pll PLL3_BASE_ADDR
157
158	/* Switch peripheral to PLL 3 */
159	ldr r0, =CCM_BASE_ADDR
160	ldr r1, =0x000010C0
161	orr r1,r1,#CONFIG_SYS_DDR_CLKSEL
162	str r1, [r0, #CLKCTL_CBCMR]
163	ldr r1, =0x13239145
164	str r1, [r0, #CLKCTL_CBCDR]
165	mov r3, #DP_OP_665
166	mov r4, #DP_MFD_665
167	mov r5, #DP_MFN_665
168	setup_pll PLL2_BASE_ADDR
169
170	/* Switch peripheral to PLL2 */
171	ldr r0, =CCM_BASE_ADDR
172	ldr r1, =0x19239145
173	str r1, [r0, #CLKCTL_CBCDR]
174	ldr r1, =0x000020C0
175	orr r1,r1,#CONFIG_SYS_DDR_CLKSEL
176	str r1, [r0, #CLKCTL_CBCMR]
177
178	mov r3, #DP_OP_216
179	mov r4, #DP_MFD_216
180	mov r5, #DP_MFN_216
181	setup_pll PLL3_BASE_ADDR
182
183
184	/* Set the platform clock dividers */
185	ldr r0, =ARM_BASE_ADDR
186	ldr r1, =0x00000725
187	str r1, [r0, #0x14]
188
189	ldr r0, =CCM_BASE_ADDR
190
191	/* Run 3.0 at Full speed, for other TO's wait till we increase VDDGP */
192	ldr r1, =0x0
193	ldr r3, [r1, #ROM_SI_REV]
194	cmp r3, #0x10
195	movls r1, #0x1
196	movhi r1, #0
197	str r1, [r0, #CLKCTL_CACRR]
198
199	/* Switch ARM back to PLL 1 */
200	mov r1, #0
201	str r1, [r0, #CLKCTL_CCSR]
202
203	/* setup the rest */
204	/* Use lp_apm (24MHz) source for perclk */
205	ldr r1, =0x000020C2
206	orr r1,r1,#CONFIG_SYS_DDR_CLKSEL
207	str r1, [r0, #CLKCTL_CBCMR]
208	/* ddr clock from PLL 1, all perclk dividers are 1 since using 24MHz */
209	ldr r1, =CONFIG_SYS_CLKTL_CBCDR
210	str r1, [r0, #CLKCTL_CBCDR]
211
212	/* Restore the default values in the Gate registers */
213	ldr r1, =0xFFFFFFFF
214	str r1, [r0, #CLKCTL_CCGR0]
215	str r1, [r0, #CLKCTL_CCGR1]
216	str r1, [r0, #CLKCTL_CCGR2]
217	str r1, [r0, #CLKCTL_CCGR3]
218	str r1, [r0, #CLKCTL_CCGR4]
219	str r1, [r0, #CLKCTL_CCGR5]
220	str r1, [r0, #CLKCTL_CCGR6]
221
222	/* Use PLL 2 for UART's, get 66.5MHz from it */
223	ldr r1, =0xA5A2A020
224	str r1, [r0, #CLKCTL_CSCMR1]
225	ldr r1, =0x00C30321
226	str r1, [r0, #CLKCTL_CSCDR1]
227
228	/* make sure divider effective */
2291:	ldr r1, [r0, #CLKCTL_CDHIPR]
230	cmp r1, #0x0
231	bne 1b
232
233	mov r1, #0x0
234	str r1, [r0, #CLKCTL_CCDR]
235
236	/* for cko - for ARM div by 8 */
237	mov r1, #0x000A0000
238	add r1, r1, #0x00000F0
239	str r1, [r0, #CLKCTL_CCOSR]
240.endm
241
242.macro setup_wdog
243	ldr r0, =WDOG1_BASE_ADDR
244	mov r1, #0x30
245	strh r1, [r0]
246.endm
247
248.section ".text.init", "x"
249
250.globl lowlevel_init
251lowlevel_init:
252	ldr r0, =GPIO1_BASE_ADDR
253	ldr r1, [r0, #0x0]
254	orr r1, r1, #(1 << 23)
255	str r1, [r0, #0x0]
256	ldr r1, [r0, #0x4]
257	orr r1, r1, #(1 << 23)
258	str r1, [r0, #0x4]
259
260#ifdef ENABLE_IMPRECISE_ABORT
261	mrs r1, spsr		/* save old spsr */
262	mrs r0, cpsr		/* read out the cpsr */
263	bic r0, r0, #0x100	/* clear the A bit */
264	msr spsr, r0		/* update spsr */
265	add lr, pc, #0x8	/* update lr */
266	movs pc, lr		/* update cpsr */
267	nop
268	nop
269	nop
270	nop
271	msr spsr, r1		/* restore old spsr */
272#endif
273
274	init_l2cc
275
276	init_aips
277
278	init_m4if
279
280	init_clock
281
282	/* r12 saved upper lr*/
283	mov pc,lr
284
285/* Board level setting value */
286DDR_PERCHARGE_CMD:	.word 0x04008008
287DDR_REFRESH_CMD:	.word 0x00008010
288DDR_LMR1_W:		.word 0x00338018
289DDR_LMR_CMD:		.word 0xB2220000
290DDR_TIMING_W:		.word 0xB02567A9
291DDR_MISC_W:		.word 0x000A0104
292