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