blob: 5239b1053c252aee4489828ed69a0ea2f69e4043 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001/* SPDX-License-Identifier: GPL-2.0+ */
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +01002/*
3 * Low-level initialization for EP93xx
4 *
5 * Copyright (C) 2009 Matthias Kaehlcke <matthias@kaehlcke.net>
Sergey Kostanbaev68286762014-06-25 23:44:29 +04006 * Copyright (C) 2013
7 * Sergey Kostanabev <sergey.kostanbaev <at> fairwaves.ru>
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +01008 *
9 * Copyright (C) 2006 Dominic Rath <Dominic.Rath@gmx.de>
Sergey Kostanbaev68286762014-06-25 23:44:29 +040010 * Copyright (C) 2006 Cirrus Logic Inc.
11 *
12 * See file CREDITS for list of people who contributed to this
13 * project.
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +010014 */
Sergey Kostanbaev68286762014-06-25 23:44:29 +040015
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
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +0100182
Sergey Kostanbaev68286762014-06-25 23:44:29 +0400183 /* 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
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +0100226
227.globl lowlevel_init
228lowlevel_init:
Sergey Kostanbaev68286762014-06-25 23:44:29 +0400229
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]
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +0100267
Sergey Kostanbaev68286762014-06-25 23:44:29 +0400268 ldr r2, [r0, #EP93XX_OFF_SMCBCR2]
269 orr r2, r2, r1
270 str r2, [r0, #EP93XX_OFF_SMCBCR2]
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +0100271
Sergey Kostanbaev68286762014-06-25 23:44:29 +0400272 ldr r2, [r0, #EP93XX_OFF_SMCBCR3]
273 orr r2, r2, r1
274 str r2, [r0, #EP93XX_OFF_SMCBCR3]
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +0100275
Sergey Kostanbaev68286762014-06-25 23:44:29 +0400276 ldr r2, [r0, #EP93XX_OFF_SMCBCR6]
277 orr r2, r2, r1
278 str r2, [r0, #EP93XX_OFF_SMCBCR6]
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +0100279
Sergey Kostanbaev68286762014-06-25 23:44:29 +0400280 ldr r2, [r0, #EP93XX_OFF_SMCBCR7]
281 orr r2, r2, r1
282 str r2, [r0, #EP93XX_OFF_SMCBCR7]
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +0100283
Sergey Kostanbaev68286762014-06-25 23:44:29 +0400284 /* 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
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +0100290
Sergey Kostanbaev68286762014-06-25 23:44:29 +0400291#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]
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +0100300
Sergey Kostanbaev68286762014-06-25 23:44:29 +0400301 nop
302 nop
303 nop
304 nop
305 nop
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +0100306
Sergey Kostanbaev68286762014-06-25 23:44:29 +0400307 /* 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}
Matthias Kaehlcke195dbd12010-02-01 21:29:39 +0100455
Sergey Kostanbaev68286762014-06-25 23:44:29 +0400456 mov lr, r6
457 mov pc, lr