1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * Board device initialization File: swarm_devs.c 5 * 6 * This is the "C" part of the board support package. The 7 * routines to create and initialize the console, wire up 8 * device drivers, and do other customization live 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 "cfe.h" 51#include "sbmips.h" 52#include "cfe_smbus.h" 53#include "env_subr.h" 54 55#include "sb1250_defs.h" 56#include "sb1250_regs.h" 57#include "sb1250_scd.h" 58#include "sb1250_smbus.h" 59#include "sb1250_wid.h" 60 61#include "swarm.h" 62#include "dev_ide.h" 63 64#include "dev_newflash.h" 65 66#include "cfe_loader.h" 67#include "cfe_autoboot.h" 68 69/* ********************************************************************* 70 * Devices we're importing 71 ********************************************************************* */ 72 73extern cfe_driver_t promice_uart; /* promice serial port */ 74extern cfe_driver_t sb1250_uart; /* SB1250 serial ports */ 75extern cfe_driver_t sb1250_ether; /* SB1250 MACs */ 76extern cfe_driver_t newflashdrv; /* flash */ 77extern cfe_driver_t idedrv; /* IDE disk */ 78extern cfe_driver_t pcmciadrv; /* PCMCIA card */ 79#if CFG_PCI 80extern void pci_add_devices(int init); /* driver collection du jour */ 81#endif 82#if CFG_TCP 83extern cfe_driver_t tcpconsole; /* TCP/IP console */ 84#endif 85#if CFG_VGACONSOLE 86extern cfe_driver_t pcconsole2; /* VGA Console */ 87static int vgainit_ok = FALSE; 88extern int vga_biosinit(void); 89#endif 90#if CFG_USB 91extern int usb_init(uint32_t addr); 92extern cfe_driver_t usb_disk; /* USB mass-storage */ 93extern cfe_driver_t usb_uart; /* USB serial ports */ 94extern cfe_driver_t usb_ether; /* USB ethernet */ 95#endif 96 97extern cfe_smbus_t sb1250_smbus; /* BCM1250 SMBus controller */ 98 99extern cfe_driver_t smbus_24lc128; /* Microchip 24lc128 eeprom */ 100extern cfe_driver_t smbus_x1241clock; /* Xicor clock */ 101extern cfe_driver_t smbus_m41t81clock; /* ST Micro clock */ 102extern cfe_driver_t smbus_x1240eeprom; /* Xicor EEPROM */ 103 104/* ********************************************************************* 105 * UI command initialization 106 ********************************************************************* */ 107 108extern void ui_init_cpu1cmds(void); 109extern void ui_init_swarmcmds(void); 110extern int ui_init_corecmds(void); 111extern int ui_init_soccmds(void); 112extern int ui_init_testcmds(void); 113extern int ui_init_tempsensorcmds(void); 114extern int ui_init_toyclockcmds(void); 115extern int ui_init_memtestcmds(void); 116extern int ui_init_resetcmds(void); 117extern int ui_init_phycmds(void); 118extern int ui_init_spdcmds(void); 119extern int ui_init_disktestcmds(void); 120extern int ui_init_ethertestcmds(void); 121extern int ui_init_flashtestcmds(void); 122 123#if CFG_USB 124extern int ui_init_usbcmds(void); 125#endif 126 127/* ********************************************************************* 128 * Other externs 129 ********************************************************************* */ 130 131extern void sb1250_show_cpu_type(void); 132 133/* ********************************************************************* 134 * Some board-specific parameters 135 ********************************************************************* */ 136 137/* 138 * Note! Configure the PROMICE for burst mode zero (one byte per 139 * access). 140 */ 141 142#define PROMICE_BASE (0x1FDFFC00) 143#define PROMICE_WORDSIZE 1 144 145#define REAL_BOOTROM_SIZE (2*1024*1024) /* region is 4MB, but rom is 2MB */ 146 147/* ********************************************************************* 148 * SysConfig switch settings and related parameters 149 ********************************************************************* */ 150 151int swarm_board_rev; 152int swarm_config_switch; 153 154#define SWARM_PROMICE_CONSOLE 0x00000001 155#define SWARM_VGA_CONSOLE 0x00000002 156 157const unsigned int swarm_startflags[16] = { 158 0, /* 0 : UART console, no PCI */ 159 SWARM_PROMICE_CONSOLE, /* 1 : PromICE console, no PCI */ 160 CFE_INIT_PCI, /* 2 : UART console, PCI */ 161 CFE_INIT_PCI | SWARM_PROMICE_CONSOLE, /* 3 : PromICE console, PCI */ 162 0, /* 4 : unused */ 163 0, /* 5 : unused */ 164 CFE_INIT_PCI | CFE_LDT_SLAVE, /* 6 : 2, plus LDT slave mode */ 165 CFE_INIT_SAFE, /* 7 : UART console, no pci, safe mode */ 166 0, /* 8 : unused */ 167 0, /* 9 : unused */ 168 CFE_INIT_PCI | SWARM_VGA_CONSOLE, /* 10 : PCI, VGA Console */ 169 0, /* 11 : unused */ 170 0, /* 12 : unused */ 171 0, /* 13 : unused */ 172 0, /* 14 : unused */ 173 0 /* 15 : unused */ 174}; 175 176 177unsigned int cpu_revision; 178 179 180/* ********************************************************************* 181 * board_console_init() 182 * 183 * Add the console device and set it to be the primary 184 * console. 185 * 186 * Input parameters: 187 * nothing 188 * 189 * Return value: 190 * nothing 191 ********************************************************************* */ 192 193void board_console_init(void) 194{ 195 uint64_t syscfg = SBREADCSR(A_SCD_SYSTEM_CFG); 196 197 cpu_revision = (unsigned int) (SBREADCSR(A_SCD_SYSTEM_REVISION) & 198 (M_SYS_PART | M_SYS_REVISION)); 199 200 /* Console */ 201 cfe_add_device(&sb1250_uart,A_DUART,0,0); 202 cfe_add_device(&promice_uart,PROMICE_BASE,PROMICE_WORDSIZE,0); 203 204#if CFG_VGACONSOLE 205 /* VGA console, for the truly adventurous! */ 206 cfe_add_device(&pcconsole2,0,0,0); 207#endif 208 209 /* 210 * Read the config switch and decide how we are going to set up 211 * the console. This is actually board revision dependent. 212 * 213 * Note that the human-readable board revision is (swarm_board_rev+1). 214 */ 215 swarm_board_rev = G_SYS_CONFIG(syscfg) & 0x3; 216 switch (swarm_board_rev) { 217 case 0: 218 /* 219 * Board revision 0. The config switch sets bits 3..5 of the 220 * SYS_CONFIG field of the syscfg register. 221 */ 222 swarm_config_switch = (G_SYS_CONFIG(syscfg) >> 3) & 0x07; 223 break; 224 225 default: 226 /* 227 * In later board revisions, the config switch sets bits 2..5. 228 */ 229 swarm_config_switch = (G_SYS_CONFIG(syscfg) >> 2) & 0x0f; 230 break; 231 } 232 233 cfe_startflags = swarm_startflags[swarm_config_switch]; 234 235 /* 236 * Choose which console we're going to use. Our three choices 237 * are the PromICE AI2 port, the "VGA" console, and 238 * the UART. 239 * 240 * The UART is the "normal" console, of course. 241 */ 242 243 if (cfe_startflags & SWARM_PROMICE_CONSOLE) { 244 cfe_set_console("promice0"); 245 } 246#if CFG_VGACONSOLE 247 /* 248 * If VGA console, "buffer" the console messages until the 249 * PCI is ready. 250 */ 251 else if (cfe_startflags & SWARM_VGA_CONSOLE) { 252 cfe_set_console(CFE_BUFFER_CONSOLE); 253 } 254#endif 255 else { 256 cfe_set_console("uart0"); 257 } 258 259 /* 260 * SMBus buses - need to be initialized before we attach 261 * devices that use them. 262 */ 263 264 cfe_add_smbus(&sb1250_smbus,A_SMB_BASE(0),0); 265 cfe_add_smbus(&sb1250_smbus,A_SMB_BASE(1),0); 266 267 /* 268 * NVRAM (environment variables - These depend on the SWARM 269 * board version since SWARM rev3 (and later) do not have Xicor 270 * clock chips. Instead, a second 24lc128 is on SMBus 1. 271 */ 272 273 switch (swarm_board_rev) { 274 case SWARM_REV_1: 275 case SWARM_REV_2: 276 cfe_add_device(&smbus_x1240eeprom,X1240_SMBUS_CHAN,X1240_SMBUS_DEV,0); 277 break; 278 default: 279 case SWARM_REV_3: 280 cfe_add_device(&smbus_24lc128,BIGEEPROM_SMBUS_CHAN_1,BIGEEPROM_SMBUS_DEV_1,0); 281 282 } 283 284 cfe_set_envdevice("eeprom0"); /* Connect NVRAM subsystem to EEPROM */ 285} 286 287 288/* ********************************************************************* 289 * board_smbus_waitready(chan) 290 * 291 * Wait until the SMBus channel is ready. We simply poll 292 * the busy bit until it clears. 293 * 294 * Input parameters: 295 * chan - channel (0 or 1) 296 * 297 * Return value: 298 * nothing 299 ********************************************************************* */ 300static int board_smbus_waitready(int chan) 301{ 302 uintptr_t reg; 303 uint64_t status; 304 305 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_STATUS)); 306 307 for (;;) { 308 status = SBREADCSR(reg); 309 if (status & M_SMB_BUSY) continue; 310 break; 311 } 312 313 if (status & M_SMB_ERROR) { 314 315 SBWRITECSR(reg,(status & M_SMB_ERROR)); 316 return -1; 317 } 318 return 0; 319} 320 321/* ********************************************************************* 322 * board_probe_x1241(chan,dev) 323 * 324 * Probe for a Xicor X1241 at the specified device and channel. 325 * 326 * Actually, we just probe for anything at this address, and 327 * assume it's a Xicor. 328 * 329 * Input parameters: 330 * chan - SMBus channel 331 * dev - device ID 332 * 333 * Return value: 334 * TRUE - X1241 is present 335 * FALSE - not present 336 ********************************************************************* */ 337 338static int board_probe_x1241(int chan,int slaveaddr) 339{ 340 uintptr_t reg; 341 int devaddr = 0; 342 int err; 343 344 /* 345 * Make sure the bus is idle (probably should 346 * ignore error here) 347 */ 348 349 if (board_smbus_waitready(chan) < 0) return FALSE; 350 351 /* 352 * Write the device address to the controller. There are two 353 * parts, the high part goes in the "CMD" field, and the 354 * low part is the data field. 355 */ 356 357 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_CMD)); 358 SBWRITECSR(reg,((devaddr >> 8) & 0x7)); 359 360 /* 361 * Write the data to the controller 362 */ 363 364 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_DATA)); 365 SBWRITECSR(reg,((devaddr & 0xFF) & 0xFF)); 366 367 /* 368 * Start the command 369 */ 370 371 reg = PHYS_TO_K1(A_SMB_REGISTER(chan,R_SMB_START)); 372 SBWRITECSR(reg,V_SMB_TT(K_SMB_TT_WR2BYTE) | slaveaddr); 373 374 /* 375 * Wait till done 376 */ 377 378 err = board_smbus_waitready(chan); 379 if (err < 0) return FALSE; 380 return TRUE; 381} 382 383/* ********************************************************************* 384 * board_device_init() 385 * 386 * Initialize and add other devices. Add everything you need 387 * for bootstrap here, like disk drives, flash memory, UARTs, 388 * network controllers, etc. 389 * 390 * Input parameters: 391 * nothing 392 * 393 * Return value: 394 * nothing 395 ********************************************************************* */ 396 397void board_device_init(void) 398{ 399 /* 400 * Print out the board version number. 401 */ 402 printf("%s board revision %d\n", CFG_BOARDNAME, swarm_board_rev + 1); 403 404 /* 405 * UART channel B 406 */ 407 408 cfe_add_device(&sb1250_uart,A_DUART,1,0); 409 410 /* 411 * Boot ROM, using "new" flash driver 412 */ 413 414 cfe_add_device(&newflashdrv, 415 BOOTROM_PHYS, 416 REAL_BOOTROM_SIZE | FLASH_FLG_BUS8 | FLASH_FLG_DEV16, 417 NULL); 418 cfe_add_device(&newflashdrv, 419 ALT_BOOTROM_PHYS, 420 REAL_BOOTROM_SIZE | FLASH_FLG_BUS8 | FLASH_FLG_DEV16, 421 NULL); 422 423#ifdef _FUNCSIM_ 424 /* 425 * As a hack, we instantiate another flash at 0x1100_0000 (the PCMCIA area) 426 * when running in the functional simulator. We can preload an image into 427 * that region for faster booting. (see build/broadcom/sim/runcfe) 428 */ 429 cfe_add_device(&newflashdrv,0x11000000,64*1024*1024,NULL); 430#endif 431 432 /* 433 * This is the 24LC128 on SMBus0. CFE doesn't use it for anything, 434 * but you can load data into it and then boot from it by changing a jumper. 435 */ 436 437 cfe_add_device(&smbus_24lc128,BIGEEPROM_SMBUS_CHAN,BIGEEPROM_SMBUS_DEV,0); 438 439 /* 440 * MACs - must init after environment, since the hw address is stored there 441 */ 442 443 cfe_add_device(&sb1250_ether,A_MAC_BASE_0,0,env_getenv("ETH0_HWADDR")); 444 cfe_add_device(&sb1250_ether,A_MAC_BASE_1,1,env_getenv("ETH1_HWADDR")); 445 446 /* 447 * IDE disks 448 */ 449 450 cfe_add_device(&idedrv,IDE_PHYS+(0x1F0<<5), 451 IDE_PROBE_MASTER_TYPE(IDE_DEVTYPE_DISK) | 452 IDE_PROBE_SLAVE_TYPE(IDE_DEVTYPE_NOPROBE), 453 NULL); 454 455 /* 456 * PCMCIA support 457 */ 458 459 cfe_add_device(&pcmciadrv,PCMCIA_PHYS,0,NULL); 460 461#if CFG_PCI 462 pci_add_devices(cfe_startflags & CFE_INIT_PCI); 463#endif 464 465 /* 466 * Clock - depends on the hardware version number, since the older 467 * boards have Xicor clocks and the newer boards have ST Micro parts. 468 */ 469 470 switch (swarm_board_rev) { 471 case SWARM_REV_1: 472 cfe_add_device(&smbus_x1241clock,X1240_SMBUS_CHAN,X1240_SMBUS_DEV,0); 473 break; 474 475 default: 476 case SWARM_REV_2: 477 case SWARM_REV_3: 478 if (board_probe_x1241(X1240_SMBUS_CHAN,X1240_SMBUS_DEV)) { 479 cfe_add_device(&smbus_x1241clock,X1240_SMBUS_CHAN,X1240_SMBUS_DEV,0); 480 } 481 else { 482 /* Add ST Micro clock driver here */ 483 cfe_add_device(&smbus_m41t81clock,M41T81_SMBUS_CHAN,M41T81_SMBUS_DEV,0); 484 } 485 } 486 487#if CFG_VGACONSOLE 488 /* 489 * VGA Console - try to init a VGA console, fall back to 490 * UART if not there. 491 */ 492 493 if (cfe_startflags & SWARM_VGA_CONSOLE) { 494 cfe_ledstr("vgai"); 495 vgainit_ok = vga_biosinit(); 496 if (vgainit_ok == 0) cfe_set_console("pcconsole0"); 497 else cfe_set_console("uart0"); 498 } 499#endif 500 501 502 /* 503 * Set variable that contains CPU speed, spit out config register 504 */ 505 506 printf("Config switch: %d\n", swarm_config_switch); 507 508 sb1250_show_cpu_type(); 509 510 /* 511 * Reset the MAC address for MAC 2, since it's hooked 512 * to the video codec. This prevents the OS from 513 * probing it. 514 */ 515 SBWRITECSR(A_MAC_REGISTER(2,R_MAC_ETHERNET_ADDR),0); 516 517 /* 518 * Some misc devices go here, mostly for playing. 519 */ 520 521#if CFG_TCP 522 cfe_add_device(&tcpconsole,0,0,0); 523#endif 524 525#if CFG_USB 526 usb_init(NULL); 527 cfe_add_device(&usb_disk,0,0,0); 528 cfe_add_device(&usb_uart,0,0,0); 529 cfe_add_device(&usb_ether,0,0,0); 530#endif 531} 532 533 534 535/* ********************************************************************* 536 * board_device_reset() 537 * 538 * Reset devices. This call is done when the firmware is restarted, 539 * as might happen when an operating system exits, just before the 540 * "reset" command is applied to the installed devices. You can 541 * do whatever board-specific things are here to keep the system 542 * stable, like stopping DMA sources, interrupts, etc. 543 * 544 * Input parameters: 545 * nothing 546 * 547 * Return value: 548 * nothing 549 ********************************************************************* */ 550 551void board_device_reset(void) 552{ 553 /* 554 * Reset the MAC address for MAC 2, since it's hooked 555 * to the video codec. This prevents the OS from 556 * probing it. 557 */ 558 SBWRITECSR(A_MAC_REGISTER(2,R_MAC_ETHERNET_ADDR),0); 559} 560 561 562/* ********************************************************************* 563 * board_setup_autoboot() 564 * 565 * Set up autoboot methods. This routine sets up the list of 566 * places to find a boot program. 567 * 568 * Input parameters: 569 * nothing 570 * 571 * Return value: 572 * nothing 573 ********************************************************************* */ 574static void board_setup_autoboot(void) 575{ 576 /* 577 * First try PCMCIA. Try to load an elf file called 'autoboot' 578 * from the root directory of the FAT filesystem on the PCMCIA card. 579 */ 580 581 cfe_add_autoboot(CFE_AUTOBOOT_DISK,0,"pcmcia0","elf","fat","autoboot"); 582 583 /* 584 * Uncomment to try IDE next. We leave this disabled for now due 585 * to the long timeout if you don't have an IDE disk connected. 586 */ 587 588 /* cfe_add_autoboot(CFE_AUTOBOOT_DISK,0,"ide0.0","raw","raw",NULL); */ 589 590 /* 591 * If you had partitioned your flash, you could boot from it like this: 592 */ 593 594 /* cfe_add_autoboot(CFE_AUTOBOOT_RAW,0,"flash0.os","elf","raw",NULL); */ 595 596 /* 597 * Now try running a script (file containing CFE commands) from 598 * the TFTP server. Your DHCP server must set option 130 599 * to contain the name of the script. Option 130 gets stored 600 * in "BOOT_SCRIPT" when a DHCP reply is received. 601 */ 602 603 cfe_add_autoboot(CFE_AUTOBOOT_NETWORK,LOADFLG_BATCH, 604 "eth0","raw","tftp","$BOOT_SERVER:$BOOT_SCRIPT"); 605 606 /* 607 * Finally, try loading whatever the DHCP server says is the boot 608 * program. Do this as an ELF file, and failing that, try a 609 * raw binary. 610 */ 611 612 cfe_add_autoboot(CFE_AUTOBOOT_NETWORK,0,"eth0","elf","tftp",NULL); 613 cfe_add_autoboot(CFE_AUTOBOOT_NETWORK,0,"eth0","raw","tftp",NULL); 614} 615 616 617/* ********************************************************************* 618 * board_final_init() 619 * 620 * Do any final initialization, such as adding commands to the 621 * user interface. 622 * 623 * If you don't want a user interface, put the startup code here. 624 * This routine is called just before CFE starts its user interface. 625 * 626 * Input parameters: 627 * nothing 628 * 629 * Return value: 630 * nothing 631 ********************************************************************* */ 632 633void board_final_init(void) 634{ 635#if CFG_UI 636 ui_init_cpu1cmds(); 637 ui_init_swarmcmds(); 638 ui_init_corecmds(); 639 ui_init_soccmds(); 640 ui_init_testcmds(); 641 ui_init_toyclockcmds(); 642 ui_init_tempsensorcmds(); 643 ui_init_memtestcmds(); 644 ui_init_resetcmds(); 645 ui_init_phycmds(); 646 ui_init_spdcmds(); 647#if CFG_USB 648 ui_init_usbcmds(); 649#endif 650 ui_init_disktestcmds(); 651 ui_init_ethertestcmds(); 652 ui_init_flashtestcmds(); 653#endif 654 655 board_setup_autoboot(); 656 657#if !CFG_UI 658 cfe_autoboot(NULL,0); 659#endif 660} 661 662 663