|  | /* | 
|  | * (C) Copyright 2001 | 
|  | * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com. | 
|  | * | 
|  | * See file CREDITS for list of people who contributed to this | 
|  | * project. | 
|  | * | 
|  | * This program is free software; you can redistribute it and/or | 
|  | * modify it under the terms of the GNU General Public License as | 
|  | * published by the Free Software Foundation; either version 2 of | 
|  | * the License, or (at your option) any later version. | 
|  | * | 
|  | * This program is distributed in the hope that it will be useful, | 
|  | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|  | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|  | * GNU General Public License for more details. | 
|  | * | 
|  | * You should have received a copy of the GNU General Public License | 
|  | * along with this program; if not, write to the Free Software | 
|  | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, | 
|  | * MA 02111-1307 USA | 
|  | */ | 
|  |  | 
|  | #include <common.h> | 
|  | #include <command.h> | 
|  | #include "w7o.h" | 
|  | #include <asm/processor.h> | 
|  |  | 
|  | #include "vpd.h" | 
|  | #include "errors.h" | 
|  | #include <watchdog.h> | 
|  |  | 
|  | unsigned long get_dram_size (void); | 
|  | void sdram_init(void); | 
|  |  | 
|  | /* | 
|  | * Macros to transform values | 
|  | * into environment strings. | 
|  | */ | 
|  | #define XMK_STR(x)	#x | 
|  | #define MK_STR(x)	XMK_STR(x) | 
|  |  | 
|  | /* ------------------------------------------------------------------------- */ | 
|  |  | 
|  | int board_early_init_f (void) | 
|  | { | 
|  | #if defined(CONFIG_W7OLMG) | 
|  | /* | 
|  | * Setup GPIO pins - reset devices. | 
|  | */ | 
|  | out32 (PPC405GP_GPIO0_ODR, 0x10000000);	/* one open drain pin */ | 
|  | out32 (PPC405GP_GPIO0_OR, 0x3E000000);	/* set output pins to default */ | 
|  | out32 (PPC405GP_GPIO0_TCR, 0x7f800000);	/* setup for output */ | 
|  |  | 
|  | /* | 
|  | * IRQ 0-15  405GP internally generated; active high; level sensitive | 
|  | * IRQ 16    405GP internally generated; active low; level sensitive | 
|  | * IRQ 17-24 RESERVED | 
|  | * IRQ 25 (EXT IRQ 0) XILINX; active low; level sensitive | 
|  | * IRQ 26 (EXT IRQ 1) PCI INT A; active low; level sensitive | 
|  | * IRQ 27 (EXT IRQ 2) PCI INT B; active low; level sensitive | 
|  | * IRQ 28 (EXT IRQ 3) SAM 2; active low; level sensitive | 
|  | * IRQ 29 (EXT IRQ 4) Battery Bad; active low; level sensitive | 
|  | * IRQ 30 (EXT IRQ 5) Level One PHY; active low; level sensitive | 
|  | * IRQ 31 (EXT IRQ 6) SAM 1; active high; level sensitive | 
|  | */ | 
|  | mtdcr (uicsr, 0xFFFFFFFF);	/* clear all ints */ | 
|  | mtdcr (uicer, 0x00000000);	/* disable all ints */ | 
|  |  | 
|  | mtdcr (uiccr, 0x00000000);	/* set all to be non-critical */ | 
|  | mtdcr (uicpr, 0xFFFFFF80);	/* set int polarities */ | 
|  | mtdcr (uictr, 0x10000000);	/* set int trigger levels */ | 
|  | mtdcr (uicvcr, 0x00000001);	/* set vect base=0, | 
|  | INT0 highest priority */ | 
|  |  | 
|  | mtdcr (uicsr, 0xFFFFFFFF);	/* clear all ints */ | 
|  |  | 
|  | #elif defined(CONFIG_W7OLMC) | 
|  | /* | 
|  | * Setup GPIO pins | 
|  | */ | 
|  | out32 (PPC405GP_GPIO0_ODR, 0x01800000);	/* XCV Done Open Drain */ | 
|  | out32 (PPC405GP_GPIO0_OR, 0x03800000);	/* set out pins to default */ | 
|  | out32 (PPC405GP_GPIO0_TCR, 0x66C00000);	/* setup for output */ | 
|  |  | 
|  | /* | 
|  | * IRQ 0-15  405GP internally generated; active high; level sensitive | 
|  | * IRQ 16    405GP internally generated; active low; level sensitive | 
|  | * IRQ 17-24 RESERVED | 
|  | * IRQ 25 (EXT IRQ 0) DBE 0; active low; level sensitive | 
|  | * IRQ 26 (EXT IRQ 1) DBE 1; active low; level sensitive | 
|  | * IRQ 27 (EXT IRQ 2) DBE 2; active low; level sensitive | 
|  | * IRQ 28 (EXT IRQ 3) DBE Common; active low; level sensitive | 
|  | * IRQ 29 (EXT IRQ 4) PCI; active low; level sensitive | 
|  | * IRQ 30 (EXT IRQ 5) RCMM Reset; active low; level sensitive | 
|  | * IRQ 31 (EXT IRQ 6) PHY; active high; level sensitive | 
|  | */ | 
|  | mtdcr (uicsr, 0xFFFFFFFF);	/* clear all ints */ | 
|  | mtdcr (uicer, 0x00000000);	/* disable all ints */ | 
|  |  | 
|  | mtdcr (uiccr, 0x00000000);	/* set all to be non-critical */ | 
|  | mtdcr (uicpr, 0xFFFFFF80);	/* set int polarities */ | 
|  | mtdcr (uictr, 0x10000000);	/* set int trigger levels */ | 
|  | mtdcr (uicvcr, 0x00000001);	/* set vect base=0, | 
|  | INT0 highest priority */ | 
|  |  | 
|  | mtdcr (uicsr, 0xFFFFFFFF);	/* clear all ints */ | 
|  |  | 
|  | #else  /* Unknown */ | 
|  | #    error "Unknown W7O board configuration" | 
|  | #endif | 
|  |  | 
|  | WATCHDOG_RESET ();	/* Reset the watchdog */ | 
|  | temp_uart_init ();	/* init the uart for debug */ | 
|  | WATCHDOG_RESET ();	/* Reset the watchdog */ | 
|  | test_led ();		/* test the LEDs */ | 
|  | test_sdram (get_dram_size ());	/* test the dram */ | 
|  | log_stat (ERR_POST1);	/* log status,post1 complete */ | 
|  | return 0; | 
|  | } | 
|  |  | 
|  |  | 
|  | /* ------------------------------------------------------------------------- */ | 
|  |  | 
|  | /* | 
|  | * Check Board Identity: | 
|  | */ | 
|  | int checkboard (void) | 
|  | { | 
|  | VPD vpd; | 
|  |  | 
|  | puts ("Board: "); | 
|  |  | 
|  | /* VPD data present in I2C EEPROM */ | 
|  | if (vpd_get_data (CFG_DEF_EEPROM_ADDR, &vpd) == 0) { | 
|  | /* | 
|  | * Known board type. | 
|  | */ | 
|  | if (vpd.productId[0] && | 
|  | ((strncmp (vpd.productId, "GMM", 3) == 0) || | 
|  | (strncmp (vpd.productId, "CMM", 3) == 0))) { | 
|  |  | 
|  | /* Output board information on startup */ | 
|  | printf ("\"%s\", revision '%c', serial# %ld, manufacturer %u\n", vpd.productId, vpd.revisionId, vpd.serialNum, vpd.manuID); | 
|  | return (0); | 
|  | } | 
|  | } | 
|  |  | 
|  | puts ("### Unknown HW ID - assuming NOTHING\n"); | 
|  | return (0); | 
|  | } | 
|  |  | 
|  | /* ------------------------------------------------------------------------- */ | 
|  |  | 
|  | phys_size_t initdram (int board_type) | 
|  | { | 
|  | /* | 
|  | * ToDo: Move the asm init routine sdram_init() to this C file, | 
|  | * or even better use some common ppc4xx code available | 
|  | * in cpu/ppc4xx | 
|  | */ | 
|  | sdram_init(); | 
|  |  | 
|  | return get_dram_size (); | 
|  | } | 
|  |  | 
|  | unsigned long get_dram_size (void) | 
|  | { | 
|  | int tmp, i, regs[4]; | 
|  | int size = 0; | 
|  |  | 
|  | /* Get bank Size registers */ | 
|  | mtdcr (memcfga, mem_mb0cf);	/* get bank 0 config reg */ | 
|  | regs[0] = mfdcr (memcfgd); | 
|  |  | 
|  | mtdcr (memcfga, mem_mb1cf);	/* get bank 1 config reg */ | 
|  | regs[1] = mfdcr (memcfgd); | 
|  |  | 
|  | mtdcr (memcfga, mem_mb2cf);	/* get bank 2 config reg */ | 
|  | regs[2] = mfdcr (memcfgd); | 
|  |  | 
|  | mtdcr (memcfga, mem_mb3cf);	/* get bank 3 config reg */ | 
|  | regs[3] = mfdcr (memcfgd); | 
|  |  | 
|  | /* compute the size, add each bank if enabled */ | 
|  | for (i = 0; i < 4; i++) { | 
|  | if (regs[i] & 0x0001) {	/* if enabled, */ | 
|  | tmp = ((regs[i] >> (31 - 14)) & 0x7);	/* get size bits */ | 
|  | tmp = 0x400000 << tmp;	/* Size bits X 4MB = size */ | 
|  | size += tmp; | 
|  | } | 
|  | } | 
|  |  | 
|  | return size; | 
|  | } | 
|  |  | 
|  | int misc_init_f (void) | 
|  | { | 
|  | return 0; | 
|  | } | 
|  |  | 
|  | static void w7o_env_init (VPD * vpd) | 
|  | { | 
|  | /* | 
|  | * Read VPD | 
|  | */ | 
|  | if (vpd_get_data (CFG_DEF_EEPROM_ADDR, vpd) != 0) | 
|  | return; | 
|  |  | 
|  | /* | 
|  | * Known board type. | 
|  | */ | 
|  | if (vpd->productId[0] && | 
|  | ((strncmp (vpd->productId, "GMM", 3) == 0) || | 
|  | (strncmp (vpd->productId, "CMM", 3) == 0))) { | 
|  | char buf[30]; | 
|  | char *eth; | 
|  | char *serial = getenv ("serial#"); | 
|  | char *ethaddr = getenv ("ethaddr"); | 
|  |  | 
|  | /* Set 'serial#' envvar if serial# isn't set */ | 
|  | if (!serial) { | 
|  | sprintf (buf, "%s-%ld", vpd->productId, | 
|  | vpd->serialNum); | 
|  | setenv ("serial#", buf); | 
|  | } | 
|  |  | 
|  | /* Set 'ethaddr' envvar if 'ethaddr' envvar is the default */ | 
|  | eth = (char *)(vpd->ethAddrs[0]); | 
|  | if (ethaddr | 
|  | && (strcmp (ethaddr, MK_STR (CONFIG_ETHADDR)) == 0)) { | 
|  | /* Now setup ethaddr */ | 
|  | sprintf (buf, "%02x:%02x:%02x:%02x:%02x:%02x", | 
|  | eth[0], eth[1], eth[2], eth[3], eth[4], | 
|  | eth[5]); | 
|  | setenv ("ethaddr", buf); | 
|  | } | 
|  | } | 
|  | }				/* w7o_env_init() */ | 
|  |  | 
|  |  | 
|  | int misc_init_r (void) | 
|  | { | 
|  | VPD vpd;		/* VPD information */ | 
|  |  | 
|  | #if defined(CONFIG_W7OLMG) | 
|  | unsigned long greg;	/* GPIO Register */ | 
|  |  | 
|  | greg = in32 (PPC405GP_GPIO0_OR); | 
|  |  | 
|  | /* | 
|  | * XXX - Unreset devices - this should be moved into VxWorks driver code | 
|  | */ | 
|  | greg |= 0x41800000L;	/* SAM, PHY, Galileo */ | 
|  |  | 
|  | out32 (PPC405GP_GPIO0_OR, greg);	/* set output pins to default */ | 
|  | #endif /* CONFIG_W7OLMG */ | 
|  |  | 
|  | /* | 
|  | * Initialize W7O environment variables | 
|  | */ | 
|  | w7o_env_init (&vpd); | 
|  |  | 
|  | /* | 
|  | * Initialize the FPGA(s). | 
|  | */ | 
|  | if (init_fpga () == 0) | 
|  | test_fpga ((unsigned short *) CONFIG_FPGAS_BASE); | 
|  |  | 
|  | /* More POST testing. */ | 
|  | post2 (); | 
|  |  | 
|  | /* Done with hardware initialization and POST. */ | 
|  | log_stat (ERR_POSTOK); | 
|  |  | 
|  | /* Call silly, fail safe boot init routine */ | 
|  | init_fsboot (); | 
|  |  | 
|  | return (0); | 
|  | } |