1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * Board device initialization File: bcm91120c_devs.c
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.
10 * Author: Mitch Lichtenberg (mpl@broadcom.com)
12 *********************************************************************
14 * Copyright 2000,2001,2002,2003
15 * Broadcom Corporation. All rights reserved.
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.
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.
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.
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 ********************************************************************* */
52 #include "lib_types.h"
53 #include "lib_queue.h"
54 #include "lib_printf.h"
55 #include "lib_string.h"
57 #include "cfe_device.h"
58 #include "cfe_timer.h"
62 #include "sb1250_defs.h"
63 #include "sb1250_regs.h"
64 #include "sb1250_pci.h"
65 #include "sb1250_ldt.h"
66 #include "sb1250_scd.h"
67 #include "sb1250_smbus.h"
69 #include "bsp_config.h"
71 #include "bcm91120c.h"
73 #include "dev_newflash.h"
75 /* *********************************************************************
76 * Devices we're importing
77 ********************************************************************* */
79 extern cfe_driver_t promice_uart
; /* promice serial port */
80 extern cfe_driver_t sb1250_uart
; /* SB1250 serial ports */
81 extern cfe_driver_t sb1250_ether
; /* SB1250 MACs */
82 extern cfe_driver_t sb1250_x1240eeprom
; /* Xicor SMBus NVRAM */
83 extern cfe_driver_t sb1250_24lc128eeprom
; /* Microchip EEPROM */
85 extern cfe_driver_t newflashdrv
; /* AMD-style flash */
87 extern cfe_driver_t x1241_clock
; /* Xicor SMBus RTC */
88 extern cfe_driver_t m41t81_clock
; /* M41T81 SMBus RTC */
89 extern int ui_init_bcm91120ccmds(void);
90 extern int ui_init_corecmds(void);
91 extern int ui_init_soccmds(void);
92 extern int ui_init_testcmds(void);
93 extern int ui_init_tempsensorcmds(void);
94 extern int ui_init_toyclockcmds(void);
95 extern int ui_init_memtestcmds(void);
96 extern int ui_init_resetcmds(void);
98 /* *********************************************************************
100 ********************************************************************* */
102 extern void sb1250_show_cpu_type(void);
104 /* *********************************************************************
105 * Some board-specific parameters
106 ********************************************************************* */
109 * Note! Configure the PROMICE for burst mode zero (one byte per
113 #define PROMICE_BASE (0x1FDFFC00)
114 #define PROMICE_WORDSIZE 1
116 /* *********************************************************************
117 * SysConfig switch settings and related parameters
118 ********************************************************************* */
123 #define UART_CONSOLE 0x00000000 /* Pseudo flag */
124 #define PROMICE_CONSOLE 0x00000001
126 const unsigned int board_startflags
[16] = {
127 /* 0 */ UART_CONSOLE
,
128 /* 1 */ PROMICE_CONSOLE
,
141 /* 14 */ PROMICE_CONSOLE
| CFE_INIT_SAFE
,
142 /* 15 */ UART_CONSOLE
| CFE_INIT_SAFE
,
146 /* *********************************************************************
147 * board_console_init()
149 * Add the console device and set it to be the primary
157 ********************************************************************* */
159 void board_console_init(void)
164 syscfg
= SBREADCSR(A_SCD_SYSTEM_CFG
);
167 * Read the config switch and decide how we are going to set up
168 * the console. This is actually board revision dependent.
170 board_rev
= G_SYS_CONFIG(syscfg
) & 0x3;
171 config_switch
= (G_SYS_CONFIG(syscfg
) >> 2) & 0x0f;
172 cfe_startflags
= board_startflags
[config_switch
];
173 #if defined(_BCM91120C_DIAG_CFG_)
174 cfe_startflags
= PROMICE_CONSOLE
;
177 /* Initialize console */
178 cfe_add_device(&sb1250_uart
,A_DUART
,0,0);
179 cfe_add_device(&promice_uart
,PROMICE_BASE
,PROMICE_WORDSIZE
,0);
181 if (cfe_startflags
& PROMICE_CONSOLE
) {
182 cfe_set_console("promice0");
185 cfe_set_console("uart0");
189 * Set variable that contains CPU speed, spit out config register
192 plldiv
= G_SYS_PLL_DIV(syscfg
);
198 cfe_cpu_speed
= 500000; /* wire func sim at 500KHz */
200 cfe_cpu_speed
= 50000000 * plldiv
; /* use PLL divisor */
204 * Many boards set up the environment here. We don't need
205 * to for the CRhine because the only thing that needs the env
206 * between here and board_device_init is the PCI config code.
212 /* *********************************************************************
213 * board_smbus_waitready(chan)
215 * Wait until the SMBus channel is ready. We simply poll
216 * the busy bit until it clears.
219 * chan - channel (0 or 1)
223 ********************************************************************* */
224 static int board_smbus_waitready(int chan
)
229 reg
= PHYS_TO_K1(A_SMB_REGISTER(chan
,R_SMB_STATUS
));
232 status
= SBREADCSR(reg
);
233 if (status
& M_SMB_BUSY
) continue;
237 if (status
& M_SMB_ERROR
) {
239 SBWRITECSR(reg
,(status
& M_SMB_ERROR
));
245 /* *********************************************************************
246 * board_probe_x1241(chan,dev)
248 * Probe for a Xicor X1241 at the specified device and channel.
250 * Actually, we just probe for anything at this address, and
251 * assume it's a Xicor.
254 * chan - SMBus channel
258 * TRUE - X1241 is present
259 * FALSE - not present
260 ********************************************************************* */
262 static int board_probe_x1241(int chan
,int slaveaddr
)
269 * Initialize the SMBus channel
272 reg
= PHYS_TO_K1(A_SMB_REGISTER(chan
,R_SMB_FREQ
));
274 SBWRITECSR(reg
,K_SMB_FREQ_400KHZ
);
276 reg
= PHYS_TO_K1(A_SMB_REGISTER(chan
,R_SMB_CONTROL
));
278 SBWRITECSR(reg
,0); /* not in direct mode, no interrupts, will poll */
281 * Make sure the bus is idle (probably should
285 if (board_smbus_waitready(chan
) < 0) return FALSE
;
288 * Write the device address to the controller. There are two
289 * parts, the high part goes in the "CMD" field, and the
290 * low part is the data field.
293 reg
= PHYS_TO_K1(A_SMB_REGISTER(chan
,R_SMB_CMD
));
294 SBWRITECSR(reg
,((devaddr
>> 8) & 0x7));
297 * Write the data to the controller
300 reg
= PHYS_TO_K1(A_SMB_REGISTER(chan
,R_SMB_DATA
));
301 SBWRITECSR(reg
,((devaddr
& 0xFF) & 0xFF));
307 reg
= PHYS_TO_K1(A_SMB_REGISTER(chan
,R_SMB_START
));
308 SBWRITECSR(reg
,V_SMB_TT(K_SMB_TT_WR2BYTE
) | slaveaddr
);
314 err
= board_smbus_waitready(chan
);
315 if (err
< 0) return FALSE
;
319 /* *********************************************************************
320 * board_device_init()
322 * Initialize and add other devices. Add everything you need
323 * for bootstrap here, like disk drives, flash memory, UARTs,
324 * network controllers, etc.
331 ********************************************************************* */
333 void board_device_init(void)
336 newflash_probe_t fprobe
;
339 * Print out the board version number.
341 printf("%s board revision ", CFG_BOARDNAME
);
344 printf("A (with 512MB DRAM)");
347 printf("A (with 256MB DRAM)");
350 printf("- UNKNOWN (%d)", board_rev
);
359 cfe_add_device(&sb1250_uart
,A_DUART
,1,0);
364 cfe_add_device(&newflashdrv
,
366 (BOOTROM_SIZE
*K64
) | FLASH_FLG_BUS8
| FLASH_FLG_DEV16
,
368 cfe_add_device(&newflashdrv
,
370 (ALT_BOOTROM_SIZE
*K64
) | FLASH_FLG_BUS8
| FLASH_FLG_DEV16
,
374 * Big Flash - partitioned into four 4MB chunks.
377 memset(&fprobe
,0,sizeof(fprobe
));
378 fprobe
.flash_phys
= BIG_FLASH_PHYS
;
379 fprobe
.flash_size
= BIG_FLASH_SIZE
*K64
;
380 fprobe
.flash_flags
= FLASH_FLG_BUS8
| FLASH_FLG_DEV16
;
381 fprobe
.flash_nparts
= 4;
382 fprobe
.flash_parts
[0].fp_size
= 4*1024*1024;
383 fprobe
.flash_parts
[0].fp_name
= NULL
;
384 fprobe
.flash_parts
[1].fp_size
= 4*1024*1024;
385 fprobe
.flash_parts
[1].fp_name
= NULL
;
386 fprobe
.flash_parts
[2].fp_size
= 4*1024*1024;
387 fprobe
.flash_parts
[2].fp_name
= NULL
;
388 fprobe
.flash_parts
[3].fp_size
= 4*1024*1024;
389 fprobe
.flash_parts
[3].fp_name
= NULL
;
391 cfe_add_device(&newflashdrv
,0,0,&fprobe
);
394 * EEPROMs, NVRAMs (environment variables), and TOY clock
395 * Probe for the X1241 - if not present, assume we have a STMicro clock.
398 if (board_probe_x1241(X1240_SMBUS_CHAN
,X1240_SMBUS_DEV
)) {
399 cfe_add_device(&sb1250_x1240eeprom
,X1240_SMBUS_CHAN
,X1240_SMBUS_DEV
,0);
400 cfe_add_device(&sb1250_24lc128eeprom
,BIGEEPROM0_SMBUS_CHAN
,BIGEEPROM0_SMBUS_DEV
,0);
401 cfe_add_device(&sb1250_24lc128eeprom
,BIGEEPROM1_SMBUS_CHAN
,BIGEEPROM1_SMBUS_DEV
,0);
402 cfe_set_envdevice("eeprom0"); /* Connect NVRAM subsystem to X1240 */
403 cfe_add_device(&x1241_clock
,X1240_SMBUS_CHAN
,X1240_SMBUS_DEV
,0);
406 cfe_add_device(&sb1250_24lc128eeprom
,BIGEEPROM0_SMBUS_CHAN
,BIGEEPROM0_SMBUS_DEV
,0);
407 cfe_add_device(&sb1250_24lc128eeprom
,BIGEEPROM1_SMBUS_CHAN
,BIGEEPROM1_SMBUS_DEV
,0);
408 cfe_set_envdevice("eeprom1"); /* Connect NVRAM to 2nd 24lc128 */
409 cfe_add_device(&m41t81_clock
,M41T81_SMBUS_CHAN
,M41T81_SMBUS_DEV
,0);
414 * MACs - must init after environment, since the hw address is stored there
416 cfe_add_device(&sb1250_ether
,A_MAC_BASE_0
,0,env_getenv("ETH0_HWADDR"));
417 cfe_add_device(&sb1250_ether
,A_MAC_BASE_1
,1,env_getenv("ETH1_HWADDR"));
420 * Set variable that contains CPU speed, spit out config register
423 syscfg
= SBREADCSR(A_SCD_SYSTEM_CFG
);
424 printf("SysCfg: %016llX [PLL_DIV: %d, IOB0_DIV: %s, IOB1_DIV: %s]\n",
426 (int)G_SYS_PLL_DIV(syscfg
),
427 (syscfg
& M_SYS_IOB0_DIV
) ? "CPUCLK/3" : "CPUCLK/4",
428 (syscfg
& M_SYS_IOB1_DIV
) ? "CPUCLK/2" : "CPUCLK/3");
429 printf("Config switch: %d\n", config_switch
);
430 if (G_SYS_PLL_DIV(syscfg
) == 0) {
431 printf("PLL_DIV of zero found, assuming 6 (300MHz)\n");
434 sb1250_show_cpu_type();
439 /* *********************************************************************
440 * board_device_reset()
442 * Reset devices. This call is done when the firmware is restarted,
443 * as might happen when an operating system exits, just before the
444 * "reset" command is applied to the installed devices. You can
445 * do whatever board-specific things are here to keep the system
446 * stable, like stopping DMA sources, interrupts, etc.
453 ********************************************************************* */
455 void board_device_reset(void)
462 /* *********************************************************************
465 * Do any final initialization, such as adding commands to the
468 * If you don't want a user interface, put the startup code here.
469 * This routine is called just before CFE starts its user interface.
476 ********************************************************************* */
478 void board_final_init(void)
480 ui_init_bcm91120ccmds();
484 ui_init_toyclockcmds();
485 ui_init_tempsensorcmds();
486 ui_init_memtestcmds();