1/* ********************************************************************* 2 * SB1250 Board Support Package 3 * 4 * Board-specific initialization File: BCM91125F_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 * 12 ********************************************************************* 13 * 14 * Copyright 2000,2001,2002,2003 15 * Broadcom Corporation. All rights reserved. 16 * 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. 23 * 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. 27 * 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. 33 * 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 ********************************************************************* */ 48 49 50#include "sbmips.h" 51#include "sb1250_genbus.h" 52#include "sb1250_regs.h" 53#include "sb1250_scd.h" 54#include "bsp_config.h" 55#include "cpu_config.h" 56#include "mipsmacros.h" 57#include "bcm91125f.h" 58#include "sb1250_draminit.h" 59#include "sb1250_smbus.h" 60 61 .text 62 63/* ********************************************************************* 64 * Macros 65 ********************************************************************* */ 66 67/* 68 * Define this to send the LED messages to the serial port instead 69 * of to the LEDs. 70 */ 71 72/*#define _SERIAL_PORT_LEDS_*/ 73 74#ifdef _SERIAL_PORT_LEDS_ 75#include "sb1250_uart.h" /* need this for serial defs */ 76#endif 77 78 79/* ********************************************************************* 80 * BOARD_EARLYINIT() 81 * 82 * Initialize board registers. This is the earliest 83 * time the BSP gets control. This routine cannot assume that 84 * memory is operational, and therefore all code in this routine 85 * must run from registers only. The $ra register must not 86 * be modified, as it contains the return address. 87 * 88 * This routine will be called from uncached space, before 89 * the caches are initialized. If you want to make 90 * subroutine calls from here, you must use the CALLKSEG1 macro. 91 * 92 * Among other things, this is where the GPIO registers get 93 * programmed to make on-board LEDs function, or other startup 94 * that has to be done before anything will work. 95 * 96 * Input parameters: 97 * nothing 98 * 99 * Return value: 100 * nothing 101 ********************************************************************* */ 102 103LEAF(board_earlyinit) 104 105 106 # 107 # Configure the GPIOs 108 # 109 110 li t0,PHYS_TO_K1(A_GPIO_DIRECTION) 111 li t1,GPIO_OUTPUT_MASK 112 sd t1,0(t0) 113 114 li t0,PHYS_TO_K1(A_GPIO_INT_TYPE) 115 li t1,GPIO_INTERRUPT_MASK 116 sd t1,0(t0) 117 118 # 119 # Turn off the diagnostic LED. 120 # 121 li t0,PHYS_TO_K1(A_GPIO_PIN_CLR) 122 li t1,M_GPIO_DEBUG_LED 123 sd t1,0(t0) 124 125 # 126 # Configure the LEDs 127 # 128 129 li t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(LEDS_CS)) 130 li t1,LEDS_PHYS >> S_IO_ADDRBASE 131 sd t1,R_IO_EXT_START_ADDR(t0) 132 133 li t1,LEDS_SIZE-1 /* Needs to be 1 smaller, se UM for details */ 134 sd t1,R_IO_EXT_MULT_SIZE(t0) 135 136 li t1,LEDS_TIMING0 137 sd t1,R_IO_EXT_TIME_CFG0(t0) 138 139 li t1,LEDS_TIMING1 140 sd t1,R_IO_EXT_TIME_CFG1(t0) 141 142 li t1,LEDS_CONFIG 143 sd t1,R_IO_EXT_CFG(t0) 144 145 # 146 # Configure CS 0 size from 4MB to 16MB 147 # 148 li t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(BOOTROM_CS)) 149 150 li t1,BOOTROM_SIZE-1 151 sd t1,R_IO_EXT_MULT_SIZE(t0) 152 153 154 155 /* 156 * If the CPU is a 1250 or hybrid, certain initialization has 157 * to be done so that the chip can be used like an 112x. 158 */ 159 160 /* First, figure out what type of SOC we're on. */ 161 ld t1, PHYS_TO_K1(A_SCD_SYSTEM_REVISION) 162 SYS_SOC_TYPE(t3, t1) 163 bne t3, K_SYS_SOC_TYPE_BCM1250, is_bcm112x 164 165 /* 166 * We have a 1250 or hybrid. Initialize registers as appropriate. 167 */ 168 169 /* 170 * If we're not already running as a uniprocessor, get us there. 171 */ 172 dsrl t1, t1, S_SYS_PART # part number now in t1 173 and t3, t1, 0xf00 174 dsrl t3, t3, 8 # t3 = numcpus 175 176 ld t4, PHYS_TO_K1(A_SCD_SYSTEM_CFG) 177 or t4, t4, M_SYS_SB_SOFTRES 178 xor t4, t4, M_SYS_SB_SOFTRES 179 sd t4, PHYS_TO_K1(A_SCD_SYSTEM_CFG) /* clear soft reset */ 180 181 beq t3, 1, 2f 182 183 or t4, t4, M_SYS_SB_SOFTRES | M_SYS_UNICPU0 184 sd t4, PHYS_TO_K1(A_SCD_SYSTEM_CFG) /* go unicpu */ 185 sync 1861: 187 b 1b 1882: 189 190 /* 191 * Clean up MC 0. 192 */ 193 194 li t0, PHYS_TO_K1(A_MC_BASE_0) 195 dli t1, V_MC_CONFIG_DEFAULT | M_MC_ECC_DISABLE | \ 196 V_MC_CS_MODE_MSB_CS 197 sd t1, R_MC_CONFIG(t0) 198 sd zero, R_MC_CS_START(t0) 199 sd zero, R_MC_CS_END(t0) 200 sd zero, R_MC_CS_INTERLEAVE(t0) 201 sd zero, R_MC_CS_ATTR(t0) 202 sd zero, R_MC_TEST_DATA(t0) 203 sd zero, R_MC_TEST_ECC(t0) 204 205 /* 206 * Zero out MAC 2's address register. (This has 207 * undefined value after reset, but OSes may check 208 * it on some parts to see if they should init 209 * the interface. This is a convenient place 210 * to zero it.) 211 */ 212 213 li t0, PHYS_TO_K1(A_MAC_BASE_2) 214 sd zero, R_MAC_ETHERNET_ADDR(t0) 215 216is_bcm112x: 217 218#ifdef _SERIAL_PORT_LEDS_ 219 220 # Program the mode register for 8 bits/char, no parity 221 222 li t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A) 223 li t1,V_DUART_BITS_PER_CHAR_8 | V_DUART_PARITY_MODE_NONE 224 sd t1,(t0) 225 226 # Program the mode register for 1 stop bit, ignore CTS 227 228 li t0,PHYS_TO_K1(A_DUART_MODE_REG_2_A) 229 li t1,M_DUART_STOP_BIT_LEN_1 230 sd t1,(t0) 231 232 # Program the baud rate to 115200 233 234 li t0,PHYS_TO_K1(A_DUART_CLK_SEL_A) 235 li t1,V_DUART_BAUD_RATE(115200) 236 sd t1,(t0) 237 238 # Dont use any interrupts 239 240 li t0,PHYS_TO_K1(A_DUART_IMR) 241 ld t1,(t0) 242 and t1,~M_DUART_IMR_ALL_A 243 sd t1,(t0) 244 245 # Enable sending and receiving 246 247 li t0,PHYS_TO_K1(A_DUART_CMD_A) 248 li t1,M_DUART_RX_EN | M_DUART_TX_EN 249 sd t1,(t0) 250 251#endif 252 253 j ra 254 255END(board_earlyinit) 256 257 258/* ********************************************************************* 259 * BOARD_DRAMINFO 260 * 261 * Return the address of the DRAM information table 262 * 263 * Input parameters: 264 * nothing 265 * 266 * Return value: 267 * v0 - DRAM info table, return 0 to use default table 268 ********************************************************************* */ 269 270#define smb_cmd t9 271#define smb_start t8 272#define smb_status t7 273#define smb_data t6 274#define spd_byte t4 275#define SMBUS_0_READBYTE(slvaddr,devaddr,result) \ 2761: ld t1,(smb_status) ; \ 277 and t1,M_SMB_BUSY ; \ 278 bnez t1,1b ; \ 279 li t1,devaddr ; \ 280 sd t1,(smb_cmd) ; \ 281 li t1,(V_SMB_TT(K_SMB_TT_WR1BYTE) | slvaddr) ; \ 282 sd t1,(smb_start) ; \ 2831: ld t1,(smb_status) ; \ 284 and t1,M_SMB_BUSY ; \ 285 bnez t1,1b ; \ 286 li t1,(V_SMB_TT(K_SMB_TT_RD1BYTE) | slvaddr) ; \ 287 sd t1,(smb_start) ; \ 2881: ld t1,(smb_status) ; \ 289 and t1,M_SMB_BUSY ; \ 290 bnez t1,1b ; \ 291 ld t1,(smb_data) ; \ 292 and t1,0xFF ; \ 293 move result,t1 294 295LEAF(board_draminfo) 296 297 /* 298 * Check a few bytes to make sure SPD EEPROM contains valid info. If it does, use it. 299 * if not, use manual tables. The ATMEL EEPROM is @ chan 0, addr 0x54. 300 */ 301 302 li smb_cmd,PHYS_TO_K1(A_SMB_CMD_0) 303 li smb_start,PHYS_TO_K1(A_SMB_START_0) 304 li smb_status,PHYS_TO_K1(A_SMB_STATUS_0) 305 li smb_data,PHYS_TO_K1(A_SMB_DATA_0) 306 307 # Initialize smbus chan 0 308 li t0,PHYS_TO_K1(A_SMB_FREQ_0) 309 li t1,K_SMB_FREQ_100KHZ 310 sd t1,(t0) 311 312 li t0,PHYS_TO_K1(A_SMB_CONTROL_0) 313 sd zero,(t0) 314 315 # Check memory type @ byte 2. 0x07(SDRAM DDR) 316 SMBUS_0_READBYTE(SPDEEPROM_SMBUS_DEV,JEDEC_SPD_MEMTYPE,spd_byte) 317 li t2,0x07 /*JEDEC SDRAM memory type*/ 318 bne spd_byte,t2,man 319 320 # Check rows @ byte 3. 0x0D(13) 321 SMBUS_0_READBYTE(SPDEEPROM_SMBUS_DEV,JEDEC_SPD_ROWS,spd_byte) 322 li t2,0x0D /*There should be 13 rows*/ 323 bne spd_byte,t2,man 324 325 # Check columns @ byte 4. 0x09(9) 326 SMBUS_0_READBYTE(SPDEEPROM_SMBUS_DEV,JEDEC_SPD_COLS,spd_byte) 327 li t2,0x09 /*There should be 9 columns*/ 328 bne spd_byte,t2,man 329 330 # Check refresh rate/type @ byte 12. 0x82 -> 128 KHZ 331 SMBUS_0_READBYTE(SPDEEPROM_SMBUS_DEV,JEDEC_SPD_RFSH,spd_byte) 332 li t2,0x82 /*Refresh rate should be set for 128 KHZ*/ 333 bne spd_byte,t2,man 334 335 # All checks passed. Use SPD to configure 336 la v0,spd 337 b done 338 339man: la v0,man_table 340 341done: 342 j ra 343 344spd: 345 346 /* 347 * Globals: Only one memory controller, no port interleaving 348 */ 349 DRAM_GLOBALS(0) 350 DRAM_CHAN_CFG(MC_CHAN1, DRT10(8,0), JEDEC, CASCHECK, BLKSIZE32, CFG_DRAM_CSINTERLEAVE, CFG_DRAM_ECC, MCFLG_DS_REDUCED) 351 DRAM_CHAN_CLKCFG(0x00,0x08,0x08,0x00,0x0F,0x0F) 352 353 DRAM_CS_SPD(MC_CS0, 0, 0, 0x54) 354 DRAM_EOT 355 356man_table: 357 358 /* 359 * DRAM globals: Only one memory controller, no port interleaving 360 */ 361 362 DRAM_GLOBALS(0) 363 364 /* 365 * 128MB on MC 1 (JEDEC SDRAM) 366 * Samsung K4H561638B - 16Mx16 chips 367 * 368 * Minimum tMEMCLK: 8.0ns (125Mhz max freq) 369 * 370 * CS0 Geometry: 13 rows, 9 columns, 2 bankbits 371 * 372 * 128khz refresh, CAS Latency 2.5 373 * Timing (ns): tCK=7.50 tRAS=45 tRP=20.00 tRRD=15.0 tRCD=20.0 tRFC=auto tRC=auto 374 * 375 * Clock Config: Default 376 */ 377 378 DRAM_CHAN_CFG(MC_CHAN1, DRT10(8,0), JEDEC, CASCHECK, BLKSIZE32, CFG_DRAM_CSINTERLEAVE, CFG_DRAM_ECC, MCFLG_DS_REDUCED) 379 DRAM_CHAN_CLKCFG(0x00,0x08,0x08,0x00,0x07,0x0F) 380 381 DRAM_CS_GEOM(MC_CS0, 13, 9, 2) 382 DRAM_CS_TIMING(DRT10(7,5), JEDEC_RFSH_128khz, JEDEC_CASLAT_25, 0, 45, DRT4(20,0), DRT4(15,0), DRT4(20,0), 0, 0) 383 384 385 DRAM_EOT 386 387END(board_draminfo) 388 389/* ********************************************************************* 390 * BOARD_UARTA_TXCHAR 391 * 392 * Transmit a single character via UART A 393 * 394 * Input parameters: 395 * a0 - character to transmit (low-order 8 bits) 396 * 397 * Return value: 398 * nothing 399 * 400 * Registers used: 401 * t0,t1 402 ********************************************************************* */ 403#ifdef _SERIAL_PORT_LEDS_ 404LEAF(board_uarta_txchar) 405 406 # Wait until there is space in the transmit buffer 407 4081: li t0,PHYS_TO_K1(A_DUART_STATUS_A) 409 ld t1,(t0) # Get status bits 410 and t1,M_DUART_TX_RDY # test for ready 411 beq t1,0,1b # keep going till ready 412 413 # Okay, now send the character. 414 415 li t0,PHYS_TO_K1(A_DUART_TX_HOLD_A) 416 sd a0,(t0) 417 418 # done! 419 420 j ra 421 422END(board_uarta_txchar) 423#endif 424 425/* ********************************************************************* 426 * BOARD_SETLEDS(x) 427 * 428 * Set LEDs for boot-time progress indication. Not used if 429 * the board does not have progress LEDs. This routine 430 * must not call any other routines, since it may be invoked 431 * either from KSEG0 or KSEG1 and it may be invoked 432 * whether or not the icache is operational. 433 * 434 * Input parameters: 435 * a0 - LED value (8 bits per character, 4 characters) 436 * 437 * Return value: 438 * nothing 439 * 440 * Registers used: 441 * t0,t1,t2,t3 442 ********************************************************************* */ 443 444#define LED_CHAR0 (32+8*3) 445#define LED_CHAR1 (32+8*2) 446#define LED_CHAR2 (32+8*1) 447#define LED_CHAR3 (32+8*0) 448 449LEAF(board_setleds) 450 451#ifdef _SERIAL_PORT_LEDS_ 452 move t3,ra 453 move t2,a0 454 455 li a0,'[' 456 bal board_uarta_txchar 457 458 move a0,t2 459 rol a0,8 460 bal board_uarta_txchar 461 462 rol a0,8 463 bal board_uarta_txchar 464 465 rol a0,8 466 bal board_uarta_txchar 467 468 rol a0,8 469 bal board_uarta_txchar 470 471 li a0,']' 472 bal board_uarta_txchar 473 li a0,13 474 bal board_uarta_txchar 475 li a0,10 476 bal board_uarta_txchar 477 478 move ra,t3 479#else 480 481 /* 482 * Sending to LEDs 483 */ 484 li t0,PHYS_TO_K1(LEDS_PHYS) 485 486 rol a0,a0,8 487 and t1,a0,0xFF 488 sb t1,LED_CHAR0(t0) 489 490 rol a0,a0,8 491 and t1,a0,0xFF 492 sb t1,LED_CHAR1(t0) 493 494 rol a0,a0,8 495 and t1,a0,0xFF 496 sb t1,LED_CHAR2(t0) 497 498 rol a0,a0,8 499 and t1,a0,0xFF 500 sb t1,LED_CHAR3(t0) 501 502#endif 503 j ra 504 505END(board_setleds) 506 507 508 509