Initial revision
diff --git a/board/rpxsuper/flash.c b/board/rpxsuper/flash.c
new file mode 100644
index 0000000..0c298ba
--- /dev/null
+++ b/board/rpxsuper/flash.c
@@ -0,0 +1,434 @@
+/*
+ * (C) Copyright 2000
+ * Marius Groeger <mgroeger@sysgo.de>
+ * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ *
+ * (C) Copyright 2000
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Flash Routines for AMD 29F080B devices
+ * Added support for 64bit and AMD 29DL323B
+ *
+ *--------------------------------------------------------------------
+ * 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 <asm/io.h>
+
+flash_info_t flash_info[CFG_MAX_FLASH_BANKS];
+
+#define RD_SWP32(x) in_le32((volatile u32*)x)
+
+/*-----------------------------------------------------------------------
+ * Functions
+ */
+
+static ulong flash_get_size (vu_long *addr, flash_info_t *info);
+static int write_word (flash_info_t *info, ulong dest, ulong data);
+
+/*-----------------------------------------------------------------------
+ */
+
+unsigned long flash_init (void)
+{
+    unsigned long size;
+    int i;
+
+    /* Init: no FLASHes known */
+    for (i=0; i<CFG_MAX_FLASH_BANKS; ++i) {
+	flash_info[i].flash_id = FLASH_UNKNOWN;
+    }
+
+    /* for now, only support the 4 MB Flash SIMM */
+    size = flash_get_size((vu_long *)CFG_FLASH0_BASE, &flash_info[0]);
+
+    /*
+     * protect monitor and environment sectors
+     */
+
+#if CFG_MONITOR_BASE >= CFG_FLASH0_BASE
+    flash_protect(FLAG_PROTECT_SET,
+		  CFG_MONITOR_BASE,
+		  CFG_MONITOR_BASE+CFG_MONITOR_LEN-1,
+		  &flash_info[0]);
+#endif
+
+#if (CFG_ENV_IS_IN_FLASH == 1) && defined(CFG_ENV_ADDR)
+# ifndef  CFG_ENV_SIZE
+#  define CFG_ENV_SIZE	CFG_ENV_SECT_SIZE
+# endif
+    flash_protect(FLAG_PROTECT_SET,
+		  CFG_ENV_ADDR,
+		  CFG_ENV_ADDR + CFG_ENV_SIZE - 1,
+		  &flash_info[0]);
+#endif
+
+    return /*size*/ (CFG_FLASH0_SIZE * 1024 * 1024);
+}
+
+/*-----------------------------------------------------------------------
+ */
+void flash_print_info  (flash_info_t *info)
+{
+    int i;
+
+    if (info->flash_id == FLASH_UNKNOWN) {
+	printf ("missing or unknown FLASH type\n");
+	return;
+    }
+
+    switch (info->flash_id & FLASH_VENDMASK) {
+    case (AMD_MANUFACT & FLASH_VENDMASK):
+	printf ("AMD ");
+	break;
+    case (FUJ_MANUFACT & FLASH_VENDMASK):
+	printf ("FUJITSU ");
+	break;
+    case (SST_MANUFACT & FLASH_VENDMASK):
+	printf ("SST ");
+	break;
+    default:
+	printf ("Unknown Vendor ");
+	break;
+    }
+
+    switch (info->flash_id & FLASH_TYPEMASK) {
+    case (AMD_ID_DL323B & FLASH_TYPEMASK):
+	printf("AM29DL323B (32 MBit)\n");
+	break;
+    default:
+	printf ("Unknown Chip Type\n");
+	break;
+    }
+
+    printf ("  Size: %ld MB in %d Sectors\n",
+	    info->size >> 20, info->sector_count);
+
+    printf ("  Sector Start Addresses:");
+    for (i = 0; i < info->sector_count; ++i) {
+	if ((i % 5) == 0) printf ("\n   ");
+	printf (" %08lX%s",
+		info->start[i],
+		info->protect[i] ? " (RO)" : "     "
+		);
+    }
+    printf ("\n");
+    return;
+}
+
+/*
+ * The following code cannot be run from FLASH!
+ */
+
+static ulong flash_get_size (vu_long *addr, flash_info_t *info)
+{
+    short i;
+    vu_long vendor[2], devid[2];
+    ulong base = (ulong)addr;
+
+    /* Reset and Write auto select command: read Manufacturer ID */
+    addr[0] = 0xf0f0f0f0;
+    addr[2 * 0x0555] = 0xAAAAAAAA;
+    addr[2 * 0x02AA] = 0x55555555;
+    addr[2 * 0x0555] = 0x90909090;
+    addr[1] = 0xf0f0f0f0;
+    addr[2 * 0x0555 + 1] = 0xAAAAAAAA;
+    addr[2 * 0x02AA + 1] = 0x55555555;
+    addr[2 * 0x0555 + 1] = 0x90909090;
+    udelay (1000);
+
+    vendor[0] = RD_SWP32(&addr[0]);
+    vendor[1] = RD_SWP32(&addr[1]);
+    if (vendor[0] != vendor[1] || vendor[0] != AMD_MANUFACT) {
+	info->size = 0;
+	goto out;
+    }
+
+    devid[0] = RD_SWP32(&addr[2]);
+    devid[1] = RD_SWP32(&addr[3]);
+
+    if (devid[0] == AMD_ID_DL323B) {
+	/*
+	* we have 2 Banks
+	* Bank 1 (23 Sectors): 0-7=8kbyte, 8-22=64kbyte
+	* Bank 2 (48 Sectors): 23-70=64kbyte
+	*/
+	info->flash_id     = (AMD_MANUFACT & FLASH_VENDMASK) |
+                             (AMD_ID_DL323B & FLASH_TYPEMASK);
+	info->sector_count = 71;
+	info->size         = 4 * (8 * 8 + 63 * 64) * 1024;
+    }
+    else {
+	info->size = 0;
+	goto out;
+    }
+
+    /* set up sector start address table */
+    for (i = 0; i < 8; i++) {
+        info->start[i] = base + (i * 0x8000);
+    }
+    for (i = 8; i < info->sector_count; i++) {
+        info->start[i] = base + (i * 0x40000) + 8 * 0x8000 - 8 * 0x40000;
+    }
+
+    /* check for protected sectors */
+    for (i = 0; i < info->sector_count; i++) {
+        /* read sector protection at sector address */
+	addr = (volatile unsigned long *)(info->start[i]);
+        addr[2 * 0x0555] = 0xAAAAAAAA;
+	addr[2 * 0x02AA] = 0x55555555;
+	addr[2 * 0x0555] = 0x90909090;
+	addr[2 * 0x0555 + 1] = 0xAAAAAAAA;
+	addr[2 * 0x02AA + 1] = 0x55555555;
+	addr[2 * 0x0555 + 1] = 0x90909090;
+	udelay (1000);
+    	base = RD_SWP32(&addr[4]);
+	base |= RD_SWP32(&addr[5]);
+	info->protect[i] = base & 0x00010001 ? 1 : 0;
+    }
+    addr = (vu_long*)info->start[0];
+
+out:
+    /* reset command */
+    addr[0] = 0xf0f0f0f0;
+    addr[1] = 0xf0f0f0f0;
+
+    return info->size;
+}
+
+
+/*-----------------------------------------------------------------------
+ */
+
+int flash_erase (flash_info_t *info, int s_first, int s_last)
+{
+    vu_long *addr = (vu_long*)(info->start[0]);
+    int flag, prot, sect, l_sect;
+    ulong start, now, last;
+
+    if ((s_first < 0) || (s_first > s_last)) {
+	if (info->flash_id == FLASH_UNKNOWN) {
+	    printf ("- missing\n");
+	} else {
+	    printf ("- no sectors to erase\n");
+	}
+	return 1;
+    }
+
+    prot = 0;
+    for (sect = s_first; sect <= s_last; sect++) {
+	if (info->protect[sect]) {
+	    prot++;
+	}
+    }
+
+    if (prot) {
+	printf ("- Warning: %d protected sectors will not be erased!\n",
+		prot);
+    } else {
+	printf ("\n");
+    }
+
+    l_sect = -1;
+
+    /* Disable interrupts which might cause a timeout here */
+    flag = disable_interrupts();
+
+    addr[2 * 0x0555] = 0xAAAAAAAA;
+    addr[2 * 0x02AA] = 0x55555555;
+    addr[2 * 0x0555] = 0x80808080;
+    addr[2 * 0x0555] = 0xAAAAAAAA;
+    addr[2 * 0x02AA] = 0x55555555;
+    addr[2 * 0x0555 + 1] = 0xAAAAAAAA;
+    addr[2 * 0x02AA + 1] = 0x55555555;
+    addr[2 * 0x0555 + 1] = 0x80808080;
+    addr[2 * 0x0555 + 1] = 0xAAAAAAAA;
+    addr[2 * 0x02AA + 1] = 0x55555555;
+    udelay (100);
+
+    /* Start erase on unprotected sectors */
+    for (sect = s_first; sect<=s_last; sect++) {
+	if (info->protect[sect] == 0) {	/* not protected */
+	    addr = (vu_long*)(info->start[sect]);
+	    addr[0] = 0x30303030;
+	    addr[1] = 0x30303030;
+	    l_sect = sect;
+	}
+    }
+
+    /* re-enable interrupts if necessary */
+    if (flag)
+      enable_interrupts();
+
+    /* wait at least 80us - let's wait 1 ms */
+    udelay (1000);
+
+    /*
+     * We wait for the last triggered sector
+     */
+    if (l_sect < 0)
+      goto DONE;
+
+    start = get_timer (0);
+    last  = start;
+    addr = (vu_long*)(info->start[l_sect]);
+    while (	(addr[0] & 0x80808080) != 0x80808080 ||
+		(addr[1] & 0x80808080) != 0x80808080) {
+	if ((now = get_timer(start)) > CFG_FLASH_ERASE_TOUT) {
+	    printf ("Timeout\n");
+	    return 1;
+	}
+	/* show that we're waiting */
+	if ((now - last) > 1000) {	/* every second */
+	    serial_putc ('.');
+	    last = now;
+	}
+    }
+
+    DONE:
+    /* reset to read mode */
+    addr = (volatile unsigned long *)info->start[0];
+    addr[0] = 0xF0F0F0F0;	/* reset bank */
+    addr[1] = 0xF0F0F0F0;	/* reset bank */
+
+    printf (" done\n");
+    return 0;
+}
+
+/*-----------------------------------------------------------------------
+ * Copy memory to flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+
+int write_buff (flash_info_t *info, uchar *src, ulong addr, ulong cnt)
+{
+    ulong cp, wp, data;
+    int i, l, rc;
+
+    wp = (addr & ~3);	/* get lower word aligned address */
+
+    /*
+     * handle unaligned start bytes
+     */
+    if ((l = addr - wp) != 0) {
+	data = 0;
+	for (i=0, cp=wp; i<l; ++i, ++cp) {
+	    data = (data << 8) | (*(uchar *)cp);
+	}
+	for (; i<4 && cnt>0; ++i) {
+	    data = (data << 8) | *src++;
+	    --cnt;
+	    ++cp;
+	}
+	for (; cnt==0 && i<4; ++i, ++cp) {
+	    data = (data << 8) | (*(uchar *)cp);
+	}
+
+	if ((rc = write_word(info, wp, data)) != 0) {
+	    return (rc);
+	}
+	wp += 4;
+    }
+
+    /*
+     * handle word aligned part
+     */
+    while (cnt >= 4) {
+	data = 0;
+	for (i=0; i<4; ++i) {
+	    data = (data << 8) | *src++;
+	}
+	if ((rc = write_word(info, wp, data)) != 0) {
+	    return (rc);
+	}
+	wp  += 4;
+	cnt -= 4;
+    }
+
+    if (cnt == 0) {
+	return (0);
+    }
+
+    /*
+     * handle unaligned tail bytes
+     */
+    data = 0;
+    for (i=0, cp=wp; i<4 && cnt>0; ++i, ++cp) {
+	data = (data << 8) | *src++;
+	--cnt;
+    }
+    for (; i<4; ++i, ++cp) {
+	data = (data << 8) | (*(uchar *)cp);
+    }
+
+    return (write_word(info, wp, data));
+}
+
+/*-----------------------------------------------------------------------
+ * Write a word to Flash, returns:
+ * 0 - OK
+ * 1 - write timeout
+ * 2 - Flash not erased
+ */
+static int write_word (flash_info_t *info, ulong dest, ulong data)
+{
+    vu_long *addr = (vu_long*)(info->start[0]);
+    ulong start;
+    int flag;
+
+    /* Check if Flash is (sufficiently) erased */
+    if ((*((vu_long *)dest) & data) != data) {
+	return (2);
+    }
+    /* Disable interrupts which might cause a timeout here */
+    flag = disable_interrupts();
+
+    if ((dest & 0x00000004) == 0) {
+        addr[2 * 0x0555] = 0xAAAAAAAA;
+	addr[2 * 0x02AA] = 0x55555555;
+        addr[2 * 0x0555] = 0xA0A0A0A0;
+    }
+    else {
+        addr[2 * 0x0555 + 1] = 0xAAAAAAAA;
+	addr[2 * 0x02AA + 1] = 0x55555555;
+        addr[2 * 0x0555 + 1] = 0xA0A0A0A0;
+    }
+
+    *((vu_long *)dest) = data;
+
+    /* re-enable interrupts if necessary */
+    if (flag)
+      enable_interrupts();
+
+    /* data polling for D7 */
+    start = get_timer (0);
+    while ((*((vu_long *)dest) & 0x80808080) != (data & 0x80808080)) {
+	if (get_timer(start) > CFG_FLASH_WRITE_TOUT) {
+	    return (1);
+	}
+    }
+    return (0);
+}
+
+/*-----------------------------------------------------------------------
+ */
diff --git a/board/rpxsuper/mii_phy.c b/board/rpxsuper/mii_phy.c
new file mode 100644
index 0000000..319f959
--- /dev/null
+++ b/board/rpxsuper/mii_phy.c
@@ -0,0 +1,108 @@
+#include <common.h>
+#include <mii_phy.h>
+#include "rpxsuper.h"
+
+#define MII_MDIO	0x01
+#define MII_MDCK	0x02
+#define MII_MDIR	0x04
+
+void
+mii_discover_phy(void)
+{
+    int known;
+    unsigned short phy_reg;
+    unsigned long phy_id;
+
+    known = 0;
+    printf("Discovering phy @ 0: ");
+    phy_id = mii_phy_read(2) << 16;
+    phy_id |= mii_phy_read(3);
+    if ((phy_id & 0xFFFFFC00) == 0x00137800) {
+	printf("Level One ");
+	if ((phy_id & 0x000003F0) == 0xE0) {
+	    printf("LXT971A Revision %d\n", (int)(phy_id & 0xF));
+	    known = 1;
+	}
+	else printf("unknown type\n");
+    }
+    else printf("unknown OUI = 0x%08lX\n", phy_id);
+
+    phy_reg = mii_phy_read(1);
+    if (!(phy_reg & 0x0004)) printf("Link is down\n");
+    if (!(phy_reg & 0x0020)) printf("Auto-negotiation not complete\n");
+    if (phy_reg & 0x0002) printf("Jabber condition detected\n");
+    if (phy_reg & 0x0010) printf("Remote fault condition detected \n");
+
+    if (known) {
+	phy_reg = mii_phy_read(17);
+	if (phy_reg & 0x0400)
+	    printf("Phy operating at %d MBit/s in %s-duplex mode\n",
+		phy_reg & 0x4000 ? 100 : 10,
+	    	phy_reg & 0x0200 ? "full" : "half");
+	else
+	    printf("bad link!!\n");
+/*
+left  off: no link, green 100MBit, yellow 10MBit
+right off: no activity, green full-duplex, yellow half-duplex
+*/
+	mii_phy_write(20, 0x0452);
+    }
+}
+
+unsigned short
+mii_phy_read(unsigned short reg)
+{
+    int i;
+    unsigned short tmp, val = 0, adr = 0;
+    t_rpx_regs *regs = (t_rpx_regs*)CFG_REGS_BASE;
+
+    tmp = 0x6002 | (adr << 7) | (reg << 2);
+    regs->bcsr4 = 0xC3;
+    for (i = 0; i < 64; i++) {
+        regs->bcsr4 ^= MII_MDCK;
+    }
+    for (i = 0; i < 16; i++) {
+	regs->bcsr4 &= ~MII_MDCK;
+	if (tmp & 0x8000) regs->bcsr4 |= MII_MDIO;
+	else regs->bcsr4 &= ~MII_MDIO;
+	regs->bcsr4 |= MII_MDCK;
+	tmp <<= 1;
+    }
+    regs->bcsr4 |= MII_MDIR;
+    for (i = 0; i < 16; i++) {
+	val <<= 1;
+	regs->bcsr4 = MII_MDIO | (regs->bcsr4 | MII_MDCK);
+	if (regs->bcsr4 & MII_MDIO) val |= 1;
+	regs->bcsr4 = MII_MDIO | (regs->bcsr4 &= ~MII_MDCK);
+    }
+    return val;
+}
+
+void
+mii_phy_write(unsigned short reg, unsigned short val)
+{
+    int i;
+    unsigned short tmp, adr = 0;
+    t_rpx_regs *regs = (t_rpx_regs*)CFG_REGS_BASE;
+
+    tmp = 0x5002 | (adr << 7) | (reg << 2);
+    regs->bcsr4 = 0xC3;
+    for (i = 0; i < 64; i++) {
+	regs->bcsr4 ^= MII_MDCK;
+    }
+    for (i = 0; i < 16; i++) {
+	regs->bcsr4 &= ~MII_MDCK;
+        if (tmp & 0x8000) regs->bcsr4 |= MII_MDIO;
+	else regs->bcsr4 &= ~MII_MDIO;
+	regs->bcsr4 |= MII_MDCK;
+	tmp <<= 1;
+    }
+    for (i = 0; i < 16; i++) {
+	regs->bcsr4 &= ~MII_MDCK;
+	if (val & 0x8000) regs->bcsr4 |= MII_MDIO;
+	else regs->bcsr4 &= ~MII_MDIO;
+	regs->bcsr4 |= MII_MDCK;
+	val <<= 1;
+    }
+}
+