--- /dev/null
+/*
+ * (C) Copyright 2001, 2002
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2002
+ * Frank Panno <fpanno@delphintech.com>, Delphin Technology AG
+ *
+ * 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 <ioports.h>
+#include <mpc8260.h>
+#include "ep8260.h"
+/*
+ * I/O Port configuration table
+ *
+ * if conf is 1, then that port pin will be configured at boot time
+ * according to the five values podr/pdir/ppar/psor/pdat for that entry
+ */
+
+const iop_conf_t iop_conf_tab[4][32] = {
+
+ /* Port A configuration */
+ { /* conf ppar psor pdir podr pdat */
+ /* PA31 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA30 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA29 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA28 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA27 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA26 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA25 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA24 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA23 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA22 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA21 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA20 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA19 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA18 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA17 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA16 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA15 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA14 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA13 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA12 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA11 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA10 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PA9 */ { 0, 1, 0, 1, 0, 0 }, /* */
+ /* PA8 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PA7 */ { 0, 0, 0, 1, 0, 0 }, /* PA7 */
+ /* PA6 */ { 0, 0, 0, 1, 0, 0 }, /* PA6 */
+ /* PA5 */ { 0, 0, 0, 1, 0, 0 }, /* PA5 */
+ /* PA4 */ { 0, 0, 0, 1, 0, 0 }, /* PA4 */
+ /* PA3 */ { 0, 0, 0, 1, 0, 0 }, /* PA3 */
+ /* PA2 */ { 0, 0, 0, 1, 0, 0 }, /* PA2 */
+ /* PA1 */ { 0, 0, 0, 1, 0, 0 }, /* PA1 */
+ /* PA0 */ { 0, 0, 0, 1, 0, 0 } /* PA0 */
+ },
+
+ /* Port B configuration */
+ { /* conf ppar psor pdir podr pdat */
+ /* PB31 */ { 0, 1, 0, 1, 0, 0 }, /* */
+ /* PB30 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PB29 */ { 0, 1, 1, 1, 0, 0 }, /* */
+ /* PB28 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PB27 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PB26 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PB25 */ { 0, 1, 0, 1, 0, 0 }, /* */
+ /* PB24 */ { 0, 1, 0, 1, 0, 0 }, /* */
+ /* PB23 */ { 0, 1, 0, 1, 0, 0 }, /* */
+ /* PB22 */ { 0, 1, 0, 1, 0, 0 }, /* */
+ /* PB21 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PB20 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PB19 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PB18 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PB17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RX_DV */
+ /* PB16 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RX_ER */
+ /* PB15 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TX_ER */
+ /* PB14 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TX_EN */
+ /* PB13 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII COL */
+ /* PB12 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII CRS */
+ /* PB11 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RxD[3] */
+ /* PB10 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RxD[2] */
+ /* PB9 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RxD[1] */
+ /* PB8 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII RxD[0] */
+ /* PB7 */ { 0, 0, 0, 0, 0, 0 }, /* PB7 */
+ /* PB6 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TxD[1] */
+ /* PB5 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TxD[2] */
+ /* PB4 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TxD[3] */
+ /* PB3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PB2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PB1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PB0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
+ },
+
+ /* Port C */
+ { /* conf ppar psor pdir podr pdat */
+ /* PC31 */ { 0, 0, 0, 1, 0, 0 }, /* PC31 */
+ /* PC30 */ { 0, 0, 0, 1, 0, 0 }, /* PC30 */
+ /* PC29 */ { 0, 1, 1, 0, 0, 0 }, /* */
+ /* PC28 */ { 0, 0, 0, 1, 0, 0 }, /* PC28 */
+ /* PC27 */ { 1, 1, 0, 1, 0, 0 }, /* FCC3 MII TxD[0] */
+ /* PC26 */ { 0, 0, 0, 1, 0, 0 }, /* PC26 */
+ /* PC25 */ { 0, 0, 0, 1, 0, 0 }, /* PC25 */
+ /* PC24 */ { 0, 0, 0, 1, 0, 0 }, /* PC24 */
+ /* PC23 */ { 0, 1, 0, 1, 0, 0 }, /* */
+ /* PC22 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PC21 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PC20 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PC19 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PC18 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PC17 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII CLK15 */
+ /* PC16 */ { 1, 1, 0, 0, 0, 0 }, /* FCC3 MII CLK16 */
+ /* PC15 */ { 0, 0, 0, 1, 0, 0 }, /* PC15 */
+ /* PC14 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PC13 */ { 0, 0, 0, 1, 0, 0 }, /* PC13 */
+ /* PC12 */ { 0, 0, 0, 1, 0, 0 }, /* PC12 */
+ /* PC11 */ { 0, 0, 0, 1, 0, 0 }, /* PC11 */
+ /* PC10 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PC9 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PC8 */ { 0, 0, 0, 1, 0, 0 }, /* PC8 */
+ /* PC7 */ { 0, 0, 0, 1, 0, 0 }, /* PC7 */
+ /* PC6 */ { 0, 0, 0, 1, 0, 0 }, /* PC6 */
+ /* PC5 */ { 0, 0, 0, 1, 0, 0 }, /* PC5 */
+ /* PC4 */ { 0, 0, 0, 1, 0, 0 }, /* PC4 */
+ /* PC3 */ { 0, 0, 0, 1, 0, 0 }, /* PC3 */
+ /* PC2 */ { 0, 0, 0, 1, 0, 1 }, /* */
+ /* PC1 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ /* PC0 */ { 0, 0, 0, 1, 0, 0 }, /* */
+ },
+
+ /* Port D */
+ { /* conf ppar psor pdir podr pdat */
+ /* PD31 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PD30 */ { 0, 1, 1, 1, 0, 0 }, /* */
+ /* PD29 */ { 0, 1, 0, 1, 0, 0 }, /* */
+ /* PD28 */ { 0, 0, 0, 1, 0, 0 }, /* PD28 */
+ /* PD27 */ { 0, 0, 0, 1, 0, 0 }, /* PD27 */
+ /* PD26 */ { 0, 0, 0, 1, 0, 0 }, /* PD26 */
+ /* PD25 */ { 0, 0, 0, 1, 0, 0 }, /* PD25 */
+ /* PD24 */ { 0, 0, 0, 1, 0, 0 }, /* PD24 */
+ /* PD23 */ { 0, 0, 0, 1, 0, 0 }, /* PD23 */
+ /* PD22 */ { 0, 0, 0, 1, 0, 0 }, /* PD22 */
+ /* PD21 */ { 0, 0, 0, 1, 0, 0 }, /* PD21 */
+ /* PD20 */ { 0, 0, 0, 1, 0, 0 }, /* PD20 */
+ /* PD19 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
+ /* PD18 */ { 0, 0, 0, 1, 0, 0 }, /* PD19 */
+ /* PD17 */ { 0, 1, 0, 0, 0, 0 }, /* */
+ /* PD16 */ { 0, 1, 0, 1, 0, 0 }, /* */
+ /* PD15 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SDA */
+ /* PD14 */ { 1, 1, 1, 0, 1, 0 }, /* I2C SCL */
+ /* PD13 */ { 0, 0, 0, 0, 0, 0 }, /* PD13 */
+ /* PD12 */ { 0, 0, 0, 0, 0, 0 }, /* PD12 */
+ /* PD11 */ { 0, 0, 0, 0, 0, 0 }, /* PD11 */
+ /* PD10 */ { 0, 0, 0, 0, 0, 0 }, /* PD10 */
+ /* PD9 */ { 1, 1, 0, 1, 0, 0 }, /* SMC1 TXD */
+ /* PD8 */ { 1, 1, 0, 0, 0, 0 }, /* SMC1 RXD */
+ /* PD7 */ { 0, 0, 0, 1, 0, 1 }, /* PD7 */
+ /* PD6 */ { 0, 0, 0, 1, 0, 1 }, /* PD6 */
+ /* PD5 */ { 0, 0, 0, 1, 0, 1 }, /* PD5 */
+ /* PD4 */ { 0, 0, 0, 1, 0, 1 }, /* PD4 */
+ /* PD3 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PD2 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PD1 */ { 0, 0, 0, 0, 0, 0 }, /* pin doesn't exist */
+ /* PD0 */ { 0, 0, 0, 0, 0, 0 } /* pin doesn't exist */
+ }
+};
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Setup CS4 to enable the Board Control/Status registers.
+ * Otherwise the smcs won't work.
+*/
+int board_pre_init (void)
+{
+ volatile t_ep_regs *regs = (t_ep_regs*)CFG_REGS_BASE;
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8260_t *memctl = &immap->im_memctl;
+ memctl->memc_br4 = CFG_BR4_PRELIM;
+ memctl->memc_or4 = CFG_OR4_PRELIM;
+ regs->bcsr1 = 0x62; /* to enable terminal on SMC1 */
+ regs->bcsr2 = 0x30; /* enable NVRAM and writing FLASH */
+ return 0;
+}
+
+void
+reset_phy(void)
+{
+ volatile t_ep_regs *regs = (t_ep_regs*)CFG_REGS_BASE;
+ regs->bcsr4 = 0xC0;
+}
+
+/*
+ * Check Board Identity:
+ * I don' know, how the next board revisions will be coded.
+ * Thats why its a static interpretation ...
+*/
+
+int
+checkboard(void)
+{
+ volatile t_ep_regs *regs = (t_ep_regs*)CFG_REGS_BASE;
+ uint major=0, minor=0;
+ switch (regs->bcsr0) {
+ case 0x02: major = 1; break;
+ case 0x03: major = 1; minor = 1; break;
+ default: break;
+ }
+ printf ("Board: Embedded Planet EP8260, Revision %d.%d\n",
+ major, minor);
+ return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+
+long int
+initdram(int board_type)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8260_t *memctl = &immap->im_memctl;
+ volatile uchar c = 0;
+ volatile uchar *ramaddr = (uchar *)(CFG_SDRAM_BASE) + 0x110;
+/*
+ ulong psdmr = CFG_PSDMR;
+#ifdef CFG_LSDRAM
+ ulong lsdmr = CFG_LSDMR;
+#endif
+*/
+ long size = CFG_SDRAM0_SIZE;
+ int i;
+
+
+/*
+* Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
+*
+* "At system reset, initialization software must set up the
+* programmable parameters in the memory controller banks registers
+* (ORx, BRx, P/LSDMR). After all memory parameters are configured,
+* system software should execute the following initialization sequence
+* for each SDRAM device.
+*
+* 1. Issue a PRECHARGE-ALL-BANKS command
+* 2. Issue eight CBR REFRESH commands
+* 3. Issue a MODE-SET command to initialize the mode register
+*
+* The initial commands are executed by setting P/LSDMR[OP] and
+* accessing the SDRAM with a single-byte transaction."
+*
+* The appropriate BRx/ORx registers have already been set when we
+* get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
+*/
+
+ memctl->memc_psrt = CFG_PSRT;
+ memctl->memc_mptpr = CFG_MPTPR;
+
+ memctl->memc_psdmr = (ulong) CFG_PSDMR | PSDMR_OP_PREA;
+ *ramaddr = c;
+
+ memctl->memc_psdmr = (ulong) CFG_PSDMR | PSDMR_OP_CBRR;
+ for (i = 0; i < 8; i++)
+ *ramaddr = c;
+
+ memctl->memc_psdmr = (ulong) CFG_PSDMR | PSDMR_OP_MRW;
+ *ramaddr = c;
+
+ memctl->memc_psdmr = (ulong) CFG_PSDMR | PSDMR_OP_NORM | PSDMR_RFEN;
+ *ramaddr = c;
+
+#ifndef CFG_RAMBOOT
+#ifdef CFG_LSDRAM
+ size += CFG_SDRAM1_SIZE;
+ ramaddr = (uchar *)(CFG_SDRAM1_BASE) + 0x8c;
+ memctl->memc_lsrt = CFG_LSRT;
+
+ memctl->memc_lsdmr = (ulong) CFG_LSDMR | PSDMR_OP_PREA;
+ *ramaddr = c;
+
+ memctl->memc_lsdmr = (ulong) CFG_LSDMR | PSDMR_OP_CBRR;
+ for (i = 0; i < 8; i++)
+ *ramaddr = c;
+
+ memctl->memc_lsdmr = (ulong) CFG_LSDMR | PSDMR_OP_MRW;
+ *ramaddr = c;
+
+ memctl->memc_lsdmr = (ulong) CFG_LSDMR | PSDMR_OP_NORM | PSDMR_RFEN;
+ *ramaddr = c;
+#endif /* CFG_LSDRAM */
+#endif /* CFG_RAMBOOT */
+ return (size * 1024 * 1024);
+}
+
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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 <i2c.h>
+#include "eric.h"
+#include <asm/processor.h>
+
+#define IBM405GP_GPIO0_OR 0xef600700 /* GPIO Output */
+#define IBM405GP_GPIO0_TCR 0xef600704 /* GPIO Three-State Control */
+#define IBM405GP_GPIO0_ODR 0xef600718 /* GPIO Open Drain */
+#define IBM405GP_GPIO0_IR 0xef60071c /* GPIO Input */
+
+int board_pre_init (void)
+{
+
+ /*-------------------------------------------------------------------------+
+ | Interrupt controller setup for the ERIC board.
+ | Note: 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) FLASH; active low; level sensitive
+ | IRQ 26 (EXT IRQ 1) PHY ; active low; level sensitive
+ | IRQ 27 (EXT IRQ 2) HOST FAIL, active low; level sensitive
+ | indicates NO Power or HOST RESET active
+ | check GPIO7 (HOST RESET#) and GPIO8 (NO Power#)
+ | for real IRQ source
+ | IRQ 28 (EXT IRQ 3) HOST; active high; level sensitive
+ | IRQ 29 (EXT IRQ 4) PCI INTC#; active low; level sensitive
+ | IRQ 30 (EXT IRQ 5) PCI INTB#; active low; level sensitive
+ | IRQ 31 (EXT IRQ 6) PCI INTA#; active low; level sensitive
+ | -> IRQ6 Pin is NOW GPIO23 and can be activateted by setting
+ | IBM405GP_GPIO0_TCR Bit 0 = 1 (driving the output as defined in IBM405GP_GPIO0_OR,
+ | else tristate)
+ | Note for ERIC board:
+ | An interrupt taken for the HOST (IRQ 28) indicates that
+ | the HOST wrote a "1" to one of the following locations
+ | - VGA CRT_GPIO0 (if R1216 is loaded)
+ | - VGA CRT_GPIO1 (if R1217 is loaded)
+ |
+ +-------------------------------------------------------------------------*/
+
+ mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */
+ mtdcr (uicer, 0x00000000); /* disable all ints */
+ mtdcr (uiccr, 0x00000000); /* set all SMI to be non-critical */
+ mtdcr (uicpr, 0xFFFFFF88); /* set int polarities; IRQ3 to 1 */
+ mtdcr (uictr, 0x10000000); /* set int trigger levels, UART0 is EDGE */
+ mtdcr (uicvcr, 0x00000001); /* set vect base=0,INT0 highest priority */
+ mtdcr (uicsr, 0xFFFFFFFF); /* clear all ints */
+
+ mtdcr (cntrl0, 0x00002000); /* set IRQ6 as GPIO23 to generate an interrupt request to the PCP2PCI bridge */
+
+ out32 (IBM405GP_GPIO0_OR, 0x60000000); /*fixme is SMB_INT high or low active??; IRQ6 is GPIO23 output */
+ out32 (IBM405GP_GPIO0_TCR, 0x7E400000);
+
+ return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ unsigned char *s = getenv ("serial#");
+ unsigned char *e;
+
+ puts ("Board: ");
+
+ if (!s || strncmp (s, "ERIC", 9)) {
+ puts ("### No HW ID - assuming ERIC");
+ } else {
+ for (e = s; *e; ++e) {
+ if (*e == ' ')
+ break;
+ }
+
+ for (; s < e; ++s) {
+ putc (*s);
+ }
+ }
+
+
+ putc ('\n');
+
+ return (0);
+}
+
+
+/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- */
+/*
+ initdram(int board_type) reads EEPROM via I2c. EEPROM contains all of
+ the necessary info for SDRAM controller configuration
+*/
+/* ------------------------------------------------------------------------- */
+/* ------------------------------------------------------------------------- */
+long int initdram (int board_type)
+{
+#ifndef CONFIG_ERIC
+ int i;
+ unsigned char datain[128];
+ int TotalSize;
+#endif
+
+
+#ifdef CONFIG_ERIC
+ /*
+ * we have no EEPROM on ERIC
+ * so let init.S do the init job for SDRAM
+ * and simply return 32MByte here
+ */
+ return (CFG_SDRAM_SIZE * 1024 * 1024);
+#else
+
+ /* Read Serial Presence Detect Information */
+ for (i = 0; i < 128; i++)
+ datain[i] = 127;
+ i2c_send (SPD_EEPROM_ADDRESS, 0, 1, datain, 128);
+ printf ("\nReading DIMM...\n");
+#if 0
+ for (i = 0; i < 128; i++) {
+ printf ("%d=0x%x ", i, datain[i]);
+ if (((i + 1) % 10) == 0)
+ printf ("\n");
+ }
+ printf ("\n");
+#endif
+
+ /*****************************/
+ /* Retrieve interesting data */
+ /*****************************/
+ /* size of a SDRAM bank */
+ /* Number of bytes per side / number of banks per side */
+ if (datain[31] == 0x08)
+ TotalSize = 32;
+ else if (datain[31] == 0x10)
+ TotalSize = 64;
+ else {
+ printf ("IIC READ ERROR!!!\n");
+ TotalSize = 32;
+ }
+
+ /* single-sided DIMM or double-sided DIMM? */
+ if (datain[5] != 1) {
+ /* double-sided DIMM => SDRAM banks 0..3 are valid */
+ printf ("double-sided DIMM\n");
+ TotalSize *= 2;
+ }
+ /* else single-sided DIMM => SDRAM bank 0 and bank 2 are valid */
+ else {
+ printf ("single-sided DIMM\n");
+ }
+
+
+ /* return size in Mb unit => *(1024*1024) */
+ return (TotalSize * 1024 * 1024);
+#endif
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+ /* TODO: XXX XXX XXX */
+ printf ("test: xxx MB - ok\n");
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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 "adciop.h"
+
+/* ------------------------------------------------------------------------- */
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+/* ------------------------------------------------------------------------- */
+
+
+int board_pre_init (void)
+{
+ /*
+ * Set port pin in escc2 to keep living, and configure user led output
+ */
+ *(unsigned char *) 0x2000033e = 0x77; /* ESCC2: PCR bit3=pwr on, bit7=led out */
+ *(unsigned char *) 0x2000033c = 0x88; /* ESCC2: PVR pwr on, led off */
+
+ /*
+ * Init pci regs
+ */
+ *(unsigned long *) 0x50000304 = 0x02900007; /* enable mem/io/master bits */
+ *(unsigned long *) 0x500001b4 = 0x00000000; /* disable pci interrupt output enable */
+ *(unsigned long *) 0x50000354 = 0x00c05800; /* disable emun interrupt output enable */
+ *(unsigned long *) 0x50000344 = 0x00000000; /* disable pme interrupt output enable */
+ *(unsigned long *) 0x50000310 = 0x00000000; /* pcibar0 */
+ *(unsigned long *) 0x50000314 = 0x00000000; /* pcibar1 */
+ *(unsigned long *) 0x50000318 = 0x00000000; /* pcibar2 */
+
+ return 0;
+}
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ unsigned char str[64];
+ int i = getenv_r ("serial#", str, sizeof (str));
+
+ puts ("Board: ");
+
+ if (!i || strncmp (str, "ADCIOP", 6)) {
+ puts ("### No HW ID - assuming ADCIOP\n");
+ return (1);
+ }
+
+ puts (str);
+
+ putc ('\n');
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ return (16 * 1024 * 1024);
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+ /* TODO: XXX XXX XXX */
+ printf ("test: 16 MB - ok\n");
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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 "dasa_sim.h"
+
+/* ------------------------------------------------------------------------- */
+
+#undef FPGA_DEBUG
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+/* ------------------------------------------------------------------------- */
+
+/* fpga configuration data - generated by bit2inc */
+static unsigned char fpgadata[] = {
+#include "fpgadata.c"
+};
+
+#define FPGA_PRG_SLEEP 32 /* fpga program sleep-time */
+#define LOAD_LONG(a) a
+
+
+/******************************************************************************
+ *
+ * sysFpgaBoot - Load fpga-image into fpga
+ *
+ */
+static int fpgaBoot (void)
+{
+ int i, j, index, len;
+ unsigned char b;
+ int imageSize;
+
+ imageSize = sizeof (fpgadata);
+
+ /* display infos on fpgaimage */
+ index = 15;
+ for (i = 0; i < 4; i++) {
+ len = fpgadata[index];
+ index += len + 3;
+ }
+
+ /* search for preamble 0xFF2X */
+ for (index = 0; index < imageSize - 1; index++) {
+ if ((fpgadata[index] == 0xff)
+ && ((fpgadata[index + 1] & 0xf0) == 0x20))
+ break;
+ }
+
+ /* enable cs1 instead of user0... */
+ *(unsigned long *) 0x50000084 &= ~0x00000002;
+
+#ifdef FPGA_DEBUG
+ printf ("%s\n",
+ ((in32 (0x50000084) & 0x00010000) == 0) ? "NOT DONE" : "DONE");
+#endif
+
+ /* init fpga by asserting and deasserting PROGRAM* (USER2)... */
+ *(unsigned long *) 0x50000084 &= ~0x00000400;
+ udelay (FPGA_PRG_SLEEP * 1000);
+
+ *(unsigned long *) 0x50000084 |= 0x00000400;
+ udelay (FPGA_PRG_SLEEP * 1000);
+
+#ifdef FPGA_DEBUG
+ printf ("%s\n",
+ ((in32 (0x50000084) & 0x00010000) == 0) ? "NOT DONE" : "DONE");
+#endif
+
+ /* cs1: disable burst, disable ready */
+ *(unsigned long *) 0x50000114 &= ~0x00000300;
+
+ /* cs1: set write timing */
+ *(unsigned long *) 0x50000118 |= 0x00010900;
+
+ /* write configuration-data into fpga... */
+ for (i = index; i < imageSize; i++) {
+ b = fpgadata[i];
+ for (j = 0; j < 8; j++) {
+ *(unsigned long *) 0x30000000 =
+ ((b & 0x80) == 0x80)
+ ? LOAD_LONG (0x03030101)
+ : LOAD_LONG (0x02020000);
+ b <<= 1;
+ }
+ }
+
+#ifdef FPGA_DEBUG
+ printf ("%s\n",
+ ((in32 (0x50000084) & 0x00010000) == 0) ? "NOT DONE" : "DONE");
+#endif
+
+ /* set cs1 to 32 bit data-width, disable burst, enable ready */
+ *(unsigned long *) 0x50000114 |= 0x00000202;
+ *(unsigned long *) 0x50000114 &= ~0x00000100;
+
+ /* cs1: set iop access to little endian */
+ *(unsigned long *) 0x50000114 &= ~0x00000010;
+
+ /* cs1: set read and write timing */
+ *(unsigned long *) 0x50000118 = 0x00010000;
+ *(unsigned long *) 0x5000011c = 0x00010001;
+
+#ifdef FPGA_DEBUG
+ printf ("%s\n",
+ ((in32 (0x50000084) & 0x00010000) == 0) ? "NOT DONE" : "DONE");
+#endif
+
+ /* wait for 30 ms... */
+ udelay (30 * 1000);
+ /* check if fpga's DONE signal - correctly booted ? */
+ if ((*(unsigned long *) 0x50000084 & 0x00010000) == 0)
+ return -1;
+
+ return 0;
+}
+
+
+int board_pre_init (void)
+{
+ /*
+ * Init pci regs
+ */
+ *(unsigned long *) 0x50000304 = 0x02900007; /* enable mem/io/master bits */
+ *(unsigned long *) 0x500001b4 = 0x00000000; /* disable pci interrupt output enable */
+ *(unsigned long *) 0x50000354 = 0x00c05800; /* disable emun interrupt output enable */
+ *(unsigned long *) 0x50000344 = 0x00000000; /* disable pme interrupt output enable */
+ *(unsigned long *) 0x50000310 = 0x00000000; /* pcibar0 */
+ *(unsigned long *) 0x50000314 = 0x00000000; /* pcibar1 */
+ *(unsigned long *) 0x50000318 = 0x00000000; /* pcibar2 */
+
+ return 0;
+}
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ int index;
+ int len;
+ unsigned char str[64];
+ int i = getenv_r ("serial#", str, sizeof (str));
+ int fpga;
+ unsigned short val;
+
+ puts ("Board: ");
+
+ /*
+ * Boot onboard FPGA
+ */
+ fpga = fpgaBoot ();
+
+ if (!i || strncmp (str, "DASA_SIM", 8)) {
+ puts ("### No HW ID - assuming DASA_SIM");
+ }
+
+ puts (str);
+
+ if (fpga == 0) {
+ val = *(unsigned short *) 0x30000202;
+ printf (" (Id=%d Version=%d Revision=%d)",
+ (val & 0x07f8) >> 3, val & 0x0001, (val & 0x0006) >> 1);
+
+ puts ("\nFPGA: ");
+
+ /* display infos on fpgaimage */
+ index = 15;
+ for (i = 0; i < 4; i++) {
+ len = fpgadata[index];
+ printf ("%s ", &(fpgadata[index + 1]));
+ index += len + 3;
+ }
+ } else {
+ puts ("\nFPGA: Booting failed!");
+ }
+
+ putc ('\n');
+
+ return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ return (16 * 1024 * 1024);
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+ /* TODO: XXX XXX XXX */
+ printf ("test: 16 MB - ok\n");
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.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 "ocrtc.h"
+#include <asm/processor.h>
+#include <i2c.h>
+#include <command.h>
+#include <cmd_boot.h>
+
+/* ------------------------------------------------------------------------- */
+
+int board_pre_init (void)
+{
+ /*
+ * 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) CAN0; active low; level sensitive
+ * IRQ 26 (EXT IRQ 1) CAN1; active low; level sensitive
+ * IRQ 27 (EXT IRQ 2) PCI SLOT 0; active low; level sensitive
+ * IRQ 28 (EXT IRQ 3) PCI SLOT 1; active low; level sensitive
+ * IRQ 29 (EXT IRQ 4) PCI SLOT 2; active low; level sensitive
+ * IRQ 30 (EXT IRQ 5) PCI SLOT 3; active low; level sensitive
+ * IRQ 31 (EXT IRQ 6) COMPACT FLASH; 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, 0xFFFFFF81); /* 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 */
+
+ /*
+ * EBC Configuration Register: clear EBTC -> high-Z ebc signals between
+ * transfers, set device-paced timeout to 256 cycles
+ */
+ mtebc (epcr, 0x20400000);
+
+ return 0;
+}
+
+
+/* ------------------------------------------------------------------------- */
+
+int misc_init_f (void)
+{
+ return 0; /* dummy implementation */
+}
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ unsigned char str[64];
+ int i = getenv_r ("serial#", str, sizeof (str));
+
+ puts ("Board: ");
+
+ if (i == -1) {
+#ifdef CONFIG_OCRTC
+ puts ("### No HW ID - assuming OCRTC");
+#endif
+#ifdef CONFIG_ORSG
+ puts ("### No HW ID - assuming ORSG");
+#endif
+ } else {
+ puts (str);
+ }
+
+ putc ('\n');
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ unsigned long val;
+
+ mtdcr (memcfga, mem_mb0cf);
+ val = mfdcr (memcfgd);
+
+#if 0
+ printf ("\nmb0cf=%x\n", val); /* test-only */
+ printf ("strap=%x\n", mfdcr (strap)); /* test-only */
+#endif
+
+ return (4 * 1024 * 1024 << ((val & 0x000e0000) >> 17));
+}
+
+/* ------------------------------------------------------------------------- */
+
+int testdram (void)
+{
+ /* TODO: XXX XXX XXX */
+ printf ("test: 16 MB - ok\n");
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ *
+ *
+ * Modified By Conn Clark to work with Esteem 192E 7/31/00
+ *
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size ( long int *base, long int maxsize);
+
+/* ------------------------------------------------------------------------- */
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+const uint sdram_table[] =
+{
+ /*
+ * Single Read. (Offset 0 in UPMA RAM)
+ *
+ * active, NOP, read, precharge, NOP */
+ 0x0F27CC04, 0x0EAECC04, 0x00B98C04, 0x00F74C00,
+ 0x11FFCC05, /* last */
+ /*
+ * SDRAM Initialization (offset 5 in UPMA RAM)
+ *
+ * This is no UPM entry point. The following definition uses
+ * the remaining space to establish an initialization
+ * sequence, which is executed by a RUN command.
+ * NOP, Program
+ */
+ 0x0F0A8C34, 0x1F354C37, /* last */
+
+ _NOT_USED_, /* Not used */
+
+ /*
+ * Burst Read. (Offset 8 in UPMA RAM)
+ * active, NOP, read, NOP, NOP, NOP, NOP, NOP */
+ 0x0F37CC04, 0x0EFECC04, 0x00FDCC04, 0x00FFCC00,
+ 0x00FFCC00, 0x01FFCC00, 0x0FFFCC00, 0x1FFFCC05, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Single Write. (Offset 18 in UPMA RAM)
+ * active, NOP, write, NOP, precharge, NOP */
+ 0x0F27CC04, 0x0EAE8C00, 0x01BD4C04, 0x0FFB8C04,
+ 0x0FF74C04, 0x1FFFCC05, /* last */
+ _NOT_USED_, _NOT_USED_,
+ /*
+ * Burst Write. (Offset 20 in UPMA RAM)
+ * active, NOP, write, NOP, NOP, NOP, NOP, NOP */
+ 0x0F37CC04, 0x0EFE8C00, 0x00FD4C00, 0x00FFCC00,
+ 0x00FFCC00, 0x01FFCC04, 0x0FFFCC04, 0x1FFFCC05, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Refresh (Offset 30 in UPMA RAM)
+ * precharge, NOP, auto_ref, NOP, NOP, NOP */
+ 0x0FF74C34, 0x0FFACCB4, 0x0FF5CC34, 0x0FFFCC34,
+ 0x0FFFCCB4, 0x1FFFCC35, /* last */
+ _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Exception. (Offset 3c in UPMA RAM)
+ */
+ 0x0FFB8C00, 0x1FF74C03, /* last */
+ _NOT_USED_, _NOT_USED_
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ puts ("Board: Esteem 192E\n");
+ return(0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+
+long int initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ long int size_b0, size_b1;
+
+ /*
+ * Explain frequency of refresh here
+ */
+
+ memctl->memc_mptpr = 0x0200; /* divide by 32 */
+
+ memctl->memc_mamr = 0x18003112; /*CFG_MAMR_8COL;*/ /* 0x18005112 TODO: explain here */
+
+ upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
+
+ /*
+ * Map cs 2 and 3 to the SDRAM banks 0 and 1 at
+ * preliminary addresses - these have to be modified after the
+ * SDRAM size has been determined.
+ */
+
+ memctl->memc_or2 = CFG_OR2_PRELIM; /* not defined yet */
+ memctl->memc_br2 = CFG_BR2_PRELIM;
+
+ memctl->memc_or3 = CFG_OR3_PRELIM;
+ memctl->memc_br3 = CFG_BR3_PRELIM;
+
+
+ /* perform SDRAM initializsation sequence */
+ memctl->memc_mar = 0x00000088;
+
+ memctl->memc_mcr = 0x80004830; /* SDRAM bank 0 execute 8 refresh */
+
+ memctl->memc_mcr = 0x80004105; /* SDRAM bank 0 */
+
+
+ memctl->memc_mcr = 0x80006830; /* SDRAM bank 1 execute 8 refresh */
+
+ memctl->memc_mcr = 0x80006105; /* SDRAM bank 1 */
+
+
+ memctl->memc_mamr = CFG_MAMR_8COL; /* 0x18803112 start refresh timer TODO: explain here */
+
+/* printf ("banks 0 and 1 are programed\n"); */
+
+ /*
+ * Check Bank 0 Memory Size for re-configuration
+ *
+ */
+
+ size_b0 = dram_size ((ulong *)SDRAM_BASE2_PRELIM, SDRAM_MAX_SIZE);
+
+ size_b1 = dram_size ((ulong *)SDRAM_BASE3_PRELIM, SDRAM_MAX_SIZE);
+
+
+ printf ("\nbank 0 size %lu\nbank 1 size %lu\n",size_b0,size_b1);
+
+
+/* printf ("bank 1 size %u\n",size_b1); */
+
+ if(size_b1 == 0) {
+
+ /*
+ * Adjust refresh rate if bank 0 isn't stuffed
+ */
+
+ memctl->memc_mptpr = 0x0400; /* divide by 64 */
+ memctl->memc_br3 &= 0x0FFFFFFFE;
+
+ /*
+ * Adjust OR2 for size of bank 0
+ */
+ memctl->memc_or2 |= 7 * size_b0;
+
+ }
+
+ else {
+
+ if(size_b0 < size_b1) {
+ memctl->memc_br2 &= 0x00007FFE;
+ memctl->memc_br3 &= 0x00007FFF;
+
+ /*
+ * Adjust OR3 for size of bank 1
+ */
+ memctl->memc_or3 |= 15 * size_b1;
+
+ /*
+ * Adjust OR2 for size of bank 0
+ */
+ memctl->memc_or2 |= 15 * size_b0;
+
+ memctl->memc_br2 += (size_b1 + 1);
+
+ }
+ else {
+
+ memctl->memc_br3 &= 0x00007FFE;
+
+
+ /*
+ * Adjust OR2 for size of bank 0
+ */
+ memctl->memc_or2 |= 15 * size_b0;
+
+ /*
+ * Adjust OR3 for size of bank 1
+ */
+ memctl->memc_or3 |= 15 * size_b1;
+
+ memctl->memc_br3 += (size_b0 + 1);
+
+
+ }
+ }
+
+
+/* before leaving set all unused i/o pins to outputs */
+
+/*
+ * --*Unused Pin List*--
+ *
+ * group/port bit number
+ * IP_B 0,1,3,4,5 Taken care of in pcmcia-cs-x.x.xx
+ * PA 5,7,8,9,14,15
+ * PB 22,23,31
+ * PC 4,5,6,7,10,11,12,13,14,15
+ * PD 5,6,7
+ *
+ */
+
+/*
+ * --*Pin Used for I/O List*--
+ *
+ * port input bit number output bit number either
+ * PB 18,26,27
+ * PD 3,4 8,9,10,11,12,13,14,15
+ *
+ */
+
+
+ immap->im_ioport.iop_papar &= ~0x05C3; /* set pins as io */
+ immap->im_ioport.iop_padir |= 0x05C3; /* set pins as output */
+ immap->im_ioport.iop_paodr &= 0x0008; /* config pins 9 & 14 as normal outputs */
+ immap->im_ioport.iop_padat |= 0x05C3; /* set unused pins as high */
+
+ immap->im_cpm.cp_pbpar &= ~0x00001331; /* set unused port b pins as io */
+ immap->im_cpm.cp_pbdir |= 0x00001331; /* set unused port b pins as output */
+ immap->im_cpm.cp_pbodr &= ~0x00001331; /* config bits 18,22,23,26,27 & 31 as normal outputs */
+ immap->im_cpm.cp_pbdat |= 0x00001331; /* set T/E LED, /NV_CS, & /POWER_ADJ_CS and the rest to a high */
+
+ immap->im_ioport.iop_pcpar &= ~0x0F3F; /* set unused port c pins as io */
+ immap->im_ioport.iop_pcdir |= 0x0F3F; /* set unused port c pins as output */
+ immap->im_ioport.iop_pcso &= ~0x0F3F; /* clear special purpose bit for unused port c pins for clarity */
+ immap->im_ioport.iop_pcdat |= 0x0F3F; /* set unused port c pins high*/
+
+ immap->im_ioport.iop_pdpar &= 0xE000; /* set pins as io */
+ immap->im_ioport.iop_pddir &= 0xE000; /* set bit 3 & 4 as inputs */
+ immap->im_ioport.iop_pddir |= 0x07FF; /* set bits 5 - 15 as outputs */
+ immap->im_ioport.iop_pddat = 0x0055; /* set alternating pattern on test port */
+
+
+
+
+ return (size_b0 + size_b1);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size ( long int *base, long int maxsize)
+{
+
+ volatile long int *addr;
+ long int cnt, val;
+
+ for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ *addr = ~cnt;
+ }
+
+ /* write 0 to base address */
+ addr = base;
+ *addr = 0;
+
+ /* check at base address */
+ if ((val = *addr) != 0) {
+ return (0);
+ }
+
+ for (cnt = 1; ; cnt <<= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ val = *addr;
+
+ if (val != (~cnt)) {
+ return (cnt * sizeof(long));
+ }
+ }
+ /* NOTREACHED */
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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 <mpc8xx.h>
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+static void read_hw_vers (void);
+
+/* ------------------------------------------------------------------------- */
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+const uint sdram_table[] = {
+
+ /* single read (offset 0x00 in upm ram) */
+
+ 0xEECEFC24, 0x100DFC24, 0xE02FBC04, 0x01AA7C04,
+ 0x1FB5FC00, 0xFFFFFC05, _NOT_USED_, _NOT_USED_,
+
+ /* burst read (offset 0x08 in upm ram) */
+
+ 0xEECEFC24, 0x100DFC24, 0xE0FFBC04, 0x10FF7C04,
+ 0xF0FFFC00, 0xF0FFFC00, 0xF0FFFC00, 0xFFFFFC00,
+ 0xFFFFFC05, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* single write (offset 0x18 in upm ram) */
+
+ 0xEECEFC24, 0x100DFC24, 0xE02BBC04, 0x01A27C00,
+ 0xEFAAFC04, 0x1FB5FC05, _NOT_USED_, _NOT_USED_,
+
+ /* burst write (offset 0x20 in upm ram) */
+
+ 0xEECEFC24, 0x103DFC24, 0xE0FBBC00, 0x10F77C00,
+ 0xF0FFFC00, 0xF0FFFC00, 0xF0FFFC04, 0xFFFFFC05,
+
+ /* init part1 (offset 0x28 in upm ram) */
+
+ 0xEFFAFC3C, 0x1FF4FC34, 0xEFFCBC34, 0x1FFC3C34,
+ 0xFFFC3C35, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* refresh (offset 0x30 in upm ram) */
+
+ 0xEFFEBC0C, 0x1FFD7C04, 0xFFFFFC04, 0xFFFFFC05,
+
+ /* init part2 (offset 0x34 in upm ram) */
+
+ 0xFFFEBC04, 0xEFFC3CB4, 0x1FFC3C34, 0xFFFC3C34,
+ 0xFFFC3C34, 0xEFE83CB4, 0x1FB57C35, _NOT_USED_,
+
+ /* exception (offset 0x3C in upm ram) */
+
+ 0xFFFFFC05, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ *
+ * Test ETX ID string (ETX_xxx...)
+ *
+ * Return 1 always.
+ */
+
+int checkboard (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ unsigned char *s = getenv ("serial#");
+ unsigned char *e;
+
+ puts ("Board: ");
+
+#ifdef SB_ETX094
+ gd->board_type = 0; /* 0 = 2SDRAM-Device */
+#else
+ gd->board_type = 1; /* 1 = 1SDRAM-Device */
+#endif
+
+ if (!s || strncmp (s, "ETX_", 4)) {
+ puts ("### No HW ID - assuming ETX_094\n");
+ read_hw_vers ();
+ return (0);
+ }
+
+ for (e = s; *e; ++e) {
+ if (*e == ' ')
+ break;
+ }
+
+ for (; s < e; ++s) {
+ putc (*s);
+ }
+ putc ('\n');
+
+ read_hw_vers ();
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ long int size_b0, size_b1, size8, size9;
+
+ upmconfig (UPMA, (uint *) sdram_table,
+ sizeof (sdram_table) / sizeof (uint));
+
+ /*
+ * Preliminary prescaler for refresh (depends on number of
+ * banks): This value is selected for four cycles every 62.4 us
+ * with two SDRAM banks or four cycles every 31.2 us with one
+ * bank. It will be adjusted after memory sizing.
+ */
+ memctl->memc_mptpr = CFG_MPTPR_1BK_4K; /* MPTPR_PTP_DIV32 0x0200 */
+
+ /* A3(SDRAM)=0 => Bursttype = Sequential
+ * A2-A0(SDRAM)=010 => Burst length = 4
+ * A4-A6(SDRAM)=010 => CasLat=2
+ */
+ memctl->memc_mar = 0x00000088;
+
+ /*
+ * Map controller banks 2 and 3 to the SDRAM banks 2 and 3 at
+ * preliminary addresses - these have to be modified after the
+ * SDRAM size has been determined.
+ */
+ memctl->memc_or2 = CFG_OR2_PRELIM;
+ memctl->memc_br2 = CFG_BR2_PRELIM;
+
+ if (board_type == 0) { /* "L" type boards have only one bank SDRAM */
+ memctl->memc_or3 = CFG_OR3_PRELIM;
+ memctl->memc_br3 = CFG_BR3_PRELIM;
+ }
+
+ memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
+
+ udelay (200);
+
+ /* perform SDRAM initializsation sequence */
+
+ memctl->memc_mcr = 0x80004128; /* SDRAM bank 0 (CS2) - Init Part 1 */
+ memctl->memc_mcr = 0x80004734; /* SDRAM bank 0 (CS2) - Init Part 2 */
+ udelay (1);
+
+ if (board_type == 0) { /* "L" type boards have only one bank SDRAM */
+ memctl->memc_mcr = 0x80006128; /* SDRAM bank 1 (CS3) - Init Part 1 */
+ memctl->memc_mcr = 0x80006734; /* SDRAM bank 1 (CS3) - Init Part 2 */
+ udelay (1);
+ }
+
+ memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
+
+ udelay (1000);
+
+ /*
+ * Check Bank 0 Memory Size for re-configuration
+ *
+ * try 8 column mode
+ */
+ size8 = dram_size (CFG_MAMR_8COL, (ulong *) SDRAM_BASE2_PRELIM,
+ SDRAM_MAX_SIZE);
+
+ udelay (1000);
+
+ /*
+ * try 9 column mode
+ */
+ size9 = dram_size (CFG_MAMR_9COL, (ulong *) SDRAM_BASE2_PRELIM,
+ SDRAM_MAX_SIZE);
+
+ if (size8 < size9) { /* leave configuration at 9 columns */
+ size_b0 = size9;
+/* debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20); */
+ } else { /* back to 8 columns */
+ size_b0 = size8;
+ memctl->memc_mamr = CFG_MAMR_8COL;
+ udelay (500);
+/* debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20); */
+ }
+
+ if (board_type == 0) { /* "L" type boards have only one bank SDRAM */
+ /*
+ * Check Bank 1 Memory Size
+ * use current column settings
+ * [9 column SDRAM may also be used in 8 column mode,
+ * but then only half the real size will be used.]
+ */
+ size_b1 =
+ dram_size (memctl->memc_mamr, (ulong *) SDRAM_BASE3_PRELIM,
+ SDRAM_MAX_SIZE);
+/* debug ("SDRAM Bank 1: %ld MB\n", size8 >> 20); */
+ } else {
+ size_b1 = 0;
+ }
+
+ udelay (1000);
+
+ /*
+ * Adjust refresh rate depending on SDRAM type, both banks
+ * For types > 128 MBit leave it at the current (fast) rate
+ */
+ if ((size_b0 < 0x02000000) && (size_b1 < 0x02000000)) {
+ /* reduce to 15.6 us (62.4 us / quad) */
+ memctl->memc_mptpr = CFG_MPTPR_2BK_4K; /*DIV16 */
+ udelay (1000);
+ }
+
+ /*
+ * Final mapping: map bigger bank first
+ */
+ if (size_b1 > size_b0) { /* SDRAM Bank 1 is bigger - map first */
+
+ memctl->memc_or3 = ((-size_b1) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+ memctl->memc_br3 =
+ (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
+
+ if (size_b0 > 0) {
+ /*
+ * Position Bank 0 immediately above Bank 1
+ */
+ memctl->memc_or2 =
+ ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+ memctl->memc_br2 =
+ ((CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V)
+ + size_b1;
+ } else {
+ unsigned long reg;
+
+ /*
+ * No bank 0
+ *
+ * invalidate bank
+ */
+ memctl->memc_br2 = 0;
+
+ /* adjust refresh rate depending on SDRAM type, one bank */
+ reg = memctl->memc_mptpr;
+ reg >>= 1; /* reduce to CFG_MPTPR_1BK_8K / _4K */
+ memctl->memc_mptpr = reg;
+ }
+
+ } else { /* SDRAM Bank 0 is bigger - map first */
+
+ memctl->memc_or2 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+ memctl->memc_br2 =
+ (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
+
+ if (size_b1 > 0) {
+ /*
+ * Position Bank 1 immediately above Bank 0
+ */
+ memctl->memc_or3 =
+ ((-size_b1) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+ memctl->memc_br3 =
+ ((CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V)
+ + size_b0;
+ } else {
+ unsigned long reg;
+
+ /*
+ * No bank 1
+ *
+ * invalidate bank
+ */
+ memctl->memc_br3 = 0;
+
+ /* adjust refresh rate depending on SDRAM type, one bank */
+ reg = memctl->memc_mptpr;
+ reg >>= 1; /* reduce to CFG_MPTPR_1BK_8K / _4K */
+ memctl->memc_mptpr = reg;
+ }
+ }
+
+ udelay (10000);
+
+ return (size_b0 + size_b1);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mamr_value, long int *base,
+ long int maxsize)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ volatile long int *addr;
+ ulong cnt, val;
+ ulong save[32]; /* to make test non-destructive */
+ unsigned char i = 0;
+
+ memctl->memc_mamr = mamr_value;
+
+ for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ /* write 0 to base address */
+ addr = base;
+ save[i] = *addr;
+ *addr = 0;
+
+ /* check at base address */
+ if ((val = *addr) != 0) {
+ *addr = save[i];
+ return (0);
+ }
+
+ for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ val = *addr;
+ *addr = save[--i];
+
+ if (val != (~cnt)) {
+ return (cnt * sizeof (long));
+ }
+ }
+ return (maxsize);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/* HW-ID Table (Bits: 2^9;2^7;2^5) */
+#define HW_ID_0 0x0000
+#define HW_ID_1 0x0020
+#define HW_ID_2 0x0080
+#define HW_ID_3 0x00a0
+#define HW_ID_4 0x0200
+#define HW_ID_5 0x0220
+#define HW_ID_6 0x0280
+#define HW_ID_7 0x02a0
+
+void read_hw_vers ()
+{
+ unsigned short rd_msk = 0x02A0;
+
+ /* HW-ID pin-definition */
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+
+ immr->im_ioport.iop_pddir &= ~(rd_msk);
+ immr->im_ioport.iop_pdpar &= ~(rd_msk);
+
+ /* debug printf("State of PD: %x\n",immr->im_ioport.iop_pddat); */
+
+ /* Check the HW-ID */
+ printf ("HW-Version: ");
+ switch (immr->im_ioport.iop_pddat & rd_msk) {
+ case HW_ID_0:
+ printf ("V0.1 - V0.3 / W97238-Q3162-A1-1-2\n");
+ break;
+ case HW_ID_1:
+ printf ("V0.9 / W50037-Q1-D6-1\n");
+ break;
+ case HW_ID_2:
+ printf ("NOT USED - assuming ID#2\n");
+ break;
+ case HW_ID_3:
+ printf ("NOT USED - assuming ID#3\n");
+ break;
+ case HW_ID_4:
+ printf ("NOT USED - assuming ID#4\n");
+ break;
+ case HW_ID_5:
+ printf ("NOT USED - assuming ID#5\n");
+ break;
+ case HW_ID_6:
+ printf ("NOT USED - assuming ID#6\n");
+ break;
+ case HW_ID_7:
+ printf ("NOT USED - assuming ID#7\n");
+ break;
+ default:
+ printf ("###Error###\n");
+ break;
+ }
+}
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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 <mpc8xx.h>
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+/*Orginal table, GPL4 disabled*/
+const uint sdram_table[] =
+{
+ /* single read (offset 0x00 in upm ram) */
+ 0x1f07cc04, 0xeeaeec04, 0x11adcc04, 0xefbbac00,
+ 0x1ff74c47,
+ /* Precharge */
+ 0x1FF74C05,
+ _NOT_USED_,
+ _NOT_USED_,
+ /* burst read (offset 0x08 in upm ram) */
+ 0x1f07cc04, 0xeeaeec04, 0x00adcc04, 0x00afcc00,
+ 0x00afcc00, 0x01afcc00, 0x0fbb8c00, 0x1ff74c47,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* single write (offset 0x18 in upm ram) */
+ 0x1f27cc04, 0xeeaeac00, 0x01b90c04, 0x1ff74c47,
+ /* Load moderegister */
+ 0x1FF74C34, /*Precharge*/
+ 0xEFEA8C34, /*NOP*/
+ 0x1FB54C35, /*Load moderegister*/
+ _NOT_USED_,
+
+ /* burst write (offset 0x20 in upm ram) */
+ 0x1f07cc04, 0xeeaeac00, 0x00ad4c00, 0x00afcc00,
+ 0x00afcc00, 0x01bb8c04, 0x1ff74c47, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* refresh (offset 0x30 in upm ram) */
+ 0x1ff5cc84, 0xffffec04, 0xffffec04, 0xffffec04,
+ 0xffffec84, 0xffffec07, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* exception (offset 0x3C in upm ram) */
+ 0x7fffec07, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+/* GPL5 driven every cycle */
+/* the display and the DSP */
+const uint dsp_disp_table[] =
+{
+ /* single read (offset 0x00 in upm ram) */
+ 0xffffc80c, 0xffffc004, 0x0fffc004, 0x0fffd004,
+ 0x0fffc000, 0x0fffc004, 0x3fffc004, 0xffffcc05,
+ /* burst read (offset 0x08 in upm ram) */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* single write (offset 0x18 in upm ram) */
+ 0xffffcc0c, 0xffffc004, 0x0fffc004, 0x0fffd004,
+ 0x0fffc000, 0x0fffc004, 0x7fffc004, 0xfffffc05,
+ /* burst write (offset 0x20 in upm ram) */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* refresh (offset 0x30 in upm ram) */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* exception (offset 0x3C in upm ram) */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+int checkboard (void)
+{
+ puts ("Board: FlagaDM V3.0\n");
+ return 0;
+}
+
+long int initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ long int size_b0;
+
+ memctl->memc_or2 = CFG_OR2;
+ memctl->memc_br2 = CFG_BR2;
+
+ udelay(100);
+ upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
+
+ memctl->memc_mptpr = MPTPR_PTP_DIV16;
+ memctl->memc_mamr = CFG_MAMR_48_SDR | MAMR_TLFA_1X;
+
+ /*Do the initialization of the SDRAM*/
+ /*Start with the precharge cycle*/
+ memctl->memc_mcr = (MCR_OP_RUN | MCR_UPM_A | MCR_MB_CS2 | \
+ MCR_MLCF(1) | MCR_MAD(0x5));
+
+ /*Then we need two refresh cycles*/
+ memctl->memc_mamr = CFG_MAMR_48_SDR | MAMR_TLFA_2X;
+ memctl->memc_mcr = (MCR_OP_RUN | MCR_UPM_A | MCR_MB_CS2 | \
+ MCR_MLCF(2) | MCR_MAD(0x30));
+
+ /*Mode register programming*/
+ memctl->memc_mar = 0x00000088; /*CAS Latency = 2 and burst length = 4*/
+ memctl->memc_mcr = (MCR_OP_RUN | MCR_UPM_A | MCR_MB_CS2 | \
+ MCR_MLCF(1) | MCR_MAD(0x1C));
+
+ /* That should do it, just enable the periodic refresh in burst of 4*/
+ memctl->memc_mamr = CFG_MAMR_48_SDR | MAMR_TLFA_4X;
+ memctl->memc_mamr |= (MAMR_PTAE | MAMR_GPL_B4DIS);
+
+ size_b0 = 16*1024*1024;
+
+ /*
+ * No bank 1 or 3
+ * invalidate bank
+ */
+ memctl->memc_br1 = 0;
+ memctl->memc_br3 = 0;
+
+ upmconfig(UPMB, (uint *)dsp_disp_table, sizeof(dsp_disp_table)/sizeof(uint));
+
+ memctl->memc_mbmr = MAMR_GPL_B4DIS;
+
+ memctl->memc_or4 = CFG_OR4;
+ memctl->memc_br4 = CFG_BR4;
+
+ return (size_b0);
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Adapted from FADS and other board config files to GTH by thomas@corelatus.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 <config.h>
+#include <watchdog.h>
+#include <mpc8xx.h>
+#include "ee_access.h"
+#include "ee_dev.h"
+
+#ifdef CONFIG_BDM
+#undef printf
+#define printf(a,...) /* nothing */
+#endif
+
+
+int checkboard (void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ int Id = 0;
+ int Rev = 0;
+ u32 Pbdat;
+
+ puts ("Board: ");
+
+ /* Turn on leds and setup for reading rev and id */
+
+#define PB_OUTS (PB_BLUE_LED|PB_ID_GND)
+#define PB_INS (PB_ID_0|PB_ID_1|PB_ID_2|PB_ID_3|PB_REV_1|PB_REV_0)
+
+ immap->im_cpm.cp_pbpar &= ~(PB_OUTS | PB_INS);
+
+ immap->im_cpm.cp_pbdir &= ~PB_INS;
+
+ immap->im_cpm.cp_pbdir |= PB_OUTS;
+ immap->im_cpm.cp_pbodr |= PB_OUTS;
+ immap->im_cpm.cp_pbdat &= ~PB_OUTS;
+
+ /* Hold 100 Mbit in reset until fpga is loaded */
+ immap->im_ioport.iop_pcpar &= ~PC_ENET100_RESET;
+ immap->im_ioport.iop_pcdir |= PC_ENET100_RESET;
+ immap->im_ioport.iop_pcso &= ~PC_ENET100_RESET;
+ immap->im_ioport.iop_pcdat &= ~PC_ENET100_RESET;
+
+ /* Turn on front led to show that we are alive */
+ immap->im_ioport.iop_papar &= ~PA_FRONT_LED;
+ immap->im_ioport.iop_padir |= PA_FRONT_LED;
+ immap->im_ioport.iop_paodr |= PA_FRONT_LED;
+ immap->im_ioport.iop_padat &= ~PA_FRONT_LED;
+
+ Pbdat = immap->im_cpm.cp_pbdat;
+
+ if (!(Pbdat & PB_ID_0))
+ Id += 1;
+ if (!(Pbdat & PB_ID_1))
+ Id += 2;
+ if (!(Pbdat & PB_ID_2))
+ Id += 4;
+ if (!(Pbdat & PB_ID_3))
+ Id += 8;
+
+ if (Pbdat & PB_REV_0)
+ Rev += 1;
+ if (Pbdat & PB_REV_1)
+ Rev += 2;
+
+ /* Turn ID off since we dont need it anymore */
+ immap->im_cpm.cp_pbdat |= PB_ID_GND;
+
+ printf ("GTH board, rev %d, id=0x%01x\n", Rev, Id);
+ return 0;
+}
+
+#define _NOT_USED_ 0xffffffff
+const uint sdram_table[] = {
+ /* Single read, offset 0 */
+ 0x0f3dfc04, 0x0eefbc04, 0x01bf7c04, 0x0feafc00,
+ 0x1fb5fc45, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* Burst read, Offset 0x8, 4 reads */
+ 0x0f3dfc04, 0x0eefbc04, 0x00bf7c04, 0x00ffec00,
+ 0x00fffc00, 0x01eafc00, 0x1fb5fc00, 0xfffffc45,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* Not used part of burst read is used for MRS, Offset 0x14 */
+ 0xefeabc34, 0x1fb57c34, 0xfffffc05, _NOT_USED_,
+ /* _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, */
+
+ /* Single write, Offset 0x18 */
+ 0x0f3dfc04, 0x0eebbc00, 0x01a27c04, 0x1fb5fc45,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* Burst write, Offset 0x20. 4 writes */
+ 0x0f3dfc04, 0x0eebbc00, 0x00b77c00, 0x00fffc00,
+ 0x00fffc00, 0x01eafc04, 0x1fb5fc45, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* Not used part of burst write is used for precharge, Offset 0x2C */
+ 0x0ff5fc04, 0xfffffc05, _NOT_USED_, _NOT_USED_,
+ /* _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_, */
+
+ /* Period timer service. Offset 0x30. Refresh. Wait at least 70 ns after refresh command */
+ 0x1ffd7c04, 0xfffffc04, 0xfffffc04, 0xfffffc05,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* Exception, Offset 0x3C */
+ 0xfffffc04, 0xfffffc05, _NOT_USED_, _NOT_USED_
+};
+
+const uint fpga_table[] = {
+ /* Single read, offset 0 */
+ 0x0cffec04, 0x00ffec04, 0x00ffec04, 0x00ffec04,
+ 0x00fffc04, 0x00fffc00, 0x00ffec04, 0xffffec05,
+
+ /* Burst read, Offset 0x8 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* Single write, Offset 0x18 */
+ 0x0cffec04, 0x00ffec04, 0x00ffec04, 0x00ffec04,
+ 0x00fffc04, 0x00fffc00, 0x00ffec04, 0xffffec05,
+
+ /* Burst write, Offset 0x20. */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* Period timer service. Offset 0x30. */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+
+ /* Exception, Offset 0x3C */
+ 0xfffffc04, 0xfffffc05, _NOT_USED_, _NOT_USED_
+};
+
+int _initsdram (uint base, uint * noMbytes)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *mc = &immap->im_memctl;
+ volatile u32 *memptr;
+
+ mc->memc_mptpr = MPTPR_PTP_DIV16; /* (16-17) */
+
+ /* SDRAM in UPMA
+
+ GPL_0 is connected instead of A19 to SDRAM.
+ According to table 16-17, AMx should be 001, i.e. type 1
+ and GPL_0 should hold address A10 when multiplexing */
+
+ mc->memc_mamr = (0x2E << MAMR_PTA_SHIFT) | MAMR_PTAE | MAMR_AMA_TYPE_1 | MAMR_G0CLA_A10 | MAMR_RLFA_1X | MAMR_WLFA_1X | MAMR_TLFA_1X; /* (16-13) */
+
+ upmconfig (UPMA, (uint *) sdram_table,
+ sizeof (sdram_table) / sizeof (uint));
+
+ /* Perform init of sdram ( Datasheet Page 9 )
+ Precharge */
+ mc->memc_mcr = 0x8000212C; /* run upm a at 0x2C (16-15) */
+
+ /* Run 2 refresh cycles */
+ mc->memc_mcr = 0x80002130; /* run upm a at 0x30 (16-15) */
+ mc->memc_mcr = 0x80002130; /* run upm a at 0x30 (16-15) */
+
+ /* Set Mode register */
+ mc->memc_mar = 0x00000088; /* set mode register (address) to 0x022 (16-17) */
+ /* Lower 2 bits are not connected to chip */
+ mc->memc_mcr = 0x80002114; /* run upm a at 0x14 (16-15) */
+
+ /* CS1, base 0x0000000 - 64 Mbyte, use UPM A */
+ mc->memc_or1 = 0xfc000000 | OR_CSNT_SAM;
+ mc->memc_br1 = BR_MS_UPMA | BR_V; /* SDRAM base always 0 */
+
+ /* Test if we really have 64 MB SDRAM */
+ memptr = (u32 *) 0;
+ *memptr = 0;
+
+ memptr = (u32 *) 0x2000000; /* First u32 in upper 32 MB */
+ *memptr = 0x12345678;
+
+ memptr = (u32 *) 0;
+ if (*memptr == 0x12345678) {
+ /* Wrapped, only have 32 MB */
+ mc->memc_or1 = 0xfe000000 | OR_CSNT_SAM;
+ *noMbytes = 32;
+ } else {
+ /* 64 MB */
+ *noMbytes = 64;
+ }
+
+ /* Setup FPGA in UPMB */
+ upmconfig (UPMB, (uint *) fpga_table,
+ sizeof (fpga_table) / sizeof (uint));
+
+ /* Enable UPWAITB */
+ mc->memc_mbmr = MAMR_GPL_B4DIS; /* (16-13) */
+
+ /* CS2, base FPGA_2_BASE - 4 MByte, use UPM B 32 Bit */
+ mc->memc_or2 = 0xffc00000 | OR_BI;
+ mc->memc_br2 = FPGA_2_BASE | BR_MS_UPMB | BR_V;
+
+ /* CS3, base FPGA_3_BASE - 4 MByte, use UPM B 16 bit */
+ mc->memc_or3 = 0xffc00000 | OR_BI;
+ mc->memc_br3 = FPGA_3_BASE | BR_MS_UPMB | BR_V | BR_PS_16;
+
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+void _sdramdisable (void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+
+ memctl->memc_br1 = 0x00000000;
+
+ /* maybe we should turn off upmb here or something */
+}
+
+/* ------------------------------------------------------------------------- */
+
+int initsdram (uint base, uint * noMbytes)
+{
+ *noMbytes = 32;
+
+#ifdef CONFIG_START_IN_RAM
+ /* SDRAM is already setup. Dont touch it */
+ return 0;
+#else
+
+ if (!_initsdram (base, noMbytes)) {
+
+ return 0;
+ } else {
+ _sdramdisable ();
+
+ return -1;
+ }
+#endif
+}
+
+long int initdram (int board_type)
+{
+ u32 *i;
+ u32 j;
+ u32 k;
+
+ /* GTH only have SDRAM */
+ uint sdramsz;
+
+ if (!initsdram (0x00000000, &sdramsz)) {
+ printf ("(%u MB SDRAM) ", sdramsz);
+ } else {
+ /********************************
+ *SDRAM ERROR, HALT PROCESSOR
+ *********************************/
+ printf ("SDRAM ERROR\n");
+ while (1);
+ }
+
+#ifndef CONFIG_START_IN_RAM
+
+#define U32_S ((sdramsz<<18)-1)
+
+#if 1
+ /* Do a simple memory test */
+ for (i = (u32 *) 0, j = 0; (u32) i < U32_S; i += 2, j += 2) {
+ *i = j + (j << 17);
+ *(i + 1) = ~(j + (j << 18));
+ }
+
+ WATCHDOG_RESET ();
+
+ printf (".");
+
+ for (i = (u32 *) 0, j = 0; (u32) i < U32_S; i += 2, j += 2) {
+ k = *i;
+ if (k != (j + (j << 17))) {
+ printf ("Mem test error, i=0x%x, 0x%x\n, 0x%x", (u32) i, j, k);
+ while (1);
+ }
+ k = *(i + 1);
+ if (k != ~(j + (j << 18))) {
+ printf ("Mem test error(+1), i=0x%x, 0x%x\n, 0x%x",
+ (u32) i + 1, j, k);
+ while (1);
+ }
+ }
+#endif
+
+ WATCHDOG_RESET ();
+
+ /* Clear memory */
+ for (i = (u32 *) 0; (u32) i < U32_S; i++) {
+ *i = 0;
+ }
+#endif /* !start in ram */
+
+ WATCHDOG_RESET ();
+
+ return (sdramsz << 20);
+}
+
+#define POWER_OFFSET 0xF0000
+#define SW_WATCHDOG_REASON 13
+
+#define BOOTDATA_OFFSET 0xF8000
+#define MAX_ATTEMPTS 5
+
+#define FAILSAFE_BOOT 1
+#define SYSTEM_BOOT 2
+
+#define WRITE_FLASH16(a, d) \
+do \
+{ \
+ *((volatile u16 *) (a)) = (d);\
+ } while(0)
+
+static void write_bootdata (volatile u16 * addr, u8 System, u8 Count)
+{
+ u16 data;
+ volatile u16 *flash = (u16 *) (CFG_FLASH_BASE);
+
+ if ((System != FAILSAFE_BOOT) & (System != SYSTEM_BOOT)) {
+ printf ("Invalid system data %u, setting failsafe\n", System);
+ System = FAILSAFE_BOOT;
+ }
+
+ if ((Count < 1) | (Count > MAX_ATTEMPTS)) {
+ printf ("Invalid boot count %u, setting 1\n", Count);
+ Count = 1;
+ }
+
+ if (System == FAILSAFE_BOOT) {
+ printf ("Setting failsafe boot in flash\n");
+ } else {
+ printf ("Setting system boot in flash\n");
+ }
+ printf ("Boot attempt %d\n", Count);
+
+ data = (System << 8) | Count;
+ /* AMD 16 bit */
+ WRITE_FLASH16 (&flash[0x555], 0xAAAA);
+ WRITE_FLASH16 (&flash[0x2AA], 0x5555);
+ WRITE_FLASH16 (&flash[0x555], 0xA0A0);
+
+ WRITE_FLASH16 (addr, data);
+}
+
+static void maybe_update_restart_reason (volatile u32 * addr32)
+{
+ /* Update addr if sw wd restart */
+ volatile u16 *flash = (u16 *) (CFG_FLASH_BASE);
+ volatile u16 *addr_16 = (u16 *) addr32;
+ u32 rsr;
+
+ /* Dont reset register now */
+ rsr = ((volatile immap_t *) CFG_IMMR)->im_clkrst.car_rsr;
+
+ rsr >>= 24;
+
+ if (rsr & 0x10) {
+ /* Was really a sw wd restart, update reason */
+
+ printf ("Last restart by software watchdog\n");
+
+ /* AMD 16 bit */
+ WRITE_FLASH16 (&flash[0x555], 0xAAAA);
+ WRITE_FLASH16 (&flash[0x2AA], 0x5555);
+ WRITE_FLASH16 (&flash[0x555], 0xA0A0);
+
+ WRITE_FLASH16 (addr_16, 0);
+
+ udelay (1000);
+
+ WATCHDOG_RESET ();
+
+ /* AMD 16 bit */
+ WRITE_FLASH16 (&flash[0x555], 0xAAAA);
+ WRITE_FLASH16 (&flash[0x2AA], 0x5555);
+ WRITE_FLASH16 (&flash[0x555], 0xA0A0);
+
+ WRITE_FLASH16 (addr_16 + 1, SW_WATCHDOG_REASON);
+
+ }
+}
+
+static void check_restart_reason (void)
+{
+ /* Update restart reason if sw watchdog was
+ triggered */
+
+ int i;
+ volatile u32 *raddr;
+
+ raddr = (u32 *) (CFG_FLASH_BASE + POWER_OFFSET);
+
+ if (*raddr == 0xFFFFFFFF) {
+ /* Nothing written */
+ maybe_update_restart_reason (raddr);
+ } else {
+ /* Search for latest written reason */
+ i = 0;
+ while ((*(raddr + 2) != 0xFFFFFFFF) & (i < 2000)) {
+ raddr += 2;
+ i++;
+ }
+ if (i >= 2000) {
+ /* Whoa, dont write any more */
+ printf ("*** No free restart reason found ***\n");
+ } else {
+ /* Check if written */
+ if (*raddr == 0) {
+ /* Erased by kernel, no new reason written */
+ maybe_update_restart_reason (raddr + 2);
+ }
+ }
+ }
+}
+
+static void check_boot_tries (void)
+{
+ /* Count the number of boot attemps
+ switch system if too many */
+
+ int i;
+ volatile u16 *addr;
+ volatile u16 data;
+ int failsafe = 1;
+ u8 system;
+ u8 count;
+
+ addr = (u16 *) (CFG_FLASH_BASE + BOOTDATA_OFFSET);
+
+ if (*addr == 0xFFFF) {
+ printf ("*** No bootdata exists. ***\n");
+ write_bootdata (addr, FAILSAFE_BOOT, 1);
+ } else {
+ /* Search for latest written bootdata */
+ i = 0;
+ while ((*(addr + 1) != 0xFFFF) & (i < 8000)) {
+ addr++;
+ i++;
+ }
+ if (i >= 8000) {
+ /* Whoa, dont write any more */
+ printf ("*** No bootdata found. Not updating flash***\n");
+ } else {
+ /* See how many times we have tried to boot real system */
+ data = *addr;
+ system = data >> 8;
+ count = data & 0xFF;
+ if ((system != SYSTEM_BOOT) & (system != FAILSAFE_BOOT)) {
+ printf ("*** Wrong system %d\n", system);
+ system = FAILSAFE_BOOT;
+ count = 1;
+ } else {
+ switch (count) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ /* Try same system again if needed */
+ count++;
+ break;
+
+ case 5:
+ /* Switch system and reset tries */
+ count = 1;
+ system = 3 - system;
+ printf ("***Too many boot attempts, switching system***\n");
+ break;
+ default:
+ /* Switch system, start over and hope it works */
+ printf ("***Unexpected data on addr 0x%x, %u***\n",
+ (u32) addr, data);
+ count = 1;
+ system = 3 - system;
+ }
+ }
+ write_bootdata (addr + 1, system, count);
+ if (system == SYSTEM_BOOT) {
+ failsafe = 0;
+ }
+ }
+ }
+ if (failsafe) {
+ printf ("Booting failsafe system\n");
+ setenv ("bootargs", "panic=1 root=/dev/hda7");
+ setenv ("bootcmd", "disk 100000 0:5;bootm 100000");
+ } else {
+ printf ("Using normal system\n");
+ setenv ("bootargs", "panic=1 root=/dev/hda4");
+ setenv ("bootcmd", "disk 100000 0:2;bootm 100000");
+ }
+}
+
+int misc_init_r (void)
+{
+ u8 Rx[80];
+ u8 Tx[5];
+ int page;
+ int read = 0;
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+
+ /* Kill fpga */
+ immap->im_ioport.iop_papar &= ~(PA_FL_CONFIG | PA_FL_CE);
+ immap->im_ioport.iop_padir |= (PA_FL_CONFIG | PA_FL_CE);
+ immap->im_ioport.iop_paodr &= ~(PA_FL_CONFIG | PA_FL_CE);
+
+ /* Enable fpga, active low */
+ immap->im_ioport.iop_padat &= ~PA_FL_CE;
+
+ /* Start configuration */
+ immap->im_ioport.iop_padat &= ~PA_FL_CONFIG;
+ udelay (2);
+
+ immap->im_ioport.iop_padat |= (PA_FL_CONFIG | PA_FL_CE);
+
+ /* Check if we need to boot failsafe system */
+ check_boot_tries ();
+
+ /* Check if we need to update restart reason */
+ check_restart_reason ();
+
+ if (ee_init_data ()) {
+ printf ("EEPROM init failed\n");
+ return (0);
+ }
+
+ /* Read the pages where ethernet address is stored */
+
+ for (page = EE_USER_PAGE_0; page <= EE_USER_PAGE_0 + 2; page++) {
+ /* Copy from nvram to scratchpad */
+ Tx[0] = RECALL_MEMORY;
+ Tx[1] = page;
+ if (ee_do_command (Tx, 2, NULL, 0, TRUE)) {
+ printf ("EE user page %d recall failed\n", page);
+ return (0);
+ }
+
+ Tx[0] = READ_SCRATCHPAD;
+ if (ee_do_command (Tx, 2, Rx + read, 9, TRUE)) {
+ printf ("EE user page %d read failed\n", page);
+ return (0);
+ }
+ /* Crc in 9:th byte */
+ if (!ee_crc_ok (Rx + read, 8, *(Rx + read + 8))) {
+ printf ("EE read failed, page %d. CRC error\n", page);
+ return (0);
+ }
+ read += 8;
+ }
+
+ /* Add eos after eth addr */
+ Rx[17] = 0;
+
+ printf ("Ethernet addr read from eeprom: %s\n\n", Rx);
+
+ if ((Rx[2] != ':') |
+ (Rx[5] != ':') |
+ (Rx[8] != ':') | (Rx[11] != ':') | (Rx[14] != ':')) {
+ printf ("*** ethernet addr invalid, using default ***\n");
+ } else {
+ setenv ("ethaddr", Rx);
+ }
+ return (0);
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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 <commproc.h>
+#include <mpc8xx.h>
+
+#ifdef CONFIG_SHOW_BOOT_PROGRESS
+# include <status_led.h>
+# define SHOW_BOOT_PROGRESS(arg) show_boot_progress(arg)
+#else
+# define SHOW_BOOT_PROGRESS(arg)
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+static ulong board_init (void);
+static void send_smi_frame (volatile scc_t * sp, volatile cbd_t * bd,
+ uchar * msg);
+
+/* ------------------------------------------------------------------------- */
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+const uint sdram_table[] = {
+ /*
+ * Single Read. (Offset 0 in UPMA RAM)
+ */
+ 0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
+ 0x1ff77c47, /* last */
+ /*
+ * SDRAM Initialization (offset 5 in UPMA RAM)
+ *
+ * This is no UPM entry point. The following definition uses
+ * the remaining space to establish an initialization
+ * sequence, which is executed by a RUN command.
+ *
+ */
+ 0x1fe77c35, 0xffaffc34, 0x1fa57c35, /* last */
+ /*
+ * Burst Read. (Offset 8 in UPMA RAM)
+ */
+ 0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
+ 0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Single Write. (Offset 18 in UPMA RAM)
+ */
+ 0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Burst Write. (Offset 20 in UPMA RAM)
+ */
+ 0x1f07fc04, 0xeeaebc00, 0x10ad4c00, 0xf0afcc00,
+ 0xf0afcc00, 0xe1bb8c06, 0x1ff77c47, /* last */
+ _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Refresh (Offset 30 in UPMA RAM)
+ */
+ 0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
+ 0xfffffc84, 0xfffffc07, /* last */
+ _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Exception. (Offset 3c in UPMA RAM)
+ */
+ 0x7ffffc07, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ *
+ * Test ID string (HERMES...)
+ *
+ * Return code for board revision and network speed
+ */
+
+int checkboard (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ unsigned char *s = getenv ("serial#");
+ unsigned char *e;
+
+ puts ("Board: ");
+
+ if (!s || strncmp (s, "HERMES", 6)) {
+ puts ("### No HW ID - assuming HERMES-PRO");
+ } else {
+ for (e = s; *e; ++e) {
+ if (*e == ' ')
+ break;
+ }
+
+ for (; s < e; ++s) {
+ putc (*s);
+ }
+ }
+
+ gd->board_type = board_init ();
+
+ printf (" Rev. %ld.x\n", (gd->board_type >> 16));
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ long int size, size8, size9;
+
+ upmconfig (UPMA, (uint *) sdram_table,
+ sizeof (sdram_table) / sizeof (uint));
+
+ /*
+ * Preliminary prescaler for refresh
+ */
+ memctl->memc_mptpr = 0x0400;
+
+ memctl->memc_mar = 0x00000088;
+
+ /*
+ * Map controller banks 1 to the SDRAM banks at preliminary address
+ */
+ memctl->memc_or1 = CFG_OR1_PRELIM;
+ memctl->memc_br1 = CFG_BR1_PRELIM;
+
+ /* HERMES-PRO boards have only one bank SDRAM */
+
+
+ udelay (200);
+
+ /* perform SDRAM initializsation sequence */
+
+ memctl->memc_mamr = 0xD0802114;
+ memctl->memc_mcr = 0x80002105;
+ udelay (1);
+ memctl->memc_mamr = 0xD0802118;
+ memctl->memc_mcr = 0x80002130;
+ udelay (1);
+ memctl->memc_mamr = 0xD0802114;
+ memctl->memc_mcr = 0x80002106;
+
+ udelay (1000);
+
+ /*
+ * Check Bank 0 Memory Size for re-configuration
+ *
+ * try 8 column mode
+ */
+ size8 = dram_size (CFG_MAMR_8COL, (ulong *) SDRAM_BASE_PRELIM,
+ SDRAM_MAX_SIZE);
+
+ udelay (1000);
+
+ /*
+ * try 9 column mode
+ */
+ size9 = dram_size (CFG_MAMR_9COL, (ulong *) SDRAM_BASE_PRELIM,
+ SDRAM_MAX_SIZE);
+
+ if (size8 < size9) { /* leave configuration at 9 columns */
+ size = size9;
+/* debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20); */
+ } else { /* back to 8 columns */
+ size = size8;
+ memctl->memc_mamr = CFG_MAMR_8COL;
+ udelay (500);
+/* debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20); */
+ }
+
+ udelay (1000);
+
+ memctl->memc_or1 = ((-size) & 0xFFFF0000) | SDRAM_TIMING;
+ memctl->memc_br1 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
+
+ udelay (10000);
+
+ return (size);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mamr_value, long int *base,
+ long int maxsize)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ volatile long int *addr;
+ ulong cnt, val;
+ ulong save[32]; /* to make test non-destructive */
+ unsigned char i = 0;
+
+ memctl->memc_mamr = mamr_value;
+
+ for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ /* write 0 to base address */
+ addr = base;
+ save[i] = *addr;
+ *addr = 0;
+
+ /* check at base address */
+ if ((val = *addr) != 0) {
+ *addr = save[i];
+ return (0);
+ }
+
+ for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ val = *addr;
+ *addr = save[--i];
+
+ if (val != (~cnt)) {
+ return (cnt * sizeof (long));
+ }
+ }
+ return (maxsize);
+}
+
+/* ------------------------------------------------------------------------- */
+
+#define PB_LED_3 0x00020000 /* Status LED's */
+#define PB_LED_2 0x00010000
+#define PB_LED_1 0x00008000
+#define PB_LED_0 0x00004000
+
+#define PB_LED_ALL (PB_LED_0 | PB_LED_1 | PB_LED_2 | PB_LED_3)
+
+#define PC_REP_SPD1 0x00000800
+#define PC_REP_SPD0 0x00000400
+
+#define PB_RESET_2081 0x00000020 /* Reset PEB2081 */
+
+#define PB_MAI_4 0x00000010 /* Configuration */
+#define PB_MAI_3 0x00000008
+#define PB_MAI_2 0x00000004
+#define PB_MAI_1 0x00000002
+#define PB_MAI_0 0x00000001
+
+#define PB_MAI_ALL (PB_MAI_0 | PB_MAI_1 | PB_MAI_2 | PB_MAI_3 | PB_MAI_4)
+
+
+#define PC_REP_MGRPRS 0x0200
+#define PC_REP_SPD 0x0040 /* Select 100 Mbps */
+#define PC_REP_RES 0x0004
+#define PC_BIT14 0x0002 /* ??? */
+#define PC_BIT15 0x0001 /* ??? ENDSL ?? */
+
+/* ------------------------------------------------------------------------- */
+
+static ulong board_init (void)
+{
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+ ulong reg, revision, speed = 100;
+ int ethspeed;
+ char *s;
+
+ if ((s = getenv ("ethspeed")) != NULL) {
+ if (strcmp (s, "100") == 0) {
+ ethspeed = 100;
+ } else if (strcmp (s, "10") == 0) {
+ ethspeed = 10;
+ } else {
+ ethspeed = 0;
+ }
+ } else {
+ ethspeed = 0;
+ }
+
+ /* Configure Port B Output Pins => 0x0003cc3F */
+ reg = PB_LED_ALL | PC_REP_SPD1 | PC_REP_SPD0 | PB_RESET_2081 |
+ PB_MAI_ALL;
+ immr->im_cpm.cp_pbpar &= ~reg;
+ immr->im_cpm.cp_pbodr &= ~reg;
+ immr->im_cpm.cp_pbdat &= ~reg; /* all 0 */
+ immr->im_cpm.cp_pbdir |= reg;
+
+ /* Check hardware revision */
+ if ((immr->im_ioport.iop_pcdat & 0x0003) == 0x0003) {
+ /*
+ * Revision 3.x hardware
+ */
+ revision = 3;
+
+ immr->im_ioport.iop_pcdat = 0x0240;
+ immr->im_ioport.iop_pcdir = (PC_REP_MGRPRS | PC_REP_SPD | PC_REP_RES | PC_BIT14); /* = 0x0246 */
+ immr->im_ioport.iop_pcdat |= PC_REP_RES;
+ } else {
+ immr->im_ioport.iop_pcdat = 0x0002;
+ immr->im_ioport.iop_pcdir = (PC_REP_MGRPRS | PC_REP_RES | PC_BIT14 | PC_BIT15); /* = 0x0207 */
+
+ if ((immr->im_ioport.iop_pcdat & PC_REP_SPD) == 0) {
+ /*
+ * Revision 2.x hardware: PC9 connected to PB21
+ */
+ revision = 2;
+
+ if (ethspeed == 0) {
+ /* both 10 and 100 Mbps allowed:
+ * select 10 Mbps and autonegotiation
+ */
+ puts (" [10+100]");
+ immr->im_cpm.cp_pbdat = 0; /* SPD1:SPD0 = 0:0 - autonegot. */
+ speed = 10;
+ } else if (ethspeed == 10) {
+ /* we are asked for 10 Mbps,
+ * so select 10 Mbps
+ */
+ puts (" [10]");
+ immr->im_cpm.cp_pbdat = 0; /* ??? */
+ speed = 10;
+ } else {
+ /* anything else:
+ * select 100 Mbps
+ */
+ puts (" [100]");
+ immr->im_cpm.cp_pbdat = PC_REP_SPD0 | PC_REP_SPD1;
+ /* SPD1:SPD0 = 1:1 - 100 Mbps */
+ speed = 100;
+ }
+ immr->im_ioport.iop_pcdat |= (PC_REP_RES | PC_BIT14);
+
+ /* must be run from RAM */
+ /* start_lxt980 (speed); */
+ /*************************/
+ } else {
+ /*
+ * Revision 1.x hardware
+ */
+ revision = 1;
+
+ immr->im_ioport.iop_pcdat = PC_REP_MGRPRS | PC_BIT14; /* = 0x0202 */
+ immr->im_ioport.iop_pcdir = (PC_REP_MGRPRS | PC_REP_SPD | PC_REP_RES | PC_BIT14 | PC_BIT15); /* = 0x0247 */
+
+ if (ethspeed == 0) {
+ /* both 10 and 100 Mbps allowed:
+ * select 100 Mbps and autonegotiation
+ */
+ puts (" [10+100]");
+ immr->im_cpm.cp_pbdat = 0; /* SPD1:SPD0 = 0:0 - autonegot. */
+ immr->im_ioport.iop_pcdat |= PC_REP_SPD;
+ } else if (ethspeed == 10) {
+ /* we are asked for 10 Mbps,
+ * so select 10 Mbps
+ */
+ puts (" [10]");
+ immr->im_cpm.cp_pbdat = PC_REP_SPD0; /* SPD1:SPD0 = 0:1 - 10 Mbps */
+ } else {
+ /* anything else:
+ * select 100 Mbps
+ */
+ puts (" [100]");
+ immr->im_cpm.cp_pbdat = PC_REP_SPD0 | PC_REP_SPD1;
+ /* SPD1:SPD0 = 1:1 - 100 Mbps */
+ immr->im_ioport.iop_pcdat |= PC_REP_SPD;
+ }
+
+ immr->im_ioport.iop_pcdat |= PC_REP_RES;
+ }
+ }
+ SHOW_BOOT_PROGRESS (0x00);
+
+ return ((revision << 16) | (speed & 0xFFFF));
+}
+
+/* ------------------------------------------------------------------------- */
+
+#define SCC_SM 1 /* Index => SCC2 */
+#define PROFF PROFF_SCC2
+
+#define SMI_MSGLEN 8 /* Length of SMI Messages */
+
+#define PHYGPCR_ADDR 0x109 /* Port Enable */
+#define PHYPCR_ADDR 0x132 /* PHY Port Control Reg. (port 1) */
+#define LEDPCR_ADDR 0x141 /* LED Port Control Reg. */
+#define RPRESET_ADDR 0x144 /* Repeater Reset */
+
+#define PHYPCR_SPEED 0x2000 /* on for 100 Mbps, off for 10 Mbps */
+#define PHYPCR_AN 0x1000 /* on to enable Auto-Negotiation */
+#define PHYPCR_REST_AN 0x0200 /* on to restart Auto-Negotiation */
+#define PHYPCR_FDX 0x0100 /* on for Full Duplex, off for HDX */
+#define PHYPCR_COLT 0x0080 /* on to enable COL signal test */
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Must run from RAM:
+ * uses parameter RAM area which is used for stack while running from ROM
+ */
+void hermes_start_lxt980 (int speed)
+{
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+ volatile cpm8xx_t *cp = (cpm8xx_t *) & (immr->im_cpm);
+ volatile scc_t *sp = (scc_t *) & (cp->cp_scc[SCC_SM]);
+ volatile cbd_t *bd;
+ volatile hdlc_pram_t *hp;
+ uchar smimsg[SMI_MSGLEN];
+ ushort phypcrval;
+ uint bd_off;
+ int pnr;
+
+ printf ("LXT9880: %3d Mbps\n", speed);
+
+ immr->im_ioport.iop_paodr |= 0x0008; /* init PAODR: PA12 (TXD2) open drain */
+ immr->im_ioport.iop_papar |= 0x400c; /* init PAPAR: TXD2, RXD2, BRGO4 */
+ immr->im_ioport.iop_padir &= 0xbff3; /* init PADIR: BRGO4 */
+ immr->im_ioport.iop_padir |= 0x4000;
+
+ /* get temporary BD; no need for permanent alloc */
+ bd_off = dpram_base_align (8);
+
+ bd = (cbd_t *) (immr->im_cpm.cp_dpmem + bd_off);
+
+ bd->cbd_bufaddr = 0;
+ bd->cbd_datlen = 0;
+ bd->cbd_sc = BD_SC_WRAP | BD_SC_LAST | BD_SC_INTRPT | BD_SC_TC;
+
+ /* init. baudrate generator BRG4 */
+ cp->cp_brgc4 = (0x00010000 | (50 << 1)); /* output 1 MHz */
+
+ cp->cp_sicr &= 0xFFFF00FF; /* SICR: mask SCC2 */
+ cp->cp_sicr |= 0x00001B00; /* SICR: SCC2 clk BRG4 */
+
+ /* init SCC_SM register */
+ sp->scc_psmr = 0x0000; /* init PSMR: no additional flags */
+ sp->scc_todr = 0x0000;
+ sp->scc_dsr = 0x7e7e;
+
+ /* init. SCC_SM parameter area */
+ hp = (hdlc_pram_t *) & cp->cp_dparam[PROFF];
+
+ hp->tbase = bd_off; /* offset from beginning of DPRAM */
+
+ hp->rfcr = 0x18;
+ hp->tfcr = 0x18;
+ hp->mrblr = 10;
+
+ hp->c_mask = 0x0000f0b8;
+ hp->c_pres = 0x0000ffff;
+
+ hp->disfc = 0;
+ hp->crcec = 0;
+ hp->abtsc = 0;
+ hp->nmarc = 0;
+ hp->retrc = 0;
+
+ hp->mflr = 10;
+
+ hp->rfthr = 1;
+
+ hp->hmask = 0;
+ hp->haddr1 = 0;
+ hp->haddr2 = 0;
+ hp->haddr3 = 0;
+ hp->haddr4 = 0;
+
+ cp->cp_cpcr = SCC_SM << 6 | 0x0001; /* SCC_SM: init TX/RX params */
+ while (cp->cp_cpcr & CPM_CR_FLG);
+
+ /* clear all outstanding SCC events */
+ sp->scc_scce = ~0;
+
+ /* enable transmitter: GSMR_L: TPL=2(16bits), TPP=3(all ones), ENT */
+ sp->scc_gsmrh = 0;
+ sp->scc_gsmrl |= SCC_GSMRL_TPL_16 | SCC_GSMRL_TPP_ALL1 |
+ SCC_GSMRL_ENT | SCC_GSMRL_MODE_HDLC;
+
+#if 0
+ smimsg[0] = 0x00; /* CHIP/HUB ID */
+ smimsg[1] = 0x38; /* WRITE CMD */
+ smimsg[2] = (RPRESET_ADDR << 4) & 0xf0;
+ smimsg[3] = RPRESET_ADDR >> 4;
+ smimsg[4] = 0x01;
+ smimsg[5] = 0x00;
+ smimsg[6] = 0x00;
+ smimsg[7] = 0x00;
+
+ send_smi_frame (sp, bd, smimsg);
+#endif
+
+ smimsg[0] = 0x7f; /* BROADCAST */
+ smimsg[1] = 0x34; /* ASSIGN HUB ID */
+ smimsg[2] = 0x00;
+ smimsg[3] = 0x00;
+ smimsg[4] = 0x00; /* HUB ID = 0 */
+ smimsg[5] = 0x00;
+ smimsg[6] = 0x00;
+ smimsg[7] = 0x00;
+
+ send_smi_frame (sp, bd, smimsg);
+
+ smimsg[0] = 0x7f; /* BROADCAST */
+ smimsg[1] = 0x3c; /* SET ARBOUT TO 0 */
+ smimsg[2] = 0x00; /* ADDRESS = 0 */
+ smimsg[3] = 0x00;
+ smimsg[4] = 0x00; /* DATA = 0 */
+ smimsg[5] = 0x00;
+ smimsg[6] = 0x00;
+ smimsg[7] = 0x00;
+
+ send_smi_frame (sp, bd, smimsg);
+
+ if (speed == 100) {
+ phypcrval = PHYPCR_SPEED; /* 100 MBIT, disable autoneg. */
+ } else {
+ phypcrval = 0; /* 10 MBIT, disable autoneg. */
+ }
+
+ /* send MSGs */
+ for (pnr = 0; pnr < 8; pnr++) {
+ smimsg[0] = 0x00; /* CHIP/HUB ID */
+ smimsg[1] = 0x38; /* WRITE CMD */
+ smimsg[2] = ((PHYPCR_ADDR + pnr) << 4) & 0xf0;
+ smimsg[3] = (PHYPCR_ADDR + pnr) >> 4;
+ smimsg[4] = (unsigned char) (phypcrval & 0xff);
+ smimsg[5] = (unsigned char) (phypcrval >> 8);
+ smimsg[6] = 0x00;
+ smimsg[7] = 0x00;
+
+ send_smi_frame (sp, bd, smimsg);
+ }
+
+ smimsg[0] = 0x00; /* CHIP/HUB ID */
+ smimsg[1] = 0x38; /* WRITE CMD */
+ smimsg[2] = (PHYGPCR_ADDR << 4) & 0xf0;
+ smimsg[3] = PHYGPCR_ADDR >> 4;
+ smimsg[4] = 0xff; /* enable port 1-8 */
+ smimsg[5] = 0x01; /* enable MII1 (0x01) */
+ smimsg[6] = 0x00;
+ smimsg[7] = 0x00;
+
+ send_smi_frame (sp, bd, smimsg);
+
+ smimsg[0] = 0x00; /* CHIP/HUB ID */
+ smimsg[1] = 0x38; /* WRITE CMD */
+ smimsg[2] = (LEDPCR_ADDR << 4) & 0xf0;
+ smimsg[3] = LEDPCR_ADDR >> 4;
+ smimsg[4] = 0xaa; /* Port 1-8 Conf.bits = 10 (Hardware control) */
+ smimsg[5] = 0xaa;
+ smimsg[6] = 0x00;
+ smimsg[7] = 0x00;
+
+ send_smi_frame (sp, bd, smimsg);
+
+ /*
+ * Disable Transmitter (so that we can free the BD, too)
+ */
+ sp->scc_gsmrl &= ~SCC_GSMRL_ENT;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void send_smi_frame (volatile scc_t * sp, volatile cbd_t * bd,
+ uchar * msg)
+{
+#ifdef DEBUG
+ unsigned hub, chip, cmd, length, addr;
+
+ hub = msg[0] & 0x1F;
+ chip = msg[0] >> 5;
+ cmd = msg[1] & 0x1F;
+ length = (msg[1] >> 5) | ((msg[2] & 0x0F) << 3);
+ addr = (msg[2] >> 4) | (msg[3] << 4);
+
+ printf ("SMI send: Hub %02x Chip %x Cmd %02x Len %d Addr %03x: "
+ "%02x %02x %02x %02x\n",
+ hub, chip, cmd, length, addr, msg[4], msg[5], msg[6], msg[7]);
+#endif /* DEBUG */
+
+ bd->cbd_bufaddr = (uint) msg;
+ bd->cbd_datlen = SMI_MSGLEN;
+ bd->cbd_sc |= BD_SC_READY;
+
+ /* wait for msg transmitted */
+ while ((sp->scc_scce & 0x0002) == 0);
+ /* clear all events */
+ sp->scc_scce = ~0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+void show_boot_progress (int status)
+{
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+
+ status ^= 0x0F;
+ status = (status & 0x0F) << 14;
+ immr->im_cpm.cp_pbdat = (immr->im_cpm.cp_pbdat & ~PB_LED_ALL) | status;
+}
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ *
+ * hacked for Hymod FPGA support by Murray.Jensen@cmst.csiro.au, 29-Jan-01
+ */
+
+#include <common.h>
+#include <command.h>
+#include <net.h>
+#include <i2c.h>
+#include <asm/iopin_8260.h>
+#include <cmd_bsp.h>
+
+/*-----------------------------------------------------------------------
+ * Board Special Commands: FPGA load/store, EEPROM erase
+ */
+
+#if (CONFIG_COMMANDS & CFG_CMD_BSP)
+
+#define LOAD_SUCCESS 0
+#define LOAD_FAIL_NOCONF 1
+#define LOAD_FAIL_NOINIT 2
+#define LOAD_FAIL_NODONE 3
+
+#define STORE_SUCCESS 0
+
+/*
+ * Programming the Hymod FPGAs
+ *
+ * The 8260 io port config table is set up so that the INIT pin is
+ * held Low (Open Drain output 0) - this will delay the automatic
+ * Power-On config until INIT is released (by making it an input).
+ *
+ * If the FPGA has been programmed before, then the assertion of PROGRAM
+ * will initiate configuration (i.e. it begins clearing the RAM).
+ *
+ * When the FPGA is ready to receive configuration data (either after
+ * releasing INIT after Power-On, or after asserting PROGRAM), it will
+ * pull INIT high.
+ *
+ * Notes from Paul Dunn:
+ *
+ * 1. program pin should be forced low for >= 300ns
+ * (about 20 bus clock cycles minimum).
+ *
+ * 2. then wait for init to go high, which signals
+ * that the FPGA has cleared its internal memory
+ * and is ready to load
+ *
+ * 3. perform load writes of entire config file
+ *
+ * 4. wait for done to go high, which should be
+ * within a few bus clock cycles. If done has not
+ * gone high after reasonable period, then load
+ * has not worked (wait several ms?)
+ */
+
+int fpga_load (int mezz, uchar * addr, ulong size)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ hymod_conf_t *cp = &gd->bd->bi_hymod_conf;
+ xlx_iopins_t *fpgaio;
+ volatile uchar *fpgabase;
+ volatile uint cnt;
+ uchar *eaddr = addr + size;
+ int result;
+
+ if (mezz) {
+ if (!cp->mezz.mmap[0].prog.exists)
+ return (LOAD_FAIL_NOCONF);
+ fpgabase = (uchar *) cp->mezz.mmap[0].prog.base;
+ fpgaio = &cp->mezz.iopins[0];
+ } else {
+ if (!cp->main.mmap[0].prog.exists)
+ return (LOAD_FAIL_NOCONF);
+ fpgabase = (uchar *) cp->main.mmap[0].prog.base;
+ fpgaio = &cp->main.iopins[0];
+ }
+
+ /* set enable HIGH if required */
+ if (fpgaio->enable_pin.flag)
+ iopin_set_high (&fpgaio->enable_pin);
+
+ /* ensure INIT is released (set it to be an input) */
+ iopin_set_in (&fpgaio->init_pin);
+
+ /* toggle PROG Low then High (will already be Low after Power-On) */
+ iopin_set_low (&fpgaio->prog_pin);
+ udelay (1); /* minimum 300ns - 1usec should do it */
+ iopin_set_high (&fpgaio->prog_pin);
+
+ /* wait for INIT High */
+ cnt = 0;
+ while (!iopin_is_high (&fpgaio->init_pin))
+ if (++cnt == 10000000) {
+ result = LOAD_FAIL_NOINIT;
+ goto done;
+ }
+
+ /* write configuration data */
+ while (addr < eaddr)
+ *fpgabase = *addr++;
+
+ /* wait for DONE High */
+ cnt = 0;
+ while (!iopin_is_high (&fpgaio->done_pin))
+ if (++cnt == 100000000) {
+ result = LOAD_FAIL_NODONE;
+ goto done;
+ }
+
+ /* success */
+ result = LOAD_SUCCESS;
+
+ done:
+
+ if (fpgaio->enable_pin.flag)
+ iopin_set_low (&fpgaio->enable_pin);
+
+ return (result);
+}
+
+/* ------------------------------------------------------------------------- */
+int
+do_fpga (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ uchar *addr, *save_addr;
+ ulong size;
+ int mezz, arg, result;
+
+ switch (argc) {
+
+ case 0:
+ case 1:
+ break;
+
+ case 2:
+ if (strcmp (argv[1], "info") == 0) {
+ printf ("\nHymod FPGA Info...\n");
+ printf (" Address Size\n");
+ printf (" Main Configuration: 0x%08x %d\n",
+ FPGA_MAIN_CFG_BASE, FPGA_MAIN_CFG_SIZE);
+ printf (" Main Register: 0x%08x %d\n",
+ FPGA_MAIN_REG_BASE, FPGA_MAIN_REG_SIZE);
+ printf (" Main Port: 0x%08x %d\n",
+ FPGA_MAIN_PORT_BASE, FPGA_MAIN_PORT_SIZE);
+ printf (" Mezz Configuration: 0x%08x %d\n",
+ FPGA_MEZZ_CFG_BASE, FPGA_MEZZ_CFG_SIZE);
+ return 0;
+ }
+ break;
+
+ case 3:
+ if (strcmp (argv[1], "store") == 0) {
+ addr = (uchar *) simple_strtoul (argv[2], NULL, 16);
+
+ save_addr = addr;
+#if 0
+ /* reading config data unimplemented */
+ while VM
+ :more config data * addr++ = *fpga;
+ result = VM:? ? ?
+#else
+ result = 0;
+#endif
+ if (result == STORE_SUCCESS) {
+ printf ("SUCCEEDED (%d bytes)\n", addr - save_addr);
+ return 0;
+ } else
+ printf ("FAILED (%d bytes)\n", addr - save_addr);
+ return 1;
+ }
+ break;
+
+ case 4:
+ if (strcmp (argv[1], "tftp") == 0) {
+ copy_filename (BootFile, argv[2], sizeof (BootFile));
+ load_addr = simple_strtoul (argv[3], NULL, 16);
+
+ if (NetLoop (TFTP) == 0) {
+ printf ("tftp transfer failed - aborting fgpa load\n");
+ return 1;
+ }
+
+ if (NetBootFileXferSize == 0) {
+ printf ("can't determine file size - aborting fpga load\n");
+ return 1;
+ }
+
+ printf ("File transfer succeeded - beginning fpga load...");
+
+ result = fpga_load (0, (uchar *) load_addr,
+ NetBootFileXferSize);
+ if (result == LOAD_SUCCESS) {
+ printf ("SUCCEEDED\n");
+ return 0;
+ } else if (result == LOAD_FAIL_NOINIT)
+ printf ("FAILED (no INIT)\n");
+ else
+ printf ("FAILED (no DONE)\n");
+ return 1;
+
+ }
+ /* fall through ... */
+
+ case 5:
+ if (strcmp (argv[1], "load") == 0) {
+ if (argc == 5) {
+ if (strcmp (argv[2], "main") == 0)
+ mezz = 0;
+ else if (strcmp (argv[2], "mezz") == 0)
+ mezz = 1;
+ else {
+ printf ("FPGA type must be either `main' or `mezz'\n");
+ return 1;
+ }
+ arg = 3;
+ } else {
+ mezz = 0;
+ arg = 2;
+ }
+ addr = (uchar *) simple_strtoul (argv[arg++], NULL, 16);
+ size = (ulong) simple_strtoul (argv[arg], NULL, 16);
+
+ result = fpga_load (mezz, addr, size);
+ if (result == LOAD_SUCCESS) {
+ printf ("SUCCEEDED\n");
+ return 0;
+ } else if (result == LOAD_FAIL_NOINIT)
+ printf ("FAILED (no INIT)\n");
+ else
+ printf ("FAILED (no DONE)\n");
+ return 1;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+}
+
+/* ------------------------------------------------------------------------- */
+int
+do_eecl (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+ uchar data[HYMOD_EEPROM_SIZE];
+ uint offset;
+ int rcode = 0;
+
+ switch (argc) {
+
+ case 1:
+ offset = HYMOD_EEOFF_MAIN;
+ break;
+
+ case 2:
+ if (strcmp (argv[1], "main") == 0) {
+ offset = HYMOD_EEOFF_MAIN;
+ break;
+ }
+ if (strcmp (argv[1], "mezz") == 0) {
+ offset = HYMOD_EEOFF_MEZZ;
+ break;
+ }
+ /* fall through ... */
+
+ default:
+ printf ("Usage:\n%s\n", cmdtp->usage);
+ return 1;
+ }
+
+ memset (data, 0, HYMOD_EEPROM_SIZE);
+ if (i2c_write
+ (CFG_I2C_EEPROM_ADDR | offset, 0, CFG_I2C_EEPROM_ADDR_LEN, data,
+ HYMOD_EEPROM_SIZE)) {
+ rcode = 1;
+ }
+
+ return rcode;
+}
+
+#endif /* CFG_CMD_BSP */
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ *
+ * Hacked for the Hymod board by Murray.Jensen@cmst.csiro.au, 20-Oct-00
+ */
+
+#include <common.h>
+#include <mpc8260.h>
+#include <ioports.h>
+#include <i2c.h>
+#include <asm/iopin_8260.h>
+
+/* ------------------------------------------------------------------------- */
+
+/* imports from eeprom.c */
+extern int eeprom_load (unsigned, hymod_eeprom_t *);
+extern int eeprom_fetch (unsigned, char *, ulong);
+extern void eeprom_print (hymod_eeprom_t *);
+
+/* imports from fetch.c */
+extern int fetch_and_parse (char *, ulong, int (*)(uchar *, uchar *));
+
+/* imports from common/main.c */
+extern char console_buffer[CFG_CBSIZE];
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * I/O Port configuration table
+ *
+ * if conf is 1, then that port pin will be configured at boot time
+ * according to the five values podr/pdir/ppar/psor/pdat for that entry
+ */
+
+const iop_conf_t iop_conf_tab[4][32] = {
+
+ /* Port A configuration */
+ { /* conf ppar psor pdir podr pdat */
+ /* PA31 */ {1, 1, 1, 0, 0, 0},
+ /* FCC1 MII COL */
+ /* PA30 */ {1, 1, 1, 0, 0, 0},
+ /* FCC1 MII CRS */
+ /* PA29 */ {1, 1, 1, 1, 0, 0},
+ /* FCC1 MII TX_ER */
+ /* PA28 */ {1, 1, 1, 1, 0, 0},
+ /* FCC1 MII TX_EN */
+ /* PA27 */ {1, 1, 1, 0, 0, 0},
+ /* FCC1 MII RX_DV */
+ /* PA26 */ {1, 1, 1, 0, 0, 0},
+ /* FCC1 MII RX_ER */
+ /* PA25 */ {1, 0, 0, 1, 0, 0},
+ /* FCC2 MII MDIO */
+ /* PA24 */ {1, 0, 0, 1, 0, 0},
+ /* FCC2 MII MDC */
+ /* PA23 */ {1, 0, 0, 1, 0, 0},
+ /* FCC3 MII MDIO */
+ /* PA22 */ {1, 0, 0, 1, 0, 0},
+ /* FCC3 MII MDC */
+ /* PA21 */ {1, 1, 0, 1, 0, 0},
+ /* FCC1 MII TxD[3] */
+ /* PA20 */ {1, 1, 0, 1, 0, 0},
+ /* FCC1 MII TxD[2] */
+ /* PA19 */ {1, 1, 0, 1, 0, 0},
+ /* FCC1 MII TxD[1] */
+ /* PA18 */ {1, 1, 0, 1, 0, 0},
+ /* FCC1 MII TxD[0] */
+ /* PA17 */ {1, 1, 0, 0, 0, 0},
+ /* FCC1 MII RxD[3] */
+ /* PA16 */ {1, 1, 0, 0, 0, 0},
+ /* FCC1 MII RxD[2] */
+ /* PA15 */ {1, 1, 0, 0, 0, 0},
+ /* FCC1 MII RxD[1] */
+ /* PA14 */ {1, 1, 0, 0, 0, 0},
+ /* FCC1 MII RxD[0] */
+ /* PA13 */ {1, 0, 0, 1, 0, 0},
+ /* FCC1 MII MDIO */
+ /* PA12 */ {1, 0, 0, 1, 0, 0},
+ /* FCC1 MII MDC */
+ /* PA11 */ {1, 0, 0, 1, 0, 0},
+ /* SEL_CD */
+ /* PA10 */ {1, 0, 0, 0, 0, 0},
+ /* FLASH STS1 */
+ /* PA9 */ {1, 0, 0, 0, 0, 0},
+ /* FLASH STS0 */
+ /* PA8 */ {1, 0, 0, 0, 0, 0},
+ /* FLASH ~PE */
+ /* PA7 */ {1, 0, 0, 0, 0, 0},
+ /* WATCH ~HRESET */
+ /* PA6 */ {1, 0, 0, 0, 1, 0},
+ /* VC DONE */
+ /* PA5 */ {1, 0, 0, 1, 1, 0},
+ /* VC INIT */
+ /* PA4 */ {1, 0, 0, 1, 0, 0},
+ /* VC ~PROG */
+ /* PA3 */ {1, 0, 0, 1, 0, 0},
+ /* VM ENABLE */
+ /* PA2 */ {1, 0, 0, 0, 1, 0},
+ /* VM DONE */
+ /* PA1 */ {1, 0, 0, 1, 1, 0},
+ /* VM INIT */
+ /* PA0 */ {1, 0, 0, 1, 0, 0}
+ /* VM ~PROG */
+ },
+
+ /* Port B configuration */
+ { /* conf ppar psor pdir podr pdat */
+ /* PB31 */ {1, 1, 0, 1, 0, 0},
+ /* FCC2 MII TX_ER */
+ /* PB30 */ {1, 1, 0, 0, 0, 0},
+ /* FCC2 MII RX_DV */
+ /* PB29 */ {1, 1, 1, 1, 0, 0},
+ /* FCC2 MII TX_EN */
+ /* PB28 */ {1, 1, 0, 0, 0, 0},
+ /* FCC2 MII RX_ER */
+ /* PB27 */ {1, 1, 0, 0, 0, 0},
+ /* FCC2 MII COL */
+ /* PB26 */ {1, 1, 0, 0, 0, 0},
+ /* FCC2 MII CRS */
+ /* PB25 */ {1, 1, 0, 1, 0, 0},
+ /* FCC2 MII TxD[3] */
+ /* PB24 */ {1, 1, 0, 1, 0, 0},
+ /* FCC2 MII TxD[2] */
+ /* PB23 */ {1, 1, 0, 1, 0, 0},
+ /* FCC2 MII TxD[1] */
+ /* PB22 */ {1, 1, 0, 1, 0, 0},
+ /* FCC2 MII TxD[0] */
+ /* PB21 */ {1, 1, 0, 0, 0, 0},
+ /* FCC2 MII RxD[0] */
+ /* PB20 */ {1, 1, 0, 0, 0, 0},
+ /* FCC2 MII RxD[1] */
+ /* PB19 */ {1, 1, 0, 0, 0, 0},
+ /* FCC2 MII RxD[2] */
+ /* PB18 */ {1, 1, 0, 0, 0, 0},
+ /* FCC2 MII RxD[3] */
+ /* PB17 */ {1, 1, 0, 0, 0, 0},
+ /* FCC3 MII RX_DV */
+ /* PB16 */ {1, 1, 0, 0, 0, 0},
+ /* FCC3 MII RX_ER */
+ /* PB15 */ {1, 1, 0, 1, 0, 0},
+ /* FCC3 MII TX_ER */
+ /* PB14 */ {1, 1, 0, 1, 0, 0},
+ /* FCC3 MII TX_EN */
+ /* PB13 */ {1, 1, 0, 0, 0, 0},
+ /* FCC3 MII COL */
+ /* PB12 */ {1, 1, 0, 0, 0, 0},
+ /* FCC3 MII CRS */
+ /* PB11 */ {1, 1, 0, 0, 0, 0},
+ /* FCC3 MII RxD[3] */
+ /* PB10 */ {1, 1, 0, 0, 0, 0},
+ /* FCC3 MII RxD[2] */
+ /* PB9 */ {1, 1, 0, 0, 0, 0},
+ /* FCC3 MII RxD[1] */
+ /* PB8 */ {1, 1, 0, 0, 0, 0},
+ /* FCC3 MII RxD[0] */
+ /* PB7 */ {1, 1, 0, 1, 0, 0},
+ /* FCC3 MII TxD[3] */
+ /* PB6 */ {1, 1, 0, 1, 0, 0},
+ /* FCC3 MII TxD[2] */
+ /* PB5 */ {1, 1, 0, 1, 0, 0},
+ /* FCC3 MII TxD[1] */
+ /* PB4 */ {1, 1, 0, 1, 0, 0},
+ /* FCC3 MII TxD[0] */
+ /* PB3 */ {0, 0, 0, 0, 0, 0},
+ /* pin doesn't exist */
+ /* PB2 */ {0, 0, 0, 0, 0, 0},
+ /* pin doesn't exist */
+ /* PB1 */ {0, 0, 0, 0, 0, 0},
+ /* pin doesn't exist */
+ /* PB0 */ {0, 0, 0, 0, 0, 0}
+ /* pin doesn't exist */
+ },
+
+ /* Port C */
+ { /* conf ppar psor pdir podr pdat */
+ /* PC31 */ {1, 0, 0, 0, 0, 0},
+ /* MEZ ~IACK */
+ /* PC30 */ {0, 0, 0, 0, 0, 0},
+ /* PC29 */ {1, 1, 0, 0, 0, 0},
+ /* CLK SCCx */
+ /* PC28 */ {1, 1, 0, 0, 0, 0},
+ /* CLK4 */
+ /* PC27 */ {1, 1, 0, 0, 0, 0},
+ /* CLK SCCF */
+ /* PC26 */ {1, 1, 0, 0, 0, 0},
+ /* CLK 32K */
+ /* PC25 */ {1, 1, 0, 0, 0, 0},
+ /* BRG4/CLK7 */
+ /* PC24 */ {0, 0, 0, 0, 0, 0},
+ /* PC23 */ {1, 1, 0, 0, 0, 0},
+ /* CLK SCCx */
+ /* PC22 */ {1, 1, 0, 0, 0, 0},
+ /* FCC1 MII RX_CLK */
+ /* PC21 */ {1, 1, 0, 0, 0, 0},
+ /* FCC1 MII TX_CLK */
+ /* PC20 */ {1, 1, 0, 0, 0, 0},
+ /* CLK SCCF */
+ /* PC19 */ {1, 1, 0, 0, 0, 0},
+ /* FCC2 MII RX_CLK */
+ /* PC18 */ {1, 1, 0, 0, 0, 0},
+ /* FCC2 MII TX_CLK */
+ /* PC17 */ {1, 1, 0, 0, 0, 0},
+ /* FCC3 MII RX_CLK */
+ /* PC16 */ {1, 1, 0, 0, 0, 0},
+ /* FCC3 MII TX_CLK */
+ /* PC15 */ {1, 0, 0, 0, 0, 0},
+ /* SCC1 UART ~CTS */
+ /* PC14 */ {1, 0, 0, 0, 0, 0},
+ /* SCC1 UART ~CD */
+ /* PC13 */ {1, 0, 0, 0, 0, 0},
+ /* SCC2 UART ~CTS */
+ /* PC12 */ {1, 0, 0, 0, 0, 0},
+ /* SCC2 UART ~CD */
+ /* PC11 */ {1, 0, 0, 1, 0, 0},
+ /* SCC1 UART ~DTR */
+ /* PC10 */ {1, 0, 0, 1, 0, 0},
+ /* SCC1 UART ~DSR */
+ /* PC9 */ {1, 0, 0, 1, 0, 0},
+ /* SCC2 UART ~DTR */
+ /* PC8 */ {1, 0, 0, 1, 0, 0},
+ /* SCC2 UART ~DSR */
+ /* PC7 */ {1, 0, 0, 0, 0, 0},
+ /* TEMP ~ALERT */
+ /* PC6 */ {1, 0, 0, 0, 0, 0},
+ /* FCC3 INT */
+ /* PC5 */ {1, 0, 0, 0, 0, 0},
+ /* FCC2 INT */
+ /* PC4 */ {1, 0, 0, 0, 0, 0},
+ /* FCC1 INT */
+ /* PC3 */ {1, 1, 1, 1, 0, 0},
+ /* SDMA IDMA2 ~DACK */
+ /* PC2 */ {1, 1, 1, 0, 0, 0},
+ /* SDMA IDMA2 ~DONE */
+ /* PC1 */ {1, 1, 0, 0, 0, 0},
+ /* SDMA IDMA2 ~DREQ */
+ /* PC0 */ {1, 1, 0, 1, 0, 0}
+ /* BRG7 */
+ },
+
+ /* Port D */
+ { /* conf ppar psor pdir podr pdat */
+ /* PD31 */ {1, 1, 0, 0, 0, 0},
+ /* SCC1 UART RxD */
+ /* PD30 */ {1, 1, 1, 1, 0, 0},
+ /* SCC1 UART TxD */
+ /* PD29 */ {1, 0, 0, 1, 0, 0},
+ /* SCC1 UART ~RTS */
+ /* PD28 */ {1, 1, 0, 0, 0, 0},
+ /* SCC2 UART RxD */
+ /* PD27 */ {1, 1, 0, 1, 0, 0},
+ /* SCC2 UART TxD */
+ /* PD26 */ {1, 0, 0, 1, 0, 0},
+ /* SCC2 UART ~RTS */
+ /* PD25 */ {1, 0, 0, 0, 0, 0},
+ /* SCC1 UART ~RI */
+ /* PD24 */ {1, 0, 0, 0, 0, 0},
+ /* SCC2 UART ~RI */
+ /* PD23 */ {1, 0, 0, 1, 0, 0},
+ /* CLKGEN PD */
+ /* PD22 */ {1, 0, 0, 0, 0, 0},
+ /* USER3 */
+ /* PD21 */ {1, 0, 0, 0, 0, 0},
+ /* USER2 */
+ /* PD20 */ {1, 0, 0, 0, 0, 0},
+ /* USER1 */
+ /* PD19 */ {1, 1, 1, 0, 0, 0},
+ /* SPI ~SEL */
+ /* PD18 */ {1, 1, 1, 0, 0, 0},
+ /* SPI CLK */
+ /* PD17 */ {1, 1, 1, 0, 0, 0},
+ /* SPI MOSI */
+ /* PD16 */ {1, 1, 1, 0, 0, 0},
+ /* SPI MISO */
+ /* PD15 */ {1, 1, 1, 0, 1, 0},
+ /* I2C SDA */
+ /* PD14 */ {1, 1, 1, 0, 1, 0},
+ /* I2C SCL */
+ /* PD13 */ {1, 0, 0, 1, 0, 1},
+ /* TEMP ~STDBY */
+ /* PD12 */ {1, 0, 0, 1, 0, 1},
+ /* FCC3 ~RESET */
+ /* PD11 */ {1, 0, 0, 1, 0, 1},
+ /* FCC2 ~RESET */
+ /* PD10 */ {1, 0, 0, 1, 0, 1},
+ /* FCC1 ~RESET */
+ /* PD9 */ {1, 0, 0, 0, 0, 0},
+ /* PD9 */
+ /* PD8 */ {1, 0, 0, 0, 0, 0},
+ /* PD8 */
+ /* PD7 */ {1, 0, 0, 1, 0, 1},
+ /* PD7 */
+ /* PD6 */ {1, 0, 0, 1, 0, 1},
+ /* PD6 */
+ /* PD5 */ {1, 0, 0, 1, 0, 1},
+ /* PD5 */
+ /* PD4 */ {1, 0, 0, 1, 0, 1},
+ /* PD4 */
+ /* PD3 */ {0, 0, 0, 0, 0, 0},
+ /* pin doesn't exist */
+ /* PD2 */ {0, 0, 0, 0, 0, 0},
+ /* pin doesn't exist */
+ /* PD1 */ {0, 0, 0, 0, 0, 0},
+ /* pin doesn't exist */
+ /* PD0 */ {0, 0, 0, 0, 0, 0}
+ /* pin doesn't exist */
+ }
+};
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * AMI FS6377 Clock Generator configuration table
+ *
+ * the "fs6377_regs[]" table entries correspond to FS6377 registers
+ * 0 - 15 (total of 16 bytes).
+ *
+ * the data is written to the FS6377 via the i2c bus using address in
+ * "fs6377_addr" (address is 7 bits - R/W bit not included).
+ */
+
+uchar fs6377_addr = 0x5c;
+
+uchar fs6377_regs[16] = {
+ 12, 75, 64, 25, 144, 128, 25, 192,
+ 0, 16, 135, 192, 224, 64, 64, 192
+};
+
+iopin_t pa11 = { IOPIN_PORTA, 11, 0 };
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * special board initialisation, after clocks and timebase have been
+ * set up but before environment and serial are initialised.
+ *
+ * added so that very early initialisations can be done using the i2c
+ * driver (which requires the clocks, to calculate the dividers, and
+ * the timebase, for udelay())
+ */
+
+int board_postclk_init (void)
+{
+ i2c_init (CFG_I2C_SPEED, CFG_I2C_SLAVE);
+
+ /*
+ * Initialise the FS6377 clock chip
+ *
+ * the secondary address is the register number from where to
+ * start the write - I want to write all the registers
+ *
+ * don't bother checking return status - we have no console yet
+ * to print it on, nor any RAM to store it in - it will be obvious
+ * if this doesn't work
+ */
+ (void) i2c_write (fs6377_addr, 0, 1, fs6377_regs,
+ sizeof (fs6377_regs));
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity: Hardwired to HYMOD
+ */
+
+int checkboard (void)
+{
+ puts ("Board: HYMOD\n");
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * miscellaneous (early - while running in flash) initialisations.
+ */
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+uint upmb_table[] = {
+ /* Read Single Beat (RSS) - offset 0x00 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Read Burst (RBS) - offset 0x08 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Write Single Beat (WSS) - offset 0x18 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Write Burst (WSS) - offset 0x20 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Refresh Timer (PTS) - offset 0x30 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Exception Condition (EXS) - offset 0x3c */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_
+};
+
+uint upmc_table[] = {
+ /* Read Single Beat (RSS) - offset 0x00 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Read Burst (RBS) - offset 0x08 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Write Single Beat (WSS) - offset 0x18 */
+ 0xF0E00000, 0xF0A00000, 0x00A00000, 0x30A00000,
+ 0xF0F40007, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Write Burst (WSS) - offset 0x20 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Refresh Timer (PTS) - offset 0x30 */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /* Exception Condition (EXS) - offset 0x3c */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_
+};
+
+int misc_init_f (void)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8260_t *memctl = &immap->im_memctl;
+
+ printf ("UPMs: ");
+
+ upmconfig (UPMB, upmb_table, sizeof upmb_table / sizeof upmb_table[0]);
+ memctl->memc_mbmr = CFG_MBMR;
+
+ upmconfig (UPMC, upmc_table, sizeof upmc_table / sizeof upmc_table[0]);
+ memctl->memc_mcmr = CFG_MCMR;
+
+ printf ("configured\n");
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+long initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8260_t *memctl = &immap->im_memctl;
+ volatile uchar c = 0, *ramaddr = (uchar *) (CFG_SDRAM_BASE + 0x8);
+ ulong psdmr = CFG_PSDMR;
+ int i;
+
+ /*
+ * Quote from 8260 UM (10.4.2 SDRAM Power-On Initialization, 10-35):
+ *
+ * "At system reset, initialization software must set up the
+ * programmable parameters in the memory controller banks registers
+ * (ORx, BRx, P/LSDMR). After all memory parameters are conÞgured,
+ * system software should execute the following initialization sequence
+ * for each SDRAM device.
+ *
+ * 1. Issue a PRECHARGE-ALL-BANKS command
+ * 2. Issue eight CBR REFRESH commands
+ * 3. Issue a MODE-SET command to initialize the mode register
+ *
+ * The initial commands are executed by setting P/LSDMR[OP] and
+ * accessing the SDRAM with a single-byte transaction."
+ *
+ * The appropriate BRx/ORx registers have already been set when we
+ * get here. The SDRAM can be accessed at the address CFG_SDRAM_BASE.
+ */
+
+ memctl->memc_psrt = CFG_PSRT;
+ memctl->memc_mptpr = CFG_MPTPR;
+
+ memctl->memc_psdmr = psdmr | PSDMR_OP_PREA;
+ *ramaddr = c;
+
+ memctl->memc_psdmr = psdmr | PSDMR_OP_CBRR;
+ for (i = 0; i < 8; i++)
+ *ramaddr = c;
+
+ memctl->memc_psdmr = psdmr | PSDMR_OP_MRW;
+ *ramaddr = c;
+
+ memctl->memc_psdmr = psdmr | PSDMR_OP_NORM | PSDMR_RFEN;
+ *ramaddr = c;
+
+ return (CFG_SDRAM_SIZE << 20);
+}
+
+/* ------------------------------------------------------------------------- */
+/* miscellaneous initialisations after relocation into ram (misc_init_r) */
+/* */
+/* loads the data in the main board and mezzanine board eeproms into */
+/* the hymod configuration struct stored in the board information area. */
+/* */
+/* if the contents of either eeprom is invalid, prompts for a serial */
+/* number (and an ethernet address if required) then fetches a file */
+/* containing information to be stored in the eeprom from the tftp server */
+/* (the file name is based on the serial number and a built-in path) */
+
+/* these are relative to the root of the server's tftp directory */
+static char *bddb_cfgdir = "/hymod/bddb";
+static char *global_env_path = "/hymod/global_env";
+
+static ulong get_serno (const char *prompt)
+{
+ for (;;) {
+ int n;
+ char *p;
+ ulong serno;
+
+ n = readline (prompt);
+
+ if (n < 0)
+ return (0);
+
+ if (n == 0)
+ continue;
+
+ serno = simple_strtol (console_buffer, &p, 10);
+
+ if (p > console_buffer && *p == '\0')
+ return (serno);
+
+ printf ("Invalid number (%s) - please re-enter\n", console_buffer);
+ }
+}
+
+static int read_eeprom (char *label, unsigned offset, hymod_eeprom_t * ep)
+{
+ char filename[50], prompt[50];
+ ulong serno;
+ int count = 0;
+
+ sprintf (prompt, "Enter %s board serial number: ", label);
+
+ for (;;) {
+
+ if (eeprom_load (offset, ep))
+ return (1);
+
+ printf ("*** %s board EEPROM contents are %sinvalid\n",
+ label, count == 0 ? "" : "STILL ");
+
+ puts ("*** will attempt to fetch from server (Ctrl-C to abort)\n");
+
+ if ((serno = get_serno (prompt)) == 0) {
+ puts ("\n*** interrupted! - ignoring eeprom contents\n");
+ return (0);
+ }
+
+ sprintf (filename, "%s/%010lu.cfg", bddb_cfgdir, serno);
+
+ printf ("*** fetching %s board EEPROM contents from server\n",
+ label);
+
+ if (eeprom_fetch (offset, filename, 0x100000) == 0) {
+ puts ("*** fetch failed - ignoring eeprom contents\n");
+ return (0);
+ }
+
+ count++;
+ }
+}
+
+static ulong main_serno;
+
+static int env_fetch_callback (uchar * name, uchar * value)
+{
+ char *ov, nv[CFG_CBSIZE], *p, *q, *nn;
+ int override = 1, append = 0, nl;
+
+ nn = name;
+ if (*nn == '-') {
+ override = 0;
+ nn++;
+ }
+
+ if ((nl = strlen (nn)) > 0 && nn[nl - 1] == '+') {
+ append = 1;
+ nn[--nl] = '\0';
+ }
+
+ p = value;
+ q = nv;
+
+ while ((*q = *p++) != '\0')
+ if (*q == '%') {
+ switch (*p++) {
+
+ case '\0': /* whoops - back up */
+ p--;
+ break;
+
+ case '%': /* a single percent character */
+ q++;
+ break;
+
+ case 's': /* main board serial number as string */
+ q += sprintf (q, "%010lu", main_serno);
+ break;
+
+ case 'S': /* main board serial number as number */
+ q += sprintf (q, "%lu", main_serno);
+ break;
+
+ default: /* ignore any others */
+ break;
+ }
+ } else
+ q++;
+
+ if ((ov = getenv (nn)) != NULL) {
+
+ if (append) {
+
+ if (strstr (ov, nv) == NULL) {
+ int ovl, nvl;
+
+ printf ("Appending '%s' to env cmd '%s'\n", nv, nn);
+
+ ovl = strlen (ov);
+ nvl = strlen (nv);
+
+ while (nvl >= 0) {
+ nv[ovl + 1 + nvl] = nv[nvl];
+ nvl--;
+ }
+
+ nv[ovl] = ' ';
+
+ while (--ovl >= 0)
+ nv[ovl] = ov[ovl];
+
+ setenv (nn, nv);
+ }
+
+ return (1);
+ }
+
+ if (!override || strcmp (ov, nv) == 0)
+ return (1);
+
+ printf ("Re-setting env cmd '%s' from '%s' to '%s'\n", nn, ov, nv);
+ } else
+ printf ("Setting env cmd '%s' to '%s'\n", nn, nv);
+
+ setenv (nn, nv);
+ return (1);
+}
+
+int misc_init_r (void)
+{
+ DECLARE_GLOBAL_DATA_PTR;
+
+ hymod_conf_t *cp = &gd->bd->bi_hymod_conf;
+ int rc;
+
+ memset ((void *) cp, 0, sizeof (*cp));
+
+ /* set up main board config info */
+
+ if (i2c_probe (CFG_I2C_EEPROM_ADDR | HYMOD_EEOFF_MAIN)) {
+
+ if (read_eeprom
+ ("main", HYMOD_EEOFF_MAIN << 8, &cp->main.eeprom))
+ cp->main.eeprom_valid = 1;
+
+ puts ("EEPROM:main...");
+
+ if (cp->main.eeprom_valid) {
+ printf ("OK (ver %u)\n", cp->main.eeprom.ver);
+ eeprom_print (&cp->main.eeprom);
+ main_serno = cp->main.eeprom.serno;
+ } else
+ puts ("BAD\n");
+
+ cp->main.mmap[0].prog.exists = 1;
+ cp->main.mmap[0].prog.size = FPGA_MAIN_CFG_SIZE;
+ cp->main.mmap[0].prog.base = FPGA_MAIN_CFG_BASE;
+
+ cp->main.mmap[0].reg.exists = 1;
+ cp->main.mmap[0].reg.size = FPGA_MAIN_REG_SIZE;
+ cp->main.mmap[0].reg.base = FPGA_MAIN_REG_BASE;
+
+ cp->main.mmap[0].port.exists = 1;
+ cp->main.mmap[0].port.size = FPGA_MAIN_PORT_SIZE;
+ cp->main.mmap[0].port.base = FPGA_MAIN_PORT_BASE;
+
+ cp->main.iopins[0].prog_pin.port = FPGA_MAIN_PROG_PORT;
+ cp->main.iopins[0].prog_pin.pin = FPGA_MAIN_PROG_PIN;
+ cp->main.iopins[0].prog_pin.flag = 1;
+ cp->main.iopins[0].init_pin.port = FPGA_MAIN_INIT_PORT;
+ cp->main.iopins[0].init_pin.pin = FPGA_MAIN_INIT_PIN;
+ cp->main.iopins[0].init_pin.flag = 1;
+ cp->main.iopins[0].done_pin.port = FPGA_MAIN_DONE_PORT;
+ cp->main.iopins[0].done_pin.pin = FPGA_MAIN_DONE_PIN;
+ cp->main.iopins[0].done_pin.flag = 1;
+#ifdef FPGA_MAIN_ENABLE_PORT
+ cp->main.iopins[0].enable_pin.port = FPGA_MAIN_ENABLE_PORT;
+ cp->main.iopins[0].enable_pin.pin = FPGA_MAIN_ENABLE_PIN;
+ cp->main.iopins[0].enable_pin.flag = 1;
+#endif
+ } else
+ puts ("EEPROM:main...NOT PRESENT\n");
+
+ /* set up mezzanine board config info */
+
+ if (i2c_probe (CFG_I2C_EEPROM_ADDR | HYMOD_EEOFF_MEZZ)) {
+
+ if (read_eeprom
+ ("mezz", HYMOD_EEOFF_MEZZ << 8, &cp->mezz.eeprom))
+ cp->mezz.eeprom_valid = 1;
+
+ puts ("EEPROM:mezz...");
+
+ if (cp->mezz.eeprom_valid) {
+ printf ("OK (ver %u)\n", cp->mezz.eeprom.ver);
+ eeprom_print (&cp->mezz.eeprom);
+ } else
+ puts ("BAD\n");
+
+ cp->mezz.mmap[0].prog.exists = 1;
+ cp->mezz.mmap[0].prog.size = FPGA_MEZZ_CFG_SIZE;
+ cp->mezz.mmap[0].prog.base = FPGA_MEZZ_CFG_BASE;
+
+ cp->mezz.mmap[0].reg.exists = 0;
+
+ cp->mezz.mmap[0].port.exists = 0;
+
+ cp->mezz.iopins[0].prog_pin.port = FPGA_MEZZ_PROG_PORT;
+ cp->mezz.iopins[0].prog_pin.pin = FPGA_MEZZ_PROG_PIN;
+ cp->mezz.iopins[0].prog_pin.flag = 1;
+ cp->mezz.iopins[0].init_pin.port = FPGA_MEZZ_INIT_PORT;
+ cp->mezz.iopins[0].init_pin.pin = FPGA_MEZZ_INIT_PIN;
+ cp->mezz.iopins[0].init_pin.flag = 1;
+ cp->mezz.iopins[0].done_pin.port = FPGA_MEZZ_DONE_PORT;
+ cp->mezz.iopins[0].done_pin.pin = FPGA_MEZZ_DONE_PIN;
+ cp->mezz.iopins[0].done_pin.flag = 1;
+#ifdef FPGA_MEZZ_ENABLE_PORT
+ cp->mezz.iopins[0].enable_pin.port = FPGA_MEZZ_ENABLE_PORT;
+ cp->mezz.iopins[0].enable_pin.pin = FPGA_MEZZ_ENABLE_PIN;
+ cp->mezz.iopins[0].enable_pin.flag = 1;
+#endif
+
+ if (cp->mezz.eeprom_valid &&
+ cp->mezz.eeprom.bdtype == HYMOD_BDTYPE_DISPLAY) {
+ /*
+ * mezzanine board is a display board - switch the SEL_CD
+ * input of the FS6377 clock generator (via I/O Port Pin PA11) to
+ * high (or 1) to select the 27MHz required by the display board
+ */
+ iopin_set_high (&pa11);
+
+ puts ("SEL_CD:toggled for display board\n");
+ }
+ } else
+ puts ("EEPROM:mezz...NOT PRESENT\n");
+
+ cp->crc =
+ crc32 (0, (unsigned char *) cp, offsetof (hymod_conf_t, crc));
+
+ if (getenv ("global_env_loaded") == NULL) {
+
+ puts ("*** global environment has not been loaded\n");
+ puts ("*** fetching from server (Control-C to Abort)\n");
+
+ rc = fetch_and_parse (global_env_path, 0x100000,
+ env_fetch_callback);
+
+ if (rc == 0)
+ puts ("*** Fetch of environment failed!\n");
+ else
+ setenv ("global_env_loaded", "yes");
+ }
+ return (0);
+}
--- /dev/null
+/*
+ * (C) Copyright 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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 <config.h>
+#include <mpc8xx.h>
+
+/*
+ * Memory Controller Using
+ *
+ * CS0 - Flash memory (0x40000000)
+ * CS1 - SDRAM (0x00000000}
+ * CS2 - S/UNI Ultra ATM155
+ * CS3 - IDT 77106 ATM25
+ * CS4 - DSP HPI
+ * CS5 - E1/T1 Interface device
+ * CS6 - PCMCIA device
+ * CS7 - PCMCIA device
+ */
+
+/* ------------------------------------------------------------------------- */
+
+#define _not_used_ 0xffffffff
+
+const uint sdram_table[] = {
+ /* single read. (offset 0 in upm RAM) */
+ 0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
+ 0x1ff77c47,
+
+ /* MRS initialization (offset 5) */
+
+ 0x1ff77c34, 0xefeabc34, 0x1fb57c35,
+
+ /* burst read. (offset 8 in upm RAM) */
+ 0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
+ 0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+
+ /* single write. (offset 18 in upm RAM) */
+ 0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+
+ /* burst write. (offset 20 in upm RAM) */
+ 0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
+ 0xf0affc00, 0xe1bbbc04, 0x1ff77c47, _not_used_,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+
+ /* refresh. (offset 30 in upm RAM) */
+ 0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
+ 0xfffffc84, 0xfffffc07, _not_used_, _not_used_,
+ _not_used_, _not_used_, _not_used_, _not_used_,
+
+ /* exception. (offset 3c in upm RAM) */
+ 0x7ffffc07, _not_used_, _not_used_, _not_used_
+};
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check Board Identity:
+ */
+
+int checkboard (void)
+{
+ puts ("Board: ICU862 Board\n");
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ long int size8, size9;
+ long int size_b0 = 0;
+ unsigned long reg;
+
+ upmconfig (UPMA, (uint *) sdram_table,
+ sizeof (sdram_table) / sizeof (uint));
+
+ /*
+ * Preliminary prescaler for refresh (depends on number of
+ * banks): This value is selected for four cycles every 62.4 us
+ * with two SDRAM banks or four cycles every 31.2 us with one
+ * bank. It will be adjusted after memory sizing.
+ */
+ memctl->memc_mptpr = CFG_MPTPR_2BK_8K;
+
+ memctl->memc_mar = 0x00000088;
+
+ /*
+ * Map controller bank 1 to the SDRAM bank at
+ * preliminary address - these have to be modified after the
+ * SDRAM size has been determined.
+ */
+ memctl->memc_or1 = CFG_OR1_PRELIM;
+ memctl->memc_br1 = CFG_BR1_PRELIM;
+
+ memctl->memc_mamr = CFG_MAMR_8COL & (~(MAMR_PTAE)); /* no refresh yet */
+
+ udelay (200);
+
+ /* perform SDRAM initializsation sequence */
+
+ memctl->memc_mcr = 0x80002105; /* SDRAM bank 0 */
+ udelay (200);
+ memctl->memc_mcr = 0x80002230; /* SDRAM bank 0 - execute twice */
+ udelay (200);
+
+ memctl->memc_mamr |= MAMR_PTAE; /* enable refresh */
+
+ udelay (1000);
+
+ /*
+ * Check Bank 0 Memory Size for re-configuration
+ *
+ * try 8 column mode
+ */
+ size8 = dram_size (CFG_MAMR_8COL, (ulong *) SDRAM_BASE1_PRELIM,
+ SDRAM_MAX_SIZE);
+
+ udelay (1000);
+
+ /*
+ * try 9 column mode
+ */
+ size9 = dram_size (CFG_MAMR_9COL, (ulong *) SDRAM_BASE1_PRELIM,
+ SDRAM_MAX_SIZE);
+
+ if (size8 < size9) { /* leave configuration at 9 columns */
+ size_b0 = size9;
+/* debug ("SDRAM Bank 0 in 9 column mode: %ld MB\n", size >> 20); */
+ } else { /* back to 8 columns */
+ size_b0 = size8;
+ memctl->memc_mamr = CFG_MAMR_8COL;
+ udelay (500);
+/* debug ("SDRAM Bank 0 in 8 column mode: %ld MB\n", size >> 20); */
+ }
+
+ udelay (1000);
+
+ /*
+ * Adjust refresh rate depending on SDRAM type, both banks
+ * For types > 128 MBit leave it at the current (fast) rate
+ */
+ if ((size_b0 < 0x02000000)) {
+ /* reduce to 15.6 us (62.4 us / quad) */
+ memctl->memc_mptpr = CFG_MPTPR_2BK_4K;
+ udelay (1000);
+ }
+
+ /*
+ * Final mapping
+ */
+
+ memctl->memc_or1 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+ memctl->memc_br1 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
+
+ /* adjust refresh rate depending on SDRAM type, one bank */
+ reg = memctl->memc_mptpr;
+ reg >>= 1; /* reduce to CFG_MPTPR_1BK_8K / _4K */
+ memctl->memc_mptpr = reg;
+
+ udelay (10000);
+
+ return (size_b0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mamr_value, long int *base,
+ long int maxsize)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ volatile long int *addr;
+ ulong cnt, val;
+ ulong save[32]; /* to make test non-destructive */
+ unsigned char i = 0;
+
+ memctl->memc_mamr = mamr_value;
+
+ for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ /* write 0 to base address */
+ addr = base;
+ save[i] = *addr;
+ *addr = 0;
+
+ /* check at base address */
+ if ((val = *addr) != 0) {
+ *addr = save[i];
+ return (0);
+ }
+
+ for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
+ addr = base + cnt; /* pointer arith! */
+ val = *addr;
+ *addr = save[--i];
+
+ if (val != (~cnt)) {
+ return (cnt * sizeof (long));
+ }
+ }
+ return (maxsize);
+}
--- /dev/null
+/*
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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 <commproc.h>
+#include <mpc8xx.h>
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+
+/* ------------------------------------------------------------------------- */
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+const uint sdram_table[] = {
+ /*
+ * Single Read. (Offset 0 in UPMA RAM)
+ */
+ 0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
+ 0x1ff77c47, /* last */
+ /*
+ * SDRAM Initialization (offset 5 in UPMA RAM)
+ *
+ * This is no UPM entry point. The following definition uses
+ * the remaining space to establish an initialization
+ * sequence, which is executed by a RUN command.
+ *
+ */
+ 0x1ff77c34, 0xefeabc34, 0x1fb57c35, /* last */
+ /*
+ * Burst Read. (Offset 8 in UPMA RAM)
+ */
+ 0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
+ 0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Single Write. (Offset 18 in UPMA RAM)
+ */
+ 0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Burst Write. (Offset 20 in UPMA RAM)
+ */
+ 0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
+ 0xf0affc00, 0xe1bbbc04, 0x1ff77c47, /* last */
+ _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Refresh (Offset 30 in UPMA RAM)
+ */
+ 0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
+ 0xfffffc84, 0xfffffc07, /* last */
+ _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Exception. (Offset 3c in UPMA RAM)
+ */
+ 0x7ffffc07, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ *
+ * Test ID string (IP860...)
+ */
+
+int checkboard (void)
+{
+ unsigned char *s, *e;
+ unsigned char buf[64];
+ int i;
+
+ puts ("Board: ");
+
+ i = getenv_r ("serial#", buf, sizeof (buf));
+ s = (i > 0) ? buf : NULL;
+
+ if (!s || strncmp (s, "IP860", 5)) {
+ puts ("### No HW ID - assuming IP860");
+ } else {
+ for (e = s; *e; ++e) {
+ if (*e == ' ')
+ break;
+ }
+
+ for (; s < e; ++s) {
+ putc (*s);
+ }
+ }
+
+ putc ('\n');
+
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ long int size;
+
+ upmconfig (UPMA, (uint *) sdram_table,
+ sizeof (sdram_table) / sizeof (uint));
+
+ /*
+ * Preliminary prescaler for refresh
+ */
+ memctl->memc_mptpr = 0x0400;
+
+ memctl->memc_mar = 0x00000088;
+
+ /*
+ * Map controller banks 2 to the SDRAM address
+ */
+ memctl->memc_or2 = CFG_OR2;
+ memctl->memc_br2 = CFG_BR2;
+
+ /* IP860 boards have only one bank SDRAM */
+
+
+ udelay (200);
+
+ /* perform SDRAM initializsation sequence */
+
+ memctl->memc_mamr = 0xC3804114;
+ memctl->memc_mcr = 0x80004105; /* run precharge pattern from loc 5 */
+ udelay (1);
+ memctl->memc_mamr = 0xC3804118;
+ memctl->memc_mcr = 0x80004130; /* run refresh pattern 8 times */
+
+ udelay (1000);
+
+ /*
+ * Check SDRAM Memory Size
+ */
+ size = dram_size (CFG_MAMR, (ulong *) SDRAM_BASE, SDRAM_MAX_SIZE);
+
+ udelay (1000);
+
+ memctl->memc_or2 = ((-size) & 0xFFFF0000) | SDRAM_TIMING;
+ memctl->memc_br2 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
+
+ udelay (10000);
+
+ /*
+ * Also, map other memory to correct position
+ */
+
+#if (defined(CFG_OR1) && defined(CFG_BR1_PRELIM))
+ memctl->memc_or1 = CFG_OR1;
+ memctl->memc_br1 = CFG_BR1;
+#endif
+
+#if defined(CFG_OR3) && defined(CFG_BR3)
+ memctl->memc_or3 = CFG_OR3;
+ memctl->memc_br3 = CFG_BR3;
+#endif
+
+#if defined(CFG_OR4) && defined(CFG_BR4)
+ memctl->memc_or4 = CFG_OR4;
+ memctl->memc_br4 = CFG_BR4;
+#endif
+
+#if defined(CFG_OR5) && defined(CFG_BR5)
+ memctl->memc_or5 = CFG_OR5;
+ memctl->memc_br5 = CFG_BR5;
+#endif
+
+#if defined(CFG_OR6) && defined(CFG_BR6)
+ memctl->memc_or6 = CFG_OR6;
+ memctl->memc_br6 = CFG_BR6;
+#endif
+
+#if defined(CFG_OR7) && defined(CFG_BR7)
+ memctl->memc_or7 = CFG_OR7;
+ memctl->memc_br7 = CFG_BR7;
+#endif
+
+ return (size);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mamr_value, long int *base,
+ long int maxsize)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ volatile long int *addr;
+ ulong cnt, val;
+ ulong save[32]; /* to make test non-destructive */
+ unsigned char i = 0;
+
+ memctl->memc_mamr = mamr_value;
+
+ for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ /* write 0 to base address */
+ addr = base;
+ save[i] = *addr;
+ *addr = 0;
+
+ /* check at base address */
+ if ((val = *addr) != 0) {
+ *addr = save[i];
+ return (0);
+ }
+
+ for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ val = *addr;
+ *addr = save[--i];
+
+ if (val != (~cnt)) {
+ return (cnt * sizeof (long));
+ }
+ }
+ return (maxsize);
+}
+
+/* ------------------------------------------------------------------------- */
+
+void reset_phy (void)
+{
+ volatile immap_t *immr = (immap_t *) CFG_IMMR;
+ ulong mask = PB_ENET_RESET | PB_ENET_JABD;
+ ulong reg;
+
+ /* Make sure PHY is not in low-power mode */
+ immr->im_cpm.cp_pbpar &= ~(mask); /* GPIO */
+ immr->im_cpm.cp_pbodr &= ~(mask); /* active output */
+
+ /* Set JABD low (no JABber Disable),
+ * and RESET high (Reset PHY)
+ */
+ reg = immr->im_cpm.cp_pbdat;
+ reg = (reg & ~PB_ENET_JABD) | PB_ENET_RESET;
+ immr->im_cpm.cp_pbdat = reg;
+
+ /* now drive outputs */
+ immr->im_cpm.cp_pbdir |= mask; /* output */
+ udelay (1000);
+ /*
+ * Release RESET signal
+ */
+ immr->im_cpm.cp_pbdat &= ~(PB_ENET_RESET);
+ udelay (1000);
+}
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * (C) Copyright 2002 Wolfgang Grandegger <wg@denx.de>
+ *
+ * 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 <ioports.h>
+#include <mpc8260.h>
+#include <asm/io.h>
+#include <asm/immap_8260.h>
+
+int hwc_flash_size (void);
+int hwc_local_sdram_size (void);
+int hwc_main_sdram_size (void);
+int hwc_serial_number (void);
+int hwc_mac_address (char *str);
+int hwc_manufact_date (char *str);
+int seeprom_read (int addr, uchar * data, int size);
+
+/*
+ * I/O Port configuration table
+ *
+ * if conf is 1, then that port pin will be configured at boot time
+ * according to the five values podr/pdir/ppar/psor/pdat for that entry
+ *
+ * The port definitions are taken from the old firmware (see
+ * also SYS/H/4539.H):
+ *
+ * ppar psor pdir podr pdat
+ * PA: 0x02ffffff 0x02c00000 0xfc403fe6 0x00000000 0x02403fc0
+ * PB: 0x0fffdeb0 0x000000b0 0x0f032347 0x00000000 0x0f000290
+ * PC: 0x030ffa55 0x030f0040 0xbcf005ea 0x00000000 0xc0c0ba7d
+ * PD: 0x09c04e3c 0x01000e3c 0x0a7ff1c3 0x00000000 0x00ce0ae9
+ */
+const iop_conf_t iop_conf_tab[4][32] = {
+
+ /* Port A configuration */
+ { /* conf ppar psor pdir podr pdat */
+ {0, 1, 0, 0, 0, 0}, /* PA31 FCC1_TXENB SLAVE */
+ {0, 1, 0, 1, 0, 0}, /* PA30 FCC1_TXCLAV SLAVE */
+ {0, 1, 0, 1, 0, 0}, /* PA29 FCC1_TXSOC */
+ {0, 1, 0, 0, 0, 0}, /* PA28 FCC1_RXENB SLAVE */
+ {0, 1, 0, 0, 0, 0}, /* PA27 FCC1_RXSOC */
+ {0, 1, 0, 1, 0, 0}, /* PA26 FCC1_RXCLAV SLAVE */
+ {0, 1, 0, 1, 0, 1}, /* PA25 FCC1_TXD0 */
+ {0, 1, 0, 1, 0, 1}, /* PA24 FCC1_TXD1 */
+ {0, 1, 0, 1, 0, 1}, /* PA23 FCC1_TXD2 */
+ {0, 1, 0, 1, 0, 1}, /* PA22 FCC1_TXD3 */
+ {0, 1, 0, 1, 0, 1}, /* PA21 FCC1_TXD4 */
+ {0, 1, 0, 1, 0, 1}, /* PA20 FCC1_TXD5 */
+ {0, 1, 0, 1, 0, 1}, /* PA19 FCC1_TXD6 */
+ {0, 1, 0, 1, 0, 1}, /* PA18 FCC1_TXD7 */
+ {0, 1, 0, 0, 0, 0}, /* PA17 FCC1_RXD7 */
+ {0, 1, 0, 0, 0, 0}, /* PA16 FCC1_RXD6 */
+ {0, 1, 0, 0, 0, 0}, /* PA15 FCC1_RXD5 */
+ {0, 1, 0, 0, 0, 0}, /* PA14 FCC1_RXD4 */
+ {0, 1, 0, 0, 0, 0}, /* PA13 FCC1_RXD3 */
+ {0, 1, 0, 0, 0, 0}, /* PA12 FCC1_RXD2 */
+ {0, 1, 0, 0, 0, 0}, /* PA11 FCC1_RXD1 */
+ {0, 1, 0, 0, 0, 0}, /* PA10 FCC1_RXD0 */
+ {0, 1, 1, 1, 0, 1}, /* PA9 TDMA1_L1TXD */
+ {0, 1, 1, 0, 0, 0}, /* PA8 TDMA1_L1RXD */
+ {0, 0, 0, 0, 0, 0}, /* PA7 CONFIG0 */
+ {0, 1, 1, 0, 0, 1}, /* PA6 TDMA1_L1RSYNC */
+ {0, 0, 0, 1, 0, 0}, /* PA5 FCC2:RxAddr[2] */
+ {0, 0, 0, 1, 0, 0}, /* PA4 FCC2:RxAddr[1] */
+ {0, 0, 0, 1, 0, 0}, /* PA3 FCC2:RxAddr[0] */
+ {0, 0, 0, 1, 0, 0}, /* PA2 FCC2:TxAddr[0] */
+ {0, 0, 0, 1, 0, 0}, /* PA1 FCC2:TxAddr[1] */
+ {0, 0, 0, 1, 0, 0} /* PA0 FCC2:TxAddr[2] */
+ },
+ /* Port B configuration */
+ { /* conf ppar psor pdir podr pdat */
+ {0, 0, 0, 1, 0, 0}, /* PB31 FCC2_RXSOC */
+ {0, 0, 0, 1, 0, 0}, /* PB30 FCC2_TXSOC */
+ {0, 0, 0, 1, 0, 0}, /* PB29 FCC2_RXCLAV */
+ {0, 0, 0, 0, 0, 0}, /* PB28 CONFIG2 */
+ {0, 1, 1, 0, 0, 1}, /* PB27 FCC2_TXD0 */
+ {0, 1, 1, 0, 0, 0}, /* PB26 FCC2_TXD1 */
+ {0, 0, 0, 1, 0, 0}, /* PB25 FCC2_TXD4 */
+ {0, 1, 1, 0, 0, 1}, /* PB24 FCC2_TXD5 */
+ {0, 0, 0, 1, 0, 0}, /* PB23 FCC2_TXD6 */
+ {0, 1, 0, 1, 0, 1}, /* PB22 FCC2_TXD7 */
+ {0, 1, 0, 0, 0, 0}, /* PB21 FCC2_RXD7 */
+ {0, 1, 0, 0, 0, 0}, /* PB20 FCC2_RXD6 */
+ {0, 1, 0, 0, 0, 0}, /* PB19 FCC2_RXD5 */
+ {0, 0, 0, 1, 0, 0}, /* PB18 FCC2_RXD4 */
+ {1, 1, 0, 0, 0, 0}, /* PB17 FCC3_RX_DV */
+ {1, 1, 0, 0, 0, 0}, /* PB16 FCC3_RX_ER */
+ {1, 1, 0, 1, 0, 0}, /* PB15 FCC3_TX_ER */
+ {1, 1, 0, 1, 0, 0}, /* PB14 FCC3_TX_EN */
+ {1, 1, 0, 0, 0, 0}, /* PB13 FCC3_COL */
+ {1, 1, 0, 0, 0, 0}, /* PB12 FCC3_CRS */
+ {1, 1, 0, 0, 0, 0}, /* PB11 FCC3_RXD3 */
+ {1, 1, 0, 0, 0, 0}, /* PB10 FCC3_RXD2 */
+ {1, 1, 0, 0, 0, 0}, /* PB9 FCC3_RXD1 */
+ {1, 1, 0, 0, 0, 0}, /* PB8 FCC3_RXD0 */
+ {1, 1, 0, 1, 0, 1}, /* PB7 FCC3_TXD0 */
+ {1, 1, 0, 1, 0, 1}, /* PB6 FCC3_TXD1 */
+ {1, 1, 0, 1, 0, 1}, /* PB5 FCC3_TXD2 */
+ {1, 1, 0, 1, 0, 1}, /* PB4 FCC3_TXD3 */
+ {0, 0, 0, 0, 0, 0}, /* PB3 */
+ {0, 0, 0, 0, 0, 0}, /* PB2 */
+ {0, 0, 0, 0, 0, 0}, /* PB1 */
+ {0, 0, 0, 0, 0, 0}, /* PB0 */
+ },
+ /* Port C configuration */
+ { /* conf ppar psor pdir podr pdat */
+ {0, 1, 0, 0, 0, 1}, /* PC31 CLK1 */
+ {0, 0, 0, 1, 0, 0}, /* PC30 U1MASTER_N */
+ {0, 1, 0, 0, 0, 1}, /* PC29 CLK3 */
+ {0, 0, 0, 1, 0, 1}, /* PC28 -MT90220_RST */
+ {0, 1, 0, 0, 0, 1}, /* PC27 CLK5 */
+ {0, 0, 0, 1, 0, 1}, /* PC26 -QUADFALC_RST */
+ {0, 1, 1, 1, 0, 1}, /* PC25 BRG4 */
+ {1, 0, 0, 1, 0, 0}, /* PC24 MDIO */
+ {1, 0, 0, 1, 0, 0}, /* PC23 MDC */
+ {0, 1, 0, 0, 0, 1}, /* PC22 CLK10 */
+ {0, 0, 0, 1, 0, 0}, /* PC21 */
+ {0, 1, 0, 0, 0, 1}, /* PC20 CLK12 */
+ {0, 1, 0, 0, 0, 1}, /* PC19 CLK13 */
+ {1, 1, 0, 0, 0, 1}, /* PC18 CLK14 */
+ {0, 1, 0, 0, 0, 0}, /* PC17 CLK15 */
+ {1, 1, 0, 0, 0, 1}, /* PC16 CLK16 */
+ {0, 1, 1, 0, 0, 0}, /* PC15 FCC1_TXADDR0 SLAVE */
+ {0, 1, 1, 0, 0, 0}, /* PC14 FCC1_RXADDR0 SLAVE */
+ {0, 1, 1, 0, 0, 0}, /* PC13 FCC1_TXADDR1 SLAVE */
+ {0, 1, 1, 0, 0, 0}, /* PC12 FCC1_RXADDR1 SLAVE */
+ {0, 0, 0, 1, 0, 0}, /* PC11 FCC2_RXD2 */
+ {0, 0, 0, 1, 0, 0}, /* PC10 FCC2_RXD3 */
+ {0, 0, 0, 1, 0, 1}, /* PC9 LTMODE */
+ {0, 0, 0, 1, 0, 1}, /* PC8 SELSYNC */
+ {0, 1, 1, 0, 0, 0}, /* PC7 FCC1_TXADDR2 SLAVE */
+ {0, 1, 1, 0, 0, 0}, /* PC6 FCC1_RXADDR2 SLAVE */
+ {0, 0, 0, 1, 0, 0}, /* PC5 FCC2_TXCLAV MASTER */
+ {0, 0, 0, 1, 0, 0}, /* PC4 FCC2_RXENB MASTER */
+ {0, 0, 0, 1, 0, 0}, /* PC3 FCC2_TXD2 */
+ {0, 0, 0, 1, 0, 0}, /* PC2 FCC2_TXD3 */
+ {0, 0, 0, 0, 0, 1}, /* PC1 PTMC -PTEENB */
+ {0, 0, 0, 1, 0, 1}, /* PC0 COMCLK_N */
+ },
+ /* Port D configuration */
+ { /* conf ppar psor pdir podr pdat */
+ {0, 0, 0, 1, 0, 1}, /* PD31 -CAM_RST */
+ {0, 0, 0, 1, 0, 0}, /* PD30 FCC2_TXENB */
+ {0, 1, 1, 0, 0, 0}, /* PD29 FCC1_RXADDR3 SLAVE */
+ {0, 1, 1, 0, 0, 1}, /* PD28 TDMC1_L1TXD */
+ {0, 1, 1, 0, 0, 0}, /* PD27 TDMC1_L1RXD */
+ {0, 1, 1, 0, 0, 1}, /* PD26 TDMC1_L1RSYNC */
+ {0, 0, 0, 1, 0, 1}, /* PD25 LED0 -OFF */
+ {0, 0, 0, 1, 0, 1}, /* PD24 LED5 -OFF */
+ {1, 0, 0, 1, 0, 1}, /* PD23 -LXT971_RST */
+ {0, 1, 1, 0, 0, 1}, /* PD22 TDMA2_L1TXD */
+ {0, 1, 1, 0, 0, 0}, /* PD21 TDMA2_L1RXD */
+ {0, 1, 1, 0, 0, 1}, /* PD20 TDMA2_L1RSYNC */
+ {0, 0, 0, 1, 0, 0}, /* PD19 FCC2_TXADDR3 */
+ {0, 0, 0, 1, 0, 0}, /* PD18 FCC2_RXADDR3 */
+ {0, 1, 0, 1, 0, 0}, /* PD17 BRG2 */
+ {0, 0, 0, 1, 0, 0}, /* PD16 */
+ {0, 0, 0, 1, 0, 0}, /* PD15 PT2TO1 */
+ {0, 0, 0, 1, 0, 1}, /* PD14 PT4TO3 */
+ {0, 0, 0, 1, 0, 1}, /* PD13 -SWMODE */
+ {0, 0, 0, 1, 0, 1}, /* PD12 -PTMODE */
+ {0, 0, 0, 1, 0, 0}, /* PD11 FCC2_RXD0 */
+ {0, 0, 0, 1, 0, 0}, /* PD10 FCC2_RXD1 */
+ {1, 1, 0, 1, 0, 1}, /* PD9 SMC1_SMTXD */
+ {1, 1, 0, 0, 0, 1}, /* PD8 SMC1_SMRXD */
+ {0, 1, 1, 0, 0, 0}, /* PD7 FCC1_TXADDR3 SLAVE */
+ {0, 0, 0, 1, 0, 0}, /* PD6 IMAMODE */
+ {0, 0, 0, 0, 0, 0}, /* PD5 CONFIG2 */
+ {0, 1, 0, 1, 0, 0}, /* PD4 BRG8 */
+ {0, 0, 0, 0, 0, 0}, /* PD3 */
+ {0, 0, 0, 0, 0, 0}, /* PD2 */
+ {0, 0, 0, 0, 0, 0}, /* PD1 */
+ {0, 0, 0, 0, 0, 0}, /* PD0 */
+ }
+};
+
+long int initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *) CFG_IMMR;
+ volatile memctl8260_t *memctl = &immap->im_memctl;
+ volatile uchar *base;
+ volatile ulong *addr, cnt, val;
+ ulong save[32]; /* to make test non-destructive */
+ int i, maxsize;
+
+ memctl->memc_psrt = CFG_PSRT;
+ memctl->memc_mptpr = CFG_MPTPR;
+
+#ifndef CFG_RAMBOOT
+ immap->im_siu_conf.sc_ppc_acr = 0x00000026;
+ immap->im_siu_conf.sc_ppc_alrh = 0x01276345;
+ immap->im_siu_conf.sc_ppc_alrl = 0x89ABCDEF;
+ immap->im_siu_conf.sc_lcl_acr = 0x00000000;
+ immap->im_siu_conf.sc_lcl_alrh = 0x01234567;
+ immap->im_siu_conf.sc_lcl_alrl = 0x89ABCDEF;
+ immap->im_siu_conf.sc_tescr1 = 0x00004000;
+ immap->im_siu_conf.sc_ltescr1 = 0x00004000;
+
+ /* Init Main SDRAM */
+#define OP_VALUE 0x404A241A
+#define OP_VALUE_M (OP_VALUE & 0x87FFFFFF);
+ base = (uchar *) CFG_SDRAM_BASE;
+ memctl->memc_psdmr = 0x28000000 | OP_VALUE_M;
+ *base = 0xFF;
+ memctl->memc_psdmr = 0x08000000 | OP_VALUE_M;
+ for (i = 0; i < 8; i++)
+ *base = 0xFF;
+ memctl->memc_psdmr = 0x18000000 | OP_VALUE_M;
+ *(base + 0x110) = 0xFF;
+ memctl->memc_psdmr = OP_VALUE;
+ memctl->memc_lsdmr = 0x4086A522;
+ *base = 0xFF;
+
+ /* We must be able to test a location outsize the maximum legal size
+ * to find out THAT we are outside; but this address still has to be
+ * mapped by the controller. That means, that the initial mapping has
+ * to be (at least) twice as large as the maximum expected size.
+ */
+ maxsize = (1 + (~memctl->memc_or1 | 0x7fff)) / 2;
+
+ /*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+ i = 0;
+ for (cnt = maxsize / sizeof (long); cnt > 0; cnt >>= 1) {
+ addr = (volatile ulong *) base + cnt; /* pointer arith! */
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ addr = (volatile ulong *) base;
+ save[i] = *addr;
+ *addr = 0;
+
+ if ((val = *addr) != 0) {
+ *addr = save[i];
+ return (0);
+ }
+
+ for (cnt = 1; cnt <= maxsize / sizeof (long); cnt <<= 1) {
+ addr = (volatile ulong *) base + cnt; /* pointer arith! */
+ val = *addr;
+ *addr = save[--i];
+ if (val != ~cnt) {
+ /* Write the actual size to ORx
+ */
+ memctl->memc_or1 |= ~(cnt * sizeof (long) - 1);
+ maxsize = cnt * sizeof (long) / 2;
+ break;
+ }
+ }
+
+ maxsize *= 2;
+ if (maxsize != hwc_main_sdram_size ())
+ printf ("Oops: memory test has not found all memory!\n");
+#endif
+
+ icache_enable ();
+ /* return total ram size of SDRAM */
+ return (maxsize);
+}
+
+int checkboard (void)
+{
+ char string[32];
+
+ hwc_manufact_date (string);
+
+ printf ("Board: Interphase 4539 (#%d %s)\n",
+ hwc_serial_number (),
+ string);
+
+#ifdef DEBUG
+ printf ("Manufacturing date: %s\n", string);
+ printf ("Serial number : %d\n", hwc_serial_number ());
+ printf ("FLASH size : %d MB\n", hwc_flash_size () >> 20);
+ printf ("Main SDRAM size : %d MB\n", hwc_main_sdram_size () >> 20);
+ printf ("Local SDRAM size : %d MB\n", hwc_local_sdram_size () >> 20);
+ hwc_mac_address (string);
+ printf ("MAC address : %s\n", string);
+#endif
+
+ return 0;
+}
+
+int misc_init_r (void)
+{
+ char *s, str[32];
+ int num;
+
+ if ((s = getenv ("serial#")) == NULL &&
+ (num = hwc_serial_number ()) != -1) {
+ sprintf (str, "%06d", num);
+ setenv ("serial#", str);
+ }
+ if ((s = getenv ("ethaddr")) == NULL && hwc_mac_address (str) == 0) {
+ setenv ("ethaddr", str);
+ }
+ return (0);
+}
+
+/***************************************************************
+ * We take some basic Hardware Configuration Parameter from the
+ * Serial EEPROM conected to the PSpan bridge. We keep it as
+ * simple as possible.
+ */
+int hwc_flash_size (void)
+{
+ uchar byte;
+
+ if (!seeprom_read (0x40, &byte, sizeof (byte))) {
+ switch ((byte >> 2) & 0x3) {
+ case 0x1:
+ return 0x0400000;
+ break;
+ case 0x2:
+ return 0x0800000;
+ break;
+ case 0x3:
+ return 0x1000000;
+ default:
+ return 0x0100000;
+ }
+ }
+ return -1;
+}
+int hwc_local_sdram_size (void)
+{
+ uchar byte;
+
+ if (!seeprom_read (0x40, &byte, sizeof (byte))) {
+ switch ((byte & 0x03)) {
+ case 0x1:
+ return 0x0800000;
+ case 0x2:
+ return 0x1000000;
+ default:
+ return 0; /* not present */
+ }
+ }
+ return -1;
+}
+int hwc_main_sdram_size (void)
+{
+ uchar byte;
+
+ if (!seeprom_read (0x41, &byte, sizeof (byte))) {
+ return 0x1000000 << ((byte >> 5) & 0x7);
+ }
+ return -1;
+}
+int hwc_serial_number (void)
+{
+ int sn = -1;
+
+ if (!seeprom_read (0xa0, (char *) &sn, sizeof (sn))) {
+ sn = cpu_to_le32 (sn);
+ }
+ return sn;
+}
+int hwc_mac_address (char *str)
+{
+ char mac[6];
+
+ if (!seeprom_read (0xb0, mac, sizeof (mac))) {
+ sprintf (str, "%02x:%02x:%02x:%02x:%02x:%02x\n",
+ mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
+ } else {
+ strcpy (str, "ERROR");
+ return -1;
+ }
+ return 0;
+}
+int hwc_manufact_date (char *str)
+{
+ uchar byte;
+ int value;
+
+ if (seeprom_read (0x92, &byte, sizeof (byte)))
+ goto out;
+ value = byte;
+ if (seeprom_read (0x93, &byte, sizeof (byte)))
+ goto out;
+ value += byte << 8;
+ sprintf (str, "%02d/%02d/%04d",
+ value & 0x1F, (value >> 5) & 0xF,
+ 1980 + ((value >> 9) & 0x1FF));
+ return 0;
+
+ out:
+ strcpy (str, "ERROR");
+ return -1;
+}
+
+#define PSPAN_ADDR 0xF0020000
+#define EEPROM_REG 0x408
+#define EEPROM_READ_CMD 0xA000
+#define PSPAN_WRITE(a,v) \
+ *((volatile unsigned long *)(PSPAN_ADDR+(a))) = v; eieio()
+#define PSPAN_READ(a) \
+ *((volatile unsigned long *)(PSPAN_ADDR+(a)))
+
+int seeprom_read (int addr, uchar * data, int size)
+{
+ ulong val, cmd;
+ int i;
+
+ for (i = 0; i < size; i++) {
+
+ cmd = EEPROM_READ_CMD;
+ cmd |= ((addr + i) << 24) & 0xff000000;
+
+ /* Wait for ACT to authorize write */
+ while ((val = PSPAN_READ (EEPROM_REG)) & 0x80)
+ eieio ();
+
+ /* Write command */
+ PSPAN_WRITE (EEPROM_REG, cmd);
+
+ /* Wait for data to be valid */
+ while ((val = PSPAN_READ (EEPROM_REG)) & 0x80)
+ eieio ();
+ /* Do it twice, first read might be erratic */
+ while ((val = PSPAN_READ (EEPROM_REG)) & 0x80)
+ eieio ();
+
+ /* Read error */
+ if (val & 0x00000040) {
+ return -1;
+ } else {
+ data[i] = (val >> 16) & 0xff;
+ }
+ }
+ return 0;
+}
--- /dev/null
+/*
+ * (C) Copyright 2000, 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Ulrich Lutz, Speech Design GmbH, ulutz@datalab.de.
+ *
+ * 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 <mpc8xx.h>
+#include <commproc.h>
+
+#ifdef CONFIG_STATUS_LED
+# include <status_led.h>
+#endif
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+
+/* ------------------------------------------------------------------------- */
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+/*
+ * 50 MHz SHARC access using UPM A
+ */
+const uint sharc_table[] =
+{
+ /*
+ * Single Read. (Offset 0 in UPM RAM)
+ */
+ 0x0FF3FC04, 0x0FF3EC00, 0x7FFFEC04, 0xFFFFEC04,
+ 0xFFFFEC05, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Burst Read. (Offset 8 in UPM RAM)
+ */
+ /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Single Write. (Offset 18 in UPM RAM)
+ */
+ 0x0FAFFC04, 0x0FAFEC00, 0x7FFFEC04, 0xFFFFEC04,
+ 0xFFFFEC05, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Burst Write. (Offset 20 in UPM RAM)
+ */
+ /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Refresh (Offset 30 in UPM RAM)
+ */
+ /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Exception. (Offset 3c in UPM RAM)
+ */
+ 0x7FFFFC07, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+
+/*
+ * 50 MHz SDRAM access using UPM B
+ */
+const uint sdram_table[] =
+{
+ /*
+ * Single Read. (Offset 0 in UPM RAM)
+ */
+ 0x0E26FC04, 0x11ADFC04, 0xEFBBBC00, 0x1FF77C45, /* last */
+ _NOT_USED_,
+ /*
+ * SDRAM Initialization (offset 5 in UPM RAM)
+ *
+ * This is no UPM entry point. The following definition uses
+ * the remaining space to establish an initialization
+ * sequence, which is executed by a RUN command.
+ *
+ */
+ 0x1FF77C35, 0xEFEABC34, 0x1FB57C35, /* last */
+ /*
+ * Burst Read. (Offset 8 in UPM RAM)
+ */
+ 0x0E26FC04, 0x10ADFC04, 0xF0AFFC00, 0xF0AFFC00,
+ 0xF1AFFC00, 0xEFBBBC00, 0x1FF77C45, /* last */
+ _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Single Write. (Offset 18 in UPM RAM)
+ */
+ 0x1F27FC04, 0xEEAEBC04, 0x01B93C00, 0x1FF77C45, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Burst Write. (Offset 20 in UPM RAM)
+ */
+ 0x0E26BC00, 0x10AD7C00, 0xF0AFFC00, 0xF0AFFC00,
+ 0xE1BBBC04, 0x1FF77C45, /* last */
+ _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Refresh (Offset 30 in UPM RAM)
+ */
+ 0x1FF5FC84, 0xFFFFFC04, 0xFFFFFC04, 0xFFFFFC84,
+ 0xFFFFFC05, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Exception. (Offset 3c in UPM RAM)
+ */
+ 0x7FFFFC07, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ *
+ */
+
+int checkboard (void)
+{
+#ifdef CONFIG_IVMS8
+ puts ("Board: IVMS8\n");
+#endif
+#ifdef CONFIG_IVML24
+ puts ("Board: IVM-L8/24\n");
+#endif
+ return (0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int
+initdram (int board_type)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immr->im_memctl;
+ long int size_b0;
+
+ /* enable SDRAM clock ("switch on" SDRAM) */
+ immr->im_cpm.cp_pbpar &= ~(CFG_PB_SDRAM_CLKE); /* GPIO */
+ immr->im_cpm.cp_pbodr &= ~(CFG_PB_SDRAM_CLKE); /* active output */
+ immr->im_cpm.cp_pbdir |= CFG_PB_SDRAM_CLKE ; /* output */
+ immr->im_cpm.cp_pbdat |= CFG_PB_SDRAM_CLKE ; /* assert SDRAM CLKE */
+ udelay(1);
+
+ /*
+ * Map controller bank 1 for ELIC SACCO
+ */
+ memctl->memc_or1 = CFG_OR1;
+ memctl->memc_br1 = CFG_BR1;
+
+ /*
+ * Map controller bank 2 for ELIC EPIC
+ */
+ memctl->memc_or2 = CFG_OR2;
+ memctl->memc_br2 = CFG_BR2;
+
+ /*
+ * Configure UPMA for SHARC
+ */
+ upmconfig(UPMA, (uint *)sharc_table, sizeof(sharc_table)/sizeof(uint));
+
+#if defined(CONFIG_IVML24)
+ /*
+ * Map controller bank 4 for HDLC Address space
+ */
+ memctl->memc_or4 = CFG_OR4;
+ memctl->memc_br4 = CFG_BR4;
+#endif
+
+ /*
+ * Map controller bank 5 for SHARC
+ */
+ memctl->memc_or5 = CFG_OR5;
+ memctl->memc_br5 = CFG_BR5;
+
+ memctl->memc_mamr = 0x00001000;
+
+ /*
+ * Configure UPMB for SDRAM
+ */
+ upmconfig(UPMB, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
+
+ memctl->memc_mptpr = CFG_MPTPR_1BK_8K;
+
+ memctl->memc_mar = 0x00000088;
+
+ /*
+ * Map controller bank 3 to the SDRAM bank at preliminary address.
+ */
+ memctl->memc_or3 = CFG_OR3_PRELIM;
+ memctl->memc_br3 = CFG_BR3_PRELIM;
+
+ memctl->memc_mbmr = CFG_MBMR_8COL; /* refresh not enabled yet */
+
+ udelay(200);
+ memctl->memc_mcr = 0x80806105; /* precharge */
+ udelay(1);
+ memctl->memc_mcr = 0x80806106; /* load mode register */
+ udelay(1);
+ memctl->memc_mcr = 0x80806130; /* autorefresh */
+ udelay(1);
+ memctl->memc_mcr = 0x80806130; /* autorefresh */
+ udelay(1);
+ memctl->memc_mcr = 0x80806130; /* autorefresh */
+ udelay(1);
+ memctl->memc_mcr = 0x80806130; /* autorefresh */
+ udelay(1);
+ memctl->memc_mcr = 0x80806130; /* autorefresh */
+ udelay(1);
+ memctl->memc_mcr = 0x80806130; /* autorefresh */
+ udelay(1);
+ memctl->memc_mcr = 0x80806130; /* autorefresh */
+ udelay(1);
+ memctl->memc_mcr = 0x80806130; /* autorefresh */
+
+ memctl->memc_mbmr |= MAMR_PTBE; /* refresh enabled */
+
+ /*
+ * Check Bank 0 Memory Size for re-configuration
+ */
+ size_b0 = dram_size (CFG_MBMR_8COL, (ulong *)SDRAM_BASE3_PRELIM, SDRAM_MAX_SIZE);
+
+ memctl->memc_mbmr = CFG_MBMR_8COL | MAMR_PTBE;
+
+ return (size_b0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mamr_value, long int *base, long int maxsize)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immr->im_memctl;
+ volatile long int *addr;
+ ulong cnt, val;
+ ulong save[32]; /* to make test non-destructive */
+ unsigned char i = 0;
+
+ memctl->memc_mbmr = mamr_value;
+
+ for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ /* write 0 to base address */
+ addr = base;
+ save[i] = *addr;
+ *addr = 0;
+
+ /* check at base address */
+ if ((val = *addr) != 0) {
+ *addr = save[i];
+ return (0);
+ }
+
+ for (cnt = 1; cnt <= maxsize/sizeof(long); cnt <<= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ val = *addr;
+ *addr = save[--i];
+
+ if (val != (~cnt)) {
+ return (cnt * sizeof(long));
+ }
+ }
+ return (maxsize);
+}
+
+/* ------------------------------------------------------------------------- */
+
+void reset_phy(void)
+{
+ immap_t *immr = (immap_t *)CFG_IMMR;
+
+ /* De-assert Ethernet Powerdown */
+ immr->im_cpm.cp_pbpar &= ~(CFG_PB_ETH_POWERDOWN); /* GPIO */
+ immr->im_cpm.cp_pbodr &= ~(CFG_PB_ETH_POWERDOWN); /* active output */
+ immr->im_cpm.cp_pbdir |= CFG_PB_ETH_POWERDOWN ; /* output */
+ immr->im_cpm.cp_pbdat &= ~(CFG_PB_ETH_POWERDOWN); /* Enable PHY power */
+ udelay(1000);
+
+ /*
+ * RESET is implemented by a positive pulse of at least 1 us
+ * at the reset pin.
+ *
+ * Configure RESET pins for NS DP83843 PHY, and RESET chip.
+ *
+ * Note: The RESET pin is high active, but there is an
+ * inverter on the SPD823TS board...
+ */
+ immr->im_ioport.iop_pcpar &= ~(CFG_PC_ETH_RESET);
+ immr->im_ioport.iop_pcdir |= CFG_PC_ETH_RESET;
+ /* assert RESET signal of PHY */
+ immr->im_ioport.iop_pcdat &= ~(CFG_PC_ETH_RESET);
+ udelay (10);
+ /* de-assert RESET signal of PHY */
+ immr->im_ioport.iop_pcdat |= CFG_PC_ETH_RESET;
+ udelay (10);
+}
+
+/* ------------------------------------------------------------------------- */
+
+void show_boot_progress (int status)
+{
+#if defined(CONFIG_STATUS_LED)
+# if defined(STATUS_LED_YELLOW)
+ status_led_set (STATUS_LED_YELLOW,
+ (status < 0) ? STATUS_LED_ON : STATUS_LED_OFF);
+# endif /* STATUS_LED_YELLOW */
+# if defined(STATUS_LED_BOOT)
+ if (status == 6)
+ status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
+# endif /* STATUS_LED_BOOT */
+#endif /* CONFIG_STATUS_LED */
+}
+
+/* ------------------------------------------------------------------------- */
+
+void ide_set_reset(int on)
+{
+ volatile immap_t *immr = (immap_t *)CFG_IMMR;
+
+ /*
+ * Configure PC for IDE Reset Pin
+ */
+ if (on) { /* assert RESET */
+ immr->im_ioport.iop_pcdat &= ~(CFG_PC_IDE_RESET);
+ } else { /* release RESET */
+ immr->im_ioport.iop_pcdat |= CFG_PC_IDE_RESET;
+ }
+
+ /* program port pin as GPIO output */
+ immr->im_ioport.iop_pcpar &= ~(CFG_PC_IDE_RESET);
+ immr->im_ioport.iop_pcso &= ~(CFG_PC_IDE_RESET);
+ immr->im_ioport.iop_pcdir |= CFG_PC_IDE_RESET;
+}
+
+/* ------------------------------------------------------------------------- */
--- /dev/null
+/*
+ * (C) Copyright 2000, 2001
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * (C) Copyright 2001
+ * Torsten Stevens, FHG IMS, stevens@ims.fhg.de
+ * Bruno Achauer, Exet AG, bruno@exet-ag.de.
+ *
+ * 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
+ */
+
+/*
+ * Derived from ../tqm8xx/tqm8xx.c
+ */
+
+#include <common.h>
+#include <mpc8xx.h>
+
+/* ------------------------------------------------------------------------- */
+
+static long int dram_size (long int, long int *, long int);
+
+/* ------------------------------------------------------------------------- */
+
+#define _NOT_USED_ 0xFFFFFFFF
+
+const uint sdram_table[] =
+{
+ /*
+ * Single Read. (Offset 0 in UPMA RAM)
+ */
+ 0x1f07fc04, 0xeeaefc04, 0x11adfc04, 0xefbbbc00,
+ 0x1ff77c47, /* last */
+ /*
+ * SDRAM Initialization (offset 5 in UPMA RAM)
+ *
+ * This is no UPM entry point. The following definition uses
+ * the remaining space to establish an initialization
+ * sequence, which is executed by a RUN command.
+ *
+ */
+ 0x1ff77c35, 0xefeabc34, 0x1fb57c35, /* last */
+ /*
+ * Burst Read. (Offset 8 in UPMA RAM)
+ */
+ 0x1f07fc04, 0xeeaefc04, 0x10adfc04, 0xf0affc00,
+ 0xf0affc00, 0xf1affc00, 0xefbbbc00, 0x1ff77c47, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Single Write. (Offset 18 in UPMA RAM)
+ */
+ 0x1f27fc04, 0xeeaebc00, 0x01b93c04, 0x1ff77c47, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Burst Write. (Offset 20 in UPMA RAM)
+ */
+ 0x1f07fc04, 0xeeaebc00, 0x10ad7c00, 0xf0affc00,
+ 0xf0affc00, 0xe1bbbc04, 0x1ff77c47, /* last */
+ _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Refresh (Offset 30 in UPMA RAM)
+ */
+ 0x1ff5fc84, 0xfffffc04, 0xfffffc04, 0xfffffc04,
+ 0xfffffc84, 0xfffffc07, 0xfffffc07, /* last */
+ _NOT_USED_,
+ _NOT_USED_, _NOT_USED_, _NOT_USED_, _NOT_USED_,
+ /*
+ * Exception. (Offset 3c in UPMA RAM)
+ */
+ 0x7ffffc07, /* last */
+ _NOT_USED_, _NOT_USED_, _NOT_USED_,
+};
+
+/* ------------------------------------------------------------------------- */
+
+
+/*
+ * Check Board Identity:
+ *
+ * Test TQ ID string (TQM8xx...)
+ * If present, check for "L" type (no second DRAM bank),
+ * otherwise "L" type is assumed as default.
+ *
+ * Return 1 for "L" type, 0 else.
+ */
+
+int checkboard (void)
+{
+ printf("Board: Lantec special edition rev.%d\n", CONFIG_LANTEC);
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+long int initdram (int board_type)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ long int size_b0;
+ int i;
+
+ /*
+ * Configure UPMA for SDRAM
+ */
+ upmconfig(UPMA, (uint *)sdram_table, sizeof(sdram_table)/sizeof(uint));
+
+ memctl->memc_mptpr = CFG_MPTPR_1BK_8K /* XXX CFG_MPTPR XXX */;
+
+ /* burst length=4, burst type=sequential, CAS latency=2 */
+ memctl->memc_mar = 0x00000088;
+
+ /*
+ * Map controller bank 3 to the SDRAM bank at preliminary address.
+ */
+ memctl->memc_or3 = CFG_OR3_PRELIM;
+ memctl->memc_br3 = CFG_BR3_PRELIM;
+
+ /* initialize memory address register */
+ memctl->memc_mamr = CFG_MAMR_8COL; /* refresh not enabled yet */
+
+ /* mode initialization (offset 5) */
+ udelay(200); /* 0x80006105 */
+ memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS3 | MCR_MLCF(1) | MCR_MAD(0x05);
+
+ /* run 2 refresh sequence with 4-beat refresh burst (offset 0x30) */
+ udelay(1); /* 0x80006130 */
+ memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS3 | MCR_MLCF(1) | MCR_MAD(0x30);
+ udelay(1); /* 0x80006130 */
+ memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS3 | MCR_MLCF(1) | MCR_MAD(0x30);
+
+ udelay(1); /* 0x80006106 */
+ memctl->memc_mcr = MCR_OP_RUN | MCR_MB_CS3 | MCR_MLCF(1) | MCR_MAD(0x06);
+
+ memctl->memc_mamr |= MAMR_PTBE; /* refresh enabled */
+
+ udelay(200);
+
+ /* Need at least 10 DRAM accesses to stabilize */
+ for (i=0; i<10; ++i) {
+ volatile unsigned long *addr = \
+ (volatile unsigned long *)SDRAM_BASE3_PRELIM;
+ unsigned long val;
+
+ val = *(addr + i);
+ *(addr + i) = val;
+ }
+
+ /*
+ * Check Bank 0 Memory Size for re-configuration
+ */
+ size_b0 = dram_size (CFG_MAMR_8COL,
+ (ulong *)SDRAM_BASE3_PRELIM,
+ SDRAM_MAX_SIZE);
+
+ memctl->memc_mamr = CFG_MAMR_8COL | MAMR_PTBE;
+
+ /*
+ * Final mapping:
+ */
+
+ memctl->memc_or3 = ((-size_b0) & 0xFFFF0000) | CFG_OR_TIMING_SDRAM;
+ memctl->memc_br3 = (CFG_SDRAM_BASE & BR_BA_MSK) | BR_MS_UPMA | BR_V;
+ udelay(1000);
+
+ return (size_b0);
+}
+
+/* ------------------------------------------------------------------------- */
+
+/*
+ * Check memory range for valid RAM. A simple memory test determines
+ * the actually available RAM size between addresses `base' and
+ * `base + maxsize'. Some (not all) hardware errors are detected:
+ * - short between address lines
+ * - short between data lines
+ */
+
+static long int dram_size (long int mamr_value, long int *base, long int maxsize)
+{
+ volatile immap_t *immap = (immap_t *)CFG_IMMR;
+ volatile memctl8xx_t *memctl = &immap->im_memctl;
+ volatile long int *addr;
+ ulong cnt, val;
+ ulong save[32]; /* to make test non-destructive */
+ unsigned char i = 0;
+
+ memctl->memc_mamr = mamr_value;
+
+ for (cnt = maxsize/sizeof(long); cnt > 0; cnt >>= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ save[i++] = *addr;
+ *addr = ~cnt;
+ }
+
+ /* write 0 to base address */
+ addr = base;
+ save[i] = *addr;
+ *addr = 0;
+
+ /* check at base address */
+ if ((val = *addr) != 0) {
+ *addr = save[i];
+ return (0);
+ }
+
+ for (cnt = 1; cnt <= maxsize/sizeof(long); cnt <<= 1) {
+ addr = base + cnt; /* pointer arith! */
+
+ val = *addr;
+ *addr = save[--i];
+
+ if (val != (~cnt)) {
+ return (cnt * sizeof(long));
+ }
+ }
+ return (maxsize);
+}
--- /dev/null
+/*
+ * MOUSSE Board Support
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * (C) Copyright 2001
+ * James Dougherty, jfd@cs.stanford.edu
+ *
+ * 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 <mpc824x.h>
+#include <asm/processor.h>
+
+#include "mousse.h"
+#include "m48t59y.h"
+#include <pci.h>
+
+
+int checkboard (void)
+{
+ ulong busfreq = get_bus_freq (0);
+ char buf[32];
+
+ puts ("Board: MOUSSE MPC8240/KAHLUA - CHRP (MAP B)\n");
+ printf ("Built: %s at %s\n", __DATE__, __TIME__);
+ printf ("MPLD: Revision %d\n", SYS_REVID_GET ());
+ printf ("Local Bus: %s MHz\n", strmhz (buf, busfreq));
+
+ return 0;
+}
+
+int checkflash (void)
+{
+ printf ("checkflash\n");
+ flash_init ();
+ return 0;
+}
+
+long int initdram (int board_type)
+{
+ return CFG_RAM_SIZE;
+}
+
+
+void get_tod (void)
+{
+ int year, month, day, hour, minute, second;
+
+ m48_tod_get (&year, &month, &day, &hour, &minute, &second);
+
+ printf (" Current date/time: %d/%d/%d %d:%d:%d \n",
+ month, day, year, hour, minute, second);
+
+}
+
+/*
+ * EPIC, PCI, and I/O devices.
+ * Initialize Mousse Platform, probe for PCI devices,
+ * Query configuration parameters if not set.
+ */
+int misc_init_f (void)
+{
+ m48_tod_init (); /* Init SGS M48T59Y TOD/NVRAM */
+ printf ("RTC: M48T589 TOD/NVRAM (%d) bytes\n", TOD_NVRAM_SIZE);
+ get_tod ();
+ return 0;
+}