]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/hal/arm/arm9/excalibur/v2_0/include/hal_platform_setup.h
Initial revision
[karo-tx-redboot.git] / packages / hal / arm / arm9 / excalibur / v2_0 / include / hal_platform_setup.h
1 #ifndef CYGONCE_HAL_PLATFORM_SETUP_H
2 #define CYGONCE_HAL_PLATFORM_SETUP_H
3 //=============================================================================
4 //
5 //      hal_platform_setup.h
6 //
7 //      Platform specific support for HAL (assembly code)
8 //
9 //=============================================================================
10 //####ECOSGPLCOPYRIGHTBEGIN####
11 // -------------------------------------------
12 // This file is part of eCos, the Embedded Configurable Operating System.
13 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
14 //
15 // eCos is free software; you can redistribute it and/or modify it under
16 // the terms of the GNU General Public License as published by the Free
17 // Software Foundation; either version 2 or (at your option) any later version.
18 //
19 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
20 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
21 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
22 // for more details.
23 //
24 // You should have received a copy of the GNU General Public License along
25 // with eCos; if not, write to the Free Software Foundation, Inc.,
26 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
27 //
28 // As a special exception, if other files instantiate templates or use macros
29 // or inline functions from this file, or you compile this file and link it
30 // with other works to produce a work based on this file, this file does not
31 // by itself cause the resulting work to be covered by the GNU General Public
32 // License. However the source code for this file must still be made available
33 // in accordance with section (3) of the GNU General Public License.
34 //
35 // This exception does not invalidate any other reasons why a work based on
36 // this file might be covered by the GNU General Public License.
37 //
38 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
39 // at http://sources.redhat.com/ecos/ecos-license/
40 // -------------------------------------------
41 //####ECOSGPLCOPYRIGHTEND####
42 //=============================================================================
43 //#####DESCRIPTIONBEGIN####
44 //
45 // Author(s):    jskov
46 // Contributors: jskov, gthomas
47 // Date:         2001-08-06
48 // Purpose:      ARM9/EXCALIBUR platform specific support routines
49 // Description: 
50 // Usage:        #include <cyg/hal/hal_platform_setup.h>
51 //     Only used by "vectors.S"         
52 //
53 //####DESCRIPTIONEND####
54 //
55 //=============================================================================
56
57 #include <pkgconf/system.h>             // System-wide configuration info
58 #include CYGBLD_HAL_VARIANT_H           // Variant specific configuration
59 #include CYGBLD_HAL_PLATFORM_H          // Platform specific configuration
60 #include CYGHWR_MEMORY_LAYOUT_H
61 #include <cyg/hal/hal_mmu.h>            // MMU definitions
62 #include <cyg/hal/excalibur.h>          // Platform specific hardware definitions
63
64 #define nDEBUG
65 #define n_ALTERA_CACHEHACK  // doesn't have any apparent effect
66
67 #if defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM) || defined(CYG_HAL_STARTUP_REDBOOT)
68 #define PLATFORM_SETUP1 _platform_setup1
69 #define CYGHWR_HAL_ARM_HAS_MMU
70 #define CYGSEM_HAL_ROM_RESET_USES_JUMP
71
72 #define CYG_DEVICE_SERIAL_BAUD_DIV (CYGNUM_HAL_ARM_EXCALIBUR_PERIPHERAL_CLOCK/CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL_BAUD/16)
73 #define CYG_DEVICE_SERIAL_BAUD_LSB (CYG_DEVICE_SERIAL_BAUD_DIV&0xff)
74 #define CYG_DEVICE_SERIAL_BAUD_MSB ((CYG_DEVICE_SERIAL_BAUD_DIV>>8)&0xff)
75
76 // We need this here - can't rely on a translation table until MMU has
77 // been initialized
78         .macro RAW_LED_MACRO x
79 #ifdef DEBUG
80         ldr     r0,=(EXCALIBUR_UART0_BASE+_UART_TD)
81         mov     r1,#(\x + 0x41)
82         str     r1,[r0]
83 #endif
84         .endm
85
86 // This macro represents the initial startup code for the platform        
87         .macro  _platform_setup1
88         // IO controller init
89         ldr     r1,=EXCALIBUR_IOCR_BASE
90         ldr     r2,=EXCALIBUR_IOCR_SDRAM_INIT
91         str     r2,[r1,#_IOCR_SDRAM]
92         ldr     r2,=EXCALIBUR_IOCR_EBI_INIT
93         str     r2,[r1,#_IOCR_EBI]
94         ldr     r2,=EXCALIBUR_IOCR_UART_INIT
95         str     r2,[r1,#_IOCR_UART]
96
97         // Expansion bus init
98         ldr     r1,=EXCALIBUR_EBI_CR
99         ldr     r2,=EXCALIBUR_EBI_CR_INIT
100         str     r2,[r1]
101
102 #ifdef DEBUG
103         // Init UART for debug tracing
104         ldr     r4,=EXCALIBUR_UART0_BASE
105         ldr     r2,=(_UART_MC_8BIT | _UART_MC_1STOP | _UART_MC_PARITY_NONE)
106         str     r2,[r4,#_UART_MC]
107         ldr     r2,=CYG_DEVICE_SERIAL_BAUD_LSB
108         str     r2,[r4,#_UART_DIV_LO]
109         ldr     r2,=CYG_DEVICE_SERIAL_BAUD_MSB
110         str     r2,[r4,#_UART_DIV_HI]
111         ldr     r2,=(_UART_FCR_TC | _UART_FCR_RC | _UART_FCR_TX_THR_15 | _UART_FCR_RX_THR_1)
112         str     r2,[r4,#_UART_FCR]
113 #endif
114
115         // Setup the PLLs see the label PLL_ADDR below for the input
116         // clock frequency and the desired output frequencies of PLL1
117         // and PLL2 Load the value into K,M,N for PLL 1 and 2
118         adr     r0,2f
119         ldmia   r0,{r0-r11}
120         str     r6,[r0]
121         str     r7,[r1]
122         str     r8,[r2]
123         str     r9,[r3]
124         str     r10,[r4]
125         str     r11,[r5]
126                 
127         // Turn on the PLLs
128         ldr     r3,=EXCALIBUR_CLK_BASE
129         ldr     r1,=(0x1035 | _CLK_PLL1_CTRL_P)
130         str     r1,[r3, #_CLK_PLL1_CTRL]
131         str     r1,[r3, #_CLK_PLL2_CTRL]
132
133         // Ensure the PLLs are not in bypass
134         ldr     r1,=(0x10 | _CLK_DERIVE_BP1 | _CLK_DERIVE_BP2)
135         str     r1,[r3, #_CLK_DERIVE]
136         orr     r1,r1,#0x300 /* Use PLL2 for AHB and for the SDRAM */
137         str     r1,[r3, #_CLK_DERIVE]
138         ldr     r2,=(_CLK_DERIVE_BP1 | _CLK_DERIVE_BP2)
139         bic     r1,r1,r2
140         str     r1,[r3, #_CLK_DERIVE]
141
142         // Poll waiting for the PLL's to lock and the bits to not be
143         // in bypass mode
144         ldr     r2,=_CLK_STATUS_L2 /*_CLK_STATUS_L1 | _CLK_STATUS_L2*/
145 1:      ldr     r1, [r3, #_CLK_STATUS]
146         and     r1, r1, r2
147         cmp     r1, r2
148         bne     1b
149
150         // Clear the interrupt caused by the change in lock status
151         ldr     r2, =(_CLK_STATUS_C1 | _CLK_STATUS_C2)
152         str     r2, [r3, #_CLK_STATUS]
153         
154         b       3f
155
156         // PLL Registers Addresses
157 2:      .long EXCALIBUR_CLK_BASE+_CLK_PLL1_KCNT
158         .long EXCALIBUR_CLK_BASE+_CLK_PLL1_MCNT
159         .long EXCALIBUR_CLK_BASE+_CLK_PLL1_NCNT
160         .long EXCALIBUR_CLK_BASE+_CLK_PLL2_KCNT
161         .long EXCALIBUR_CLK_BASE+_CLK_PLL2_MCNT
162         .long EXCALIBUR_CLK_BASE+_CLK_PLL2_NCNT
163         // PLL Registers Values ensure this follows on from the
164         // addresses the code depends on it
165         .long 0x40000 // CLK_PLL1_KCNT_VAL  = 1
166         .long 0x20101 // CLK_PLL1_MCNT_VAL  = 2
167         .long 0x40000 // CLK_PLL1_NCNT_VAL  = 1
168         .long 0x40000 // CLK_PLL2_KCNT_VAL  = 1
169         .long 0x20303 // CLK_PLL2_MCNT_VAL  = 6
170         .long 0x40000 // CLK_PLL2_NCNT_VAL  = 1
171 3:
172
173         RAW_LED_MACRO 0
174
175         // Jump to ROM
176         ldr     r1,=(EXCALIBUR_MMAP_BASE + _MMAP_EBI0)
177         ldr     r2,=_MMAP_EBI0_INIT
178         str     r2,[r1]
179         ldr     r1,=CYGMEM_REGION_rom
180         add     pc,pc,r1
181         nop
182         nop
183
184         // Disable ROM mapping
185         ldr     r1,=EXCALIBUR_BOOT_CR
186         ldr     r2,=EXCALIBUR_BOOT_CR_BM
187         str     r2,[r1]
188
189         RAW_LED_MACRO 1
190
191         // Disable and clear caches
192         
193         mrc  p15,0,r0,c1,c0,0
194         bic  r0,r0,#0x1000              // disable ICache
195         bic  r0,r0,#0x0007              // disable DCache,
196                                         // MMU and alignment faults
197         mcr  p15,0,r0,c1,c0,0
198         nop
199         nop
200         nop
201         nop
202         nop
203         nop
204         nop
205         nop
206         mov  r0,#0
207         mcr  p15,0,r0,c7,c6,0           // clear data cache
208         mcr  p15,0,r0,c7,c5,0           // clear instruction cache
209         
210 #if 0
211         mrc  p15,0,r0,c15,c1,0          // disable streaming
212         orr  r0,r0,#0x80
213         mcr  p15,0,r0,c15,c1,0
214 #endif
215
216         RAW_LED_MACRO 2
217
218         // Set memory mapping
219         ldr     r1,=EXCALIBUR_MMAP_BASE
220         ldr     r2,=_MMAP_REGISTERS_INIT
221         str     r2,[r1,#_MMAP_REGISTERS]
222         ldr     r2,=_MMAP_SRAM0_INIT
223         str     r2,[r1,#_MMAP_SRAM0]
224         ldr     r2,=_MMAP_SRAM1_INIT
225         str     r2,[r1,#_MMAP_SRAM1]
226         ldr     r2,=_MMAP_DPSRAM0_INIT
227         str     r2,[r1,#_MMAP_DPSRAM0]
228         ldr     r2,=_MMAP_DPSRAM1_INIT
229         str     r2,[r1,#_MMAP_DPSRAM1]
230         ldr     r2,=_MMAP_SDRAM0_INIT
231         str     r2,[r1,#_MMAP_SDRAM0]
232         ldr     r2,=_MMAP_SDRAM1_INIT
233         str     r2,[r1,#_MMAP_SDRAM1]
234         ldr     r2,=_MMAP_PLD0_INIT
235         str     r2,[r1,#_MMAP_PLD0]
236         ldr     r2,=_MMAP_PLD1_INIT
237         str     r2,[r1,#_MMAP_PLD1]
238         ldr     r2,=_MMAP_PLD2_INIT
239         str     r2,[r1,#_MMAP_PLD2]
240         ldr     r2,=_MMAP_PLD3_INIT
241         str     r2,[r1,#_MMAP_PLD3]
242         ldr     r2,=_MMAP_EBI1_INIT
243         str     r2,[r1,#_MMAP_EBI1]
244         ldr     r2,=_MMAP_EBI2_INIT
245         str     r2,[r1,#_MMAP_EBI2]
246         ldr     r2,=_MMAP_EBI3_INIT
247         str     r2,[r1,#_MMAP_EBI3]
248
249         RAW_LED_MACRO 3
250
251         // FIXME: Disable MMAP registers?
252
253         RAW_LED_MACRO 4
254
255         // DPSRAM init
256         ldr     r2,=EXCALIBUR_DPSRAM_BASE
257         ldr     r1,=_DPSRAM0_LCR_INIT
258         str     r1,[r2,#_DPSRAM0_LCR]
259         ldr     r1,=_DPSRAM1_LCR_INIT
260         str     r1,[r2,#_DPSRAM1_LCR]
261
262         RAW_LED_MACRO 5
263
264 #ifdef _ALTERA_CACHEHACK
265         mrc     p15,0,r0,c1,c0,0
266         orr     r0,r0,#0x1000              // enable ICache
267         mcr     p15,0,r0,c1,c0,0
268         nop
269         nop
270         nop
271         nop
272         nop
273         nop
274         nop
275         nop
276 #endif //  _ALTERA_CACHEHACK
277
278         //  Setup the SDR
279
280         // All the clock values below assume the SDR is running @ 100 MHz
281
282         // 1. Wait for the PLL's to lock this was already done in
283         // Setup_plls Then wait another 100uS, which given we're
284         // running @ 150MHz is 15,000 clock cycles
285         mov     r3,#0x3b00 // (15104)
286 1:      subs    r3,r3,#1
287         bne     1b
288
289
290         // 2. Set up all the SDRAM Controllers configuration settings
291         // These are done using LDMIA's as it's more efficient, they're
292         // done in the order they appear in the datasheet with the
293         // exception of SDRAM_INIT which has to be written last
294
295         // Load the address of the first seven SDRAM registers and the
296         // contents
297         adr     r0,SDRAM_REGS_ADDR
298         ldmia   r0,{r0-r5}
299
300         adr     r6,SDRAM_REGS_VALUE
301         ldmia   r6,{r6-r11}
302         str     r6,[r0]
303         str     r7,[r1]
304         str     r8,[r2]
305         str     r9,[r3]
306         str     r10,[r4]
307         str     r11,[r5]
308
309         ldr     r11,=EXCALIBUR_SDRAM_BASE
310         ldr     r0,=EXCALIBUR_SDRAM_WIDTH
311         ldr     r1,=(_SDRAM_WIDTH_W | _SDRAM_WIDTH_LK)  /* 32 bit wide */
312         str     r1,[r0]
313
314 #ifdef _ALTERA_CACHEHACK
315         // OK we have a minor "feature/bug" in the chip which requires
316         // us to be a little clever now.  The code between the labels
317         // Cache_Start and Cache_stop starts the SDRAM controller and
318         // issues the pre_charge command
319  
320         // It must execute within one refresh period, so we must load
321         // this code and the code it calls (Issue_SDRAM_Command) into
322         // cache, as typical flashes have a cycle time of ~100nS If we
323         // are doing byte loads that's ~400ns per instruction.  Depending
324         // upon the size of the DDR the refresh period can be as low as
325         // 7us (smallest we found).
326         adr     r1,SDR_Cache_Start
327         adr     r2,SDR_Cache_Stop       
328         adr     r3,Issue_SDRAM_Command
329         adr     r4,End_Issue_SDRAM_Command
330
331 SDR_Load_Code:  
332         mcr     p15,0,r1,c7,c13,1
333         add     r1,r1,#32
334         cmp     r1,r2
335         ble     SDR_Load_Code
336         
337 SDR_Load_Code2:         
338         mcr     p15,0,r3,c7,c13,1
339         add     r3,r3,#32
340         cmp     r3,r4
341         ble     SDR_Load_Code2
342 #endif // _ALTERA_CACHEHACK
343
344         // setup the timer for later
345         ldr     r4,=EXCALIBUR_TIMER0_LIMIT
346         mvn     r5, #1
347         str     r5, [r4]
348
349         ldr     r4,=_SDRAM_INIT_PR
350         ldr     r5,=_SDRAM_INIT_RF
351         ldr     r6,=_SDRAM_INIT_LM
352         ldr     r9,=EXCALIBUR_TIMER0_READ
353         ldr     r10,=EXCALIBUR_TIMER0_CR
354
355         // Enable the controller by setting the EN bit in the
356         // SDRAM_INIT register
357         mov     r1,#_SDRAM_INIT_EN
358 SDR_Cache_Start:
359         str     r1,[r11, #_SDRAM_INIT]
360
361         // Short delay
362         mov     r3, #EXCALIBUR_TIMER_CR_S
363         str     r3, [r10]
364         ldr     r3, [r9]
365         add     r3,r3,#200 
366 short_delay:
367         ldr     r8, [r9]
368         cmp     r3, r8
369         bgt     short_delay
370         mov     r3, #0
371         str     r3, [r10]
372
373         // 4. Issue pre-charge all command
374         mov     r1,r4
375         bl      Issue_SDRAM_Command
376
377         // 5. Issue two Refresh Commands
378         mov     r1, r5
379         mov     r4,#2
380 SDR_RF_Command:
381         bl      Issue_SDRAM_Command
382         subs    r4,r4,#1
383         bne     SDR_RF_Command
384
385         // 6. Issue a load mode command with the DLL being Reset
386         mov     r1, r6
387         bl      Issue_SDRAM_Command
388
389 SDR_Cache_Stop:
390         b        10f
391
392
393         //--------------------------------------------
394         // Issue a command from the SDRAM controller
395         // Assumes:
396         // r1 is the command to be issued
397         // r2 and r3 are trashed
398 Issue_SDRAM_Command:
399         mov     r2,#_SDRAM_INIT_EN
400         orr     r2,r2,r1
401         str     r2,[r11, #_SDRAM_INIT]
402  
403         // OK chip bug, the busy bit does not work properly, so we need
404         // to insert a delay of 50 SDRAM clock cycles here NB Obviously
405         // this must change when either the SDRAM clock or the processor
406         // clock change
407         ldr     r2,=(EXCALIBUR_CLK_BASE+_CLK_AHB1_COUNT)
408         ldr     r3, [r2]
409         add     r3,r3,#200 // CPU 150 MHz SDRAM 75 MHz
410 clock_cycles:
411         ldr     r8, [r2]
412         cmp     r3, r8
413         bgt     clock_cycles
414         mov     pc, lr
415 End_Issue_SDRAM_Command:
416         
417
418         // SDRAM Register Addresses
419 SDRAM_REGS_ADDR: 
420         .long EXCALIBUR_SDRAM_BASE+_SDRAM_TIMING1
421         .long EXCALIBUR_SDRAM_BASE+_SDRAM_TIMING2
422         .long EXCALIBUR_SDRAM_BASE+_SDRAM_CONFIG
423         .long EXCALIBUR_SDRAM_BASE+_SDRAM_REFRESH
424         .long EXCALIBUR_SDRAM_BASE+_SDRAM_ADDR
425         .long EXCALIBUR_SDRAM_BASE+_SDRAM_MODE0
426         .long EXCALIBUR_SDRAM_BASE+_SDRAM_MODE1
427
428 SDRAM_REGS_VALUE:
429         .long 0x00004892 /* SDRAM_TIMING1_VAL */
430         .long 0x000007b0 /* SDRAM_TIMING2_VAL */
431         .long 0x00000000 /* DDR */
432         .long 0x00000492 /* SDRAM_REFRESH_VAL */
433         .long 0x0000Ca80 /* SDRAM_ADDR_VAL */
434         .long 0x00000023 /* SDRAM_MODE0_VAL */
435         .long 0x00000000 /* SDRAM_MODE1_VAL */
436 10:
437 #ifdef _ALTERA_CACHEHACK
438         mrc     p15,0,r0,c1,c0,0
439         bic     r0,r0,#0x1000              // disable ICache
440         mcr     p15,0,r0,c1,c0,0
441         nop
442         nop
443         nop
444         nop
445         nop
446         nop
447         nop
448         nop
449 #endif // _ALTERA_CACHEHACK
450
451         RAW_LED_MACRO 6
452
453 #if defined(CYG_HAL_STARTUP_ROMRAM) || defined(CYG_HAL_STARTUP_REDBOOT)
454         ldr     r0,=__rom_vectors_lma   // Relocate FLASH/ROM to SDRAM
455         ldr     r1,=__rom_vectors_vma   // ram base & length
456         ldr     r2,=__ram_data_end
457 20:     ldr     r3,[r0],#4
458         str     r3,[r1],#4
459         cmp     r1,r2
460         bne     20b
461         ldr     r0,=30f
462         nop
463         mov     pc,r0
464         nop
465 30:     nop
466 #endif
467
468         RAW_LED_MACRO 7
469
470         // Set up a stack [for calling C code]
471         ldr     r1,=__startup_stack
472         ldr     r2,=EXCALIBUR_SDRAM_PHYS_BASE
473         orr     sp,r1,r2
474
475         // Create MMU tables
476         bl      hal_mmu_init
477
478         RAW_LED_MACRO 8
479
480         // Enable MMU
481         ldr     r2,=10f
482         ldr     r1,=MMU_Control_Init|MMU_Control_M
483         mcr     MMU_CP,0,r1,MMU_Control,c0
484         mov     pc,r2    // Change address spaces
485         nop
486         nop
487         nop
488 10:
489
490         RAW_LED_MACRO 9
491         .endm
492         
493 #else // defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM) || defined(CYG_HAL_STARTUP_REDBOOT)
494 #define PLATFORM_SETUP1
495 #endif
496
497 //-----------------------------------------------------------------------------
498 #ifdef DEBUG
499 #define CYGHWR_LED_MACRO                                \
500         ldr     r0,=(EXCALIBUR_UART0_BASE+_UART_TD);    \
501         mov     r1,#((\x) + 0x61);                      \
502         str     r1,[r0];
503 #endif
504
505 //-----------------------------------------------------------------------------
506 // end of hal_platform_setup.h
507 #endif // CYGONCE_HAL_PLATFORM_SETUP_H