]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - arch/arm/cpu/arm920t/ep93xx/lowlevel_init.S
Merge branch 'karo-tx-uboot' into kc-merge
[karo-tx-uboot.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