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