xref: /OK3568_Linux_fs/u-boot/arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun/*
2*4882a593Smuzhiyun * Low-level initialization for EP93xx
3*4882a593Smuzhiyun *
4*4882a593Smuzhiyun * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
5*4882a593Smuzhiyun * Copyright (C) 2013
6*4882a593Smuzhiyun * Sergey Kostanabev <sergey.kostanbaev <at> fairwaves.ru>
7*4882a593Smuzhiyun *
8*4882a593Smuzhiyun * Copyright (C) 2006 Dominic Rath <Dominic.Rath@gmx.de>
9*4882a593Smuzhiyun * Copyright (C) 2006 Cirrus Logic Inc.
10*4882a593Smuzhiyun *
11*4882a593Smuzhiyun * See file CREDITS for list of people who contributed to this
12*4882a593Smuzhiyun * project.
13*4882a593Smuzhiyun *
14*4882a593Smuzhiyun * SPDX-License-Identifier:	GPL-2.0+
15*4882a593Smuzhiyun */
16*4882a593Smuzhiyun
17*4882a593Smuzhiyun#include <config.h>
18*4882a593Smuzhiyun#include <asm/arch-ep93xx/ep93xx.h>
19*4882a593Smuzhiyun
20*4882a593Smuzhiyun/*
21*4882a593Smuzhiyun/* Configure the SDRAM based on the supplied settings.
22*4882a593Smuzhiyun *
23*4882a593Smuzhiyun * Input:	r0 - SDRAM DEVCFG register
24*4882a593Smuzhiyun *		r2 - configuration for SDRAM chips
25*4882a593Smuzhiyun * Output:	none
26*4882a593Smuzhiyun * Modifies:	r3, r4
27*4882a593Smuzhiyun */
28*4882a593Smuzhiyunep93xx_sdram_config:
29*4882a593Smuzhiyun	/* Program the SDRAM device configuration register. */
30*4882a593Smuzhiyun	ldr	r3, =SDRAM_BASE
31*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS0
32*4882a593Smuzhiyun	str	r0, [r3, #SDRAM_OFF_DEVCFG0]
33*4882a593Smuzhiyun#endif
34*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS1
35*4882a593Smuzhiyun	str	r0, [r3, #SDRAM_OFF_DEVCFG1]
36*4882a593Smuzhiyun#endif
37*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS2
38*4882a593Smuzhiyun	str	r0, [r3, #SDRAM_OFF_DEVCFG2]
39*4882a593Smuzhiyun#endif
40*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS3
41*4882a593Smuzhiyun	str	r0, [r3, #SDRAM_OFF_DEVCFG3]
42*4882a593Smuzhiyun#endif
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun	/* Set the Initialize and MRS bits (issue continuous NOP commands
45*4882a593Smuzhiyun	 * (INIT & MRS set))
46*4882a593Smuzhiyun	 */
47*4882a593Smuzhiyun	ldr	r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_INIT | \
48*4882a593Smuzhiyun			EP93XX_SDRAMCTRL_GLOBALCFG_MRS | \
49*4882a593Smuzhiyun			EP93XX_SDRAMCTRL_GLOBALCFG_CKE)
50*4882a593Smuzhiyun	str	r4, [r3, #SDRAM_OFF_GLCONFIG]
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun	/* Delay for 200us. */
53*4882a593Smuzhiyun	mov	r4, #0x3000
54*4882a593Smuzhiyundelay1:
55*4882a593Smuzhiyun	subs	r4, r4, #1
56*4882a593Smuzhiyun	bne	delay1
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun	/* Clear the MRS bit to issue a precharge all. */
59*4882a593Smuzhiyun	ldr	r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_INIT | \
60*4882a593Smuzhiyun			EP93XX_SDRAMCTRL_GLOBALCFG_CKE)
61*4882a593Smuzhiyun	str	r4, [r3, #SDRAM_OFF_GLCONFIG]
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun	/* Temporarily set the refresh timer to 0x10. Make it really low so
64*4882a593Smuzhiyun	 * that refresh cycles are generated.
65*4882a593Smuzhiyun	 */
66*4882a593Smuzhiyun	ldr	r4, =0x10
67*4882a593Smuzhiyun	str	r4, [r3, #SDRAM_OFF_REFRSHTIMR]
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun	/* Delay for at least 80 SDRAM clock cycles. */
70*4882a593Smuzhiyun	mov	r4, #80
71*4882a593Smuzhiyundelay2:
72*4882a593Smuzhiyun	subs	r4, r4, #1
73*4882a593Smuzhiyun	bne	delay2
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun	/* Set the refresh timer to the fastest required for any device
76*4882a593Smuzhiyun	 * that might be used. Set 9.6 ms refresh time.
77*4882a593Smuzhiyun	 */
78*4882a593Smuzhiyun	ldr	r4, =0x01e0
79*4882a593Smuzhiyun	str	r4, [r3, #SDRAM_OFF_REFRSHTIMR]
80*4882a593Smuzhiyun
81*4882a593Smuzhiyun	/* Select mode register update mode. */
82*4882a593Smuzhiyun	ldr	r4, =(EP93XX_SDRAMCTRL_GLOBALCFG_CKE | \
83*4882a593Smuzhiyun			EP93XX_SDRAMCTRL_GLOBALCFG_MRS)
84*4882a593Smuzhiyun	str	r4, [r3, #SDRAM_OFF_GLCONFIG]
85*4882a593Smuzhiyun
86*4882a593Smuzhiyun	/* Program the mode register on the SDRAM by performing fake read */
87*4882a593Smuzhiyun	ldr	r4, [r2]
88*4882a593Smuzhiyun
89*4882a593Smuzhiyun	/* Select normal operating mode. */
90*4882a593Smuzhiyun	ldr	r4, =EP93XX_SDRAMCTRL_GLOBALCFG_CKE
91*4882a593Smuzhiyun	str	r4, [r3, #SDRAM_OFF_GLCONFIG]
92*4882a593Smuzhiyun
93*4882a593Smuzhiyun	/* Return to the caller. */
94*4882a593Smuzhiyun	mov	pc, lr
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun/*
97*4882a593Smuzhiyun * Test to see if the SDRAM has been configured in a usable mode.
98*4882a593Smuzhiyun *
99*4882a593Smuzhiyun * Input:	r0 - Test address of SDRAM
100*4882a593Smuzhiyun * Output:	r0 - 0 -- Test OK, -1 -- Failed
101*4882a593Smuzhiyun * Modifies:	r0-r5
102*4882a593Smuzhiyun */
103*4882a593Smuzhiyunep93xx_sdram_test:
104*4882a593Smuzhiyun	/* Load the test patterns to be written to SDRAM. */
105*4882a593Smuzhiyun	ldr	r1, =0xf00dface
106*4882a593Smuzhiyun	ldr	r2, =0xdeadbeef
107*4882a593Smuzhiyun	ldr	r3, =0x08675309
108*4882a593Smuzhiyun	ldr	r4, =0xdeafc0ed
109*4882a593Smuzhiyun
110*4882a593Smuzhiyun	/* Store the test patterns to SDRAM. */
111*4882a593Smuzhiyun	stmia	r0, {r1-r4}
112*4882a593Smuzhiyun
113*4882a593Smuzhiyun	/* Load the test patterns from SDRAM one at a time and compare them
114*4882a593Smuzhiyun	 * to the actual pattern.
115*4882a593Smuzhiyun	 */
116*4882a593Smuzhiyun	ldr	r5, [r0]
117*4882a593Smuzhiyun	cmp	r5, r1
118*4882a593Smuzhiyun	ldreq	r5, [r0, #0x0004]
119*4882a593Smuzhiyun	cmpeq	r5, r2
120*4882a593Smuzhiyun	ldreq	r5, [r0, #0x0008]
121*4882a593Smuzhiyun	cmpeq	r5, r3
122*4882a593Smuzhiyun	ldreq	r5, [r0, #0x000c]
123*4882a593Smuzhiyun	cmpeq	r5, r4
124*4882a593Smuzhiyun
125*4882a593Smuzhiyun	/* Return -1 if a mismatch was encountered, 0 otherwise. */
126*4882a593Smuzhiyun	mvnne	r0, #0xffffffff
127*4882a593Smuzhiyun	moveq	r0, #0x00000000
128*4882a593Smuzhiyun
129*4882a593Smuzhiyun	/* Return to the caller. */
130*4882a593Smuzhiyun	mov	pc, lr
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun/*
133*4882a593Smuzhiyun * Determine the size of the SDRAM. Use data=address for the scan.
134*4882a593Smuzhiyun *
135*4882a593Smuzhiyun * Input:	r0 - Start SDRAM address
136*4882a593Smuzhiyun * Return:	r0 - Single block size
137*4882a593Smuzhiyun *		r1 - Valid block mask
138*4882a593Smuzhiyun *		r2 - Total block count
139*4882a593Smuzhiyun * Modifies:	r0-r5
140*4882a593Smuzhiyun */
141*4882a593Smuzhiyunep93xx_sdram_size:
142*4882a593Smuzhiyun	/* Store zero at offset zero. */
143*4882a593Smuzhiyun	str	r0, [r0]
144*4882a593Smuzhiyun
145*4882a593Smuzhiyun	/* Start checking for an alias at 1MB into SDRAM. */
146*4882a593Smuzhiyun	ldr	r1, =0x00100000
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun	/* Store the offset at the current offset. */
149*4882a593Smuzhiyuncheck_block_size:
150*4882a593Smuzhiyun	str	r1, [r0, r1]
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun	/* Read back from zero. */
153*4882a593Smuzhiyun	ldr	r2, [r0]
154*4882a593Smuzhiyun
155*4882a593Smuzhiyun	/* Stop searching of an alias was found. */
156*4882a593Smuzhiyun	cmp	r1, r2
157*4882a593Smuzhiyun	beq	found_block_size
158*4882a593Smuzhiyun
159*4882a593Smuzhiyun	/* Advance to the next power of two boundary. */
160*4882a593Smuzhiyun	mov	r1, r1, lsl #1
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun	/* Loop back if the size has not reached 256MB. */
163*4882a593Smuzhiyun	cmp	r1, #0x10000000
164*4882a593Smuzhiyun	bne	check_block_size
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun	/* A full 256MB of memory was found, so return it now. */
167*4882a593Smuzhiyun	ldr	r0, =0x10000000
168*4882a593Smuzhiyun	ldr	r1, =0x00000000
169*4882a593Smuzhiyun	ldr	r2, =0x00000001
170*4882a593Smuzhiyun	mov	pc, lr
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun	/* An alias was found. See if the first block is 128MB in size. */
173*4882a593Smuzhiyunfound_block_size:
174*4882a593Smuzhiyun	cmp	r1, #0x08000000
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun	/* The first block is 128MB, so there is no further memory. Return it
177*4882a593Smuzhiyun	 * now.
178*4882a593Smuzhiyun	 */
179*4882a593Smuzhiyun	ldreq	r0, =0x08000000
180*4882a593Smuzhiyun	ldreq	r1, =0x00000000
181*4882a593Smuzhiyun	ldreq	r2, =0x00000001
182*4882a593Smuzhiyun	moveq	pc, lr
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun	/* Save the block size, set the block address bits to zero, and
185*4882a593Smuzhiyun	 * initialize the block count to one.
186*4882a593Smuzhiyun	 */
187*4882a593Smuzhiyun	mov	r3, r1
188*4882a593Smuzhiyun	ldr	r4, =0x00000000
189*4882a593Smuzhiyun	ldr	r5, =0x00000001
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun	/* Look for additional blocks of memory by searching for non-aliases. */
192*4882a593Smuzhiyunfind_blocks:
193*4882a593Smuzhiyun	/* Store zero back to address zero. It may be overwritten. */
194*4882a593Smuzhiyun	str	r0, [r0]
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun	/* Advance to the next power of two boundary. */
197*4882a593Smuzhiyun	mov	r1, r1, lsl #1
198*4882a593Smuzhiyun
199*4882a593Smuzhiyun	/* Store the offset at the current offset. */
200*4882a593Smuzhiyun	str	r1, [r0, r1]
201*4882a593Smuzhiyun
202*4882a593Smuzhiyun	/* Read back from zero. */
203*4882a593Smuzhiyun	ldr	r2, [r0]
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun	/* See if a non-alias was found. */
206*4882a593Smuzhiyun	cmp	r1, r2
207*4882a593Smuzhiyun
208*4882a593Smuzhiyun	/* If a non-alias was found, then or in the block address bit and
209*4882a593Smuzhiyun	 * multiply the block count by two (since there are two unique
210*4882a593Smuzhiyun	 * blocks, one with this bit zero and one with it one).
211*4882a593Smuzhiyun	 */
212*4882a593Smuzhiyun	orrne	r4, r4, r1
213*4882a593Smuzhiyun	movne	r5, r5, lsl #1
214*4882a593Smuzhiyun
215*4882a593Smuzhiyun	/* Continue searching if there are more address bits to check. */
216*4882a593Smuzhiyun	cmp	r1, #0x08000000
217*4882a593Smuzhiyun	bne	find_blocks
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun	/* Return the block size, address mask, and count. */
220*4882a593Smuzhiyun	mov	r0, r3
221*4882a593Smuzhiyun	mov	r1, r4
222*4882a593Smuzhiyun	mov	r2, r5
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun	/* Return to the caller. */
225*4882a593Smuzhiyun	mov	pc, lr
226*4882a593Smuzhiyun
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun.globl lowlevel_init
229*4882a593Smuzhiyunlowlevel_init:
230*4882a593Smuzhiyun
231*4882a593Smuzhiyun	mov	r6, lr
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun	/* Make sure caches are off and invalidated. */
234*4882a593Smuzhiyun	ldr	r0, =0x00000000
235*4882a593Smuzhiyun	mcr	p15, 0, r0, c1, c0, 0
236*4882a593Smuzhiyun	nop
237*4882a593Smuzhiyun	nop
238*4882a593Smuzhiyun	nop
239*4882a593Smuzhiyun	nop
240*4882a593Smuzhiyun	nop
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun	/* Turn off the green LED and turn on the red LED. If the red LED
243*4882a593Smuzhiyun	 * is left on for too long, the external reset circuit described
244*4882a593Smuzhiyun	 * by application note AN258 will cause the system to reset.
245*4882a593Smuzhiyun	 */
246*4882a593Smuzhiyun	ldr	r1, =EP93XX_LED_DATA
247*4882a593Smuzhiyun	ldr	r0, [r1]
248*4882a593Smuzhiyun	bic	r0, r0, #EP93XX_LED_GREEN_ON
249*4882a593Smuzhiyun	orr	r0, r0, #EP93XX_LED_RED_ON
250*4882a593Smuzhiyun	str	r0, [r1]
251*4882a593Smuzhiyun
252*4882a593Smuzhiyun	/* Undo the silly static memory controller programming performed
253*4882a593Smuzhiyun	 * by the boot rom.
254*4882a593Smuzhiyun	 */
255*4882a593Smuzhiyun	ldr	r0, =SMC_BASE
256*4882a593Smuzhiyun
257*4882a593Smuzhiyun	/* Set WST1 and WST2 to 31 HCLK cycles (slowest access) */
258*4882a593Smuzhiyun	ldr	r1, =0x0000fbe0
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun	/* Reset EP93XX_OFF_SMCBCR0 */
261*4882a593Smuzhiyun	ldr	r2, [r0]
262*4882a593Smuzhiyun	orr	r2, r2, r1
263*4882a593Smuzhiyun	str	r2, [r0]
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun	ldr	r2, [r0, #EP93XX_OFF_SMCBCR1]
266*4882a593Smuzhiyun	orr	r2, r2, r1
267*4882a593Smuzhiyun	str	r2, [r0, #EP93XX_OFF_SMCBCR1]
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun	ldr	r2, [r0, #EP93XX_OFF_SMCBCR2]
270*4882a593Smuzhiyun	orr	r2, r2, r1
271*4882a593Smuzhiyun	str	r2, [r0, #EP93XX_OFF_SMCBCR2]
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun	ldr	r2, [r0, #EP93XX_OFF_SMCBCR3]
274*4882a593Smuzhiyun	orr	r2, r2, r1
275*4882a593Smuzhiyun	str	r2, [r0, #EP93XX_OFF_SMCBCR3]
276*4882a593Smuzhiyun
277*4882a593Smuzhiyun	ldr	r2, [r0, #EP93XX_OFF_SMCBCR6]
278*4882a593Smuzhiyun	orr	r2, r2, r1
279*4882a593Smuzhiyun	str	r2, [r0, #EP93XX_OFF_SMCBCR6]
280*4882a593Smuzhiyun
281*4882a593Smuzhiyun	ldr	r2, [r0, #EP93XX_OFF_SMCBCR7]
282*4882a593Smuzhiyun	orr	r2, r2, r1
283*4882a593Smuzhiyun	str	r2, [r0, #EP93XX_OFF_SMCBCR7]
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun	/* Set the PLL1 and processor clock. */
286*4882a593Smuzhiyun	ldr	r0, =SYSCON_BASE
287*4882a593Smuzhiyun#ifdef CONFIG_EDB9301
288*4882a593Smuzhiyun	/* 332MHz, giving a 166MHz processor clock. */
289*4882a593Smuzhiyun	ldr	r1, = 0x02b49907
290*4882a593Smuzhiyun#else
291*4882a593Smuzhiyun
292*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_INDUSTRIAL
293*4882a593Smuzhiyun	/* 384MHz, giving a 196MHz processor clock. */
294*4882a593Smuzhiyun	ldr	r1, =0x02a4bb38
295*4882a593Smuzhiyun#else
296*4882a593Smuzhiyun	/* 400MHz, giving a 200MHz processor clock. */
297*4882a593Smuzhiyun	ldr	r1, =0x02a4e39e
298*4882a593Smuzhiyun#endif
299*4882a593Smuzhiyun#endif
300*4882a593Smuzhiyun	str	r1, [r0, #SYSCON_OFF_CLKSET1]
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun	nop
303*4882a593Smuzhiyun	nop
304*4882a593Smuzhiyun	nop
305*4882a593Smuzhiyun	nop
306*4882a593Smuzhiyun	nop
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun	/* Need to make sure that SDRAM is configured correctly before
309*4882a593Smuzhiyun	 * coping the code into it.
310*4882a593Smuzhiyun	 */
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS0
313*4882a593Smuzhiyun	mov	r11, #SDRAM_DEVCFG0_BASE
314*4882a593Smuzhiyun#endif
315*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS1
316*4882a593Smuzhiyun	mov	r11, #SDRAM_DEVCFG1_BASE
317*4882a593Smuzhiyun#endif
318*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS2
319*4882a593Smuzhiyun	mov	r11, #SDRAM_DEVCFG2_BASE
320*4882a593Smuzhiyun#endif
321*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS3
322*4882a593Smuzhiyun	ldr	r0, =SYSCON_BASE
323*4882a593Smuzhiyun	ldr	r0, [r0, #SYSCON_OFF_SYSCFG]
324*4882a593Smuzhiyun	ands	r0, r0, #SYSCON_SYSCFG_LASDO
325*4882a593Smuzhiyun	moveq	r11, #SDRAM_DEVCFG3_ASD0_BASE
326*4882a593Smuzhiyun	movne	r11, #SDRAM_DEVCFG3_ASD1_BASE
327*4882a593Smuzhiyun#endif
328*4882a593Smuzhiyun	/* See Table 13-5 in EP93xx datasheet for more info about DRAM
329*4882a593Smuzhiyun	 * register mapping */
330*4882a593Smuzhiyun
331*4882a593Smuzhiyun	/* Try a 32-bit wide configuration of SDRAM. */
332*4882a593Smuzhiyun	ldr	r0, =(EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT | \
333*4882a593Smuzhiyun			EP93XX_SDRAMCTRL_DEVCFG_SROMLL | \
334*4882a593Smuzhiyun			EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2 | \
335*4882a593Smuzhiyun			EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2)
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun	/* Set burst count: 4 and CAS: 2
338*4882a593Smuzhiyun	 * Burst mode [A11:A10]; CAS [A16:A14]
339*4882a593Smuzhiyun	 */
340*4882a593Smuzhiyun	orr	r2, r11, #0x00008800
341*4882a593Smuzhiyun	bl	ep93xx_sdram_config
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun	/* Test the SDRAM. */
344*4882a593Smuzhiyun	mov	r0, r11
345*4882a593Smuzhiyun	bl	ep93xx_sdram_test
346*4882a593Smuzhiyun	cmp	r0, #0x00000000
347*4882a593Smuzhiyun	beq	ep93xx_sdram_done
348*4882a593Smuzhiyun
349*4882a593Smuzhiyun	/* Try a 16-bit wide configuration of SDRAM. */
350*4882a593Smuzhiyun	ldr	r0, =(EP93XX_SDRAMCTRL_DEVCFG_BANKCOUNT | \
351*4882a593Smuzhiyun			EP93XX_SDRAMCTRL_DEVCFG_SROMLL | \
352*4882a593Smuzhiyun			EP93XX_SDRAMCTRL_DEVCFG_CASLAT_2 | \
353*4882a593Smuzhiyun			EP93XX_SDRAMCTRL_DEVCFG_RASTOCAS_2 | \
354*4882a593Smuzhiyun			EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH)
355*4882a593Smuzhiyun
356*4882a593Smuzhiyun	/* Set burst count: 8, CAS: 2, sequential burst
357*4882a593Smuzhiyun	 * Accoring to Table 13-3 for 16bit operations mapping must be shifted.
358*4882a593Smuzhiyun	 * Burst mode [A10:A9]; CAS [A15:A13]
359*4882a593Smuzhiyun	 */
360*4882a593Smuzhiyun	orr	r2, r11, #0x00004600
361*4882a593Smuzhiyun	bl	ep93xx_sdram_config
362*4882a593Smuzhiyun
363*4882a593Smuzhiyun	/* Test the SDRAM. */
364*4882a593Smuzhiyun	mov	r0, r11
365*4882a593Smuzhiyun	bl	ep93xx_sdram_test
366*4882a593Smuzhiyun	cmp	r0, #0x00000000
367*4882a593Smuzhiyun	beq	ep93xx_sdram_done
368*4882a593Smuzhiyun
369*4882a593Smuzhiyun	/* Turn off the red LED. */
370*4882a593Smuzhiyun	ldr	r0, =EP93XX_LED_DATA
371*4882a593Smuzhiyun	ldr	r1, [r0]
372*4882a593Smuzhiyun	bic	r1, r1, #EP93XX_LED_RED_ON
373*4882a593Smuzhiyun	str	r1, [r0]
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun	/* There is no SDRAM so flash the green LED. */
376*4882a593Smuzhiyunflash_green:
377*4882a593Smuzhiyun	orr	r1, r1, #EP93XX_LED_GREEN_ON
378*4882a593Smuzhiyun	str	r1, [r0]
379*4882a593Smuzhiyun	ldr	r2, =0x00010000
380*4882a593Smuzhiyunflash_green_delay_1:
381*4882a593Smuzhiyun	subs	r2, r2, #1
382*4882a593Smuzhiyun	bne	flash_green_delay_1
383*4882a593Smuzhiyun	bic	r1, r1, #EP93XX_LED_GREEN_ON
384*4882a593Smuzhiyun	str	r1, [r0]
385*4882a593Smuzhiyun	ldr	r2, =0x00010000
386*4882a593Smuzhiyunflash_green_delay_2:
387*4882a593Smuzhiyun	subs	r2, r2, #1
388*4882a593Smuzhiyun	bne	flash_green_delay_2
389*4882a593Smuzhiyun	orr	r1, r1, #EP93XX_LED_GREEN_ON
390*4882a593Smuzhiyun	str	r1, [r0]
391*4882a593Smuzhiyun	ldr	r2, =0x00010000
392*4882a593Smuzhiyunflash_green_delay_3:
393*4882a593Smuzhiyun	subs	r2, r2, #1
394*4882a593Smuzhiyun	bne	flash_green_delay_3
395*4882a593Smuzhiyun	bic	r1, r1, #EP93XX_LED_GREEN_ON
396*4882a593Smuzhiyun	str	r1, [r0]
397*4882a593Smuzhiyun	ldr	r2, =0x00050000
398*4882a593Smuzhiyunflash_green_delay_4:
399*4882a593Smuzhiyun	subs	r2, r2, #1
400*4882a593Smuzhiyun	bne	flash_green_delay_4
401*4882a593Smuzhiyun	b	flash_green
402*4882a593Smuzhiyun
403*4882a593Smuzhiyun
404*4882a593Smuzhiyunep93xx_sdram_done:
405*4882a593Smuzhiyun	ldr	r1, =EP93XX_LED_DATA
406*4882a593Smuzhiyun	ldr	r0, [r1]
407*4882a593Smuzhiyun	bic	r0, r0, #EP93XX_LED_RED_ON
408*4882a593Smuzhiyun	str	r0, [r1]
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun	/* Determine the size of the SDRAM. */
411*4882a593Smuzhiyun	mov	r0, r11
412*4882a593Smuzhiyun	bl	ep93xx_sdram_size
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun	/* Save the SDRAM characteristics. */
415*4882a593Smuzhiyun	mov	r8, r0
416*4882a593Smuzhiyun	mov	r9, r1
417*4882a593Smuzhiyun	mov	r10, r2
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun	/* Compute total memory size into r1 */
420*4882a593Smuzhiyun	mul	r1, r8, r10
421*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS0
422*4882a593Smuzhiyun	ldr	r2, [r0, #SDRAM_OFF_DEVCFG0]
423*4882a593Smuzhiyun#endif
424*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS1
425*4882a593Smuzhiyun	ldr	r2, [r0, #SDRAM_OFF_DEVCFG1]
426*4882a593Smuzhiyun#endif
427*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS2
428*4882a593Smuzhiyun	ldr	r2, [r0, #SDRAM_OFF_DEVCFG2]
429*4882a593Smuzhiyun#endif
430*4882a593Smuzhiyun#ifdef CONFIG_EDB93XX_SDCS3
431*4882a593Smuzhiyun	ldr	r2, [r0, #SDRAM_OFF_DEVCFG3]
432*4882a593Smuzhiyun#endif
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun	/* Consider small DRAM size as:
435*4882a593Smuzhiyun	 * < 32Mb for 32bit bus
436*4882a593Smuzhiyun	 * < 64Mb for 16bit bus
437*4882a593Smuzhiyun	 */
438*4882a593Smuzhiyun	tst	r2, #EP93XX_SDRAMCTRL_DEVCFG_EXTBUSWIDTH
439*4882a593Smuzhiyun	moveq	r1, r1, lsr #1
440*4882a593Smuzhiyun	cmp	r1, #0x02000000
441*4882a593Smuzhiyun
442*4882a593Smuzhiyun#if defined(CONFIG_EDB9301)
443*4882a593Smuzhiyun	/* Set refresh counter to 20ms for small DRAM size, otherwise 9.6ms */
444*4882a593Smuzhiyun	movlt	r1, #0x03f0
445*4882a593Smuzhiyun	movge	r1, #0x01e0
446*4882a593Smuzhiyun#else
447*4882a593Smuzhiyun	/* Set refresh counter to 30.7ms for small DRAM size, otherwise 15ms */
448*4882a593Smuzhiyun	movlt	r1, #0x0600
449*4882a593Smuzhiyun	movge	r1, #0x2f0
450*4882a593Smuzhiyun#endif
451*4882a593Smuzhiyun	str	r1, [r0, #SDRAM_OFF_REFRSHTIMR]
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun	/* Save the memory configuration information. */
454*4882a593Smuzhiyun	orr	r0, r11, #UBOOT_MEMORYCNF_BANK_SIZE
455*4882a593Smuzhiyun	stmia	r0, {r8-r11}
456*4882a593Smuzhiyun
457*4882a593Smuzhiyun	mov	lr, r6
458*4882a593Smuzhiyun	mov	pc, lr
459