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