1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * Board device initialization File: bcm91480ht_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: Binh Vo 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 "cfe_smbus.h" 52#include "env_subr.h" 53 54#include "bcm1480_regs.h" 55#include "bcm1480_scd.h" 56#include "bcm1480_mc.h" 57#include "sb1250_genbus.h" 58#include "lib_physio.h" 59 60#include "bcm91480ht.h" 61 62#include "dev_newflash.h" 63 64//QQQ 65//#undef CFG_USB 66 67/* ********************************************************************* 68 * Devices we're importing 69 ********************************************************************* */ 70 71extern cfe_driver_t promice_uart; /* promice serial port */ 72extern cfe_driver_t sb1250_uart; /* SB1250 serial ports */ 73extern cfe_driver_t sb1250_ether; /* SB1250 MACs */ 74extern cfe_driver_t newflashdrv; /* AMD-style flash */ 75#if CFG_PCI 76extern void pci_add_devices(int init); 77#endif 78#if CFG_TCP 79extern cfe_driver_t tcpconsole; /* TCP/IP console */ 80#endif 81#if CFG_USB 82static void board_usb_init(void); 83extern int usb_init(uint32_t addr); 84extern cfe_driver_t usb_disk; 85extern cfe_driver_t usb_uart; /* USB serial ports */ 86extern cfe_driver_t usb_ether; /* USB ethernet */ 87extern int ui_init_usbcmds(void); 88#endif 89 90 91extern cfe_smbus_t sb1250_smbus; /* SiByte SMBus host */ 92 93extern cfe_driver_t smbus_24lc128; /* Microchip EEPROM */ 94extern cfe_driver_t smbus_m41t81clock; /* ST Micro clock */ 95extern cfe_driver_t smbus_switch; /* PCA9543A SMBus switch */ 96 97 98/* ********************************************************************* 99 * Commands we're importing 100 ********************************************************************* */ 101 102extern int ui_docommands(char *); 103 104extern void ui_init_cpu1cmds(void); 105extern void ui_init_bcm91480htcmds(void); 106extern int ui_init_soccmds(void); 107extern int ui_init_testcmds(void); 108extern int ui_init_toyclockcmds(void); 109extern int ui_init_tempsensorcmds(void); 110extern int ui_init_memtestcmds(void); 111extern int ui_init_resetcmds(void); 112extern int ui_init_phycmds(void); 113extern int ui_init_spdcmds(void); 114extern int ui_init_disktestcmds(void); 115extern int ui_init_ethertestcmds(void); 116extern int ui_init_flashtestcmds(void); 117#if CFG_LDT 118extern int ui_init_pmcmds(void); 119extern int ui_init_swtrccmds(void); 120extern int ui_init_ccncmds(void); 121#endif 122 123/* ********************************************************************* 124 * Some other stuff we use 125 ********************************************************************* */ 126 127extern void sb1250_show_cpu_type(void); 128 129/* ********************************************************************* 130 * Some board-specific parameters 131 ********************************************************************* */ 132 133/* 134 * Note! Configure the PROMICE for burst mode zero (one byte per 135 * access). 136 */ 137 138#define PROMICE_BASE (0x1FDFFC00) 139#define PROMICE_WORDSIZE 1 140 141#define REAL_BOOTROM_SIZE (2*1024*1024) /* region is 4MB, but rom is 2MB */ 142 143/* ********************************************************************* 144 * SysConfig switch settings and related parameters 145 ********************************************************************* */ 146 147static int board_config; 148static int board_rev; 149 150#define PROMICE_CONSOLE 0x00000001 151 152 153 154/* ********************************************************************* 155 * board_console_init() 156 * 157 * Add the console device and set it to be the primary 158 * console. 159 * 160 * Input parameters: 161 * nothing 162 * 163 * Return value: 164 * nothing 165 ********************************************************************* */ 166 167void board_console_init(void) 168{ 169 uint64_t sysrev; 170 uint64_t syscfg; 171 172 sysrev = SBREADCSR(A_SCD_SYSTEM_REVISION); 173 syscfg = SBREADCSR(A_SCD_SYSTEM_CFG); 174 175 /* Console */ 176 cfe_add_device(&sb1250_uart,A_BCM1480_DUART(0),0,0); 177 cfe_add_device(&promice_uart,PROMICE_BASE,PROMICE_WORDSIZE,0); 178 179 /* 180 * Read the config switch and decide how we are going to set up 181 * the console. 182 * 183 * Note that the human-readable board revision is the revision 184 * encoded by the revision bits + 1. 185 */ 186 board_config = board_get_config(); 187 board_rev = (board_config & BOARD_CFG_REV_MASK) + 1; 188 189 cfe_startflags = 0; 190 191 /* Set up CFE start flags based on config switch */ 192 193 switch (board_config & BOARD_CFG_CONS_MASK) { 194 case BOARD_CFG_CONS_UART0: 195 default: 196 break; 197 198 case BOARD_CFG_CONS_PROMICE: 199 cfe_startflags |= PROMICE_CONSOLE; 200 break; 201 } 202 203 /* XXX This is a kludge. 204 205 There are not enough config switch bits to deal with HT modes 206 and node configuration options. However, if the node ID is set 207 to non-zero, HT DMA becomes non-coherent and existing CFE 208 drivers will not work for devices behind the PLX bridge. 209 210 For now, if CFG_INIT_PCI is set, leave the node ID as zero 211 and auto-configure PCI. Otherwise, assign the node ID 212 according to CFG_NODE_ID and rely on an explicit node_enable 213 call to initialize PCI/HT. 214 215 Unfortunately, late initialization does not install the 216 drivers for a device attached to the otherwise usable 217 PCI-X interface. 218 */ 219 220 if ((board_config & BOARD_CFG_INIT_PCI) != 0) { 221 cfe_startflags |= CFE_INIT_PCI; 222 } 223 else { 224 unsigned int node_id = (board_config & BOARD_CFG_NODE_ID ? 5 : 4); 225 226 syscfg &= ~M_BCM1480_SYS_NODEID; 227 syscfg |= V_BCM1480_SYS_NODEID(node_id); 228 229 /* XXX workaround: write value to SCD before updating sys_cfg */ 230 SBWRITECSR(A_BCM1480_SCD_SCRATCH, syscfg); 231 232 SBWRITECSR(A_SCD_SYSTEM_CFG, syscfg); 233 } 234 235 /* Configure console */ 236 237 if (cfe_startflags & PROMICE_CONSOLE) { 238 cfe_set_console("promice0"); 239 } 240 else { 241 cfe_set_console("uart0"); 242 } 243 244 /* 245 * SMBus buses - need to be initialized before we attach 246 * devices that use them. 247 */ 248 249 cfe_add_smbus(&sb1250_smbus,A_SMB_BASE(0),0); 250 cfe_add_smbus(&sb1250_smbus,A_SMB_BASE(1),0); 251 252 /* 253 * NVRAM (environment variables) 254 */ 255 256 cfe_add_device(&smbus_24lc128,BIGEEPROM_SMBUS_CHAN_1,BIGEEPROM_SMBUS_DEV_1,0); 257 cfe_set_envdevice("eeprom0"); /* Connect NVRAM subsystem to EEPROM */ 258 259 cfe_add_device(&smbus_switch,SMBUS_SWITCH_CHAN_0,SMBUS_SWITCH_DEV_0,0); 260 261} 262 263 264/* ********************************************************************* 265 * board_device_init() 266 * 267 * Initialize and add other devices. Add everything you need 268 * for bootstrap here, like disk drives, flash memory, UARTs, 269 * network controllers, etc. 270 * 271 * Input parameters: 272 * nothing 273 * 274 * Return value: 275 * nothing 276 ********************************************************************* */ 277 278void board_device_init(void) 279{ 280 uint64_t syscfg; 281 uint64_t mcreg; 282 283 syscfg = SBREADCSR(A_SCD_SYSTEM_CFG); 284 285 /* 286 * Print out the board version number and config straps 287 */ 288 289 printf("%s board revision %d\n",CFG_BOARDNAME,board_rev); 290 printf("%s configuration switches: 0x%x\n",CFG_BOARDNAME,board_config); 291 292 /* Enable token ring timeouts. By default, references to 293 unimplemented south ring addresses will give no response and 294 thus hang the CPU. */ 295 phys_write64(A_BCM1480_NC_SR_TIMEOUT_COUNTER_SEL, 0x1); 296 297 /* Similarly for node controller timeouts. */ 298 phys_write64(A_BCM1480_NC_TIMEOUT_COUNTER_SEL, 0x1); 299 300 /* 301 * UART channel B on primary DUART 302 */ 303 304 cfe_add_device(&sb1250_uart,A_BCM1480_DUART(0),1,0); 305 306 /* 307 * UARTs on second DUART, if enabled 308 */ 309 310 if (syscfg & M_BCM1480_SYS_DUART1_ENABLE) { 311 cfe_add_device(&sb1250_uart,A_BCM1480_DUART(2),0,0); 312 cfe_add_device(&sb1250_uart,A_BCM1480_DUART(2),1,0); 313 } 314 315#ifndef _FUNCSIM_ 316 /* 317 * Boot ROM, using "new" flash driver 318 */ 319 320 cfe_add_device(&newflashdrv, 321 BOOTROM_PHYS, 322 REAL_BOOTROM_SIZE | FLASH_FLG_BUS8 | FLASH_FLG_DEV16, 323 NULL); 324 cfe_add_device(&newflashdrv, 325 ALT_BOOTROM_PHYS, 326 REAL_BOOTROM_SIZE | FLASH_FLG_BUS8 | FLASH_FLG_DEV16, 327 NULL); 328#endif /*_FUNCSIM_*/ 329 330 /* 331 * This is the 24LC128 on SMBus0. CFE doesn't use it for anything, 332 * but you can load data into it and then boot from it by changing a jumper. 333 */ 334 335 cfe_add_device(&smbus_24lc128,BIGEEPROM_SMBUS_CHAN,BIGEEPROM_SMBUS_DEV,0); 336 337 /* 338 * MACs - must init after environment, since the hw address is stored there 339 */ 340 341#if (!CFG_BOOTRAM && !CFG_L2_RAM) 342 cfe_add_device(&sb1250_ether,A_MAC_BASE_0,0,env_getenv("ETH0_HWADDR")); 343 cfe_add_device(&sb1250_ether,A_MAC_BASE_1,1,env_getenv("ETH1_HWADDR")); 344 cfe_add_device(&sb1250_ether,A_MAC_BASE_2,2,env_getenv("ETH2_HWADDR")); 345#endif 346 cfe_add_device(&sb1250_ether,A_MAC_BASE_3,3,env_getenv("ETH3_HWADDR")); 347 348 349#if CFG_PCI 350 pci_add_devices(cfe_startflags & CFE_INIT_PCI); 351#endif 352 353#if CFG_USB 354 board_usb_init(); 355 usb_init(NULL); /* Discover registers dynamically */ 356 cfe_add_device(&usb_disk,0,0,0); 357 cfe_add_device(&usb_uart,0,0,0); 358 cfe_add_device(&usb_ether,0,0,0); 359#endif 360 361 362 /* 363 * Real-time clock 364 */ 365 366 cfe_add_device(&smbus_m41t81clock,M41T81_SMBUS_CHAN,M41T81_SMBUS_DEV,0); 367 368 /* 369 * Display config register and CPU type 370 */ 371 372 sb1250_show_cpu_type(); 373 374 mcreg = SBREADCSR(A_BCM1480_MC_REGISTER(0,R_BCM1480_MC_CLOCK_CFG)); 375 if (G_BCM1480_MC_CLK_RATIO(mcreg)) { 376 printf("Memory controller #0: %dMHz\n", 377 (cfe_cpu_speed / 2000000) * 4 / ((int)G_BCM1480_MC_CLK_RATIO(mcreg))); 378 } 379 380 mcreg = SBREADCSR(A_BCM1480_MC_REGISTER(1,R_BCM1480_MC_CLOCK_CFG)); 381 if (G_BCM1480_MC_CLK_RATIO(mcreg)) { 382 printf("Memory controller #1: %dMHz\n", 383 (cfe_cpu_speed / 2000000) * 4 / ((int)G_BCM1480_MC_CLK_RATIO(mcreg))); 384 } 385 386 printf("Switch Clock: %dMHz\n", 387 (cfe_cpu_speed * 2 / 1000000) / ((int)G_BCM1480_SYS_SW_DIV(syscfg))); 388 389 if (G_BCM1480_SYS_NODEID(syscfg) != 0) { 390 printf("Node Id: %d\n", G_BCM1480_SYS_NODEID(syscfg)); 391 } 392 393 /* 394 * Some misc devices go here, mostly for playing. 395 */ 396 397#if CFG_TCP 398 cfe_add_device(&tcpconsole,0,0,0); 399#endif 400 401} 402 403 404 405 406/* ********************************************************************* 407 * board_device_reset() 408 * 409 * Reset devices. This call is done when the firmware is restarted, 410 * as might happen when an operating system exits, just before the 411 * "reset" command is applied to the installed devices. You can 412 * do whatever board-specific things are here to keep the system 413 * stable, like stopping DMA sources, interrupts, etc. 414 * 415 * Input parameters: 416 * nothing 417 * 418 * Return value: 419 * nothing 420 ********************************************************************* */ 421 422void board_device_reset(void) 423{ 424} 425 426 427/* ********************************************************************* 428 * board_final_init() 429 * 430 * Do any final initialization, such as adding commands to the 431 * user interface. 432 * 433 * If you don't want a user interface, put the startup code here. 434 * This routine is called just before CFE starts its user interface. 435 * 436 * Input parameters: 437 * nothing 438 * 439 * Return value: 440 * nothing 441 ********************************************************************* */ 442 443void board_final_init(void) 444{ 445 int flag; 446 447 ui_init_cpu1cmds(); 448 ui_init_bcm91480htcmds(); 449 ui_init_soccmds(); 450 ui_init_testcmds(); 451 ui_init_toyclockcmds(); 452 ui_init_tempsensorcmds(); 453 ui_init_memtestcmds(); 454 ui_init_resetcmds(); 455 ui_init_phycmds(); 456 ui_init_spdcmds(); 457 ui_init_disktestcmds(); 458 ui_init_ethertestcmds(); 459 ui_init_flashtestcmds(); 460#if CFG_LDT 461 ui_init_pmcmds(); 462 ui_init_swtrccmds(); 463 ui_init_ccncmds(); 464#endif 465 466#if CFG_USB 467 ui_init_usbcmds(); 468#endif 469 470 if ((board_config & BOARD_CFG_DO_STARTUP) != 0) { 471 /* Change STARTUP's flags so it can run or error message if not set */ 472 if (env_getenv("STARTUP") == NULL) { 473 printf("*** STARTUP environment variable not set.\n\n"); 474 } 475 else { 476 flag = env_envtype("STARTUP"); 477 flag &= ~ENV_FLG_STARTUP_NORUN; 478 env_setflags("STARTUP",flag); 479 } 480 } 481 else { 482 if (env_getenv("STARTUP") != NULL) { 483 /* Don't run the commands in STARTUP */ 484 flag = env_envtype("STARTUP"); 485 flag |= ENV_FLG_STARTUP_NORUN; 486 env_setflags("STARTUP",flag); 487 } 488 } 489} 490 491#if CFG_USB 492/* ********************************************************************* 493 * board_usb_init() 494 * 495 * Turn on the OHCI controller at the core. 496 * 497 * Input parameters: 498 * nothing 499 * 500 * Return value: 501 * nothing 502 ********************************************************************* */ 503static void board_usb_init(void) 504{ 505 506} 507#endif 508 509 510 511