1 #ifndef CYGONCE_HAL_PLATFORM_SETUP_H
2 #define CYGONCE_HAL_PLATFORM_SETUP_H
3 //=============================================================================
5 // hal_platform_setup.h
7 // Platform specific support for HAL (assembly code)
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.
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.
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
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.
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.
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.
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####
46 // Contributors: jskov, gthomas
48 // Purpose: ARM9/EXCALIBUR platform specific support routines
50 // Usage: #include <cyg/hal/hal_platform_setup.h>
51 // Only used by "vectors.S"
53 //####DESCRIPTIONEND####
55 //=============================================================================
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
65 #define n_ALTERA_CACHEHACK // doesn't have any apparent effect
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
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)
76 // We need this here - can't rely on a translation table until MMU has
78 .macro RAW_LED_MACRO x
80 ldr r0,=(EXCALIBUR_UART0_BASE+_UART_TD)
86 // This macro represents the initial startup code for the platform
87 .macro _platform_setup1
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]
98 ldr r1,=EXCALIBUR_EBI_CR
99 ldr r2,=EXCALIBUR_EBI_CR_INIT
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]
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
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]
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)
140 str r1,[r3, #_CLK_DERIVE]
142 // Poll waiting for the PLL's to lock and the bits to not be
144 ldr r2,=_CLK_STATUS_L2 /*_CLK_STATUS_L1 | _CLK_STATUS_L2*/
145 1: ldr r1, [r3, #_CLK_STATUS]
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]
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
176 ldr r1,=(EXCALIBUR_MMAP_BASE + _MMAP_EBI0)
177 ldr r2,=_MMAP_EBI0_INIT
179 ldr r1,=CYGMEM_REGION_rom
184 // Disable ROM mapping
185 ldr r1,=EXCALIBUR_BOOT_CR
186 ldr r2,=EXCALIBUR_BOOT_CR_BM
191 // Disable and clear caches
194 bic r0,r0,#0x1000 // disable ICache
195 bic r0,r0,#0x0007 // disable DCache,
196 // MMU and alignment faults
207 mcr p15,0,r0,c7,c6,0 // clear data cache
208 mcr p15,0,r0,c7,c5,0 // clear instruction cache
211 mrc p15,0,r0,c15,c1,0 // disable streaming
213 mcr p15,0,r0,c15,c1,0
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]
251 // FIXME: Disable MMAP registers?
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]
264 #ifdef _ALTERA_CACHEHACK
266 orr r0,r0,#0x1000 // enable ICache
276 #endif // _ALTERA_CACHEHACK
280 // All the clock values below assume the SDR is running @ 100 MHz
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)
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
295 // Load the address of the first seven SDRAM registers and the
297 adr r0,SDRAM_REGS_ADDR
300 adr r6,SDRAM_REGS_VALUE
309 ldr r11,=EXCALIBUR_SDRAM_BASE
310 ldr r0,=EXCALIBUR_SDRAM_WIDTH
311 ldr r1,=(_SDRAM_WIDTH_W | _SDRAM_WIDTH_LK) /* 32 bit wide */
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
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
332 mcr p15,0,r1,c7,c13,1
338 mcr p15,0,r3,c7,c13,1
342 #endif // _ALTERA_CACHEHACK
344 // setup the timer for later
345 ldr r4,=EXCALIBUR_TIMER0_LIMIT
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
355 // Enable the controller by setting the EN bit in the
356 // SDRAM_INIT register
357 mov r1,#_SDRAM_INIT_EN
359 str r1,[r11, #_SDRAM_INIT]
362 mov r3, #EXCALIBUR_TIMER_CR_S
373 // 4. Issue pre-charge all command
375 bl Issue_SDRAM_Command
377 // 5. Issue two Refresh Commands
381 bl Issue_SDRAM_Command
385 // 6. Issue a load mode command with the DLL being Reset
387 bl Issue_SDRAM_Command
393 //--------------------------------------------
394 // Issue a command from the SDRAM controller
396 // r1 is the command to be issued
397 // r2 and r3 are trashed
399 mov r2,#_SDRAM_INIT_EN
401 str r2,[r11, #_SDRAM_INIT]
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
407 ldr r2,=(EXCALIBUR_CLK_BASE+_CLK_AHB1_COUNT)
409 add r3,r3,#200 // CPU 150 MHz SDRAM 75 MHz
415 End_Issue_SDRAM_Command:
418 // SDRAM Register Addresses
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
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 */
437 #ifdef _ALTERA_CACHEHACK
439 bic r0,r0,#0x1000 // disable ICache
449 #endif // _ALTERA_CACHEHACK
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
470 // Set up a stack [for calling C code]
471 ldr r1,=__startup_stack
472 ldr r2,=EXCALIBUR_SDRAM_PHYS_BASE
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
493 #else // defined(CYG_HAL_STARTUP_ROM) || defined(CYG_HAL_STARTUP_ROMRAM) || defined(CYG_HAL_STARTUP_REDBOOT)
494 #define PLATFORM_SETUP1
497 //-----------------------------------------------------------------------------
499 #define CYGHWR_LED_MACRO \
500 ldr r0,=(EXCALIBUR_UART0_BASE+_UART_TD); \
501 mov r1,#((\x) + 0x61); \
505 //-----------------------------------------------------------------------------
506 // end of hal_platform_setup.h
507 #endif // CYGONCE_HAL_PLATFORM_SETUP_H