]> git.ipfire.org Git - people/ms/u-boot.git/blob - arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S
arm: ep9315: Return back Cirrus Logic EDB9315A board support
[people/ms/u-boot.git] / arch / arm / cpu / arm920t / ep93xx / lowlevel_init.S
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 */
28 ep93xx_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
54 delay1:
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
71 delay2:
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 */
103 ep93xx_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 */
141 ep93xx_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. */
149 check_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. */
173 found_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. */
192 find_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
229 lowlevel_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. */
376 flash_green:
377 orr r1, r1, #EP93XX_LED_GREEN_ON
378 str r1, [r0]
379 ldr r2, =0x00010000
380 flash_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
386 flash_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
392 flash_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
398 flash_green_delay_4:
399 subs r2, r2, #1
400 bne flash_green_delay_4
401 b flash_green
402
403
404 ep93xx_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