SPDX: Convert all of our single license tags to Linux Kernel style
[oweals/u-boot.git] / arch / arm / cpu / arm920t / ep93xx / lowlevel_init.S
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  */
27 ep93xx_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
53 delay1:
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
70 delay2:
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  */
102 ep93xx_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  */
140 ep93xx_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. */
148 check_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. */
172 found_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. */
191 find_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
228 lowlevel_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. */
375 flash_green:
376         orr     r1, r1, #EP93XX_LED_GREEN_ON
377         str     r1, [r0]
378         ldr     r2, =0x00010000
379 flash_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
385 flash_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
391 flash_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
397 flash_green_delay_4:
398         subs    r2, r2, #1
399         bne     flash_green_delay_4
400         b       flash_green
401
402
403 ep93xx_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