allow coexistance of N build and AC build.
[tomato.git] / release / src-rt-6.x / cfe / cfe / arch / mips / board / bcm947xx / src / bcm947xx_devs.c
blob29d864d69d32048507ab83908511290c1e3b982c
1 /*
2 * Broadcom Common Firmware Environment (CFE)
3 * Board device initialization, File: bcm947xx_devs.c
5 * Copyright (C) 2011, Broadcom Corporation
6 * All Rights Reserved.
7 *
8 * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Broadcom Corporation;
9 * the contents of this file may not be disclosed to third parties, copied
10 * or duplicated in any form, in whole or in part, without the prior
11 * written permission of Broadcom Corporation.
13 * $Id: bcm947xx_devs.c 324903 2012-03-30 19:57:48Z $
16 #include "sbmips.h"
17 #include "lib_types.h"
18 #include "lib_printf.h"
19 #include "lib_physio.h"
20 #include "cfe.h"
21 #include "cfe_error.h"
22 #include "cfe_iocb.h"
23 #include "cfe_device.h"
24 #include "cfe_timer.h"
25 #include "ui_command.h"
26 #include "bsp_config.h"
27 #include "dev_newflash.h"
28 #include "env_subr.h"
29 #include "pcivar.h"
30 #include "pcireg.h"
31 #include "../../../../../dev/ns16550.h"
32 #include "net_ebuf.h"
33 #include "net_ether.h"
34 #include "net_api.h"
36 #include <typedefs.h>
37 #include <osl.h>
38 #include <bcmutils.h>
39 #include <hndsoc.h>
40 #include <siutils.h>
41 #include <sbchipc.h>
42 #include <hndpci.h>
43 #include "bsp_priv.h"
44 #include <trxhdr.h>
45 #include <bcmdevs.h>
46 #include <bcmnvram.h>
47 #include <hndcpu.h>
48 #include <hndchipc.h>
49 #include <hndpmu.h>
50 #include <epivers.h>
51 #if CFG_NFLASH
52 #include <nflash.h>
53 #endif
54 #include <cfe_devfuncs.h>
55 #include <cfe_ioctl.h>
57 #define MAX_WAIT_TIME 20 /* seconds to wait for boot image */
58 #define MIN_WAIT_TIME 3 /* seconds to wait for boot image */
60 #define RESET_DEBOUNCE_TIME (500*1000) /* 500 ms */
62 /* Defined as sih by bsp_config.h for convenience */
63 si_t *bcm947xx_sih = NULL;
65 /* Configured devices */
66 #if (CFG_FLASH || CFG_SFLASH || CFG_NFLASH) && CFG_XIP
67 #error "XIP and Flash cannot be defined at the same time"
68 #endif
70 extern cfe_driver_t ns16550_uart;
71 #if CFG_FLASH
72 extern cfe_driver_t newflashdrv;
73 #endif
74 #if CFG_SFLASH
75 extern cfe_driver_t sflashdrv;
76 #endif
77 #if CFG_NFLASH
78 extern cfe_driver_t nflashdrv;
79 #endif
80 #if CFG_ET
81 extern cfe_driver_t bcmet;
82 #endif
83 #if CFG_WL
84 extern cfe_driver_t bcmwl;
85 #endif
86 #if CFG_BCM57XX
87 extern cfe_driver_t bcm5700drv;
88 #endif
90 /* Reset NVRAM */
91 static int restore_defaults = 0;
92 extern char *flashdrv_nvram;
94 static void
95 board_console_add(void *regs, uint irq, uint baud_base, uint reg_shift)
97 physaddr_t base;
99 /* The CFE NS16550 driver expects a physical address */
100 base = PHYSADDR((physaddr_t) regs);
101 cfe_add_device(&ns16550_uart, base, baud_base, &reg_shift);
104 #if CFG_FLASH || CFG_SFLASH || CFG_NFLASH
105 #if !CFG_SIM
106 static void
107 reset_release_wait(void)
109 int gpio;
110 uint32 gpiomask;
112 if ((gpio = nvram_resetgpio_init ((void *)sih)) < 0)
113 return;
115 /* Reset button is active low */
116 gpiomask = (uint32)1 << gpio;
117 while (1) {
118 if (si_gpioin(sih) & gpiomask) {
119 OSL_DELAY(RESET_DEBOUNCE_TIME);
121 if (si_gpioin(sih) & gpiomask)
122 break;
126 #endif /* !CFG_SIM */
127 #endif /* CFG_FLASH || CFG_SFLASH || CFG_NFLASH */
130 * board_console_init()
132 * Add the console device and set it to be the primary
133 * console.
135 * Input parameters:
136 * nothing
138 * Return value:
139 * nothing
141 void
142 board_console_init(void)
144 #if !CFG_SIM
145 uint32 mipsclock = 0, siclock = 0, pciclock = 0;
146 char *nvstr;
147 uint origidx;
148 chipcregs_t *cc;
149 #endif
151 #if !CFG_MINIMAL_SIZE
152 cfe_set_console(CFE_BUFFER_CONSOLE);
153 #endif
155 /* Initialize SB access */
156 sih = si_kattach(SI_OSH);
157 ASSERT(sih);
159 #if !CFG_SIM
160 /* Check whether NVRAM reset needs be done */
161 if (nvram_reset((void *)sih) > 0)
162 restore_defaults = 1;
163 #endif
165 /* Initialize NVRAM access accordingly. In case of invalid NVRAM, load defaults */
166 //if (asus_nvram_init((void *)sih) > 0)
167 // restore_defaults = 1;
168 restore_defaults = 0;
170 #if CFG_SIM
171 restore_defaults = 0;
173 /* Figure out current MIPS clock speed */
174 if ((cfe_cpu_speed = si_cpu_clock(sih)) == 0)
175 cfe_cpu_speed = 133000000;
176 #else /* !CFG_SIM */
178 if (!restore_defaults) {
179 char *end;
181 /* MIPS clock speed override */
182 if ((nvstr = nvram_get("clkfreq"))) {
183 mipsclock = bcm_strtoul(nvstr, &end, 0) * 1000000;
184 if (*end == ',') {
185 nvstr = ++end;
186 siclock = bcm_strtoul(nvstr, &end, 0) * 1000000;
187 if (*end == ',') {
188 nvstr = ++end;
189 pciclock = bcm_strtoul(nvstr, &end, 0) * 1000000;
194 if (mipsclock) {
195 /* Set current MIPS clock speed */
196 si_mips_setclock(sih, mipsclock, siclock, pciclock);
200 /* Figure out current MIPS clock speed */
201 if ((cfe_cpu_speed = si_cpu_clock(sih)) == 0)
202 cfe_cpu_speed = 133000000;
204 /* Next sections all want to talk to chipcommon */
205 origidx = si_coreidx(sih);
206 cc = si_setcoreidx(sih, SI_CC_IDX);
208 nvstr = nvram_get("boardpwrctl");
210 if ((CHIPID(sih->chip) == BCM4716_CHIP_ID) ||
211 (CHIPID(sih->chip) == BCM4748_CHIP_ID) ||
212 (CHIPID(sih->chip) == BCM47162_CHIP_ID)) {
213 uint32 reg, new;
215 /* Adjust regulator settings */
216 W_REG(osh, &cc->regcontrol_addr, 2);
217 /* Readback to ensure completion of the write */
218 (void)R_REG(osh, &cc->regcontrol_addr);
219 reg = R_REG(osh, &cc->regcontrol_data);
220 /* Make the regulator frequency to 1.2MHz
221 * 00 1.2MHz
222 * 01 200kHz
223 * 10 600kHz
224 * 11 2.4MHz
226 reg &= ~0x00c00000;
227 /* Take 2.5v regulator output down one notch,
228 * officially to 2.45, but in reality to be
229 * closer to 2.5 than the default.
231 reg |= 0xf0000000;
233 /* Bits corresponding to mask 0x00078000
234 * controls 1.3v source
235 * Value Voltage
236 * ========================
237 * 0xf0000000 1.2 V (default)
238 * 0xf0008000 0.975
239 * 0xf0010000 1
240 * 0xf0018000 1.025
241 * 0xf0020000 1.05
242 * 0xf0028000 1.075
243 * 0xf0030000 1.1
244 * 0xf0038000 1.125
245 * 0xf0040000 1.15
246 * 0xf0048000 1.175
247 * 0xf0050000 1.225
248 * 0xf0058000 1.25
249 * 0xf0060000 1.275
250 * 0xf0068000 1.3
251 * 0xf0070000 1.325
252 * 0xf0078000 1.35
254 if (nvstr) {
255 uint32 pwrctl = bcm_strtoul(nvstr, NULL, 0);
257 reg &= ~0xf0c78000;
258 reg |= (pwrctl & 0xf0c78000);
260 W_REG(osh, &cc->regcontrol_data, reg);
262 /* Turn off unused PLLs */
263 W_REG(osh, &cc->pllcontrol_addr, 6);
264 (void)R_REG(osh, &cc->pllcontrol_addr);
265 new = reg = R_REG(osh, &cc->pllcontrol_data);
266 if (sih->chippkg == BCM4716_PKG_ID)
267 new |= 0x68; /* Channels 3, 5 & 6 off in 4716 */
268 if ((sih->chipst & 0x00000c00) == 0x00000400)
269 new |= 0x10; /* Channel 4 if MII mode */
270 if (new != reg) {
271 /* apply new value */
272 W_REG(osh, &cc->pllcontrol_data, new);
273 (void)R_REG(osh, &cc->pllcontrol_data);
274 W_REG(osh, &cc->pmucontrol,
275 PCTL_PLL_PLLCTL_UPD | PCTL_NOILP_ON_WAIT |
276 PCTL_HT_REQ_EN | PCTL_ALP_REQ_EN | PCTL_LPO_SEL);
280 if ((CHIPID(sih->chip) == BCM5356_CHIP_ID) ||
281 (CHIPID(sih->chip) == BCM5357_CHIP_ID) ||
282 (CHIPID(sih->chip) == BCM53572_CHIP_ID) ||
283 (CHIPID(sih->chip) == BCM4749_CHIP_ID)) {
284 uint32 reg;
286 /* Change regulator if requested */
287 if (nvstr) {
288 uint32 pwrctl = bcm_strtoul(nvstr, NULL, 0);
290 W_REG(osh, &cc->regcontrol_addr, 1);
291 /* Readback to ensure completion of the write */
292 (void)R_REG(osh, &cc->regcontrol_addr);
293 reg = R_REG(osh, &cc->regcontrol_data);
294 reg &= ~0x00018f00;
295 reg |= (pwrctl & 0x00018f00);
297 W_REG(osh, &cc->regcontrol_data, reg);
301 /* On AI chips, change sflash divisor if requested. */
302 if (sih->socitype == SOCI_AI) {
303 char *end;
304 uint32 fltype, clkdiv, bpclock, sflmaxclk, sfldiv;
306 fltype = sih->cccaps & CC_CAP_FLASH_MASK;
307 if ((fltype != SFLASH_ST) && (fltype != SFLASH_AT))
308 goto nosflch;
310 /* sdram_init is really a field in the nvram header */
311 nvstr = nvram_get("sdram_init");
312 sflmaxclk = bcm_strtoul(nvstr, &end, 0);
313 if ((sflmaxclk = 0xffff) || (sflmaxclk == 0x0419))
314 goto nosflch;
316 sflmaxclk &= 0xf;
317 if (sflmaxclk == 0)
318 goto nosflch;
320 bpclock = si_clock(sih);
321 sflmaxclk *= 10000000;
322 for (sfldiv = 2; sfldiv < 16; sfldiv += 2) {
323 if ((bpclock / sfldiv) < sflmaxclk)
324 break;
326 if (sfldiv > 14)
327 sfldiv = 14;
329 clkdiv = R_REG(osh, &cc->clkdiv);
330 if (((clkdiv & CLKD_SFLASH) >> CLKD_SFLASH_SHIFT) != sfldiv) {
331 clkdiv = (clkdiv & ~CLKD_SFLASH) | (sfldiv << CLKD_SFLASH_SHIFT);
332 W_REG(osh, &cc->clkdiv, clkdiv);
335 nosflch:
337 si_setcoreidx(sih, origidx);
338 #endif /* !CFG_SIM */
340 /* Initialize clocks and interrupts */
341 si_mips_init(sih, 0);
343 /* Initialize UARTs */
344 si_serial_init(sih, board_console_add);
346 if (cfe_finddev("uart0"))
347 cfe_set_console("uart0");
351 #if (CFG_FLASH || CFG_SFLASH)
352 static void
353 flash_memory_size_config(newflash_probe_t *fprobe)
355 chipcregs_t *cc = NULL;
356 uint size, reg_sz, val;
358 if ((cc = (chipcregs_t *)si_setcoreidx(sih, SI_CC_IDX)))
359 return;
361 size = fprobe->flash_size; /* flash total size */
363 if (size <= 4*1024*1024)
364 reg_sz = FLSTRCF4706_1ST_MADDR_SEG_4MB;
365 else if (size > 4*1024*1024 && size <= 8*1024*1024)
366 reg_sz = FLSTRCF4706_1ST_MADDR_SEG_8MB;
367 else if (size > 8*1024*1024 && size <= 16*1024*1024)
368 reg_sz = FLSTRCF4706_1ST_MADDR_SEG_16MB;
369 else if (size > 16*1024*1024 && size <= 32*1024*1024)
370 reg_sz = FLSTRCF4706_1ST_MADDR_SEG_32MB;
371 else if (size > 32*1024*1024 && size <= 64*1024*1024)
372 reg_sz = FLSTRCF4706_1ST_MADDR_SEG_64MB;
373 else if (size > 64*1024*1024 && size <= 128*1024*1024)
374 reg_sz = FLSTRCF4706_1ST_MADDR_SEG_128MB;
375 else
376 reg_sz = FLSTRCF4706_1ST_MADDR_SEG_256MB;
378 val = R_REG(NULL, &cc->eci.flashconf.flashstrconfig);
379 val &= ~FLSTRCF4706_1ST_MADDR_SEG_MASK;
380 val |= reg_sz;
382 W_REG(NULL, &cc->eci.flashconf.flashstrconfig, val);
384 #endif /* (CFG_FLASH || CFG_SFLASH) */
386 #if (CFG_FLASH || CFG_SFLASH || CFG_NFLASH)
387 #if (CFG_NFLASH || defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE))
388 static int
389 get_flash_size(char *device_name)
391 int fd;
392 flash_info_t flashinfo;
393 int res = -1;
395 fd = cfe_open(device_name);
396 if ((fd > 0) &&
397 (cfe_ioctl(fd, IOCTL_FLASH_GETINFO,
398 (unsigned char *) &flashinfo,
399 sizeof(flash_info_t), &res, 0) == 0)) {
400 return flashinfo.flash_size;
403 return -1;
405 #endif /* CFG_NFLASH */
407 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
408 static
409 int calculate_max_image_size(char *device_name,int reserved_space_begin,int reserved_space_end,int *need_commit)
411 int image_size = 0;
412 char *nvram_setting;
413 char buf[64];
415 *need_commit=0;
417 #ifdef DUAL_IMAGE
418 if (!nvram_get(IMAGE_BOOT))
419 #else
420 if (!nvram_get(BOOTPARTITION))
421 #endif
422 return 0;
424 nvram_setting = nvram_get(IMAGE_SIZE);
426 if (nvram_setting) {
427 image_size = atoi(nvram_setting)*1024;
428 #ifdef CFG_NFLASH
429 } else if (device_name[0] == 'n') {
430 /* use 8 meg for nand flash */
431 image_size = (NFL_BOOT_OS_SIZE - reserved_space_begin)/2;
432 image_size = image_size - image_size%(64*1024);
433 #endif
434 } else {
435 int flash_size;
437 flash_size = get_flash_size(device_name);
438 if (flash_size > 0) {
439 int available_size =
440 flash_size - (reserved_space_begin + reserved_space_end);
442 /* Calculate the 2nd offset with divide the
443 * availabe space by 2
444 * Make sure it is aligned to 64Kb to set
445 * the rootfs search algorithm
447 image_size = available_size/2;
448 image_size = image_size - image_size%(128*1024);
451 /* 1st image start from bootsz end */
452 sprintf(buf, "%d", reserved_space_begin);
453 if (!nvram_match(IMAGE_FIRST_OFFSET, buf)) {
454 printf("The 1st image start addr changed, set to %s[%x] (was %s)\n",
455 buf,reserved_space_begin,nvram_get(IMAGE_FIRST_OFFSET));
456 nvram_set(IMAGE_FIRST_OFFSET, buf);
457 *need_commit = 1;
459 sprintf(buf, "%d", reserved_space_begin + image_size);
460 if (!nvram_match(IMAGE_SECOND_OFFSET, buf)) {
461 printf("The 2nd image start addr changed, set to %s[%x] (was %s)\n",
462 buf,reserved_space_begin + image_size, nvram_get(IMAGE_SECOND_OFFSET));
463 nvram_set(IMAGE_SECOND_OFFSET, buf);
464 *need_commit = 1;
467 return image_size;
469 #endif /* FAILSAFE_UPGRADE|| DUAL_IMAGE */
471 #ifdef CFG_NFLASH
472 static void
473 flash_nflash_init(void)
475 newflash_probe_t fprobe;
476 chipcregs_t *cc = NULL;
477 cfe_driver_t *drv;
478 struct nflash *nfl_info;
479 int j;
480 char *val;
481 int bootflags = 0;
482 int max_image_size = 0;
483 #if defined(DUAL_IMAGE) || defined(FAILSAFE_UPGRADE)
484 int need_commit = 0;
485 #endif
487 memset(&fprobe, 0, sizeof(fprobe));
489 if (CHIPID(sih->chip) == BCM4706_CHIP_ID || sih->ccrev == 38) {
490 drv = &nflashdrv;
491 fprobe.flash_phys = (CHIPID(sih->chip) == BCM4706_CHIP_ID) ? 0 : SI_FLASH1;
492 cc = (chipcregs_t *)si_setcoreidx(sih, SI_CC_IDX);
493 fprobe.flash_cmdset = (int)cc;
494 } else {
495 printf("Can't find nandflash! ccrev = %d, chipst= %d \n", sih->ccrev, sih->chipst);
496 return;
499 nfl_info = nflash_init(sih, cc);
500 if (nfl_info == 0)
501 return;
503 /* check bootflags */
504 if ((val = nvram_get("bootflags")))
505 bootflags = atoi(val);
507 j = 0;
508 /* kernel in nand flash */
509 if ((bootflags & FLASH_KERNEL_NFLASH) == FLASH_KERNEL_NFLASH) {
510 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
511 max_image_size = calculate_max_image_size("nflash0",0,0,&need_commit);
512 #endif
513 /* Because CFE can only boot from the beginning of a partition */
514 fprobe.flash_parts[j].fp_size = sizeof(struct trx_header);
515 fprobe.flash_parts[j++].fp_name = "trx";
516 fprobe.flash_parts[j].fp_size = max_image_size ?
517 max_image_size - sizeof(struct trx_header) : 0;
518 fprobe.flash_parts[j++].fp_name = "os";
519 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
520 if (max_image_size) {
521 fprobe.flash_parts[j].fp_size = sizeof(struct trx_header);
522 fprobe.flash_parts[j++].fp_name = "trx2";
523 fprobe.flash_parts[j].fp_size = max_image_size;
524 fprobe.flash_parts[j++].fp_name = "os2";
526 #endif
527 fprobe.flash_nparts = j;
529 cfe_add_device(drv, 0, 0, &fprobe);
531 /* Because CFE can only boot from the beginning of a partition */
532 j = 0;
533 fprobe.flash_parts[j].fp_size = max_image_size ?
534 max_image_size : NFL_BOOT_OS_SIZE;
535 fprobe.flash_parts[j++].fp_name = "trx";
536 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
537 if (max_image_size) {
538 fprobe.flash_parts[j].fp_size = NFL_BOOT_OS_SIZE - max_image_size;
539 fprobe.flash_parts[j++].fp_name = "trx2";
541 #endif
544 fprobe.flash_parts[j].fp_size = 0;
545 fprobe.flash_parts[j++].fp_name = "brcmnand";
546 fprobe.flash_nparts = j;
548 cfe_add_device(drv, 0, 0, &fprobe);
550 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
551 if (need_commit) nvram_commit();
552 #endif
554 #endif /* CFG_NFLASH */
557 static void
558 flash_init(void)
560 newflash_probe_t fprobe;
561 chipcregs_t *cc = NULL;
562 uint32 fltype, bootsz, *bisz;
563 cfe_driver_t *drv;
564 int j = 0;
565 int max_image_size = 0;
566 #if defined(DUAL_IMAGE) || defined(FAILSAFE_UPGRADE)
567 char *val;
568 int bootflags = 0;
569 int need_commit = 0;
570 #endif
572 memset(&fprobe, 0, sizeof(fprobe));
574 if ((cc = (chipcregs_t *)si_setcoreidx(sih, SI_CC_IDX))) {
575 #ifdef CFG_NFLASH
576 if ((sih->ccrev == 38) && ((sih->chipst & (1 << 4)) != 0)) {
577 fltype = NFLASH;
578 fprobe.flash_phys = SI_FLASH1;
579 } else
580 #endif
582 fltype = R_REG(NULL, &cc->capabilities) & CC_CAP_FLASH_MASK;
583 fprobe.flash_phys = SI_FLASH2;
585 } else
586 return;
588 switch (fltype) {
589 #if CFG_FLASH
590 case PFLASH:
591 drv = &newflashdrv;
592 fprobe.flash_flags = FLASH_FLG_BUS16 | FLASH_FLG_DEV16;
593 if (!(R_REG(NULL, &cc->flash_config) & CC_CFG_DS))
594 fprobe.flash_flags = FLASH_FLG_BUS8 | FLASH_FLG_DEV16;
595 break;
596 #endif
597 #if CFG_SFLASH
598 case SFLASH_ST:
599 case SFLASH_AT:
600 ASSERT(cc);
601 drv = &sflashdrv;
602 /* Overload cmdset field */
603 fprobe.flash_cmdset = (int)cc;
604 break;
605 #endif
606 #if CFG_NFLASH
607 case NFLASH:
608 drv = &nflashdrv;
609 fprobe.flash_cmdset = (int)cc;
610 break;
611 #endif
612 default:
613 /* No flash or unsupported flash */
614 return;
617 /* Default is 256K boot partition */
618 bootsz = 256 * 1024;
620 /* Do we have a self-describing binary image? */
621 bisz = (uint32 *)PHYS_TO_K1(fprobe.flash_phys + BISZ_OFFSET);
622 if (bisz[BISZ_MAGIC_IDX] == BISZ_MAGIC) {
623 int isz = bisz[BISZ_DATAEND_IDX] - bisz[BISZ_TXTST_IDX];
625 if (isz > (1024 * 1024))
626 bootsz = 2048 * 1024;
627 else if (isz > (512 * 1024))
628 bootsz = 1024 * 1024;
629 else if (isz > (256 * 1024))
630 bootsz = 512 * 1024;
631 else if (isz <= (128 * 1024))
632 bootsz = 128 * 1024;
634 printf("Boot partition size = %d(0x%x)\n", bootsz, bootsz);
636 #if CFG_NFLASH
637 if (fltype == NFLASH) {
638 struct nflash *nfl_info;
639 int flash_size = 0;
641 nfl_info = nflash_init(sih, cc);
642 if (nfl_info) {
643 if (bootsz > nfl_info->blocksize) {
644 /* Prepare double space in case of bad blocks */
645 bootsz = (bootsz << 1);
646 } else {
647 /* CFE occupies at least one block */
648 bootsz = nfl_info->blocksize;
652 /* Because sometimes we want to program the entire device */
653 fprobe.flash_nparts = 0;
654 cfe_add_device(drv, 0, 0, &fprobe);
656 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
657 max_image_size = calculate_max_image_size("nflash0",NFL_BOOT_SIZE,0,&need_commit);
658 #endif
659 /* Because sometimes we want to program the entire device */
660 /* Because CFE can only boot from the beginning of a partition */
661 j = 0;
662 fprobe.flash_parts[j].fp_size = bootsz;
663 fprobe.flash_parts[j++].fp_name = "boot";
664 fprobe.flash_parts[j].fp_size = (NFL_BOOT_SIZE - bootsz);
665 fprobe.flash_parts[j++].fp_name = "nvram";
667 fprobe.flash_parts[j].fp_size = sizeof(struct trx_header);
668 fprobe.flash_parts[j++].fp_name = "trx";
669 fprobe.flash_parts[j].fp_size = max_image_size ?
670 max_image_size - sizeof(struct trx_header) : 0;
671 fprobe.flash_parts[j++].fp_name = "os";
672 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
673 if (max_image_size) {
674 fprobe.flash_parts[j].fp_size = sizeof(struct trx_header);
675 fprobe.flash_parts[j++].fp_name = "trx2";
676 fprobe.flash_parts[j].fp_size = max_image_size;
677 fprobe.flash_parts[j++].fp_name = "os2";
679 #endif
681 fprobe.flash_nparts = j;
682 cfe_add_device(drv, 0, 0, &fprobe);
684 /* Because CFE can only flash an entire partition */
685 j = 0;
686 fprobe.flash_parts[j].fp_size = bootsz;
687 fprobe.flash_parts[j++].fp_name = "boot";
688 fprobe.flash_parts[j].fp_size = (NFL_BOOT_SIZE - bootsz);
689 fprobe.flash_parts[j++].fp_name = "nvram";
690 fprobe.flash_parts[j].fp_size = max_image_size;
691 fprobe.flash_parts[j++].fp_name = "trx";
692 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
693 if (max_image_size) {
694 fprobe.flash_parts[j].fp_size = NFL_BOOT_OS_SIZE - NFL_BOOT_SIZE - max_image_size;
695 fprobe.flash_parts[j++].fp_name = "trx2";
697 #endif
698 flash_size = get_flash_size("nflash0") - NFL_BOOT_OS_SIZE;
699 if (flash_size > 0) {
700 fprobe.flash_parts[j].fp_size = flash_size;
701 fprobe.flash_parts[j++].fp_name = "brcmnand";
704 fprobe.flash_nparts = j;
705 cfe_add_device(drv, 0, 0, &fprobe);
707 /* Change nvram device name for NAND boot */
708 flashdrv_nvram = "nflash0.nvram";
709 } else
710 #endif /* CFG_NFLASH */
712 /* Because sometimes we want to program the entire device */
713 fprobe.flash_nparts = 0;
714 cfe_add_device(drv, 0, 0, &fprobe);
716 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
717 /* check bootflags */
718 if ((val = nvram_get("bootflags")))
719 bootflags = atoi(val);
721 /* If the kernel is not in nand flash, split up the sflash */
722 if ((bootflags & FLASH_KERNEL_NFLASH) != FLASH_KERNEL_NFLASH)
723 max_image_size = calculate_max_image_size("flash0",bootsz,NVRAM_SPACE,
724 &need_commit);
725 #endif
727 /* Because CFE can only boot from the beginning of a partition */
728 j = 0;
729 fprobe.flash_parts[j].fp_size = bootsz;
730 fprobe.flash_parts[j++].fp_name = "boot";
731 fprobe.flash_parts[j].fp_size = sizeof(struct trx_header);
732 fprobe.flash_parts[j++].fp_name = "trx";
733 fprobe.flash_parts[j].fp_size = max_image_size ?
734 max_image_size - sizeof(struct trx_header) : 0;
735 fprobe.flash_parts[j++].fp_name = "os";
736 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
737 if (max_image_size) {
738 fprobe.flash_parts[j].fp_size = sizeof(struct trx_header);
739 fprobe.flash_parts[j++].fp_name = "trx2";
740 fprobe.flash_parts[j].fp_size = 0;
741 fprobe.flash_parts[j++].fp_name = "os2";
743 #endif
744 fprobe.flash_parts[j].fp_size = NVRAM_SPACE;
745 fprobe.flash_parts[j++].fp_name = "nvram";
746 fprobe.flash_nparts = j;
747 cfe_add_device(drv, 0, 0, &fprobe);
749 /* Because CFE can only flash an entire partition */
750 j = 0;
751 fprobe.flash_parts[j].fp_size = bootsz;
752 fprobe.flash_parts[j++].fp_name = "boot";
753 fprobe.flash_parts[j].fp_size = max_image_size;
754 fprobe.flash_parts[j++].fp_name = "trx";
755 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
756 if (max_image_size) {
757 fprobe.flash_parts[j].fp_size = 0;
758 fprobe.flash_parts[j++].fp_name = "trx2";
760 #endif
761 fprobe.flash_parts[j].fp_size = NVRAM_SPACE;
762 fprobe.flash_parts[j++].fp_name = "nvram";
763 fprobe.flash_nparts = j;
764 cfe_add_device(drv, 0, 0, &fprobe);
767 #if (CFG_FLASH || CFG_SFLASH)
768 if (CHIPID(sih->chip) == BCM4706_CHIP_ID)
769 flash_memory_size_config(&fprobe);
770 #endif /* (CFG_FLASH || CFG_SFLASH) */
772 #ifdef CFG_NFLASH
773 /* If boot from sflash and nand flash present */
774 if ((fltype != NFLASH) && ((CHIPID(sih->chip) == BCM4706_CHIP_ID) || sih->ccrev == 38) &&
775 (sih->cccaps & CC_CAP_NFLASH)) {
776 flash_nflash_init();
778 #endif /* CFG_NFLASH */
780 #if defined(FAILSAFE_UPGRADE) || defined(DUAL_IMAGE)
781 if (need_commit) nvram_commit();
782 #endif
784 #endif /* CFG_FLASH || CFG_SFLASH || CFG_NFLASH */
787 * board_device_init()
789 * Initialize and add other devices. Add everything you need
790 * for bootstrap here, like disk drives, flash memory, UARTs,
791 * network controllers, etc.
793 * Input parameters:
794 * nothing
796 * Return value:
797 * nothing
799 void
800 board_device_init(void)
802 unsigned int unit;
804 #if CFG_ET || CFG_WL || CFG_BCM57XX
805 void *regs;
806 #endif
808 /* Set by board_console_init() */
809 ASSERT(sih);
812 #if CFG_FLASH || CFG_SFLASH || CFG_NFLASH
813 flash_init();
814 #endif
816 for (unit = 0; unit < SI_MAXCORES; unit++) {
817 #if CFG_ET
818 if ((regs = si_setcore(sih, ENET_CORE_ID, unit)))
819 cfe_add_device(&bcmet, BCM47XX_ENET_ID, unit, regs);
821 #if CFG_GMAC
822 if ((regs = si_setcore(sih, GMAC_CORE_ID, unit)))
823 cfe_add_device(&bcmet, BCM47XX_GMAC_ID, unit, regs);
824 #endif
825 #endif /* CFG_ET */
826 #if CFG_WL
827 if ((regs = si_setcore(sih, D11_CORE_ID, unit)))
828 cfe_add_device(&bcmwl, BCM4306_D11G_ID, unit, regs);
829 #endif
830 #if CFG_BCM57XX
831 if ((regs = si_setcore(sih, GIGETH_CORE_ID, unit)))
832 cfe_add_device(&bcm5700drv, BCM47XX_GIGETH_ID, unit, regs);
833 #endif
838 * board_device_reset()
840 * Reset devices. This call is done when the firmware is restarted,
841 * as might happen when an operating system exits, just before the
842 * "reset" command is applied to the installed devices. You can
843 * do whatever board-specific things are here to keep the system
844 * stable, like stopping DMA sources, interrupts, etc.
846 * Input parameters:
847 * nothing
849 * Return value:
850 * nothing
852 void
853 board_device_reset(void)
858 * board_final_init()
860 * Do any final initialization, such as adding commands to the
861 * user interface.
863 * If you don't want a user interface, put the startup code here.
864 * This routine is called just before CFE starts its user interface.
866 * Input parameters:
867 * nothing
869 * Return value:
870 * nothing
872 void
873 board_final_init(void)
875 char *addr, *mask, *wait_time;
876 char buf[512], *cur = buf;
877 #if !CFG_SIM
878 char *boot_cfg = NULL;
879 char *go_cmd = "go;";
880 #endif
881 int commit = 0;
882 uint32 ncdl;
883 #if CFG_WL && CFG_WLU && CFG_SIM
884 char *ssid;
885 #endif
887 ui_init_bcm947xxcmds();
889 /* Force commit of embedded NVRAM */
890 //commit = restore_defaults;
891 commit = 0;
893 /* Set the SDRAM NCDL value into NVRAM if not already done */
894 if ((getintvar(NULL, "sdram_ncdl") == 0) &&
895 ((ncdl = si_memc_get_ncdl(sih)) != 0)) {
896 sprintf(buf, "0x%x", ncdl);
897 nvram_set("sdram_ncdl", buf);
898 commit = 1;
901 /* Set the bootloader version string if not already done */
902 sprintf(buf, "CFE %s", EPI_VERSION_STR);
903 if (strcmp(nvram_safe_get("pmon_ver"), buf) != 0) {
904 nvram_set("pmon_ver", buf);
905 commit = 1;
908 #if CFG_FLASH || CFG_SFLASH || CFG_NFLASH
909 #if !CFG_SIM
910 /* Commit NVRAM */
911 if (commit) {
912 printf("Committing NVRAM...");
913 nvram_commit();
914 printf("done\n");
915 if (restore_defaults) {
916 printf("Waiting for reset button release...");
917 reset_release_wait();
918 printf("done\n");
921 #endif
923 #if !CFG_SIM
924 /* Reboot after restoring defaults */
925 if (restore_defaults)
926 si_watchdog(sih, 1);
927 #endif /* !CFG_SIM */
928 #else
929 if (commit)
930 printf("Flash not configured, not commiting NVRAM...\n");
931 #endif /* CFG_FLASH || CFG_SFLASH || CFG_NFLASH */
934 * Read the wait_time NVRAM variable and set the tftp max retries.
935 * Assumption: tftp_rrq_timeout & tftp_recv_timeout are set to 1sec.
937 if ((wait_time = nvram_get("wait_time")) != NULL) {
938 tftp_max_retries = atoi(wait_time);
939 if (tftp_max_retries > MAX_WAIT_TIME)
940 tftp_max_retries = MAX_WAIT_TIME;
941 else if (tftp_max_retries < MIN_WAIT_TIME)
942 tftp_max_retries = MIN_WAIT_TIME;
945 /* Configure network */
946 if (cfe_finddev("eth0")) {
947 if ((addr = nvram_get("lan_ipaddr")) &&
948 (mask = nvram_get("lan_netmask")))
949 sprintf(buf, "ifconfig eth0 -addr=%s -mask=%s",
950 addr, mask);
951 else
952 sprintf(buf, "ifconfig eth0 -auto");
954 ui_docommand(buf);
956 #if CFG_WL && CFG_WLU && CFG_SIM
957 if ((ssid = nvram_get("wl0_ssid"))) {
958 sprintf(buf, "wl join %s", ssid);
959 ui_docommand(buf);
961 #endif
963 #if !CFG_SIM
964 /* Try to run boot_config command if configured.
965 * make sure to leave space for "go" command.
967 if ((boot_cfg = nvram_get("boot_config"))) {
968 if (strlen(boot_cfg) < (sizeof(buf) - sizeof(go_cmd)))
969 cur += sprintf(cur, "%s;", boot_cfg);
970 else
971 printf("boot_config too long, skipping to autoboot\n");
974 /* Boot image */
975 cur += sprintf(cur, go_cmd);
976 #endif /* !CFG_SIM */
978 /* Startup */
979 if (cur > buf)
980 env_setenv("STARTUP", buf, ENV_FLG_NORMAL);