Add support for AMCC Sequoia PPC440EPx eval board
- Add support for PPC440EPx & PPC440GRx
- Add support for PPC440EP(x)/GR(x) NAND controller
  in cpu/ppc4xx directory
- Add NAND boot functionality for Sequoia board,
  please see doc/README.nand-boot-ppc440 for details
- This Sequoia NAND image doesn't support environment
  in NAND for now. This will be added in a short while.
Patch by Stefan Roese, 07 Sep 2006
diff --git a/cpu/ppc4xx/405gp_pci.c b/cpu/ppc4xx/405gp_pci.c
index 0b0686b..03128d3 100644
--- a/cpu/ppc4xx/405gp_pci.c
+++ b/cpu/ppc4xx/405gp_pci.c
@@ -555,7 +555,8 @@
 #ifdef CONFIG_PCI_SCAN_SHOW
 		printf("PCI:   Bus Dev VenId DevId Class Int\n");
 #endif
-#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
+#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) && \
+    !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
 		out16r( PCIX0_CMD, in16r( PCIX0_CMD ) | PCI_COMMAND_MASTER);
 #endif
 		hose->last_busno = pci_hose_scan(hose);
diff --git a/cpu/ppc4xx/4xx_enet.c b/cpu/ppc4xx/4xx_enet.c
index fab65af..5b1c17c 100644
--- a/cpu/ppc4xx/4xx_enet.c
+++ b/cpu/ppc4xx/4xx_enet.c
@@ -130,7 +130,17 @@
 #define BI_PHYMODE_NONE	 0
 #define BI_PHYMODE_ZMII	 1
 #define BI_PHYMODE_RGMII 2
+#define BI_PHYMODE_GMII  3
+#define BI_PHYMODE_RTBI  4
+#define BI_PHYMODE_TBI   5
+#if defined (CONFIG_440EPX)
+#define BI_PHYMODE_SMII  6
+#define BI_PHYMODE_MII   7
+#endif
 
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define SDR0_MFR_ETH_CLK_SEL_V(n)	((0x01<<27) / (n+1))
+#endif
 
 /*-----------------------------------------------------------------------------+
  * Global variables. TX and RX descriptors and buffers.
@@ -181,7 +191,7 @@
 {
 	EMAC_4XX_HW_PST hw_p = dev->priv;
 	uint32_t failsafe = 10000;
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	unsigned long mfr;
 #endif
 
@@ -205,19 +215,19 @@
 	}
 
 	/* EMAC RESET */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	/* provide clocks for EMAC internal loopback  */
 	mfsdr (sdr_mfr, mfr);
-	mfr |= 0x08000000;
+	mfr |= SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum);
 	mtsdr(sdr_mfr, mfr);
 #endif
 
 	out32 (EMAC_M0 + hw_p->hw_addr, EMAC_M0_SRST);
 
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	/* remove clocks for EMAC internal loopback  */
 	mfsdr (sdr_mfr, mfr);
-	mfr &= ~0x08000000;
+	mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(hw_p->devnum);
 	mtsdr(sdr_mfr, mfr);
 #endif
 
@@ -317,10 +327,50 @@
 	out32 (RGMII_FER, rmiifer);
 
 	return ((int)pfc1);
-
 }
 #endif	/* CONFIG_440_GX */
 
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+int ppc_4xx_eth_setup_bridge(int devnum, bd_t * bis)
+{
+	unsigned long zmiifer=0x0;
+
+	/*
+	 * Right now only 2*RGMII is supported. Please extend when needed.
+	 * sr - 2006-08-29
+	 */
+	switch (1) {
+	case 0:
+		/* 1 x GMII port */
+		out32 (ZMII_FER, 0x00);
+		out32 (RGMII_FER, 0x00000037);
+		bis->bi_phymode[0] = BI_PHYMODE_GMII;
+		bis->bi_phymode[1] = BI_PHYMODE_NONE;
+		break;
+	case 1:
+		/* 2 x RGMII ports */
+		out32 (ZMII_FER, 0x00);
+		out32 (RGMII_FER, 0x00000055);
+		bis->bi_phymode[0] = BI_PHYMODE_RGMII;
+		bis->bi_phymode[1] = BI_PHYMODE_RGMII;
+		break;
+	case 2:
+		/* 2 x SMII ports */
+
+		break;
+	default:
+		break;
+	}
+
+	/* Ensure we setup mdio for this devnum and ONLY this devnum */
+	zmiifer = in32 (ZMII_FER);
+	zmiifer |= (ZMII_FER_MDI) << ZMII_FER_V(devnum);
+	out32 (ZMII_FER, zmiifer);
+
+	return ((int)0x0);
+}
+#endif	/* CONFIG_440EPX */
+
 static int ppc_4xx_eth_init (struct eth_device *dev, bd_t * bis)
 {
 	int i, j;
@@ -332,13 +382,16 @@
 	unsigned mode_reg;
 	unsigned short devnum;
 	unsigned short reg_short;
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 	sys_info_t sysinfo;
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	int ethgroup = -1;
 #endif
 #endif
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || defined(CONFIG_440SPE)
 	unsigned long mfr;
 #endif
 
@@ -352,7 +405,9 @@
 		return -1;
 	}
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 	/* Need to get the OPB frequency so we can access the PHY */
 	get_sys_info (&sysinfo);
 #endif
@@ -407,7 +462,7 @@
 
 #if defined(CONFIG_440EP) || defined(CONFIG_440GR)
 	out32 (ZMII_FER, (ZMII_FER_RMII | ZMII_FER_MDI) << ZMII_FER_V (devnum));
-#elif defined(CONFIG_440GX)
+#elif defined(CONFIG_440GX) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	ethgroup = ppc_4xx_eth_setup_bridge(devnum, bis);
 #elif defined(CONFIG_440GP)
 	/* set RMII mode */
@@ -429,10 +484,10 @@
 	__asm__ volatile ("eieio");
 
 	/* reset emac so we have access to the phy */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	/* provide clocks for EMAC internal loopback  */
 	mfsdr (sdr_mfr, mfr);
-	mfr |= 0x08000000;
+	mfr |= SDR0_MFR_ETH_CLK_SEL_V(devnum);
 	mtsdr(sdr_mfr, mfr);
 #endif
 
@@ -444,15 +499,19 @@
 		udelay (1000);
 		failsafe--;
 	}
+	if (failsafe <= 0)
+		printf("\nProblem resetting EMAC!\n");
 
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	/* remove clocks for EMAC internal loopback  */
 	mfsdr (sdr_mfr, mfr);
-	mfr &= ~0x08000000;
+	mfr &= ~SDR0_MFR_ETH_CLK_SEL_V(devnum);
 	mtsdr(sdr_mfr, mfr);
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 	/* Whack the M1 register */
 	mode_reg = 0x0;
 	mode_reg &= ~0x00000038;
@@ -502,15 +561,39 @@
 	 * otherwise, just check the speeds & feeds
 	 */
 	if (hw_p->first_init == 0) {
+#if defined(CONFIG_88E1111_CLK_DELAY)
+		/*
+		 * On some boards (e.g. ALPR) the Marvell 88E1111 PHY needs
+		 * the "RGMII transmit timing control" and "RGMII receive
+		 * timing control" bits set, so that Gbit communication works
+		 * without problems.
+		 * Also set the "Transmitter disable" to 1 to enable the
+		 * transmitter.
+		 * After setting these bits a soft-reset must occur for this
+		 * change to become active.
+		 */
+		miiphy_read (dev->name, reg, 0x14, &reg_short);
+		reg_short |= (1 << 7) | (1 << 1) | (1 << 0);
+		miiphy_write (dev->name, reg, 0x14, reg_short);
+#endif
+#if defined(CONFIG_M88E1111_PHY) /* test-only: merge with CONFIG_88E1111_CLK_DELAY !!! */
+		miiphy_write (dev->name, reg, 0x14, 0x0ce3);
+		miiphy_write (dev->name, reg, 0x18, 0x4101);
+		miiphy_write (dev->name, reg, 0x09, 0x0e00);
+		miiphy_write (dev->name, reg, 0x04, 0x01e1);
+#endif
 		miiphy_reset (dev->name, reg);
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+
 #if defined(CONFIG_CIS8201_PHY)
 		/*
 		 * Cicada 8201 PHY needs to have an extended register whacked
 		 * for RGMII mode.
 		 */
-		if ( ((devnum == 2) || (devnum ==3)) && (4 == ethgroup) ) {
+		if (((devnum == 2) || (devnum == 3)) && (4 == ethgroup)) {
 #if defined(CONFIG_CIS8201_SHORT_ETCH)
 			miiphy_write (dev->name, reg, 23, 0x1300);
 #else
@@ -580,7 +663,8 @@
 			(int) speed, (duplex == HALF) ? "HALF" : "FULL");
 	}
 
-#if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE)
+#if defined(CONFIG_440) && !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+    !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
 #if defined(CONFIG_440EP) || defined(CONFIG_440GR)
 	mfsdr(sdr_mfr, reg);
 	if (speed == 100) {
@@ -603,15 +687,34 @@
 			reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V (devnum));
 		else if (speed == 100)
 			reg = (RGMII_SSR_SP_100MBPS << RGMII_SSR_V (devnum));
-		else
+		else if (speed == 10)
 			reg = (RGMII_SSR_SP_10MBPS << RGMII_SSR_V (devnum));
-
+		else {
+			printf("Error in RGMII Speed\n");
+			return -1;
+		}
 		out32 (RGMII_SSR, reg);
 	}
 #endif /* defined(CONFIG_440) && !defined(CONFIG_440SP) */
 
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+	if (speed == 1000)
+		reg = (RGMII_SSR_SP_1000MBPS << RGMII_SSR_V (devnum));
+	else if (speed == 100)
+		reg = (RGMII_SSR_SP_100MBPS << RGMII_SSR_V (devnum));
+	else if (speed == 10)
+		reg = (RGMII_SSR_SP_10MBPS << RGMII_SSR_V (devnum));
+	else {
+		printf("Error in RGMII Speed\n");
+		return -1;
+	}
+	out32 (RGMII_SSR, reg);
+#endif
+
 	/* set the Mal configuration reg */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 	mtdcr (malmcr, MAL_CR_PLBB | MAL_CR_OPBBL | MAL_CR_LEA |
 	       MAL_CR_PLBLT_DEFAULT | MAL_CR_EOPIE | 0x00330000);
 #else
@@ -795,8 +898,10 @@
 
 	/* set speed */
 	if (speed == _1000BASET) {
-#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 		unsigned long pfc1;
+
 		mfsdr (sdr_pfc1, pfc1);
 		pfc1 |= SDR0_PFC1_EM_1000;
 		mtsdr (sdr_pfc1, pfc1);
@@ -942,6 +1047,14 @@
 #define UIC0SR		uic0sr
 #endif
 
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define UICMSR_ETHX	uic0msr
+#define UICSR_ETHX	uic0sr
+#else
+#define UICMSR_ETHX	uic1msr
+#define UICSR_ETHX	uic1sr
+#endif
+
 int enetInt (struct eth_device *dev)
 {
 	int serviced;
@@ -950,6 +1063,7 @@
 	unsigned long emac_isr = 0;
 	unsigned long mal_rx_eob;
 	unsigned long my_uic0msr, my_uic1msr;
+	unsigned long my_uicmsr_ethx;
 
 #if defined(CONFIG_440GX)
 	unsigned long my_uic2msr;
@@ -977,8 +1091,11 @@
 #if defined(CONFIG_440GX)
 		my_uic2msr = mfdcr (uic2msr);
 #endif
+		my_uicmsr_ethx = mfdcr (UICMSR_ETHX);
+
 		if (!(my_uic0msr & (UIC_MRE | UIC_MTE))
-		    && !(my_uic1msr & (UIC_ETH0 | UIC_ETH1 | UIC_MS | UIC_MTDE | UIC_MRDE))) {
+		    && !(my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))
+		    && !(my_uicmsr_ethx & (UIC_ETH0 | UIC_ETH1))) {
 			/* not for us */
 			return (rc);
 		}
@@ -997,8 +1114,7 @@
 			mal_isr = mfdcr (malesr);
 			/* look for mal error */
 			if (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE)) {
-				mal_err (dev, mal_isr, my_uic0msr,
-					 MAL_UIC_DEF, MAL_UIC_ERR);
+				mal_err (dev, mal_isr, my_uic1msr, MAL_UIC_DEF, MAL_UIC_ERR);
 				serviced = 1;
 				rc = 0;
 			}
@@ -1006,7 +1122,7 @@
 
 		/* port by port dispatch of emac interrupts */
 		if (hw_p->devnum == 0) {
-			if (UIC_ETH0 & my_uic1msr) {	/* look for EMAC errors */
+			if (UIC_ETH0 & my_uicmsr_ethx) {	/* look for EMAC errors */
 				emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);
 				if ((hw_p->emac_ier & emac_isr) != 0) {
 					emac_err (dev, emac_isr);
@@ -1017,14 +1133,15 @@
 			if ((hw_p->emac_ier & emac_isr)
 			    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {
 				mtdcr (UIC0SR, UIC_MRE | UIC_MTE);	/* Clear */
-				mtdcr (uic1sr, UIC_ETH0 | UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */
+				mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */
+				mtdcr (UICSR_ETHX, UIC_ETH0); /* Clear */
 				return (rc);	/* we had errors so get out */
 			}
 		}
 
 #if !defined(CONFIG_440SP)
 		if (hw_p->devnum == 1) {
-			if (UIC_ETH1 & my_uic1msr) {	/* look for EMAC errors */
+			if (UIC_ETH1 & my_uicmsr_ethx) {	/* look for EMAC errors */
 				emac_isr = in32 (EMAC_ISR + hw_p->hw_addr);
 				if ((hw_p->emac_ier & emac_isr) != 0) {
 					emac_err (dev, emac_isr);
@@ -1035,7 +1152,8 @@
 			if ((hw_p->emac_ier & emac_isr)
 			    || (my_uic1msr & (UIC_MS | UIC_MTDE | UIC_MRDE))) {
 				mtdcr (UIC0SR, UIC_MRE | UIC_MTE);	/* Clear */
-				mtdcr (uic1sr, UIC_ETH1 | UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */
+				mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE); /* Clear */
+				mtdcr (UICSR_ETHX, UIC_ETH1); /* Clear */
 				return (rc);	/* we had errors so get out */
 			}
 		}
@@ -1102,10 +1220,10 @@
 		mtdcr (uic1sr, UIC_MS | UIC_MTDE | UIC_MRDE);	/* Clear */
 		switch (hw_p->devnum) {
 		case 0:
-			mtdcr (uic1sr, UIC_ETH0);
+			mtdcr (UICSR_ETHX, UIC_ETH0);
 			break;
 		case 1:
-			mtdcr (uic1sr, UIC_ETH1);
+			mtdcr (UICSR_ETHX, UIC_ETH1);
 			break;
 #if defined (CONFIG_440GX)
 		case 2:
@@ -1512,7 +1630,7 @@
 
 		if (0 == virgin) {
 			/* set the MAL IER ??? names may change with new spec ??? */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 			mal_ier =
 				MAL_IER_PT | MAL_IER_PRE | MAL_IER_PWE |
 				MAL_IER_DE | MAL_IER_OTE | MAL_IER_OE | MAL_IER_PE ;
diff --git a/cpu/ppc4xx/Makefile b/cpu/ppc4xx/Makefile
index 93416b5..16dc8d6 100644
--- a/cpu/ppc4xx/Makefile
+++ b/cpu/ppc4xx/Makefile
@@ -30,7 +30,7 @@
 COBJS	= 405gp_pci.o 4xx_enet.o \
 	  bedbug_405.o commproc.o \
 	  cpu.o cpu_init.o i2c.o interrupts.o \
-	  miiphy.o sdram.o serial.o \
+	  miiphy.o ndfc.o sdram.o serial.o \
 	  spd_sdram.o speed.o traps.o usb_ohci.o usbdev.o \
 	  440spe_pcie.o
 
diff --git a/cpu/ppc4xx/cpu.c b/cpu/ppc4xx/cpu.c
index bc51fbf..94478db 100644
--- a/cpu/ppc4xx/cpu.c
+++ b/cpu/ppc4xx/cpu.c
@@ -41,14 +41,15 @@
 DECLARE_GLOBAL_DATA_PTR;
 #endif
 
-
 #if defined(CONFIG_440)
 #define FREQ_EBC		(sys_info.freqEPB)
 #else
 #define FREQ_EBC		(sys_info.freqPLB / sys_info.pllExtBusDiv)
 #endif
 
-#if defined(CONFIG_405GP) || defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_405GP) || \
+    defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 
 #define PCI_ASYNC
 
@@ -58,7 +59,8 @@
 	return (mfdcr(strap) & PSR_PCI_ASYNC_EN);
 #endif
 
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	unsigned long val;
 
 	mfsdr(sdr_sdstp1, val);
@@ -82,9 +84,10 @@
 	return (mfdcr(cpc0_strp1) & CPC0_STRP1_PAE_MASK);
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
-     defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
-     defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || \
+    defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 	unsigned long val;
 
 	mfsdr(sdr_sdstp1, val);
@@ -93,8 +96,10 @@
 }
 #endif
 
-#if defined(CONFIG_405EP) || defined(CONFIG_440EP) || defined(CONFIG_440GR) ||  \
-     defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#if defined(CONFIG_405EP) || defined(CONFIG_440GX) || \
+    defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 
 #define I2C_BOOTROM
 
@@ -102,17 +107,75 @@
 {
 #if defined(CONFIG_405EP)
 	return (mfdcr(cpc0_boot) & CPC0_BOOT_SEP);
-#endif
-
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
-     defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
-	defined(CONFIG_440SPE)
+#else
 	unsigned long val;
 
 	mfsdr(sdr_sdcs, val);
 	return (val & SDR0_SDCS_SDD);
 #endif
+}
+
+#if defined(CONFIG_440GX)
+#define SDR0_PINSTP_SHIFT	29
+static char *bootstrap_str[] = {
+	"EBC (16 bits)",
+	"EBC (8 bits)",
+	"EBC (32 bits)",
+	"EBC (8 bits)",
+	"PCI",
+	"I2C (Addr 0x54)",
+	"Reserved",
+	"I2C (Addr 0x50)",
+};
+#endif
+
+#if defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#define SDR0_PINSTP_SHIFT	30
+static char *bootstrap_str[] = {
+	"EBC (8 bits)",
+	"PCI",
+	"I2C (Addr 0x54)",
+	"I2C (Addr 0x50)",
+};
+#endif
+
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#define SDR0_PINSTP_SHIFT	29
+static char *bootstrap_str[] = {
+	"EBC (8 bits)",
+	"PCI",
+	"NAND (8 bits)",
+	"EBC (16 bits)",
+	"EBC (16 bits)",
+	"I2C (Addr 0x54)",
+	"PCI",
+	"I2C (Addr 0x52)",
+};
+#endif
+
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+#define SDR0_PINSTP_SHIFT	29
+static char *bootstrap_str[] = {
+	"EBC (8 bits)",
+	"EBC (16 bits)",
+	"EBC (16 bits)",
+	"NAND (8 bits)",
+	"PCI",
+	"I2C (Addr 0x54)",
+	"PCI",
+	"I2C (Addr 0x52)",
+};
+#endif
+
+#if defined(SDR0_PINSTP_SHIFT)
+static int bootstrap_option(void)
+{
+	unsigned long val;
+
+	mfsdr(sdr_pinstp, val);
+	return ((val & 0xe0000000) >> SDR0_PINSTP_SHIFT);
 }
+#endif /* SDR0_PINSTP_SHIFT */
 #endif
 
 
@@ -244,6 +307,22 @@
 #endif /* CONFIG_440GR */
 #endif /* CONFIG_440 */
 
+	case PVR_440EPX1_RA:
+		puts("EPx Rev. A - Security/Kasumi support");
+		break;
+
+	case PVR_440EPX2_RA:
+		puts("EPx Rev. A - No Security/Kasumi support");
+		break;
+
+	case PVR_440GRX1_RA:
+		puts("GRx Rev. A - Security/Kasumi support");
+		break;
+
+	case PVR_440GRX2_RA:
+		puts("GRx Rev. A - No Security/Kasumi support");
+		break;
+
 	case PVR_440SP_RA:
 		puts("SP Rev. A");
 		break;
@@ -272,6 +351,10 @@
 
 #if defined(I2C_BOOTROM)
 	printf ("       I2C boot EEPROM %sabled\n", i2c_bootrom_enabled() ? "en" : "dis");
+#if defined(SDR0_PINSTP_SHIFT)
+	printf ("       Bootstrap Option %c - ", (char)bootstrap_option() + 'A');
+	printf ("Boot ROM Location %s\n", bootstrap_str[bootstrap_option()]);
+#endif
 #endif
 
 #if defined(CONFIG_PCI)
diff --git a/cpu/ppc4xx/interrupts.c b/cpu/ppc4xx/interrupts.c
index 886f405..c5a9f02 100644
--- a/cpu/ppc4xx/interrupts.c
+++ b/cpu/ppc4xx/interrupts.c
@@ -57,12 +57,13 @@
 
 void uic1_interrupt( void * parms); /* UIC1 handler */
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 static struct irq_action irq_vecs2[32]; /* For UIC2 */
 void uic2_interrupt( void * parms); /* UIC2 handler */
 #endif /* CONFIG_440GX CONFIG_440SPE */
 
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 static struct irq_action irq_vecs3[32]; /* For UIC3 */
 void uic3_interrupt( void * parms); /* UIC3 handler */
 #endif /* CONFIG_440SPE */
@@ -119,12 +120,13 @@
 		irq_vecs1[vec].handler = NULL;
 		irq_vecs1[vec].arg = NULL;
 		irq_vecs1[vec].count = 0;
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 		irq_vecs2[vec].handler = NULL;
 		irq_vecs2[vec].arg = NULL;
 		irq_vecs2[vec].count = 0;
 #endif /* CONFIG_440GX */
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440SPE) || defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 		irq_vecs3[vec].handler = NULL;
 		irq_vecs3[vec].arg = NULL;
 		irq_vecs3[vec].count = 0;
@@ -230,6 +232,32 @@
 
 } /* external_interrupt CONFIG_440GX */
 
+#elif defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+void external_interrupt(struct pt_regs *regs)
+{
+	ulong uic_msr;
+
+	/*
+	 * Read masked interrupt status register to determine interrupt source
+	 */
+	/* 440 SPe uses base uic register */
+	uic_msr = mfdcr(uic0msr);
+
+	if ( (UICB0_UIC1CI & uic_msr) || (UICB0_UIC1NCI & uic_msr) )
+		uic1_interrupt(0);
+
+	if ( (UICB0_UIC2CI & uic_msr) || (UICB0_UIC2NCI & uic_msr) )
+		uic2_interrupt(0);
+
+	if (uic_msr & ~(UICB0_ALL))
+		uic0_interrupt(0);
+
+	mtdcr(uic0sr, uic_msr);
+
+	return;
+
+} /* external_interrupt CONFIG_440EPX & CONFIG_440GRX */
+
 #elif defined(CONFIG_440SPE)
 void external_interrupt(struct pt_regs *regs)
 {
@@ -303,7 +331,8 @@
 }
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 /* Handler for UIC0 interrupt */
 void uic0_interrupt( void * parms)
 {
@@ -394,7 +423,8 @@
 }
 #endif /* defined(CONFIG_440) */
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 /* Handler for UIC2 interrupt */
 void uic2_interrupt( void * parms)
 {
@@ -496,7 +526,8 @@
 	int i = vec;
 
 #if defined(CONFIG_440)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	if ((vec > 31) && (vec < 64)) {
 		i = vec - 32;
 		irqa = irq_vecs1;
@@ -523,7 +554,8 @@
 	irqa[i].arg = arg;
 
 #if defined(CONFIG_440)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	if ((vec > 31) && (vec < 64))
 		mtdcr (uic1er, mfdcr (uic1er) | (0x80000000 >> i));
 	else if (vec > 63)
@@ -546,7 +578,8 @@
 	int i = vec;
 
 #if defined(CONFIG_440)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	if ((vec > 31) && (vec < 64)) {
 		irqa = irq_vecs1;
 		i = vec - 32;
@@ -567,7 +600,8 @@
 #endif
 
 #if defined(CONFIG_440)
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	if ((vec > 31) && (vec < 64))
 		mtdcr (uic1er, mfdcr (uic1er) & ~(0x80000000 >> i));
 	else if (vec > 63)
@@ -635,7 +669,8 @@
 	printf("\n");
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 	printf ("\nUIC 2\n");
 	printf ("Nr  Routine   Arg       Count\n");
 
diff --git a/cpu/ppc4xx/miiphy.c b/cpu/ppc4xx/miiphy.c
index aa580ed..6b98025 100644
--- a/cpu/ppc4xx/miiphy.c
+++ b/cpu/ppc4xx/miiphy.c
@@ -173,7 +173,8 @@
 	}
 	sta_reg = reg;		/* reg address */
 	/* set clock (50Mhz) and read flags */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 #if defined(CONFIG_IBM_EMAC4_V4)      /* EMAC4 V4 changed bit setting */
 		sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_READ;
 #else
@@ -183,7 +184,9 @@
 	sta_reg = (sta_reg | EMAC_STACR_READ) & ~EMAC_STACR_CLK_100MHZ;
 #endif
 
-#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && !defined(CONFIG__440SP) && !defined(CONFIG__440SPE)
+#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \
+    !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+    !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
 	sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ;
 #endif
 	sta_reg = sta_reg | (addr << 5);	/* Phy address */
@@ -244,7 +247,8 @@
 	sta_reg = 0;
 	sta_reg = reg;		/* reg address */
 	/* set clock (50Mhz) and read flags */
-#if defined(CONFIG_440GX) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440GX) || defined(CONFIG_440SPE) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 #if defined(CONFIG_IBM_EMAC4_V4)      /* EMAC4 V4 changed bit setting */
 		sta_reg = (sta_reg & ~EMAC_STACR_OP_MASK) | EMAC_STACR_WRITE;
 #else
@@ -254,7 +258,9 @@
 	sta_reg = (sta_reg | EMAC_STACR_WRITE) & ~EMAC_STACR_CLK_100MHZ;
 #endif
 
-#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && !defined(CONFIG__440SP) && !defined(CONFIG__440SPE)
+#if defined(CONFIG_PHY_CLK_FREQ) && !defined(CONFIG_440GX) && \
+    !defined(CONFIG_440SP) && !defined(CONFIG_440SPE) && \
+    !defined(CONFIG_440EPX) && !defined(CONFIG_440GRX)
 	sta_reg = sta_reg | CONFIG_PHY_CLK_FREQ;	/* Set clock frequency (PLB freq. dependend) */
 #endif
 	sta_reg = sta_reg | ((unsigned long) addr << 5);/* Phy address */
diff --git a/cpu/ppc4xx/ndfc.c b/cpu/ppc4xx/ndfc.c
new file mode 100644
index 0000000..e4ab326
--- /dev/null
+++ b/cpu/ppc4xx/ndfc.c
@@ -0,0 +1,173 @@
+/*
+ * Overview:
+ *   Platform independend driver for NDFC (NanD Flash Controller)
+ *   integrated into EP440 cores
+ *
+ * (C) Copyright 2006
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * Based on original work by
+ *	Thomas Gleixner
+ *	Copyright 2006 IBM
+ *
+ * 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>
+
+#if (CONFIG_COMMANDS & CFG_CMD_NAND) && !defined(CFG_NAND_LEGACY)
+
+#include <nand.h>
+#include <linux/mtd/ndfc.h>
+#include <asm/processor.h>
+#include <ppc440.h>
+
+static u8 hwctl = 0;
+
+static void ndfc_hwcontrol(struct mtd_info *mtdinfo, int cmd)
+{
+	switch (cmd) {
+	case NAND_CTL_SETCLE:
+		hwctl |= 0x1;
+		break;
+
+	case NAND_CTL_CLRCLE:
+		hwctl &= ~0x1;
+		break;
+
+	case NAND_CTL_SETALE:
+		hwctl |= 0x2;
+		break;
+
+	case NAND_CTL_CLRALE:
+		hwctl &= ~0x2;
+		break;
+	}
+}
+
+static void ndfc_write_byte(struct mtd_info *mtdinfo, u_char byte)
+{
+        struct nand_chip *this = mtdinfo->priv;
+        ulong base = (ulong) this->IO_ADDR_W;
+
+	if (hwctl & 0x1)
+		out8(base + NDFC_CMD, byte);
+	else if (hwctl & 0x2)
+		out8(base + NDFC_ALE, byte);
+	else
+		out8(base + NDFC_DATA, byte);
+}
+
+static u_char ndfc_read_byte(struct mtd_info *mtdinfo)
+{
+        struct nand_chip *this = mtdinfo->priv;
+        ulong base = (ulong) this->IO_ADDR_W;
+
+	return (in8(base + NDFC_DATA));
+}
+
+static int ndfc_dev_ready(struct mtd_info *mtdinfo)
+{
+        struct nand_chip *this = mtdinfo->priv;
+        ulong base = (ulong) this->IO_ADDR_W;
+
+	while (!(in32(base + NDFC_STAT) & NDFC_STAT_IS_READY))
+		;
+
+	return 1;
+}
+
+#ifndef CONFIG_NAND_SPL
+/*
+ * Don't use these speedup functions in NAND boot image, since the image
+ * has to fit into 4kByte.
+ */
+
+/*
+ * Speedups for buffer read/write/verify
+ *
+ * NDFC allows 32bit read/write of data. So we can speed up the buffer
+ * functions. No further checking, as nand_base will always read/write
+ * page aligned.
+ */
+static void ndfc_read_buf(struct mtd_info *mtdinfo, uint8_t *buf, int len)
+{
+        struct nand_chip *this = mtdinfo->priv;
+        ulong base = (ulong) this->IO_ADDR_W;
+	uint32_t *p = (uint32_t *) buf;
+
+	for(;len > 0; len -= 4)
+		*p++ = in32(base + NDFC_DATA);
+}
+
+static void ndfc_write_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
+{
+        struct nand_chip *this = mtdinfo->priv;
+        ulong base = (ulong) this->IO_ADDR_W;
+	uint32_t *p = (uint32_t *) buf;
+
+	for(; len > 0; len -= 4)
+		out32(base + NDFC_DATA, *p++);
+}
+
+static int ndfc_verify_buf(struct mtd_info *mtdinfo, const uint8_t *buf, int len)
+{
+        struct nand_chip *this = mtdinfo->priv;
+        ulong base = (ulong) this->IO_ADDR_W;
+	uint32_t *p = (uint32_t *) buf;
+
+	for(; len > 0; len -= 4)
+		if (*p++ != in32(base + NDFC_DATA))
+			return -1;
+
+	return 0;
+}
+#endif /* #ifndef CONFIG_NAND_SPL */
+
+void board_nand_init(struct nand_chip *nand)
+{
+	nand->eccmode = NAND_ECC_SOFT;
+
+	nand->hwcontrol  = ndfc_hwcontrol;
+	nand->read_byte  = ndfc_read_byte;
+	nand->write_byte = ndfc_write_byte;
+	nand->dev_ready  = ndfc_dev_ready;
+
+#ifndef CONFIG_NAND_SPL
+	nand->write_buf  = ndfc_write_buf;
+	nand->read_buf   = ndfc_read_buf;
+	nand->verify_buf = ndfc_verify_buf;
+#else
+	/*
+	 * Setup EBC (CS0 only right now)
+	 */
+	mtdcr(ebccfga, xbcfg);
+	mtdcr(ebccfgd, 0xb8400000);
+
+	mtebc(pb0cr, CFG_EBC_PB0CR);
+	mtebc(pb0ap, CFG_EBC_PB0AP);
+#endif
+
+	/* Set NandFlash Core Configuration Register */
+	/* Chip select 3, 1col x 2 rows */
+	out32(CFG_NAND_BASE + NDFC_CCR, 0x00000000 | (CFG_NAND_CS << 24));
+	out32(CFG_NAND_BASE + NDFC_BCFG0 + (CFG_NAND_CS << 2), 0x80002222);
+}
+
+#endif
diff --git a/cpu/ppc4xx/serial.c b/cpu/ppc4xx/serial.c
index ad3ca6e..fab0d95 100644
--- a/cpu/ppc4xx/serial.c
+++ b/cpu/ppc4xx/serial.c
@@ -264,10 +264,12 @@
 #endif	/* CONFIG_IOP480 */
 
 /*****************************************************************************/
-#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_440) || defined(CONFIG_405EP)
+#if defined(CONFIG_405GP) || defined(CONFIG_405CR) || defined(CONFIG_405EP) || \
+    defined(CONFIG_440)
 
 #if defined(CONFIG_440)
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 #define UART0_BASE  CFG_PERIPHERAL_BASE + 0x00000300
 #define UART1_BASE  CFG_PERIPHERAL_BASE + 0x00000400
 #else
@@ -279,15 +281,34 @@
 #define UART2_BASE  CFG_PERIPHERAL_BASE + 0x00000600
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
-#define CR0_MASK        0xdfffffff
-#define CR0_EXTCLK_ENA  0x00800000
-#define CR0_UDIV_POS    0
-#else
+#if defined(CONFIG_440GP)
 #define CR0_MASK        0x3fff0000
 #define CR0_EXTCLK_ENA  0x00600000
 #define CR0_UDIV_POS    16
-#endif /* CONFIG_440GX */
+#define UDIV_SUBTRACT	1
+#define UART0_SDR	cntrl0
+#define MFREG(a, d)	d = mfdcr(a)
+#define MTREG(a, d)	mtdcr(a, d)
+#else /* #if defined(CONFIG_440GP) */
+/* all other 440 PPC's access clock divider via sdr register */
+#define CR0_MASK        0xdfffffff
+#define CR0_EXTCLK_ENA  0x00800000
+#define CR0_UDIV_POS    0
+#define UDIV_SUBTRACT	0
+#define UART0_SDR	sdr_uart0
+#define UART1_SDR	sdr_uart1
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPx) || \
+    defined(CONFIG_440GR) || defined(CONFIG_440GRx) || \
+    defined(CONFIG_440SP) || defined(CONFIG_440SPe)
+#define UART2_SDR	sdr_uart2
+#endif
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPx) || \
+    defined(CONFIG_440GR) || defined(CONFIG_440GRx)
+#define UART3_SDR	sdr_uart3
+#endif
+#define MFREG(a, d)	mfsdr(a, d)
+#define MTREG(a, d)	mtsdr(a, d)
+#endif /* #if defined(CONFIG_440GP) */
 #elif defined(CONFIG_405EP)
 #define UART0_BASE      0xef600300
 #define UART1_BASE      0xef600400
@@ -309,23 +330,17 @@
 #if defined(CONFIG_UART1_CONSOLE)
 #define ACTING_UART0_BASE	UART1_BASE
 #define ACTING_UART1_BASE	UART0_BASE
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
-	defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
-	defined(CONFIG_440SPE)
-#define UART0_SDR           sdr_uart1
-#define UART1_SDR           sdr_uart0
-#endif /* CONFIG_440GX */
 #else
 #define ACTING_UART0_BASE	UART0_BASE
 #define ACTING_UART1_BASE	UART1_BASE
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
-	defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
-	defined(CONFIG_440SPE)
-#define UART0_SDR           sdr_uart0
-#define UART1_SDR           sdr_uart1
-#endif /* CONFIG_440GX */
 #endif
 
+#if defined(CONFIG_SERIAL_MULTI)
+#define UART_BASE	dev_base
+#else
+#define UART_BASE	ACTING_UART0_BASE
+#endif
+
 #if defined(CONFIG_405EP) && defined(CFG_EXT_SERIAL_CLOCK)
 #error "External serial clock not supported on AMCC PPC405EP!"
 #endif
@@ -419,7 +434,7 @@
 	*pbdiv = div/udiv;
 
 }
-#endif /* defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLK */
+#endif /* defined(CONFIG_440) && !defined(CFG_EXT_SERIAL_CLK) */
 
 /*
  * Minimal serial functions needed to use one of the SMC ports
@@ -441,23 +456,9 @@
 	unsigned long tmp;
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || \
-	defined(CONFIG_440SPE)
-#if defined(CONFIG_SERIAL_MULTI)
-	if (UART0_BASE == dev_base) {
-		mfsdr(UART0_SDR,reg);
-		reg &= ~CR0_MASK;
-	} else {
-		mfsdr(UART1_SDR,reg);
-		reg &= ~CR0_MASK;
-	}
-#else
-	mfsdr(UART0_SDR,reg);
+	MFREG(UART0_SDR, reg);
 	reg &= ~CR0_MASK;
-#endif
-#else
-	reg = mfdcr(cntrl0) & ~CR0_MASK;
-#endif /* CONFIG_440GX */
+
 #ifdef CFG_EXT_SERIAL_CLOCK
 	reg |= CR0_EXTCLK_ENA;
 	udiv = 1;
@@ -471,47 +472,34 @@
 	serial_divs (gd->baudrate, &udiv, &bdiv);
 #endif
 
-#if defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
-	defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
-	defined(CONFIG_440SPE)
-	reg |= udiv << CR0_UDIV_POS;	/* set the UART divisor */
-#if defined(CONFIG_SERIAL_MULTI)
-	if (UART0_BASE == dev_base) {
-		mtsdr (UART0_SDR,reg);
-	} else {
-		mtsdr (UART1_SDR,reg);
-	}
-#else
-	mtsdr (UART0_SDR,reg);
+	reg |= (udiv - UDIV_SUBTRACT) << CR0_UDIV_POS;	/* set the UART divisor */
+
+	/*
+	 * Configure input clock to baudrate generator for all
+	 * available serial ports here
+	 */
+	MTREG(UART0_SDR, reg);
+#if defined(UART1_SDR)
+	MTREG(UART1_SDR, reg);
 #endif
-#else
-	reg |= (udiv - 1) << CR0_UDIV_POS;	/* set the UART divisor */
-	mtdcr (cntrl0, reg);
+#if defined(UART2_SDR)
+	MTREG(UART2_SDR, reg);
 #endif
-
-#if defined(CONFIG_SERIAL_MULTI)
-	out8 (dev_base + UART_LCR, 0x80);	/* set DLAB bit */
-	out8 (dev_base + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
-	out8 (dev_base + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
-	out8 (dev_base + UART_FCR, 0x00);	/* disable FIFO */
-	out8 (dev_base + UART_MCR, 0x00);	/* no modem control DTR RTS */
-	val = in8 (dev_base + UART_LSR);	/* clear line status */
-	val = in8 (dev_base + UART_RBR);	/* read receive buffer */
-	out8 (dev_base + UART_SCR, 0x00);	/* set scratchpad */
-	out8 (dev_base + UART_IER, 0x00);	/* set interrupt enable reg */
-#else
-	out8 (ACTING_UART0_BASE + UART_LCR, 0x80);	/* set DLAB bit */
-	out8 (ACTING_UART0_BASE + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
-	out8 (ACTING_UART0_BASE + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
-	out8 (ACTING_UART0_BASE + UART_FCR, 0x00);	/* disable FIFO */
-	out8 (ACTING_UART0_BASE + UART_MCR, 0x00);	/* no modem control DTR RTS */
-	val = in8 (ACTING_UART0_BASE + UART_LSR);	/* clear line status */
-	val = in8 (ACTING_UART0_BASE + UART_RBR);	/* read receive buffer */
-	out8 (ACTING_UART0_BASE + UART_SCR, 0x00);	/* set scratchpad */
-	out8 (ACTING_UART0_BASE + UART_IER, 0x00);	/* set interrupt enable reg */
+#if defined(UART3_SDR)
+	MTREG(UART3_SDR, reg);
 #endif
+
+	out8(UART_BASE + UART_LCR, 0x80);	/* set DLAB bit */
+	out8(UART_BASE + UART_DLL, bdiv);	/* set baudrate divisor */
+	out8(UART_BASE + UART_DLM, bdiv >> 8);	/* set baudrate divisor */
+	out8(UART_BASE + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
+	out8(UART_BASE + UART_FCR, 0x00);	/* disable FIFO */
+	out8(UART_BASE + UART_MCR, 0x00);	/* no modem control DTR RTS */
+	val = in8(UART_BASE + UART_LSR);	/* clear line status */
+	val = in8(UART_BASE + UART_RBR);	/* read receive buffer */
+	out8(UART_BASE + UART_SCR, 0x00);	/* set scratchpad */
+	out8(UART_BASE + UART_IER, 0x00);	/* set interrupt enable reg */
+
 	return (0);
 }
 
@@ -564,29 +552,17 @@
 	tmp = gd->baudrate * udiv * 16;
 	bdiv = (clk + tmp / 2) / tmp;
 
-#if defined(CONFIG_SERIAL_MULTI)
-	out8 (dev_base + UART_LCR, 0x80);	/* set DLAB bit */
-	out8 (dev_base + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
-	out8 (dev_base + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
-	out8 (dev_base + UART_FCR, 0x00);	/* disable FIFO */
-	out8 (dev_base + UART_MCR, 0x00);	/* no modem control DTR RTS */
-	val = in8 (dev_base + UART_LSR);	/* clear line status */
-	val = in8 (dev_base + UART_RBR);	/* read receive buffer */
-	out8 (dev_base + UART_SCR, 0x00);	/* set scratchpad */
-	out8 (dev_base + UART_IER, 0x00);	/* set interrupt enable reg */
-#else
-	out8 (ACTING_UART0_BASE + UART_LCR, 0x80);	/* set DLAB bit */
-	out8 (ACTING_UART0_BASE + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
-	out8 (ACTING_UART0_BASE + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
-	out8 (ACTING_UART0_BASE + UART_FCR, 0x00);	/* disable FIFO */
-	out8 (ACTING_UART0_BASE + UART_MCR, 0x00);	/* no modem control DTR RTS */
-	val = in8 (ACTING_UART0_BASE + UART_LSR);	/* clear line status */
-	val = in8 (ACTING_UART0_BASE + UART_RBR);	/* read receive buffer */
-	out8 (ACTING_UART0_BASE + UART_SCR, 0x00);	/* set scratchpad */
-	out8 (ACTING_UART0_BASE + UART_IER, 0x00);	/* set interrupt enable reg */
-#endif
+	out8(UART_BASE + UART_LCR, 0x80);	/* set DLAB bit */
+	out8(UART_BASE + UART_DLL, bdiv);	/* set baudrate divisor */
+	out8(UART_BASE + UART_DLM, bdiv >> 8);	/* set baudrate divisor */
+	out8(UART_BASE + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
+	out8(UART_BASE + UART_FCR, 0x00);	/* disable FIFO */
+	out8(UART_BASE + UART_MCR, 0x00);	/* no modem control DTR RTS */
+	val = in8(UART_BASE + UART_LSR);	/* clear line status */
+	val = in8(UART_BASE + UART_RBR);	/* read receive buffer */
+	out8(UART_BASE + UART_SCR, 0x00);	/* set scratchpad */
+	out8(UART_BASE + UART_IER, 0x00);	/* set interrupt enable reg */
+
 	return (0);
 }
 
@@ -598,55 +574,10 @@
 void serial_setbrg (void)
 #endif
 {
-	unsigned long tmp;
-	unsigned long clk;
-	unsigned long udiv;
-	unsigned short bdiv;
-
-#ifdef CFG_EXT_SERIAL_CLOCK
-	clk = CFG_EXT_SERIAL_CLOCK;
-#else
-	clk = gd->cpu_clk;
-#endif
-
-#ifdef CONFIG_405EP
-	udiv = ((mfdcr (cpc0_ucr) & UCR0_MASK) >> UCR0_UDIV_POS);
-#else
-	udiv = ((mfdcr (cntrl0) & 0x3e) >> 1) + 1;
-#endif /* CONFIG_405EP */
-
-#if !defined(CFG_EXT_SERIAL_CLOCK) && \
-	( defined(CONFIG_440GX) || defined(CONFIG_440EP) || \
-	  defined(CONFIG_440GR) || defined(CONFIG_440SP) || \
-	  defined(CONFIG_440SPE) )
-	serial_divs (gd->baudrate, &udiv, &bdiv);
-	tmp = udiv << CR0_UDIV_POS;		/* set the UART divisor */
-#if defined(CONFIG_SERIAL_MULTI)
-	if (UART0_BASE == dev_base) {
-		mtsdr (UART0_SDR, tmp);
-	} else {
-		mtsdr (UART1_SDR, tmp);
-	}
-#else
-	mtsdr (UART0_SDR, tmp);
-#endif
-
-#else
-
-	tmp = gd->baudrate * udiv * 16;
-	bdiv = (clk + tmp / 2) / tmp;
-#endif /* !defined(CFG_EXT_SERIAL_CLOCK) && (...) */
-
 #if defined(CONFIG_SERIAL_MULTI)
-	out8 (dev_base + UART_LCR, 0x80);	/* set DLAB bit */
-	out8 (dev_base + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8 (dev_base + UART_DLM, bdiv >> 8);/* set baudrate divisor */
-	out8 (dev_base + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
+	serial_init_dev(dev_base);
 #else
-	out8 (ACTING_UART0_BASE + UART_LCR, 0x80);	/* set DLAB bit */
-	out8 (ACTING_UART0_BASE + UART_DLL, bdiv);	/* set baudrate divisor */
-	out8 (ACTING_UART0_BASE + UART_DLM, bdiv >> 8);/* set baudrate divisor */
-	out8 (ACTING_UART0_BASE + UART_LCR, 0x03);	/* clear DLAB; set 8 bits, no parity */
+	serial_init();
 #endif
 }
 
@@ -667,19 +598,11 @@
 
 	/* check THRE bit, wait for transmiter available */
 	for (i = 1; i < 3500; i++) {
-#if defined(CONFIG_SERIAL_MULTI)
-		if ((in8 (dev_base + UART_LSR) & 0x20) == 0x20)
-#else
-		if ((in8 (ACTING_UART0_BASE + UART_LSR) & 0x20) == 0x20)
-#endif
+		if ((in8 (UART_BASE + UART_LSR) & 0x20) == 0x20)
 			break;
 		udelay (100);
 	}
-#if defined(CONFIG_SERIAL_MULTI)
-	out8 (dev_base + UART_THR, c);	/* put character out */
-#else
-	out8 (ACTING_UART0_BASE + UART_THR, c);	/* put character out */
-#endif
+	out8 (UART_BASE + UART_THR, c);	/* put character out */
 }
 
 #if defined(CONFIG_SERIAL_MULTI)
@@ -709,11 +632,7 @@
 #if defined(CONFIG_HW_WATCHDOG)
 		WATCHDOG_RESET ();	/* Reset HW Watchdog, if needed */
 #endif	/* CONFIG_HW_WATCHDOG */
-#if defined(CONFIG_SERIAL_MULTI)
-		status = in8 (dev_base + UART_LSR);
-#else
-		status = in8 (ACTING_UART0_BASE + UART_LSR);
-#endif
+		status = in8 (UART_BASE + UART_LSR);
 		if ((status & asyncLSRDataReady1) != 0x0) {
 			break;
 		}
@@ -721,22 +640,14 @@
 				asyncLSROverrunError1 |
 				asyncLSRParityError1  |
 				asyncLSRBreakInterrupt1 )) != 0) {
-#if defined(CONFIG_SERIAL_MULTI)
-			out8 (dev_base + UART_LSR,
-#else
-			out8 (ACTING_UART0_BASE + UART_LSR,
-#endif
+			out8 (UART_BASE + UART_LSR,
 			      asyncLSRFramingError1 |
 			      asyncLSROverrunError1 |
 			      asyncLSRParityError1  |
 			      asyncLSRBreakInterrupt1);
 		}
 	}
-#if defined(CONFIG_SERIAL_MULTI)
-	return (0x000000ff & (int) in8 (dev_base));
-#else
-	return (0x000000ff & (int) in8 (ACTING_UART0_BASE));
-#endif
+	return (0x000000ff & (int) in8 (UART_BASE));
 }
 
 #if defined(CONFIG_SERIAL_MULTI)
@@ -747,11 +658,7 @@
 {
 	unsigned char status;
 
-#if defined(CONFIG_SERIAL_MULTI)
-	status = in8 (dev_base + UART_LSR);
-#else
-	status = in8 (ACTING_UART0_BASE + UART_LSR);
-#endif
+	status = in8 (UART_BASE + UART_LSR);
 	if ((status & asyncLSRDataReady1) != 0x0) {
 		return (1);
 	}
@@ -759,11 +666,7 @@
 			asyncLSROverrunError1 |
 			asyncLSRParityError1  |
 			asyncLSRBreakInterrupt1 )) != 0) {
-#if defined(CONFIG_SERIAL_MULTI)
-		out8 (dev_base + UART_LSR,
-#else
-		out8 (ACTING_UART0_BASE + UART_LSR,
-#endif
+		out8 (UART_BASE + UART_LSR,
 		      asyncLSRFramingError1 |
 		      asyncLSROverrunError1 |
 		      asyncLSRParityError1  |
diff --git a/cpu/ppc4xx/speed.c b/cpu/ppc4xx/speed.c
index e552c03..2d16a83 100644
--- a/cpu/ppc4xx/speed.c
+++ b/cpu/ppc4xx/speed.c
@@ -199,7 +199,8 @@
 
 #elif defined(CONFIG_440)
 
-#if  defined(CONFIG_440EP) || defined(CONFIG_440GR)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
 void get_sys_info (sys_info_t *sysInfo)
 {
 	unsigned long temp;
diff --git a/cpu/ppc4xx/start.S b/cpu/ppc4xx/start.S
index 60ed2d5..5a1ab38 100644
--- a/cpu/ppc4xx/start.S
+++ b/cpu/ppc4xx/start.S
@@ -117,12 +117,16 @@
 
 	.extern ext_bus_cntlr_init
 	.extern sdram_init
+#ifdef CONFIG_NAND_U_BOOT
+	.extern reconfig_tlb0
+#endif
 
 /*
  * Set up GOT: Global Offset Table
  *
  * Use r14 to access the GOT
  */
+#if !defined(CONFIG_NAND_SPL)
 	START_GOT
 	GOT_ENTRY(_GOT2_TABLE_)
 	GOT_ENTRY(_FIXUP_TABLE_)
@@ -136,6 +140,18 @@
 	GOT_ENTRY(_end)
 	GOT_ENTRY(__bss_start)
 	END_GOT
+#endif /* CONFIG_NAND_SPL */
+
+#if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
+	/*
+	 * NAND U-Boot image is started from offset 0
+	 */
+	.text
+	bl	reconfig_tlb0
+	GET_GOT
+	bl	cpu_init_f	/* run low-level CPU init code	   (from Flash) */
+	bl	board_init_f
+#endif
 
 /*
  * 440 Startup -- on reset only the top 4k of the effective
@@ -150,11 +166,21 @@
  */
 
 #if defined(CONFIG_440)
+#if !defined(CONFIG_NAND_SPL)
     .section .bootpg,"ax"
+#endif
     .globl _start_440
 
 /**************************************************************************/
 _start_440:
+        /*--------------------------------------------------------------------+
+        | 440EPX BUP Change - Hardware team request
+        +--------------------------------------------------------------------*/
+#if defined(CONFIG_440EPX) || defined(CONFIG_440GRX)
+	sync
+	nop
+	nop
+#endif
 	/*----------------------------------------------------------------+
 	| Core bug fix.  Clear the esr
 	+-----------------------------------------------------------------*/
@@ -171,15 +197,19 @@
 	mtspr	srr1,r0
 	mtspr	csrr0,r0
 	mtspr	csrr1,r0
-#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)  /* NOTE: 440GX adds machine check status regs */
+	/* NOTE: 440GX adds machine check status regs */
+#if defined(CONFIG_440) && !defined(CONFIG_440GP)
 	mtspr	mcsrr0,r0
 	mtspr	mcsrr1,r0
-	mfspr	r1, mcsr
+	mfspr	r1,mcsr
 	mtspr	mcsr,r1
 #endif
 	/*----------------------------------------------------------------*/
 	/* Initialize debug */
 	/*----------------------------------------------------------------*/
+	mfspr	r1,dbcr0
+	andis.	r1, r1, 0x8000	/* test DBCR0[EDM] bit			*/
+	bne	skip_debug_init	/* if set, don't clear debug register	*/
 	mtspr	dbcr0,r0
 	mtspr	dbcr1,r0
 	mtspr	dbcr2,r0
@@ -193,6 +223,7 @@
 
 	mfspr	r1,dbsr
 	mtspr	dbsr,r1		/* Clear all valid bits */
+skip_debug_init:
 
 	/*----------------------------------------------------------------*/
 	/* CCR0 init */
@@ -352,7 +383,53 @@
 	/*----------------------------------------------------------------*/
 	/* Continue from 'normal' start */
 	/*----------------------------------------------------------------*/
-2:	bl	3f
+2:
+
+#if defined(CONFIG_NAND_SPL)
+	/*
+	 * Enable internal SRAM
+	 */
+	lis	r2,0x7fff
+	ori	r2,r2,0xffff
+	mfdcr	r1,isram0_dpc
+	and	r1,r1,r2		/* Disable parity check */
+	mtdcr	isram0_dpc,r1
+	mfdcr	r1,isram0_pmeg
+	and	r1,r1,r2		/* Disable pwr mgmt */
+	mtdcr	isram0_pmeg,r1
+
+	/*
+	 * Copy SPL from cache into internal SRAM
+	 */
+	li	r4,(CFG_NAND_BOOT_SPL_SIZE >> 2) - 1
+	mtctr	r4
+	lis	r2,CFG_NAND_BOOT_SPL_SRC@h
+	ori	r2,r2,CFG_NAND_BOOT_SPL_SRC@l
+	lis	r3,CFG_NAND_BOOT_SPL_DST@h
+	ori	r3,r3,CFG_NAND_BOOT_SPL_DST@l
+spl_loop:
+	lwzu	r4,4(r2)
+	stwu	r4,4(r3)
+	bdnz	spl_loop
+
+	/*
+	 * Jump to code in RAM
+	 */
+	bl	00f
+00:	mflr	r10
+	lis	r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@h
+	ori	r3,r3,(CFG_NAND_BOOT_SPL_SRC - CFG_NAND_BOOT_SPL_DST)@l
+	sub	r10,r10,r3
+	addi	r10,r10,28
+	mtlr	r10
+	blr
+
+start_ram:
+	sync
+	isync
+#endif
+
+	bl	3f
 	b	_start
 
 3:	li	r0,0
@@ -366,6 +443,7 @@
  * r3 - 1st arg to board_init(): IMMP pointer
  * r4 - 2nd arg to board_init(): boot flag
  */
+#ifndef CONFIG_NAND_SPL
 	.text
 	.long	0x27051956		/* U-Boot Magic Number			*/
 	.globl	version_string
@@ -379,6 +457,7 @@
  * location (0x100) is where the CriticalInput Execption should be.
  */
 	. = EXC_OFF_SYS_RESET
+#endif
 	.globl	_start
 _start:
 
@@ -417,7 +496,8 @@
 	/* Setup the internal SRAM */
 	/*----------------------------------------------------------------*/
 	li	r0,0
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR)
+
+#ifdef CFG_INIT_RAM_DCACHE
 	/* Clear Dcache to use as RAM */
 	addis	r3,r0,CFG_INIT_RAM_ADDR@h
 	ori	r3,r3,CFG_INIT_RAM_ADDR@l
@@ -433,19 +513,22 @@
 	dcbz	r0,r3
 	addi	r3,r3,32
 	bdnz	..d_ag
-#else
-#if defined (CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
+#endif /* CFG_INIT_RAM_DCACHE */
+
+	/* 440EP & 440GR are only 440er PPC's without internal SRAM */
+#if !defined(CONFIG_440EP) && !defined(CONFIG_440GR)
+	/* not all PPC's have internal SRAM usable as L2-cache */
+#if defined(CONFIG_440GX) || defined(CONFIG_440SP) || defined(CONFIG_440SPE)
 	mtdcr	l2_cache_cfg,r0		/* Ensure L2 Cache is off */
 #endif
-	mtdcr	isram0_sb1cr,r0		/* Disable bank 1 */
 
-	li	r2,0x7fff
+	lis	r2,0x7fff
 	ori	r2,r2,0xffff
 	mfdcr	r1,isram0_dpc
 	and	r1,r1,r2		/* Disable parity check */
 	mtdcr	isram0_dpc,r1
 	mfdcr	r1,isram0_pmeg
-	andis.	r1,r1,r2		/* Disable pwr mgmt */
+	and	r1,r1,r2		/* Disable pwr mgmt */
 	mtdcr	isram0_pmeg,r1
 
 	lis	r1,0x8000		/* BAS = 8000_0000 */
@@ -474,11 +557,12 @@
 	lis	r1, 0x0003
 	ori	r1,r1, 0x0984		/* fourth 64k */
 	mtdcr	isram0_sb3cr,r1
-#else
+#elif defined(CONFIG_440GP)
 	ori	r1,r1,0x0380		/* 8k rw */
 	mtdcr	isram0_sb0cr,r1
-#endif
+	mtdcr	isram0_sb1cr,r0		/* Disable bank 1 */
 #endif
+#endif /* #if !defined(CONFIG_440EP) && !defined(CONFIG_440GR) */
 
 	/*----------------------------------------------------------------*/
 	/* Setup the stack in internal SRAM */
@@ -495,10 +579,14 @@
 	stwu	r1,-8(r1)		/* Save back chain and move SP */
 	stw	r0,+12(r1)		/* Save return addr (underflow vect) */
 
+#ifdef CONFIG_NAND_SPL
+	bl	nand_boot		/* will not return */
+#else
 	GET_GOT
 
 	bl	cpu_init_f	/* run low-level CPU init code	   (from Flash) */
 	bl	board_init_f
+#endif
 
 #endif /* CONFIG_440 */
 
@@ -808,6 +896,7 @@
 	/*----------------------------------------------------------------------- */
 
 
+#ifndef CONFIG_NAND_SPL
 /*****************************************************************************/
 	.globl	_start_of_vectors
 _start_of_vectors:
@@ -1013,6 +1102,7 @@
 	lwz	r1,GPR1(r1)
 	SYNC
 	rfci
+#endif /* CONFIG_NAND_SPL */
 
 /* Cache functions.
 */
@@ -1254,6 +1344,7 @@
 
 /*------------------------------------------------------------------------------*/
 
+#ifndef CONFIG_NAND_SPL
 /*
  * void relocate_code (addr_sp, gd, addr_moni)
  *
@@ -1267,7 +1358,9 @@
  */
 	.globl	relocate_code
 relocate_code:
-#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || defined(CONFIG_440SPE)
+#if defined(CONFIG_440EP) || defined(CONFIG_440GR) || \
+    defined(CONFIG_440EPX) || defined(CONFIG_440GRX) || \
+    defined(CONFIG_440SPE)
 	/*
 	 * On some 440er platforms the cache is enabled in the first TLB (Boot-CS)
 	 * to speed up the boot process. Now this cache needs to be disabled.
@@ -1482,22 +1575,22 @@
 	cmplw	0, r7, r8
 	blt	4b
 
-#if !defined(CONFIG_440GX) && !defined(CONFIG_440SPE)
+#if !defined(CONFIG_440)
 	addi	r7,r0,0x1000		/* set ME bit (Machine Exceptions) */
 	oris	r7,r7,0x0002		/* set CE bit (Critical Exceptions) */
 	mtmsr	r7			/* change MSR */
 #else
-	bl	__440gx_msr_set
-	b	__440gx_msr_continue
+	bl	__440_msr_set
+	b	__440_msr_continue
 
-__440gx_msr_set:
+__440_msr_set:
 	addi	r7,r0,0x1000		/* set ME bit (Machine Exceptions) */
 	oris	r7,r7,0x0002		/* set CE bit (Critical Exceptions) */
 	mtspr	srr1,r7
 	mflr	r7
 	mtspr	srr0,r7
 	rfi
-__440gx_msr_continue:
+__440_msr_continue:
 #endif
 
 	mtlr	r4			/* restore link register	*/
@@ -1516,6 +1609,7 @@
 	stw	r0, 4(r7)
 
 	blr
+#endif /* CONFIG_NAND_SPL */
 
 
 /**************************************************************************/
diff --git a/cpu/ppc4xx/usb_ohci.c b/cpu/ppc4xx/usb_ohci.c
index bb57658..ab852c5 100644
--- a/cpu/ppc4xx/usb_ohci.c
+++ b/cpu/ppc4xx/usb_ohci.c
@@ -76,7 +76,7 @@
 #define m16_swap(x) swap_16(x)
 #define m32_swap(x) swap_32(x)
 
-#ifdef CONFIG_440EP
+#if defined(CONFIG_440EP) || defined(CONFIG_440EPX)
 #define ohci_cpu_to_le16(x) (x)
 #define ohci_cpu_to_le32(x) (x)
 #else
@@ -1599,7 +1599,11 @@
 	gohci.disabled = 1;
 	gohci.sleeping = 0;
 	gohci.irq = -1;
-	gohci.regs = (struct ohci_regs *)(CFG_PERIPHERAL_BASE | 0x1000);
+#if defined(CONFIG_440EP)
+ 	gohci.regs = (struct ohci_regs *)(CFG_PERIPHERAL_BASE | 0x1000);
+#elif defined(CONFIG_440EPX)
+	gohci.regs = (struct ohci_regs *)(CFG_USB_HOST);
+#endif
 
 	gohci.flags = 0;
 	gohci.slot_name = "ppc440";
diff --git a/cpu/ppc4xx/usbdev.c b/cpu/ppc4xx/usbdev.c
index 8262c54..6140d2a 100644
--- a/cpu/ppc4xx/usbdev.c
+++ b/cpu/ppc4xx/usbdev.c
@@ -3,7 +3,7 @@
 #include <common.h>
 #include <asm/processor.h>
 
-#ifdef CONFIG_440EP
+#if (defined(CONFIG_440EP) || defined(CONFIG_440EPX)) && (CONFIG_COMMANDS & CFG_CMD_USB)
 
 #include <usb.h>
 #include "usbdev.h"
@@ -186,8 +186,23 @@
 	return 0;
 }
 
+#if defined(CONFIG_440EPX)
 void usb_dev_init()
 {
+	printf("USB 2.0 Device init\n");
+
+	/*usb dev init */
+	*(unsigned char *)USB2D0_POWER_8 = 0xa1;	/* 2.0 */
+
+	/*enable interrupts */
+	*(unsigned char *)USB2D0_INTRUSBE_8 = 0x0f;
+
+	irq_install_handler(VECNUM_HSB2D, (interrupt_handler_t *) usbInt,
+			    NULL);
+}
+#else
+void usb_dev_init()
+{
 #ifdef USB_2_0_DEVICE
 	printf("USB 2.0 Device init\n");
 	/*select 2.0 device */
@@ -210,5 +225,6 @@
 	irq_install_handler(VECNUM_USBDEV, (interrupt_handler_t *) usbInt,
 			    NULL);
 }
+#endif
 
-#endif				/*CONFIG_440EP */
+#endif /* CONFIG_440EP || CONFIG_440EPX */
diff --git a/cpu/ppc4xx/vecnum.h b/cpu/ppc4xx/vecnum.h
index 93cef02..70e436a 100644
--- a/cpu/ppc4xx/vecnum.h
+++ b/cpu/ppc4xx/vecnum.h
@@ -31,7 +31,94 @@
 #ifndef _VECNUMS_H_
 #define _VECNUMS_H_
 
-#if defined(CONFIG_440SPE)
+#if defined(CONFIG_440EPX) || defined(CONFIG_440_GRX)
+
+/* UIC 0 */
+#define VECNUM_U0                   0  /* UART 0                        */
+#define VECNUM_U1                   1  /* UART 1                        */
+#define VECNUM_IIC0                 2  /* IIC                           */
+#define VECNUM_KRD                  3  /* Kasumi Ready for data         */
+#define VECNUM_KDA                  4  /* Kasumi Data Available         */
+#define VECNUM_PCRW                 5  /* PCI command register write    */
+#define VECNUM_PPM                  6  /* PCI power management          */
+#define VECNUM_IIC1                 7  /* IIC                           */
+#define VECNUM_SPI                  8  /* SPI                           */
+#define VECNUM_EPCISER              9  /* External PCI SERR             */
+#define VECNUM_MTE                 10  /* MAL TXEOB                     */
+#define VECNUM_MRE                 11  /* MAL RXEOB                     */
+#define VECNUM_D0                  12  /* DMA channel 0                 */
+#define VECNUM_D1                  13  /* DMA channel 1                 */
+#define VECNUM_D2                  14  /* DMA channel 2                 */
+#define VECNUM_D3                  15  /* DMA channel 3                 */
+#define VECNUM_UD0                 16  /* UDMA irq 0                    */
+#define VECNUM_UD1                 17  /* UDMA irq 1                    */
+#define VECNUM_UD2                 18  /* UDMA irq 2                    */
+#define VECNUM_UD3                 19  /* UDMA irq 3                    */
+#define VECNUM_HSB2D               20  /* USB2.0 Device                 */
+#define VECNUM_USBDEV		   20  /* USB 1.1/USB 2.0 Device        */
+#define VECNUM_OHCI1               21  /* USB2.0 Host OHCI irq 1        */
+#define VECNUM_OHCI2               22  /* USB2.0 Host OHCI irq 2        */
+#define VECNUM_EIP94               23  /* Security EIP94                */
+#define VECNUM_ETH0                24  /* Emac 0                        */
+#define VECNUM_ETH1                25  /* Emac 1                        */
+#define VECNUM_EHCI                26  /* USB2.0 Host EHCI              */
+#define VECNUM_EIR4                27  /* External interrupt 4          */
+#define VECNUM_UIC2NC              28  /* UIC2 non-critical interrupt   */
+#define VECNUM_UIC2C               29  /* UIC2 critical interrupt       */
+#define VECNUM_UIC1NC              30  /* UIC1 non-critical interrupt   */
+#define VECNUM_UIC1C               31  /* UIC1 critical interrupt       */
+
+/* UIC 1 */
+#define VECNUM_MS           (32 +  0)  /* MAL SERR                      */
+#define VECNUM_MTDE         (32 +  1)  /* MAL TXDE                      */
+#define VECNUM_MRDE         (32 +  2)  /* MAL RXDE                      */
+#define VECNUM_U2           (32 +  3)  /* UART 2                        */
+#define VECNUM_U3           (32 +  4)  /* UART 3                        */
+#define VECNUM_EBCO         (32 +  5)  /* EBCO interrupt status         */
+#define VECNUM_NDFC         (32 +  6)  /* NDFC                          */
+#define VECNUM_KSLE         (32 +  7)  /* KASUMI slave error            */
+#define VECNUM_CT5          (32 +  8)  /* GPT compare timer 5           */
+#define VECNUM_CT6          (32 +  9)  /* GPT compare timer 6           */
+#define VECNUM_PLB34I0      (32 + 10)  /* PLB3X4X MIRQ0                 */
+#define VECNUM_PLB34I1      (32 + 11)  /* PLB3X4X MIRQ1                 */
+#define VECNUM_PLB34I2      (32 + 12)  /* PLB3X4X MIRQ2                 */
+#define VECNUM_PLB34I3      (32 + 13)  /* PLB3X4X MIRQ3                 */
+#define VECNUM_PLB34I4      (32 + 14)  /* PLB3X4X MIRQ4                 */
+#define VECNUM_PLB34I5      (32 + 15)  /* PLB3X4X MIRQ5                 */
+#define VECNUM_CT0          (32 + 16)  /* GPT compare timer 0           */
+#define VECNUM_CT1          (32 + 17)  /* GPT compare timer 1           */
+#define VECNUM_EIR7         (32 + 18)  /* External interrupt 7          */
+#define VECNUM_EIR8         (32 + 19)  /* External interrupt 8          */
+#define VECNUM_EIR9         (32 + 20)  /* External interrupt 9          */
+#define VECNUM_CT2          (32 + 21)  /* GPT compare timer 2           */
+#define VECNUM_CT3          (32 + 22)  /* GPT compare timer 3           */
+#define VECNUM_CT4          (32 + 23)  /* GPT compare timer 4           */
+#define VECNUM_SRE          (32 + 24)  /* Serial ROM error              */
+#define VECNUM_GPTDC        (32 + 25)  /* GPT decrementer pulse         */
+#define VECNUM_RSVD0        (32 + 26)  /* Reserved                      */
+#define VECNUM_EPCIPER      (32 + 27)  /* External PCI PERR             */
+#define VECNUM_EIR0         (32 + 28)  /* External interrupt 0          */
+#define VECNUM_EWU0         (32 + 29)  /* Ethernet 0 wakeup             */
+#define VECNUM_EIR1         (32 + 30)  /* External interrupt 1          */
+#define VECNUM_EWU1         (32 + 31)  /* Ethernet 1 wakeup             */
+
+#define VECNUM_TXDE         VECNUM_MTDE
+#define VECNUM_RXDE         VECNUM_MRDE
+
+/* UIC 2 */
+#define VECNUM_EIR5         (62 +  0)  /* External interrupt 5          */
+#define VECNUM_EIR6         (62 +  1)  /* External interrupt 6          */
+#define VECNUM_OPB          (62 +  2)  /* OPB to PLB bridge int stat    */
+#define VECNUM_EIR2         (62 +  3)  /* External interrupt 2          */
+#define VECNUM_EIR3         (62 +  4)  /* External interrupt 3          */
+#define VECNUM_DDR2         (62 +  5)  /* DDR2 sdram                    */
+#define VECNUM_MCTX0        (62 +  6)  /* MAl intp coalescence TX0      */
+#define VECNUM_MCTX1        (62 +  7)  /* MAl intp coalescence TX1      */
+#define VECNUM_MCTR0        (62 +  8)  /* MAl intp coalescence TR0      */
+#define VECNUM_MCTR1        (62 +  9)  /* MAl intp coalescence TR1      */
+
+#elif defined(CONFIG_440SPE)
+
 /* UIC 0 */
 #define VECNUM_U0           0           /* UART0                        */
 #define VECNUM_U1           1           /* UART1                        */