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