1/* ********************************************************************* 2 * BCM1280/BCM1480 Board Support Package 3 * 4 * Board-specific initialization File: BCM91280E_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 "bcm1480_regs.h" 52#include "bcm1480_scd.h" 53#include "bcm1480_l2c.h" 54#include "sb1250_genbus.h" 55#include "bcm1480_draminit.h" 56#include "jedec.h" 57#include "bsp_config.h" 58#include "cpu_config.h" 59#include "mipsmacros.h" 60#include "bcm91280e.h" 61 62 .text 63 64 65 66/* ********************************************************************* 67 * Macros 68 ********************************************************************* */ 69 70/* 71#define _SERIAL_PORT_LEDS_ 72*/ 73 74#ifdef _SERIAL_PORT_LEDS_ 75#include "sb1250_uart.h" 76#endif 77 78/* ********************************************************************* 79 * LED macros 80 ********************************************************************* */ 81 82#define SETLEDS1(a,b,c,d) \ 83 li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \ 84 JAL_KSEG1(board_setleds) 85#define SETLEDS(a,b,c,d) \ 86 li a0,(((a)<<24)|((b)<<16)|((c)<<8)|(d)) ; \ 87 JAL_KSEG1(board_setleds) 88 89 90/* ********************************************************************* 91 * BOARD_EARLYINIT() 92 * 93 * Initialize board registers. This is the earliest 94 * time the BSP gets control. This routine cannot assume that 95 * memory is operational, and therefore all code in this routine 96 * must run from registers only. The $ra register must not 97 * be modified, as it contains the return address. 98 * 99 * This routine will be called from uncached space, before 100 * the caches are initialized. If you want to make 101 * subroutine calls from here, you must use the JAL_KSEG1 macro. 102 * 103 * Among other things, this is where the GPIO registers get 104 * programmed to make on-board LEDs function, or other startup 105 * that has to be done before anything will work. 106 * 107 * Input parameters: 108 * nothing 109 * 110 * Return value: 111 * nothing 112 ********************************************************************* */ 113 114LEAF(board_earlyinit) 115 116 move s0, ra 117 118 # 119 # Configure the GPIOs 120 # 121 122 li t0,PHYS_TO_K1(A_GPIO_DIRECTION) 123 li t1,GPIO_OUTPUT_MASK 124 sd t1,0(t0) 125 126 li t0,PHYS_TO_K1(A_GPIO_INT_TYPE) 127 li t1,GPIO_INTERRUPT_MASK 128 sd t1,0(t0) 129 130#if CFG_L2_RAM /* Variant for using L2 as memory via TLB for 32 bits */ 131 # 132 # Set up the L2 cache to be used as SRAM by setting the 133 # way_disable address (the actual flush will be done by 134 # sb1250_l2cache_init). 135 # 136 li t0,PHYS_TO_K1(A_BCM1480_L2_MAKE_WAY_ENABLE_LO(0x00)) 137 sd zero,(t0) 138 li t0,PHYS_TO_K1(A_BCM1480_L2_MAKE_WAY_ENABLE_HI(0x08)) 139 sd zero,(t0) 140 141 # Use the result of a load to stall the pipe here. 142 # Ref sec 5.4.2 (aka page 92, 1250_1125UM100-R). 143 # XXX Probably not necessary for these early, global accesses. 144 ld t0,(t0) 145 addu t0,t0,t0 146#endif 147 148 # 149 # Configure the alternate boot ROM 150 # 151 152 li t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(ALT_BOOTROM_CS)) 153 154 li t1,ALT_BOOTROM_PHYS >> S_IO_ADDRBASE 155 sd t1,R_IO_EXT_START_ADDR(t0) 156 157 li t1,ALT_BOOTROM_SIZE-1 158 sd t1,R_IO_EXT_MULT_SIZE(t0) 159 160 li t1,ALT_BOOTROM_TIMING0 161 sd t1,R_IO_EXT_TIME_CFG0(t0) 162 163 li t1,ALT_BOOTROM_TIMING1 164 sd t1,R_IO_EXT_TIME_CFG1(t0) 165 166 li t1,ALT_BOOTROM_CONFIG 167 sd t1,R_IO_EXT_CFG(t0) 168 169 170 # 171 # Configure the LEDs 172 # 173 li t0,PHYS_TO_K1(A_IO_EXT_CS_BASE(LEDS_CS)) 174 li t1,LEDS_PHYS >> S_IO_ADDRBASE 175 sd t1,R_IO_EXT_START_ADDR(t0) 176 177 li t1,LEDS_SIZE-1 /* Needs to be 1 smaller, se UM for details */ 178 sd t1,R_IO_EXT_MULT_SIZE(t0) 179 180 li t1,LEDS_TIMING0 181 sd t1,R_IO_EXT_TIME_CFG0(t0) 182 183 li t1,LEDS_TIMING1 184 sd t1,R_IO_EXT_TIME_CFG1(t0) 185 186 li t1,LEDS_CONFIG 187 sd t1,R_IO_EXT_CFG(t0) 188 189 # 190 # Make sure that the mailbox registers are cleared 191 # 192 193 li t0,PHYS_TO_K1(A_BCM1480_IMR_REGISTER(0,R_BCM1480_IMR_MAILBOX_0_CLR_CPU)) 194 nor t1, zero, zero 195 sd t1,(t0) 196 li t0,PHYS_TO_K1(A_BCM1480_IMR_REGISTER(0,R_BCM1480_IMR_MAILBOX_1_CLR_CPU)) 197 sd t1,(t0) 198 199#ifdef _SERIAL_PORT_LEDS_ 200 201 # Program the mode register for 8 bits/char, no parity 202 203 li t0,PHYS_TO_K1(A_DUART_MODE_REG_1_A) 204 li t1,V_DUART_BITS_PER_CHAR_8 | V_DUART_PARITY_MODE_NONE 205 sd t1,(t0) 206 207 # Program the mode register for 1 stop bit, ignore CTS 208 209 li t0,PHYS_TO_K1(A_DUART_MODE_REG_2_A) 210 li t1,M_DUART_STOP_BIT_LEN_1 211 sd t1,(t0) 212 213 # Program the baud rate to 115200 214 215 li t0,PHYS_TO_K1(A_DUART_CLK_SEL_A) 216 li t1,V_DUART_BAUD_RATE(CFG_SERIAL_BAUD_RATE) 217 sd t1,(t0) 218 219 # Dont use any interrupts 220 221 li t0,PHYS_TO_K1(A_DUART_IMR) 222 ld t1,(t0) 223 and t1,~M_DUART_IMR_ALL_A 224 sd t1,(t0) 225 226 # Enable sending and receiving 227 228 li t0,PHYS_TO_K1(A_DUART_CMD_A) 229 li t1,M_DUART_RX_EN | M_DUART_TX_EN 230 sd t1,(t0) 231 232#endif 233 234 235 # 236 # If the config switches request that half the cache be 237 # disabled (to model 512kB-cache parts on boards w/ 1MB 238 # caches), disable half of the cache now. 239 # 240 241 SETLEDS1('D','L','2','?') 242 243 JAL_KSEG1(board_get_config) 244 245 and v0, v0, BOARD_CFG_HALF_L2 246 beqz v0, 1f # Disable not requested. Done. 247 248 SETLEDS1('D','L','2','!') 249 250 la t0, PHYS_TO_K1(A_BCM1480_L2_MISC0_VALUE) 251 ld t0, 0(t0) 252 253 and t0, t0, (M_BCM1480_L2C_MISC0_CACHE_DISABLE \ 254 | M_BCM1480_L2C_MISC0_CACHE_QUAD) 255 bnez t0, 1f # Some bits set -> half already 256 # disabled -> Done. 257 258 SETLEDS1('D','L','2','H') 259 260 la t0, PHYS_TO_K1(A_BCM1480_L2_MAKECACHEDISABLE(1)) 261 sd zero, 0(t0) # disable half. 262 sync 263 264 # read back a mgmt register just to make sure the write has 265 # completed. 266 la t0, PHYS_TO_K1(A_BCM1480_L2_MISC0_VALUE) 267 ld zero, 0(t0) 268 sync 2691: 270 SETLEDS1('D','L','2','D') 271 272 273 # 274 # If the config switches request that only two CPUs remain 275 # enabled (to model 2-CPU parts on boards w/ more than two CPUs), 276 # disable CPUs until only two remain. 277 # 278 279 SETLEDS1('D','C',' ','?') 280 281 JAL_KSEG1(board_get_config) 282 283 and v0, v0, BOARD_CFG_2CPU 284 beqz v0, 1f # Disable not requested. Done. 285 286 SETLEDS1('D','C',' ','!') 287 288 li s1, 2 289 la s2, PHYS_TO_K1(A_SCD_SYSTEM_CFG) 290 291 JAL_KSEG1(bcm1480_num_cpus) 292 ble v0, s1, 1f # #cpus <= 2? Done. 293 294 # disable CPU 3. 295 SETLEDS1('D','C','3','!') 296 ld t0, 0(s2) 297 or t0, M_BCM1480_SYS_DISABLECPU3 298 BCM1480_WRITE_SYSTEM_CFG(s2, t0) 299 300 JAL_KSEG1(bcm1480_num_cpus) 301 ble v0, s1, 1f # #cpus <= 2? Done. 302 303 # disable CPU 2. 304 SETLEDS1('D','C','2','!') 305 ld t0, 0(s2) 306 or t0, M_BCM1480_SYS_DISABLECPU2 307 BCM1480_WRITE_SYSTEM_CFG(s2, t0) 308 309 # If we reach this point, CPUs 2 and 3 have just been 310 # disabled. Therefore we have two CPUs disabled, and 311 # we're done. 3121: 313 SETLEDS1('D','C',' ','D') 314 315 316 move ra, s0 317 j ra 318 319END(board_earlyinit) 320 321 322/* ********************************************************************* 323 * BOARD_DRAMINFO 324 * 325 * Return the address of the DRAM information table 326 * 327 * Input parameters: 328 * nothing 329 * 330 * Return value: 331 * v0 - DRAM info table, return 0 to use default table 332 ********************************************************************* */ 333 334 335#define VPN2_256K(va) (((va)>>(13+6))<<6) 336#define PFN(pa) ((pa)>>12) 337#define PGMASK_256K (0x3F<<13) 338 339LEAF(board_draminfo) 340 341 342#if CFG_L2_RAM /* Variant for using L2 as memory via TLB for 32 bits */ 343 /* 344 * Map 512K of L2 space to VA 0x300000 using a pair of 256K 345 * page frames. 346 * This is an abuse of the function, but it is called at the 347 * correct point in the initialization sequence, where adding 348 * new function calls is delicate. 349 */ 350 351 .set push 352 .set mips64 353 354 dli v0,(VPN2_256K(0x00300000)<<13) 355 dmtc0 v0,C0_TLBHI 356 li v0,(PFN(0xd0300000)<<6 | (5<<3) | 7) 357 mtc0 v0,C0_TLBLO0 358 li v0,(PFN(0xd0340000)<<6 | (5<<3) | 7) 359 mtc0 v0,C0_TLBLO1 360 li v0,PGMASK_256K 361 mtc0 v0,C0_PGMASK 362 li v0,1 363 mtc0 v0,C0_WIRED 364 li v0,0 365 mtc0 v0,C0_INDEX 366 tlbwi 367 368 HAZARD 369 370 .set pop 371#endif /* CFG_L2_RAM */ 372 373 /* 374 * Return pointer to DRAM table. 375 */ 376 377 la v0,dramtab 378 j ra 379 380 381dramtab: 382 383 DRAM_GLOBALS(CFG_DRAM_INTERLEAVE) 384 385 DRAM_CHAN_CFG(MC_CHAN0, DRT10(3,0), DRT10(3,0), MC_32BIT_CHAN, JEDEC_DDR2, CASCHECK, CFG_DRAM_CSINTERLEAVE, CFG_DRAM_ECC, 0) 386 DRAM_CS_GEOM(MC_CS0, 14, 10, 2, 0) 387 DRAM_CS_TIMING(DRT10(3,0), JEDEC_RFSH_128khz, JEDEC_CASLAT_DDR2_5, 0, 45, DRT4(15,0), DRT4(7,5), DRT4(15,0), 105, 55) 388 DRAM_CS_TIMING2(0,DRT4(7,5),0) 389 DRAM_CHAN_ODTCFG(0x00,0x00,0x00,0x00,CS_ODD_ODT_EN,ODT_75,0) 390 DRAM_CHAN_DLLCFG2(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) 391 392 393 DRAM_CHAN_CFG(MC_CHAN1, DRT10(3,0), DRT10(3,0), MC_32BIT_CHAN, JEDEC_DDR2, CASCHECK, CFG_DRAM_CSINTERLEAVE, CFG_DRAM_ECC, 0) 394 DRAM_CS_GEOM(MC_CS0, 14, 10, 2, 0) 395 DRAM_CS_TIMING(DRT10(3,0), JEDEC_RFSH_128khz, JEDEC_CASLAT_DDR2_5, 0, 45, DRT4(15,0), DRT4(7,5), DRT4(15,0), 105, 55) 396 DRAM_CS_TIMING2(0,DRT4(7,5),0) 397 DRAM_CHAN_ODTCFG(0x00,0x00,0x00,0x00,CS_ODD_ODT_EN,ODT_75,0) 398 DRAM_CHAN_DLLCFG2(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) 399 400 401 DRAM_CHAN_CFG(MC_CHAN2, DRT10(3,0), DRT10(3,0), MC_32BIT_CHAN, JEDEC_DDR2, CASCHECK, CFG_DRAM_CSINTERLEAVE, CFG_DRAM_ECC, 0) 402 DRAM_CS_GEOM(MC_CS0, 14, 10, 2, 0) 403 DRAM_CS_TIMING(DRT10(3,0), JEDEC_RFSH_128khz, JEDEC_CASLAT_DDR2_5, 0, 45, DRT4(15,0), DRT4(7,5), DRT4(15,0), 105, 55) 404 DRAM_CS_TIMING2(0,DRT4(7,5),0) 405 DRAM_CHAN_ODTCFG(0x00,0x00,0x00,0x00,CS_ODD_ODT_EN,ODT_75,0) 406 DRAM_CHAN_DLLCFG2(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) 407 408 409 DRAM_CHAN_CFG(MC_CHAN3, DRT10(3,0), DRT10(3,0), MC_32BIT_CHAN, JEDEC_DDR2, CASCHECK, CFG_DRAM_CSINTERLEAVE, CFG_DRAM_ECC, 0) 410 DRAM_CS_GEOM(MC_CS0, 14, 10, 2, 0) 411 DRAM_CS_TIMING(DRT10(3,0), JEDEC_RFSH_128khz, JEDEC_CASLAT_DDR2_5, 0, 45, DRT4(15,0), DRT4(7,5), DRT4(15,0), 105, 55) 412 DRAM_CS_TIMING2(0,DRT4(7,5),0) 413 DRAM_CHAN_ODTCFG(0x00,0x00,0x00,0x00,CS_ODD_ODT_EN,ODT_75,0) 414 DRAM_CHAN_DLLCFG2(0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00) 415 416 DRAM_EOT 417 418END(board_draminfo) 419 420 421/* ********************************************************************* 422 * BOARD_PIAI2_TXCHAR 423 * 424 * Transmit a single character via UART A 425 * 426 * Input parameters: 427 * a0 - character to transmit (low-order 8 bits) 428 * 429 * Return value: 430 * nothing 431 * 432 * Registers used: 433 * t0,t1 434 ********************************************************************* */ 435 436#ifdef _PROMICE_PORT_LEDS_ 437 438LEAF(board_piai2_txchar) 439 440 # Wait until there is space in the transmit buffer 441 442 li t0,PHYS_TO_K1(BOARD_PROMICE_BASE) 443 4441: lb t1,BOARD_PROMICE_STATUS(t0) 445 andi t1,TDA 446 bne t1,zero,1b 447 448 # Okay, now send the character. 449 450 sb a0,BOARD_PROMICE_ZERO(t0) 451 452 # done! 453 454 j ra 455 456END(board_piai2_txchar) 457#endif 458 459/* ********************************************************************* 460 * BOARD_UARTA_TXCHAR 461 * 462 * Transmit a single character via UART A 463 * 464 * Input parameters: 465 * a0 - character to transmit (low-order 8 bits) 466 * 467 * Return value: 468 * nothing 469 * 470 * Registers used: 471 * t0,t1 472 ********************************************************************* */ 473 474#ifdef _SERIAL_PORT_LEDS_ 475board_uarta_txchar: 476 477 # Wait until there is space in the transmit buffer 478 4791: li t0,PHYS_TO_K1(A_DUART_STATUS_A) 480 ld t1,(t0) # Get status bits 481 and t1,M_DUART_TX_RDY # test for ready 482 beq t1,0,1b # keep going till ready 483 484 # Okay, now send the character. 485 486 li t0,PHYS_TO_K1(A_DUART_TX_HOLD_A) 487 sd a0,(t0) 488 489 # done! 490 491 j ra 492 493 494#endif 495 496/* ********************************************************************* 497 * BOARD_SETLEDS(x) 498 * 499 * Set LEDs for boot-time progress indication. Not used if 500 * the board does not have progress LEDs. This routine 501 * must not call any other routines, since it may be invoked 502 * either from KSEG0 or KSEG1 and it may be invoked 503 * whether or not the icache is operational. 504 * 505 * Input parameters: 506 * a0 - LED value (8 bits per character, 4 characters) 507 * 508 * Return value: 509 * nothing 510 * 511 * Registers used: 512 * t0,t1,t2,t3 513 ********************************************************************* */ 514 515 516#define LED_CHAR0 (32+8*3) 517#define LED_CHAR1 (32+8*2) 518#define LED_CHAR2 (32+8*1) 519#define LED_CHAR3 (32+8*0) 520 521 522LEAF(board_setleds) 523 524 /* 525 * Sending to LEDs 526 */ 527 528 li t0,PHYS_TO_K1(LEDS_PHYS) 529 530 rol a0,a0,8 531 and t1,a0,0xFF 532 sb t1,LED_CHAR0(t0) 533 534 rol a0,a0,8 535 and t1,a0,0xFF 536 sb t1,LED_CHAR1(t0) 537 538 rol a0,a0,8 539 and t1,a0,0xFF 540 sb t1,LED_CHAR2(t0) 541 542 rol a0,a0,8 543 and t1,a0,0xFF 544 sb t1,LED_CHAR3(t0) 545 546 547 548#ifdef _SERIAL_PORT_LEDS_ 549 move t3,ra 550 move t2,a0 551 552 li a0,'[' 553 bal board_uarta_txchar 554 555 move a0,t2 556 rol a0,8 557 bal board_uarta_txchar 558 rol a0,8 559 bal board_uarta_txchar 560 rol a0,8 561 bal board_uarta_txchar 562 rol a0,8 563 bal board_uarta_txchar 564 565 li a0,']' 566 bal board_uarta_txchar 567 li a0,13 568 bal board_uarta_txchar 569 li a0,10 570 bal board_uarta_txchar 571 572 move a0,t2 573 move ra,t3 574 575#endif 576 577 j ra 578 579END(board_setleds) 580 581LEAF(board_get_config) 582 .set push 583 .set noreorder 584 .set nomacro 585 lui t0, %hi(PHYS_TO_K1(A_SCD_SYSTEM_CFG)) 586 ld t0, %lo(PHYS_TO_K1(A_SCD_SYSTEM_CFG))(t0) 587 dsrl t0, t0, S_BCM1480_SYS_CONFIG 588 li v0, (M_BCM1480_SYS_CONFIG >> S_BCM1480_SYS_CONFIG) 589 and v0, v0, t0 590 jr ra 591 nop 592 .set pop 593END(board_get_config) 594 595 596 597