1 /* *********************************************************************
2 * SB1250 Board Support Package
4 * Board-specific initialization File: SWARM_INIT.S
6 * This module contains the assembly-language part of the init
7 * code for this board support package. The routine
8 * "board_earlyinit" lives here.
10 * Author: Mitch Lichtenberg (mpl@broadcom.com)
12 *********************************************************************
14 * Copyright 2000,2001,2002,2003
15 * Broadcom Corporation. All rights reserved.
17 * This software is furnished under license and may be used and
18 * copied only in accordance with the following terms and
19 * conditions. Subject to these conditions, you may download,
20 * copy, install, use, modify and distribute modified or unmodified
21 * copies of this software in source and/or binary form. No title
22 * or ownership is transferred hereby.
24 * 1) Any source code used, modified or distributed must reproduce
25 * and retain this copyright notice and list of conditions
26 * as they appear in the source file.
28 * 2) No right is granted to use any trade name, trademark, or
29 * logo of Broadcom Corporation. The "Broadcom Corporation"
30 * name may not be used to endorse or promote products derived
31 * from this software without the prior written permission of
32 * Broadcom Corporation.
34 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
35 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
36 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
37 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
38 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
39 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
40 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
44 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
45 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
46 * THE POSSIBILITY OF SUCH DAMAGE.
47 ********************************************************************* */
51 #include "sb1250_genbus.h"
52 #include "sb1250_regs.h"
53 #include "sb1250_scd.h"
54 #include "bsp_config.h"
56 #include "mipsmacros.h"
57 #include "sb1250_draminit.h"
62 /* *********************************************************************
64 ********************************************************************* */
68 * Define this to send the LED messages to the serial port instead
72 /* #define _SERIAL_PORT_LEDS_ */
74 #ifdef _SERIAL_PORT_LEDS_
75 #include "sb1250_uart.h" /* need this for serial defs */
79 #if (CFG_UNIPROCESSOR_CPU0 && !CFG_MULTI_CPUS)
80 /* *********************************************************************
81 * sb1250_switch_unicpu0
83 * Switch the processor into uniprocessor CPU0 mode - this
84 * effectively disables CPU1 and changes the CPU to look
85 * like an 1125 with a big L2 cache (an 1150, if you will).
87 * This routine will do one of two things: If we are already in
88 * uniprocessor mode, it just returns. If we are not in uni
89 * mode, we muck with the SCD to enable uni mode and do a
90 * soft reset. The processor will reset and eventuall wind
91 * back here, where it will notice that the uni mode is turned
92 * on and execution will continue.
102 * register s0 must be preserved, it contains the return address
103 ********************************************************************* */
105 LEAF(sb1250_switch_unicpu0)
108 * If the CPU is a 1250 or hybrid, certain initialization has
109 * to be done so that the chip can be used like an 112x.
112 /* First, figure out what type of SOC we're on. */
113 ld t0, PHYS_TO_K1(A_SCD_SYSTEM_REVISION)
114 and t1, t0, M_SYS_PART
115 dsrl t1, t1, S_SYS_PART # part number now in t1
116 and t2, t0, M_SYS_REVISION
117 dsrl t2, t2, S_SYS_REVISION # revision now in t2
120 * Calculating SOC type:
121 * soc_type = part & 0xf;
122 * if (system_revision <= PASS2
123 * && (soc_type == 2 || soc_type == 5))
124 * soc_type = 0; # really a 1250.
127 andi t3, t1, 0xf # soc_type (t3) = part & 0xf;
128 bgt t2, K_SYS_REVISION_PASS2, soc_type_ok
129 beq t3, 2, soc_type_bogus
130 beq t3, 5, soc_type_bogus
139 * We have a 1250 or hybrid. Initialize registers as appropriate.
144 * If we're not already running as a uniprocessor, get us there.
147 dsrl t3, t3, 8 # t3 = numcpus
149 ld t4, PHYS_TO_K1(A_SCD_SYSTEM_CFG)
150 or t4, t4, M_SYS_SB_SOFTRES
151 xor t4, t4, M_SYS_SB_SOFTRES
152 sd t4, PHYS_TO_K1(A_SCD_SYSTEM_CFG) /* clear soft reset */
156 or t4, t4, M_SYS_SB_SOFTRES | M_SYS_UNICPU0
157 sd t4, PHYS_TO_K1(A_SCD_SYSTEM_CFG) /* go unicpu */
160 1: b 1b # loop till reset sinks in
164 END(sb1250_switch_unicpu0)
167 /* *********************************************************************
170 * Initialize board registers. This is the earliest
171 * time the BSP gets control. This routine cannot assume that
172 * memory is operational, and therefore all code in this routine
173 * must run from registers only. The $ra register must not
174 * be modified, as it contains the return address.
176 * This routine will be called from uncached space, before
177 * the caches are initialized. If you want to make
178 * subroutine calls from here, you must use the CALLKSEG1 macro.
180 * Among other things, this is where the GPIO registers get
181 * programmed to make on-board LEDs function, or other startup
182 * that has to be done before anything will work.
189 ********************************************************************* */
191 LEAF(board_earlyinit)
195 # If configured, switch the chip into uniprocessor mode
197 #if (CFG_UNIPROCESSOR_CPU0 && !CFG_MULTI_CPUS)
198 move s0,ra # need this to get out of here
199 bal sb1250_switch_unicpu0 # might not return
200 move ra,s0 # restore saved return address
204 # Reprogram the SCD to make sure UART0 is enabled.
205 # Some CSWARM boards have the SER0 enable bit when
206 # they're not supposed to, which switches the UART
207 # into synchronous mode. Kill off the SCD bit.
208 # XXX this should be investigated in hardware, as
209 # XXX it is a strap option on the CPU.
212 li t0,PHYS_TO_K1(A_SCD_SYSTEM_CFG)
214 dli t2,~M_SYS_SER0_ENABLE
219 # Configure the GPIOs
222 li t0,PHYS_TO_K1(A_GPIO_DIRECTION)
223 li t1,GPIO_OUTPUT_MASK
226 li t0,PHYS_TO_K1(A_GPIO_INT_TYPE)
227 li t1,GPIO_INTERRUPT_MASK
231 # Turn on the diagnostic LED and turn off the sturgeon NMI
233 li t0,PHYS_TO_K1(A_GPIO_PIN_SET)
234 li t1,M_GPIO_DEBUG_LED
237 li t0,PHYS_TO_K1(A_GPIO_PIN_CLR)
238 li t1,M_GPIO_STURGEON_NMI
246 li t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(LEDS_CS))
247 li t1,LEDS_PHYS >> S_IO_ADDRBASE
248 sd t1,R_IO_EXT_START_ADDR(t0)
250 li t1,LEDS_SIZE-1 /* Needs to be 1 smaller, se UM for details */
251 sd t1,R_IO_EXT_MULT_SIZE(t0)
254 sd t1,R_IO_EXT_TIME_CFG0(t0)
257 sd t1,R_IO_EXT_TIME_CFG1(t0)
260 sd t1,R_IO_EXT_CFG(t0)
265 # Configure the alternate boot ROM
268 li t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(ALT_BOOTROM_CS))
270 li t1,ALT_BOOTROM_PHYS >> S_IO_ADDRBASE
271 sd t1,R_IO_EXT_START_ADDR(t0)
273 li t1,ALT_BOOTROM_SIZE-1
274 sd t1,R_IO_EXT_MULT_SIZE(t0)
276 li t1,ALT_BOOTROM_TIMING0
277 sd t1,R_IO_EXT_TIME_CFG0(t0)
279 li t1,ALT_BOOTROM_TIMING1
280 sd t1,R_IO_EXT_TIME_CFG1(t0)
282 li t1,ALT_BOOTROM_CONFIG
283 sd t1,R_IO_EXT_CFG(t0)
288 # Configure the IDE interface
291 li t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(IDE_CS))
293 li t1,IDE_PHYS >> S_IO_ADDRBASE
294 sd t1,R_IO_EXT_START_ADDR(t0)
297 sd t1,R_IO_EXT_MULT_SIZE(t0)
300 sd t1,R_IO_EXT_TIME_CFG0(t0)
303 sd t1,R_IO_EXT_TIME_CFG1(t0)
306 sd t1,R_IO_EXT_CFG(t0)
310 # Configure the PCMCIA
313 li t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(PCMCIA_CS))
315 li t1,PCMCIA_PHYS >> S_IO_ADDRBASE
316 sd t1,R_IO_EXT_START_ADDR(t0)
319 sd t1,R_IO_EXT_MULT_SIZE(t0)
322 sd t1,R_IO_EXT_TIME_CFG0(t0)
325 sd t1,R_IO_EXT_TIME_CFG1(t0)
328 sd t1,R_IO_EXT_CFG(t0)
330 #ifdef _SERIAL_PORT_LEDS_
333 * If sending the LED messages to the serial port, we will need
334 * to initialize the port now.
337 # Program the mode register for 8 bits/char, no parity
339 li t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A)
340 li t1,V_DUART_BITS_PER_CHAR_8 | V_DUART_PARITY_MODE_NONE
343 # Program the mode register for 1 stop bit, ignore CTS
345 li t0,PHYS_TO_K1(A_DUART_MODE_REG_2_A)
346 li t1,M_DUART_STOP_BIT_LEN_1
349 # Program the baud rate to 115200
351 li t0,PHYS_TO_K1(A_DUART_CLK_SEL_A)
352 li t1,V_DUART_BAUD_RATE(CFG_SERIAL_BAUD_RATE)
355 # Dont use any interrupts
357 li t0,PHYS_TO_K1(A_DUART_IMR)
359 and t1,~M_DUART_IMR_ALL_A
362 # Enable sending and receiving
364 li t0,PHYS_TO_K1(A_DUART_CMD_A)
365 li t1,M_DUART_RX_EN | M_DUART_TX_EN
376 /* *********************************************************************
379 * Return the address of the DRAM information table
385 * v0 - DRAM info table, return 0 to use default table
386 ********************************************************************* */
393 #ifdef _HARDWIRED_MEMORY_TABLE
396 move v0,zero # auto configure
405 DRAM_GLOBALS(CFG_DRAM_INTERLEAVE)
408 /* 128MB on MC0 (SDRAM) */
409 DRAM_CHAN_CFG(MC_CHAN0, DRT10(8,0), JEDEC,CASCHECK, BLKSIZE32, CFG_DRAM_CSINTERLEAVE, CFG_DRAM_ECC, 0)
410 DRAM_CS_GEOM(MC_CS0, 12, 8, 2)
411 DRAM_CS_TIMING(DRT10(7,5), JEDEC_RFSH_64khz, JEDEC_CASLAT_25, 0, 45, DRT4(20,0), DRT4(15,0), DRT4(20,0), 0, 0)
418 /* *********************************************************************
421 * Transmit a single character via UART A
424 * a0 - character to transmit (low-order 8 bits)
431 ********************************************************************* */
432 #ifdef _SERIAL_PORT_LEDS_
433 LEAF(board_uarta_txchar)
435 # Wait until there is space in the transmit buffer
437 1: li t0,PHYS_TO_K1(A_DUART_STATUS_A)
438 ld t1,(t0) # Get status bits
439 and t1,M_DUART_TX_RDY # test for ready
440 beq t1,0,1b # keep going till ready
442 # Okay, now send the character.
444 li t0,PHYS_TO_K1(A_DUART_TX_HOLD_A)
451 END(board_uarta_txchar)
454 /* *********************************************************************
457 * Set LEDs for boot-time progress indication. Not used if
458 * the board does not have progress LEDs. This routine
459 * must not call any other routines, since it may be invoked
460 * either from KSEG0 or KSEG1 and it may be invoked
461 * whether or not the icache is operational.
464 * a0 - LED value (8 bits per character, 4 characters)
471 ********************************************************************* */
474 #define LED_CHAR0 (32+8*3)
475 #define LED_CHAR1 (32+8*2)
476 #define LED_CHAR2 (32+8*1)
477 #define LED_CHAR3 (32+8*0)
481 #ifdef _SERIAL_PORT_LEDS_
484 * Sending to serial port
490 bal board_uarta_txchar
494 bal board_uarta_txchar
496 bal board_uarta_txchar
498 bal board_uarta_txchar
500 bal board_uarta_txchar
503 bal board_uarta_txchar
513 li t0,PHYS_TO_K1(LEDS_PHYS)