1/* ********************************************************************* 2 * SB1250 Board Support Package 3 * 4 * Board-specific initialization File: LAUSANNE_INIT.S 5 * 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. 9 * 10 * Author: Mitch Lichtenberg 11 * Lausanne edits: Jeffrey Cheng 12 * 13 ********************************************************************* 14 * 15 * Copyright 2000,2001,2002,2003 16 * Broadcom Corporation. All rights reserved. 17 * 18 * This software is furnished under license and may be used and 19 * copied only in accordance with the following terms and 20 * conditions. Subject to these conditions, you may download, 21 * copy, install, use, modify and distribute modified or unmodified 22 * copies of this software in source and/or binary form. No title 23 * or ownership is transferred hereby. 24 * 25 * 1) Any source code used, modified or distributed must reproduce 26 * and retain this copyright notice and list of conditions 27 * as they appear in the source file. 28 * 29 * 2) No right is granted to use any trade name, trademark, or 30 * logo of Broadcom Corporation. The "Broadcom Corporation" 31 * name may not be used to endorse or promote products derived 32 * from this software without the prior written permission of 33 * Broadcom Corporation. 34 * 35 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 36 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 37 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 38 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 39 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 40 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 41 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 42 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 43 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 44 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 45 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 46 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 47 * THE POSSIBILITY OF SUCH DAMAGE. 48 ********************************************************************* */ 49 50 51#include "sbmips.h" 52#include "sb1250_genbus.h" 53#include "sb1250_regs.h" 54#include "sb1250_scd.h" 55#include "bsp_config.h" 56#include "cpu_config.h" 57#include "lausanne.h" 58#include "mipsmacros.h" 59#include "sb1250_draminit.h" 60 61 .text 62 63 64/* ********************************************************************* 65 * Macros 66 ********************************************************************* */ 67 68 69/* 70 * Define this to send the LED messages to the serial port instead 71 * of to the LEDs. 72 */ 73 74/* #define _SERIAL_PORT_LEDS_ */ 75 76#ifdef _SERIAL_PORT_LEDS_ 77#include "sb1250_uart.h" /* need this for serial defs */ 78#endif 79 80 81/* ********************************************************************* 82 * BOARD_EARLYINIT() 83 * 84 * Initialize board registers. This is the earliest 85 * time the BSP gets control. This routine cannot assume that 86 * memory is operational, and therefore all code in this routine 87 * must run from registers only. The $ra register must not 88 * be modified, as it contains the return address. 89 * 90 * This routine will be called from uncached space, before 91 * the caches are initialized. If you want to make 92 * subroutine calls from here, you must use the CALLKSEG1 macro. 93 * 94 * Among other things, this is where the GPIO registers get 95 * programmed to make on-board LEDs function, or other startup 96 * that has to be done before anything will work. 97 * 98 * Input parameters: 99 * nothing 100 * 101 * Return value: 102 * nothing 103 ********************************************************************* */ 104 105LEAF(board_earlyinit) 106 107 # 108 # Reprogram the SCD to make sure UART0 is enabled. 109 # Some CSWARM boards have the SER0 enable bit when 110 # they're not supposed to, which switches the UART 111 # into synchronous mode. Kill off the SCD bit. 112 # XXX this should be investigated in hardware, as 113 # XXX it is a strap option on the CPU. 114 # 115 116 li t0,PHYS_TO_K1(A_SCD_SYSTEM_CFG) 117 ld t1,0(t0) 118 dli t2,~M_SYS_SER0_ENABLE 119 and t1,t1,t2 120 sd t1,0(t0) 121 122 # 123 # First turn off flash burst mode 124 # 125 li t0,PHYS_TO_K1(A_GPIO_PIN_CLR) 126 li t1,_SB_MAKEMASK1(GPIO_FLASH_BYTE_EN) 127 sd t1,0(t0) 128 129 # 130 # Configure the GPIOs 131 # 132 133 li t0,PHYS_TO_K1(A_GPIO_DIRECTION) 134 li t1,GPIO_OUTPUT_MASK 135 sd t1,0(t0) 136 137 li t0,PHYS_TO_K1(A_GPIO_INT_TYPE) 138 li t1,GPIO_INTERRUPT_MASK 139 sd t1,0(t0) 140 141 # 142 # Configure the LEDs 143 # 144 145 li t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(LEDS_CS)) 146 li t1,LEDS_PHYS >> S_IO_ADDRBASE 147 sd t1,R_IO_EXT_START_ADDR(t0) 148 149 li t1,LEDS_SIZE-1 /* Needs to be 1 smaller, se UM for details */ 150 sd t1,R_IO_EXT_MULT_SIZE(t0) 151 152 li t1,LEDS_TIMING0 153 sd t1,R_IO_EXT_TIME_CFG0(t0) 154 155 li t1,LEDS_TIMING1 156 sd t1,R_IO_EXT_TIME_CFG1(t0) 157 158 li t1,LEDS_CONFIG 159 sd t1,R_IO_EXT_CFG(t0) 160 161 162 163 # 164 # Configure the alternate boot ROM 165 # 166 167 li t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(ALT_BOOTROM_CS)) 168 169 li t1,ALT_BOOTROM_PHYS >> S_IO_ADDRBASE 170 sd t1,R_IO_EXT_START_ADDR(t0) 171 172 li t1,ALT_BOOTROM_SIZE-1 173 sd t1,R_IO_EXT_MULT_SIZE(t0) 174 175 li t1,ALT_BOOTROM_TIMING0 176 sd t1,R_IO_EXT_TIME_CFG0(t0) 177 178 li t1,ALT_BOOTROM_TIMING1 179 sd t1,R_IO_EXT_TIME_CFG1(t0) 180 181 li t1,ALT_BOOTROM_CONFIG 182 sd t1,R_IO_EXT_CFG(t0) 183 184 185 186 # 187 # Configure the CPLD interface 188 # 189 190 li t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(CPLD_CS)) 191 192 li t1,CPLD_PHYS >> S_IO_ADDRBASE 193 sd t1,R_IO_EXT_START_ADDR(t0) 194 195 li t1,CPLD_SIZE-1 196 sd t1,R_IO_EXT_MULT_SIZE(t0) 197 198 li t1,CPLD_TIMING0 199 sd t1,R_IO_EXT_TIME_CFG0(t0) 200 201 li t1,CPLD_TIMING1 202 sd t1,R_IO_EXT_TIME_CFG1(t0) 203 204 li t1,CPLD_CONFIG 205 sd t1,R_IO_EXT_CFG(t0) 206 207 208 209#ifdef _SERIAL_PORT_LEDS_ 210 211 /* 212 * If sending the LED messages to the serial port, we will need 213 * to initialize the port now. 214 */ 215 216 # Program the mode register for 8 bits/char, no parity 217 218 li t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A) 219 li t1,V_DUART_BITS_PER_CHAR_8 | V_DUART_PARITY_MODE_NONE 220 sd t1,(t0) 221 222 # Program the mode register for 1 stop bit, ignore CTS 223 224 li t0,PHYS_TO_K1(A_DUART_MODE_REG_2_A) 225 li t1,M_DUART_STOP_BIT_LEN_1 226 sd t1,(t0) 227 228 # Program the baud rate to 115200 229 230 li t0,PHYS_TO_K1(A_DUART_CLK_SEL_A) 231 li t1,V_DUART_BAUD_RATE(CFG_SERIAL_BAUD_RATE) 232 sd t1,(t0) 233 234 # Dont use any interrupts 235 236 li t0,PHYS_TO_K1(A_DUART_IMR) 237 ld t1,(t0) 238 and t1,~M_DUART_IMR_ALL_A 239 sd t1,(t0) 240 241 # Enable sending and receiving 242 243 li t0,PHYS_TO_K1(A_DUART_CMD_A) 244 li t1,M_DUART_RX_EN | M_DUART_TX_EN 245 sd t1,(t0) 246 247#endif 248 249 250 j ra 251 252END(board_earlyinit) 253 254 255/* ********************************************************************* 256 * BOARD_DRAMINFO 257 * 258 * Return the address of the DRAM information table 259 * 260 * Input parameters: 261 * nothing 262 * 263 * Return value: 264 * v0 - DRAM info table, return 0 to use default table 265 ********************************************************************* */ 266 267 268LEAF(board_draminfo) 269 270 la v0,myinfo 271 j ra 272 273myinfo: 274 275 276 /* 277 * Global data: Interleave mode from bsp_config.h 278 */ 279 280 DRAM_GLOBALS(CFG_DRAM_INTERLEAVE) /* do port interleaving if possible */ 281 282 /* 283 * Memory channel 0: Configure via SMBUS, Automatic Timing, Big Memory mode, Force Register 284 * 285 * There's an external register on the board, so dimms appear to be "registered" even though 286 * the SPD says they're not. 287 * 288 * SPD SMBus Channel 0 Device 0x50 -> MC0 slot 0 \___ goes to real MC0 CS0 via external decode 289 * SPD SMBus Channel 0 Device 0x51 -> MC0 slot 1 / 290 * SPD SMBus Channel 0 Device 0x52 -> MC0 slot 2 \___ goes to real MC0 CS1 via external decode 291 * SPD SMBus Channel 0 Device 0x53 -> MC0 slot 3 / 292 * 293 * DRAM must always be added in pairs! 294 */ 295 296 DRAM_CHAN_CFG(MC_CHAN0, CFG_DRAM_MIN_tMEMCLK, JEDEC, CASCHECK, CFG_DRAM_BLOCK_SIZE, NOCSINTLV, CFG_DRAM_ECC, (MCFLG_BIGMEM | MCFLG_FORCEREG)) 297 DRAM_CHAN_CLKCFG(0x0F,0x08,0x08,0x00,0x0F,0x00) 298 299 DRAM_CS_SPD(MC_CS0, 0, 0, 0x50) 300 DRAM_CS_SPD(MC_CS1, 0, 0, 0x52) 301 302 /* 303 * Memory channel 1: Configure via SMBUS, Automatic Timing, Big Memory mode, Force Register 304 * 305 * There's an external register on the board, so dimms appear to be "registered" even though 306 * the SPD says they're not. 307 * 308 * SPD SMBus Channel 0 Device 0x54 -> MC1 slot 0 \___ goes to real MC1 CS0 via external decode 309 * SPD SMBus Channel 0 Device 0x55 -> MC1 slot 1 / 310 * SPD SMBus Channel 0 Device 0x56 -> MC1 slot 2 \___ goes to real MC1 CS1 via external decode 311 * SPD SMBus Channel 0 Device 0x57 -> MC1 slot 3 / 312 * 313 * DRAM must always be added in pairs! 314 */ 315 316 DRAM_CHAN_CFG(MC_CHAN1, CFG_DRAM_MIN_tMEMCLK, JEDEC, CASCHECK, CFG_DRAM_BLOCK_SIZE, NOCSINTLV, CFG_DRAM_ECC, (MCFLG_BIGMEM | MCFLG_FORCEREG)) 317 DRAM_CHAN_CLKCFG(0x0F,0x08,0x08,0x00,0x0F,0x00) 318 319 DRAM_CS_SPD(MC_CS0, 0, 0, 0x54) 320 DRAM_CS_SPD(MC_CS1, 0, 0, 0x56) 321 322 /* 323 * End of Table 324 */ 325 326 DRAM_EOT 327 328 329 330END(board_draminfo) 331 332 333/* ********************************************************************* 334 * BOARD_UARTA_TXCHAR 335 * 336 * Transmit a single character via UART A 337 * 338 * Input parameters: 339 * a0 - character to transmit (low-order 8 bits) 340 * 341 * Return value: 342 * nothing 343 * 344 * Registers used: 345 * t0,t1 346 ********************************************************************* */ 347#ifdef _SERIAL_PORT_LEDS_ 348LEAF(board_uarta_txchar) 349 350 # Wait until there is space in the transmit buffer 351 3521: li t0,PHYS_TO_K1(A_DUART_STATUS_A) 353 ld t1,(t0) # Get status bits 354 and t1,M_DUART_TX_RDY # test for ready 355 beq t1,0,1b # keep going till ready 356 357 # Okay, now send the character. 358 359 li t0,PHYS_TO_K1(A_DUART_TX_HOLD_A) 360 sd a0,(t0) 361 362 # done! 363 364 j ra 365 366END(board_uarta_txchar) 367#endif 368 369/* ********************************************************************* 370 * BOARD_SETLEDS(x) 371 * 372 * Set LEDs for boot-time progress indication. Not used if 373 * the board does not have progress LEDs. This routine 374 * must not call any other routines, since it may be invoked 375 * either from KSEG0 or KSEG1 and it may be invoked 376 * whether or not the icache is operational. 377 * 378 * Input parameters: 379 * a0 - LED value (8 bits per character, 4 characters) 380 * 381 * Return value: 382 * nothing 383 * 384 * Registers used: 385 * t0,t1,t2,t3 386 ********************************************************************* */ 387 388 389#define LED_CHAR0 (32+8*3) 390#define LED_CHAR1 (32+8*2) 391#define LED_CHAR2 (32+8*1) 392#define LED_CHAR3 (32+8*0) 393 394LEAF(board_setleds) 395 396#ifdef _SERIAL_PORT_LEDS_ 397 398 /* 399 * Sending to serial port 400 */ 401 move t3,ra 402 move t2,a0 403 404 li a0,'[' 405 bal board_uarta_txchar 406 407 move a0,t2 408 rol a0,8 409 bal board_uarta_txchar 410 rol a0,8 411 bal board_uarta_txchar 412 rol a0,8 413 bal board_uarta_txchar 414 rol a0,8 415 bal board_uarta_txchar 416 417 li a0,']' 418 bal board_uarta_txchar 419 420 move ra,t3 421 j ra 422 423#else 424 425 /* 426 * Sending to LEDs 427 */ 428 li t0,PHYS_TO_K1(LEDS_PHYS) 429 430 rol a0,a0,8 431 and t1,a0,0xFF 432 sb t1,LED_CHAR0(t0) 433 434 rol a0,a0,8 435 and t1,a0,0xFF 436 sb t1,LED_CHAR1(t0) 437 438 rol a0,a0,8 439 and t1,a0,0xFF 440 sb t1,LED_CHAR2(t0) 441 442 rol a0,a0,8 443 and t1,a0,0xFF 444 sb t1,LED_CHAR3(t0) 445 446 j ra 447#endif 448 449END(board_setleds) 450 451