Merge branch 'post' of git://git.denx.de/u-boot-blackfin

* 'post' of git://git.denx.de/u-boot-blackfin:
  Blackfin: uart: implement loop callback for post
  Blackfin: bf537-stamp/bf548-ezkit: update POST flash block range
  Blackfin: post: generalize led/button tests with GPIOs
  Blackfin: bf537-stamp: drop uart/flash post tests
  Blackfin: post: drop custom test list
  Blackfin: bf537-stamp: convert to gpio post hotkey
diff --git a/.gitignore b/.gitignore
index 2a82cd9..289ffab 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,6 +19,7 @@
 # Top-level generic files
 #
 
+/MLO
 /System.map
 /u-boot
 /u-boot.hex
diff --git a/MAINTAINERS b/MAINTAINERS
index 5b2fb57..287938a 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -634,6 +634,7 @@
 
 Fabio Estevam <fabio.estevam@freescale.com>
 
+	mx25pdk		i.MX25
 	mx31pdk		i.MX31
 	mx53ard		i.MX53
 	mx53smd		i.MX53
@@ -797,8 +798,6 @@
 Steve Sakoman <sakoman@gmail.com>
 
 	omap3_overo	ARM ARMV7 (OMAP3xx SoC)
-	omap4_panda	ARM ARMV7 (OMAP4xx SoC)
-	omap4_sdp4430	ARM ARMV7 (OMAP4xx SoC)
 
 Jens Scharsig <esw@bus-elektronik.de>
 
@@ -838,6 +837,11 @@
 	cm4116		ks8695p
 	cm4148		ks8695p
 
+Aneesh V <aneesh@ti.com>
+
+	omap4_panda	ARM ARMV7 (OMAP4xx SoC)
+	omap4_sdp4430	ARM ARMV7 (OMAP4xx SoC)
+
 Marek Vasut <marek.vasut@gmail.com>
 
 	balloon3	xscale/pxa
@@ -847,6 +851,7 @@
 	vpac270		xscale/pxa
 	zipitz2		xscale/pxa
  	efikamx		i.MX51
+	efikasb		i.MX51
 
 Hugo Villeneuve <hugo.villeneuve@lyrtech.com>
 
diff --git a/arch/arm/cpu/arm1136/mx31/generic.c b/arch/arm/cpu/arm1136/mx31/generic.c
index e3a4d1b..c6def5d 100644
--- a/arch/arm/cpu/arm1136/mx31/generic.c
+++ b/arch/arm/cpu/arm1136/mx31/generic.c
@@ -180,7 +180,7 @@
 {
 	u32 srev = get_cpu_rev();
 
-	printf("CPU:   Freescale i.MX31 rev %d.%d%s at %d MHz.",
+	printf("CPU:   Freescale i.MX31 rev %d.%d%s at %d MHz.\n",
 			(srev & 0xF0) >> 4, (srev & 0x0F),
 			((srev & 0x8000) ? " unknown" : ""),
 			mx31_get_mcu_main_clk() / 1000000);
diff --git a/arch/arm/cpu/arm1136/mx31/timer.c b/arch/arm/cpu/arm1136/mx31/timer.c
index c05a39d..717a2b7 100644
--- a/arch/arm/cpu/arm1136/mx31/timer.c
+++ b/arch/arm/cpu/arm1136/mx31/timer.c
@@ -173,8 +173,8 @@
 #else
 	secs = 64;
 #endif
-	writew(readw(&wdog->wcr) | (secs << WDOG_WT_SHIFT) | WDOG_ENABLE,
-		&wdog->wcr);
+	setbits_le16(&wdog->wcr, (secs << WDOG_WT_SHIFT) | WDOG_ENABLE
+							 | WDOG_WDZST);
 }
 
 
diff --git a/arch/arm/cpu/arm926ejs/davinci/Makefile b/arch/arm/cpu/arm926ejs/davinci/Makefile
index 3183e6a..0310957 100644
--- a/arch/arm/cpu/arm926ejs/davinci/Makefile
+++ b/arch/arm/cpu/arm926ejs/davinci/Makefile
@@ -28,11 +28,12 @@
 LIB	= $(obj)lib$(SOC).o
 
 COBJS-y				+= cpu.o timer.o psc.o
+COBJS-$(CONFIG_AM18018_LOWLEVEL)       += am1808_lowlevel.o
 COBJS-$(CONFIG_SOC_DM355)	+= dm355.o
 COBJS-$(CONFIG_SOC_DM365)	+= dm365.o
 COBJS-$(CONFIG_SOC_DM644X)	+= dm644x.o
 COBJS-$(CONFIG_SOC_DM646X)	+= dm646x.o
-COBJS-$(CONFIG_DRIVER_TI_EMAC)	+= lxt972.o dp83848.o et1011c.o
+COBJS-$(CONFIG_DRIVER_TI_EMAC)	+= lxt972.o dp83848.o et1011c.o ksz8873.o
 
 SOBJS	= reset.o
 
diff --git a/arch/arm/cpu/arm926ejs/davinci/am1808_lowlevel.c b/arch/arm/cpu/arm926ejs/davinci/am1808_lowlevel.c
new file mode 100644
index 0000000..1ea4a9f
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/davinci/am1808_lowlevel.c
@@ -0,0 +1,428 @@
+/*
+ * SoC-specific lowlevel code for AM1808 and similar chips
+ *
+ * Copyright (C) 2011
+ * Heiko Schocher, DENX Software Engineering, hs@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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#include <common.h>
+#include <nand.h>
+#include <ns16550.h>
+#include <post.h>
+#include <asm/arch/am1808_lowlevel.h>
+#include <asm/arch/hardware.h>
+#include <asm/arch/ddr2_defs.h>
+#include <asm/arch/emif_defs.h>
+
+void am1808_waitloop(unsigned long loopcnt)
+{
+	unsigned long	i;
+
+	for (i = 0; i < loopcnt; i++)
+		asm("   NOP");
+}
+
+int am1808_pll_init(struct davinci_pllc_regs *reg, unsigned long pllmult)
+{
+	if (reg == davinci_pllc0_regs)
+		/* Unlock PLL registers. */
+		clrbits_le32(&davinci_syscfg_regs->cfgchip0, 0x00000010);
+
+	/*
+	 * Set PLLENSRC '0',bit 5, PLL Enable(PLLEN) selection is controlled
+	 * through MMR
+	 */
+	clrbits_le32(&reg->pllctl, 0x00000020);
+	/* PLLCTL.EXTCLKSRC bit 9 should be left at 0 for Freon */
+	clrbits_le32(&reg->pllctl, 0x00000200);
+
+	/* Set PLLEN=0 => PLL BYPASS MODE */
+	clrbits_le32(&reg->pllctl, 0x00000001);
+
+	am1808_waitloop(150);
+
+	if (reg == davinci_pllc0_regs) {
+		/*
+		 * Select the Clock Mode bit 8 as External Clock or On Chip
+		 * Oscilator
+		 */
+		dv_maskbits(&reg->pllctl, 0xFFFFFEFF);
+		setbits_le32(&reg->pllctl, (CONFIG_SYS_DV_CLKMODE << 8));
+	}
+
+	/* Clear PLLRST bit to reset the PLL */
+	clrbits_le32(&reg->pllctl, 0x00000008);
+
+	/* Disable the PLL output */
+	setbits_le32(&reg->pllctl, 0x00000010);
+
+	/* PLL initialization sequence */
+	/*
+	 * Power up the PLL- PWRDN bit set to 0 to bring the PLL out of
+	 * power down bit
+	 */
+	clrbits_le32(&reg->pllctl, 0x00000002);
+
+	/* Enable the PLL from Disable Mode PLLDIS bit to 0 */
+	clrbits_le32(&reg->pllctl, 0x00000010);
+
+	/* Program the required multiplier value in PLLM */
+	writel(pllmult, &reg->pllm);
+
+	/* program the postdiv */
+	if (reg == davinci_pllc0_regs)
+		writel((0x8000 | CONFIG_SYS_AM1808_PLL0_POSTDIV),
+			&reg->postdiv);
+	else
+		writel((0x8000 | CONFIG_SYS_AM1808_PLL1_POSTDIV),
+			&reg->postdiv);
+
+	/*
+	 * Check for the GOSTAT bit in PLLSTAT to clear to 0 to indicate that
+	 * no GO operation is currently in progress
+	 */
+	while ((readl(&reg->pllstat) & 0x1) == 1)
+		;
+
+	if (reg == davinci_pllc0_regs) {
+		writel(CONFIG_SYS_AM1808_PLL0_PLLDIV1, &reg->plldiv1);
+		writel(CONFIG_SYS_AM1808_PLL0_PLLDIV2, &reg->plldiv2);
+		writel(CONFIG_SYS_AM1808_PLL0_PLLDIV3, &reg->plldiv3);
+		writel(CONFIG_SYS_AM1808_PLL0_PLLDIV4, &reg->plldiv4);
+		writel(CONFIG_SYS_AM1808_PLL0_PLLDIV5, &reg->plldiv5);
+		writel(CONFIG_SYS_AM1808_PLL0_PLLDIV6, &reg->plldiv6);
+		writel(CONFIG_SYS_AM1808_PLL0_PLLDIV7, &reg->plldiv7);
+	} else {
+		writel(CONFIG_SYS_AM1808_PLL1_PLLDIV1, &reg->plldiv1);
+		writel(CONFIG_SYS_AM1808_PLL1_PLLDIV2, &reg->plldiv2);
+		writel(CONFIG_SYS_AM1808_PLL1_PLLDIV3, &reg->plldiv3);
+	}
+
+	/*
+	 * Set the GOSET bit in PLLCMD to 1 to initiate a new divider
+	 * transition.
+	 */
+	setbits_le32(&reg->pllcmd, 0x01);
+
+	/*
+	 * Wait for the GOSTAT bit in PLLSTAT to clear to 0
+	 * (completion of phase alignment).
+	 */
+	while ((readl(&reg->pllstat) & 0x1) == 1)
+		;
+
+	/* Wait for PLL to reset properly. See PLL spec for PLL reset time */
+	am1808_waitloop(200);
+
+	/* Set the PLLRST bit in PLLCTL to 1 to bring the PLL out of reset */
+	setbits_le32(&reg->pllctl, 0x00000008);
+
+	/* Wait for PLL to lock. See PLL spec for PLL lock time */
+	am1808_waitloop(2400);
+
+	/*
+	 * Set the PLLEN bit in PLLCTL to 1 to remove the PLL from bypass
+	 * mode
+	 */
+	setbits_le32(&reg->pllctl, 0x00000001);
+
+
+	/*
+	 * clear EMIFA and EMIFB clock source settings, let them
+	 * run off SYSCLK
+	 */
+	if (reg == davinci_pllc0_regs)
+		dv_maskbits(&davinci_syscfg_regs->cfgchip3, 0xFFFFFFF8);
+
+	return 0;
+}
+
+void am1808_lpc_transition(unsigned char pscnum, unsigned char module,
+		unsigned char domain, unsigned char state)
+{
+	struct davinci_psc_regs	*reg;
+	dv_reg_p mdstat, mdctl;
+
+	if (pscnum == 0) {
+		reg = davinci_psc0_regs;
+		mdstat = &reg->psc0.mdstat[module];
+		mdctl = &reg->psc0.mdctl[module];
+	} else {
+		reg = davinci_psc1_regs;
+		mdstat = &reg->psc1.mdstat[module];
+		mdctl = &reg->psc1.mdctl[module];
+	}
+
+	/* Wait for any outstanding transition to complete */
+	while ((readl(&reg->ptstat) & (0x00000001 << domain)))
+		;
+
+	/* If we are already in that state, just return */
+	if ((readl(mdstat) & 0x1F) == state)
+		return;
+
+	/* Perform transition */
+	writel((readl(mdctl) & 0xFFFFFFE0) | state, mdctl);
+	setbits_le32(&reg->ptcmd, (0x00000001 << domain));
+
+	/* Wait for transition to complete */
+	while (readl(&reg->ptstat) & (0x00000001 << domain))
+		;
+
+	/* Wait and verify the state */
+	while ((readl(mdstat) & 0x1F) != state)
+		;
+}
+
+int am1808_ddr_setup(unsigned int freq)
+{
+	unsigned long	tmp;
+
+	/* Enable the Clock to DDR2/mDDR */
+	am1808_lpc_transition(1, 6, 0, PSC_ENABLE);
+
+	tmp = readl(&davinci_syscfg1_regs->vtpio_ctl);
+	if ((tmp & VTP_POWERDWN) == VTP_POWERDWN) {
+		/* Begin VTP Calibration */
+		clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN);
+		clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK);
+		setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ);
+		clrbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ);
+		setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_CLKRZ);
+
+		/* Polling READY bit to see when VTP calibration is done */
+		tmp = readl(&davinci_syscfg1_regs->vtpio_ctl);
+		while ((tmp & VTP_READY) != VTP_READY)
+			tmp = readl(&davinci_syscfg1_regs->vtpio_ctl);
+
+		setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_LOCK);
+		setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_POWERDWN);
+
+		setbits_le32(&davinci_syscfg1_regs->vtpio_ctl, VTP_IOPWRDWN);
+	}
+
+	writel(CONFIG_SYS_AM1808_DDR2_DDRPHYCR, &dv_ddr2_regs_ctrl->ddrphycr);
+	clrbits_le32(&davinci_syscfg1_regs->ddr_slew,
+		(1 << DDR_SLEW_CMOSEN_BIT));
+
+	setbits_le32(&dv_ddr2_regs_ctrl->sdbcr, DV_DDR_BOOTUNLOCK);
+
+	writel((CONFIG_SYS_AM1808_DDR2_SDBCR & ~0xf0000000) |
+		(readl(&dv_ddr2_regs_ctrl->sdbcr) & 0xf0000000), /*rsv Bytes*/
+		&dv_ddr2_regs_ctrl->sdbcr);
+	writel(CONFIG_SYS_AM1808_DDR2_SDBCR2, &dv_ddr2_regs_ctrl->sdbcr2);
+
+	writel(CONFIG_SYS_AM1808_DDR2_SDTIMR, &dv_ddr2_regs_ctrl->sdtimr);
+	writel(CONFIG_SYS_AM1808_DDR2_SDTIMR2, &dv_ddr2_regs_ctrl->sdtimr2);
+
+	clrbits_le32(&dv_ddr2_regs_ctrl->sdbcr,
+		(1 << DV_DDR_SDCR_TIMUNLOCK_SHIFT));
+
+	/*
+	 * LPMODEN and MCLKSTOPEN must be set!
+	 * Without this bits set, PSC don;t switch states !!
+	 */
+	writel(CONFIG_SYS_AM1808_DDR2_SDRCR |
+		(1 << DV_DDR_SRCR_LPMODEN_SHIFT) |
+		(1 << DV_DDR_SRCR_MCLKSTOPEN_SHIFT),
+		&dv_ddr2_regs_ctrl->sdrcr);
+
+	/* SyncReset the Clock to EMIF3A SDRAM */
+	am1808_lpc_transition(1, 6, 0, PSC_SYNCRESET);
+	/* Enable the Clock to EMIF3A SDRAM */
+	am1808_lpc_transition(1, 6, 0, PSC_ENABLE);
+
+	/* disable self refresh */
+	clrbits_le32(&dv_ddr2_regs_ctrl->sdrcr, 0xc0000000);
+	writel(0x30, &dv_ddr2_regs_ctrl->pbbpr);
+
+	return 0;
+}
+
+static void am1808_set_mdctl(dv_reg_p mdctl)
+{
+	if ((readl(mdctl) & 0x1F) != PSC_ENABLE)
+		writel(((readl(mdctl) & 0xFFFFFFE0) | PSC_ENABLE), mdctl);
+}
+
+void am1808_psc_init(void)
+{
+	struct davinci_psc_regs	*reg;
+	int i;
+
+	/* PSC 0 domain 0 init */
+	reg = davinci_psc0_regs;
+	while ((readl(&reg->ptstat) & 0x00000001))
+		;
+
+	for (i = 3; i <= 4 ; i++)
+		am1808_set_mdctl(&reg->psc0.mdctl[i]);
+
+	for (i = 7; i <= 12 ; i++)
+		am1808_set_mdctl(&reg->psc0.mdctl[i]);
+
+	/* Do Always-On Power Domain Transitions */
+	setbits_le32(&reg->ptcmd, 0x00000001);
+	while (readl(&reg->ptstat) & 0x00000001)
+		;
+
+	/* PSC1, domain 1 init */
+	reg = davinci_psc1_regs;
+	while ((readl(&reg->ptstat) & 0x00000001))
+		;
+
+	am1808_set_mdctl(&reg->psc1.mdctl[3]);
+	am1808_set_mdctl(&reg->psc1.mdctl[6]);
+
+	/* UART1 + UART2 */
+	for (i = 12 ; i <= 13 ; i++)
+		am1808_set_mdctl(&reg->psc1.mdctl[i]);
+
+	am1808_set_mdctl(&reg->psc1.mdctl[26]);
+	am1808_set_mdctl(&reg->psc1.mdctl[31]);
+
+	/* Do Always-On Power Domain Transitions */
+	setbits_le32(&reg->ptcmd, 0x00000001);
+	while (readl(&reg->ptstat) & 0x00000001)
+		;
+}
+
+void am1808_pinmux_ctl(unsigned long offset, unsigned long mask,
+	unsigned long value)
+{
+	clrbits_le32(&davinci_syscfg_regs->pinmux[offset], mask);
+	setbits_le32(&davinci_syscfg_regs->pinmux[offset], (mask & value));
+}
+
+__attribute__((weak))
+void board_gpio_init(void)
+{
+	return;
+}
+
+#if defined(CONFIG_NAND_SPL)
+void nand_boot(void)
+{
+	__attribute__((noreturn)) void (*uboot)(void);
+
+	/* copy image from NOR to RAM */
+	memcpy((void *)CONFIG_SYS_NAND_U_BOOT_DST,
+		(void *)CONFIG_SYS_NAND_U_BOOT_OFFS,
+		CONFIG_SYS_NAND_U_BOOT_SIZE);
+
+	/* and jump to it ... */
+	uboot = (void *)CONFIG_SYS_NAND_U_BOOT_START;
+	(*uboot)();
+}
+#endif
+
+#if defined(CONFIG_NAND_SPL)
+void board_init_f(ulong bootflag)
+#else
+int arch_cpu_init(void)
+#endif
+{
+	/*
+	 * copied from arch/arm/cpu/arm926ejs/start.S
+	 *
+	 * flush v4 I/D caches
+	 */
+	asm("mov	r0, #0");
+	asm("mcr	p15, 0, r0, c7, c7, 0");	/* flush v3/v4 cache */
+	asm("mcr	p15, 0, r0, c8, c7, 0");	/* flush v4 TLB */
+
+	/*
+	 * disable MMU stuff and caches
+	 */
+	asm("mrc	p15, 0, r0, c1, c0, 0");
+	/* clear bits 13, 9:8 (--V- --RS) */
+	asm("bic	r0, r0, #0x00002300");
+	/* clear bits 7, 2:0 (B--- -CAM) */
+	asm("bic	r0, r0, #0x00000087");
+	/* set bit 2 (A) Align */
+	asm("orr	r0, r0, #0x00000002");
+	/* set bit 12 (I) I-Cache */
+	asm("orr	r0, r0, #0x00001000");
+	asm("mcr	p15, 0, r0, c1, c0, 0");
+
+	/* Unlock kick registers */
+	writel(0x83e70b13, &davinci_syscfg_regs->kick0);
+	writel(0x95a4f1e0, &davinci_syscfg_regs->kick1);
+
+	dv_maskbits(&davinci_syscfg_regs->suspsrc,
+		((1 << 27) | (1 << 22) | (1 << 20) | (1 << 5) |	(1 << 16)));
+
+	/* System PSC setup - enable all */
+	am1808_psc_init();
+
+	/* Setup Pinmux */
+	am1808_pinmux_ctl(0, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX0);
+	am1808_pinmux_ctl(1, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX1);
+	am1808_pinmux_ctl(2, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX2);
+	am1808_pinmux_ctl(3, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX3);
+	am1808_pinmux_ctl(4, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX4);
+	am1808_pinmux_ctl(5, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX5);
+	am1808_pinmux_ctl(6, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX6);
+	am1808_pinmux_ctl(7, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX7);
+	am1808_pinmux_ctl(8, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX8);
+	am1808_pinmux_ctl(9, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX9);
+	am1808_pinmux_ctl(10, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX10);
+	am1808_pinmux_ctl(11, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX11);
+	am1808_pinmux_ctl(12, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX12);
+	am1808_pinmux_ctl(13, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX13);
+	am1808_pinmux_ctl(14, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX14);
+	am1808_pinmux_ctl(15, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX15);
+	am1808_pinmux_ctl(16, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX16);
+	am1808_pinmux_ctl(17, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX17);
+	am1808_pinmux_ctl(18, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX18);
+	am1808_pinmux_ctl(19, 0xFFFFFFFF, CONFIG_SYS_AM1808_PINMUX19);
+
+	/* PLL setup */
+	am1808_pll_init(davinci_pllc0_regs, CONFIG_SYS_AM1808_PLL0_PLLM);
+	am1808_pll_init(davinci_pllc1_regs, CONFIG_SYS_AM1808_PLL1_PLLM);
+
+	/* GPIO setup */
+	board_gpio_init();
+
+	/* setup CSn config */
+	writel(CONFIG_SYS_AM1808_CS2CFG, &davinci_emif_regs->ab1cr);
+	writel(CONFIG_SYS_AM1808_CS3CFG, &davinci_emif_regs->ab2cr);
+
+	am1808_lpc_transition(1, 13, 0, PSC_ENABLE);
+	NS16550_init((NS16550_t)(CONFIG_SYS_NS16550_COM1),
+			CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE);
+
+	/*
+	 * Fix Power and Emulation Management Register
+	 * see sprufw3a.pdf page 37 Table 24
+	 */
+	writel(readl((CONFIG_SYS_NS16550_COM1 + 0x30)) | 0x00006001,
+		(CONFIG_SYS_NS16550_COM1 + 0x30));
+#if defined(CONFIG_NAND_SPL)
+	puts("ddr init\n");
+	am1808_ddr_setup(132);
+
+	puts("boot u-boot ...\n");
+
+	nand_boot();
+#else
+	am1808_ddr_setup(132);
+	return 0;
+#endif
+}
diff --git a/arch/arm/cpu/arm926ejs/davinci/cpu.c b/arch/arm/cpu/arm926ejs/davinci/cpu.c
index b705dfd..02819f6 100644
--- a/arch/arm/cpu/arm926ejs/davinci/cpu.c
+++ b/arch/arm/cpu/arm926ejs/davinci/cpu.c
@@ -115,7 +115,18 @@
 out:
 	return pll_out;
 }
-#endif /* CONFIG_SOC_DA8XX */
+#ifdef CONFIG_DISPLAY_CPUINFO
+int print_cpuinfo(void)
+{
+	printf("Cores: ARM %d MHz",
+			clk_get(DAVINCI_ARM_CLKID) / 1000000);
+	printf("\nDDR:   %d MHz\n",
+			/* DDR PHY uses an x2 input clock */
+			clk_get(0x10001) / 1000000);
+	return 0;
+}
+#endif
+#else /* CONFIG_SOC_DA8XX */
 
 #ifdef CONFIG_DISPLAY_CPUINFO
 
@@ -194,7 +205,8 @@
 	return pll_sysclk_mhz(DAVINCI_PLL_CNTRL0_BASE, ARM_PLLDIV) * 1000000;
 }
 #endif
-#endif
+#endif /* CONFIG_DISPLAY_CPUINFO */
+#endif /* !CONFIG_SOC_DA8XX */
 
 /*
  * Initializes on-chip ethernet controllers.
diff --git a/arch/arm/cpu/arm926ejs/davinci/ksz8873.c b/arch/arm/cpu/arm926ejs/davinci/ksz8873.c
new file mode 100644
index 0000000..634eda0
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/davinci/ksz8873.c
@@ -0,0 +1,68 @@
+/*
+ * Micrel KSZ8873 PHY Driver for TI DaVinci
+ * (TMS320DM644x) based boards.
+ *
+ * Copyright (C) 2011 Heiko Schocher <hsdenx.de>
+ *
+ * based on:
+ * National Semiconductor DP83848 PHY Driver for TI DaVinci
+ * (TMS320DM644x) based boards.
+ *
+ * Copyright (C) 2007 Sergey Kubushyn <ksi@koi8.net>
+ *
+ * --------------------------------------------------------
+ *
+ * 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 <miiphy.h>
+#include <net.h>
+#include <asm/arch/emac_defs.h>
+#include <asm/io.h>
+
+int ksz8873_is_phy_connected(int phy_addr)
+{
+	u_int16_t	dummy;
+
+	return davinci_eth_phy_read(phy_addr, MII_PHYSID1, &dummy);
+}
+
+int ksz8873_get_link_speed(int phy_addr)
+{
+	emac_regs *emac = (emac_regs *)EMAC_BASE_ADDR;
+
+	/* we always have a link to the switch, 100 FD */
+	writel((EMAC_MACCONTROL_MIIEN_ENABLE |
+		EMAC_MACCONTROL_FULLDUPLEX_ENABLE),
+	       &emac->MACCONTROL);
+	return 1;
+}
+
+
+int ksz8873_init_phy(int phy_addr)
+{
+	return 1;
+}
+
+
+int ksz8873_auto_negotiate(int phy_addr)
+{
+	return dp83848_get_link_speed(phy_addr);
+}
diff --git a/arch/arm/cpu/arm926ejs/davinci/timer.c b/arch/arm/cpu/arm926ejs/davinci/timer.c
index 8b1734c..c7bf7a5 100644
--- a/arch/arm/cpu/arm926ejs/davinci/timer.c
+++ b/arch/arm/cpu/arm926ejs/davinci/timer.c
@@ -39,23 +39,10 @@
 
 #include <common.h>
 #include <asm/io.h>
+#include <asm/arch/timer_defs.h>
 
 DECLARE_GLOBAL_DATA_PTR;
 
-struct davinci_timer {
-	u_int32_t	pid12;
-	u_int32_t	emumgt;
-	u_int32_t	na1;
-	u_int32_t	na2;
-	u_int32_t	tim12;
-	u_int32_t	tim34;
-	u_int32_t	prd12;
-	u_int32_t	prd34;
-	u_int32_t	tcr;
-	u_int32_t	tgcr;
-	u_int32_t	wdtcr;
-};
-
 static struct davinci_timer * const timer =
 	(struct davinci_timer *)CONFIG_SYS_TIMERBASE;
 
@@ -121,3 +108,34 @@
 {
 	return CONFIG_SYS_HZ;
 }
+
+#ifdef CONFIG_HW_WATCHDOG
+static struct davinci_timer * const wdttimer =
+	(struct davinci_timer *)CONFIG_SYS_WDTTIMERBASE;
+
+/*
+ * See prufw2.pdf for using Timer as a WDT
+ */
+void davinci_hw_watchdog_enable(void)
+{
+	writel(0x0, &wdttimer->tcr);
+	writel(0x0, &wdttimer->tgcr);
+	/* TIMMODE = 2h */
+	writel(0x08 | 0x03 | ((TIM_CLK_DIV - 1) << 8), &wdttimer->tgcr);
+	writel(CONFIG_SYS_WDT_PERIOD_LOW, &wdttimer->prd12);
+	writel(CONFIG_SYS_WDT_PERIOD_HIGH, &wdttimer->prd34);
+	writel(2 << 22, &wdttimer->tcr);
+	writel(0x0, &wdttimer->tim12);
+	writel(0x0, &wdttimer->tim34);
+	/* set WDEN bit, WDKEY 0xa5c6 */
+	writel(0xa5c64000, &wdttimer->wdtcr);
+	/* clear counter register */
+	writel(0xda7e4000, &wdttimer->wdtcr);
+}
+
+void davinci_hw_watchdog_reset(void)
+{
+	writel(0xa5c64000, &wdttimer->wdtcr);
+	writel(0xda7e4000, &wdttimer->wdtcr);
+}
+#endif
diff --git a/arch/arm/cpu/arm926ejs/mx25/generic.c b/arch/arm/cpu/arm926ejs/mx25/generic.c
index 76e4b5c..8e60a26 100644
--- a/arch/arm/cpu/arm926ejs/mx25/generic.c
+++ b/arch/arm/cpu/arm926ejs/mx25/generic.c
@@ -105,13 +105,64 @@
 	return lldiv (fref, div);
 }
 
+u32 get_cpu_rev(void)
+{
+	u32 srev;
+	u32 system_rev = 0x25000;
+
+	/* read SREV register from IIM module */
+	struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE;
+	srev = readl(&iim->iim_srev);
+
+	switch (srev) {
+	case 0x00:
+		system_rev |= CHIP_REV_1_0;
+		break;
+	case 0x01:
+		system_rev |= CHIP_REV_1_1;
+		break;
+	default:
+		system_rev |= 0x8000;
+		break;
+	}
+
+	return system_rev;
+}
+
 #if defined(CONFIG_DISPLAY_CPUINFO)
+static char *get_reset_cause(void)
+{
+	/* read RCSR register from CCM module */
+	struct ccm_regs *ccm =
+		(struct ccm_regs *)IMX_CCM_BASE;
+
+	u32 cause = readl(&ccm->rcsr) & 0x0f;
+
+	if (cause == 0)
+		return "POR";
+	else if (cause == 1)
+		return "RST";
+	else if ((cause & 2) == 2)
+		return "WDOG";
+	else if ((cause & 4) == 4)
+		return "SW RESET";
+	else if ((cause & 8) == 8)
+		return "JTAG";
+	else
+		return "unknown reset";
+
+}
+
 int print_cpuinfo (void)
 {
 	char buf[32];
+	u32 cpurev = get_cpu_rev();
 
-	printf ("CPU:   Freescale i.MX25 at %s MHz\n\n",
+	printf("CPU:   Freescale i.MX25 rev%d.%d%s at %s MHz\n",
+		(cpurev & 0xF0) >> 4, (cpurev & 0x0F),
+		((cpurev & 0x8000) ? " unknown" : ""),
 		strmhz (buf, imx_get_armclk ()));
+	printf("Reset cause: %s\n\n", get_reset_cause());
 	return 0;
 }
 #endif
diff --git a/arch/arm/cpu/arm926ejs/start.S b/arch/arm/cpu/arm926ejs/start.S
index d164d6d..5e30745 100644
--- a/arch/arm/cpu/arm926ejs/start.S
+++ b/arch/arm/cpu/arm926ejs/start.S
@@ -51,9 +51,18 @@
  */
 
 
+#ifdef CONFIG_SYS_DV_NOR_BOOT_CFG
+.globl _start
+_start:
+.globl _NOR_BOOT_CFG
+_NOR_BOOT_CFG:
+	.word	CONFIG_SYS_DV_NOR_BOOT_CFG
+	b	reset
+#else
 .globl _start
 _start:
 	b	reset
+#endif
 #ifdef CONFIG_SPL_BUILD
 /* No exception handlers in preloader */
 	ldr	pc, _hang
diff --git a/arch/arm/cpu/armv7/mx5/clock.c b/arch/arm/cpu/armv7/mx5/clock.c
index 00610a0..0769a64 100644
--- a/arch/arm/cpu/armv7/mx5/clock.c
+++ b/arch/arm/cpu/armv7/mx5/clock.c
@@ -29,11 +29,13 @@
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/crm_regs.h>
 #include <asm/arch/clock.h>
+#include <div64.h>
 
 enum pll_clocks {
 	PLL1_CLOCK = 0,
 	PLL2_CLOCK,
 	PLL3_CLOCK,
+	PLL4_CLOCK,
 	PLL_CLOCKS,
 };
 
@@ -41,25 +43,65 @@
 	[PLL1_CLOCK] = (struct mxc_pll_reg *)PLL1_BASE_ADDR,
 	[PLL2_CLOCK] = (struct mxc_pll_reg *)PLL2_BASE_ADDR,
 	[PLL3_CLOCK] = (struct mxc_pll_reg *)PLL3_BASE_ADDR,
+#ifdef	CONFIG_MX53
+	[PLL4_CLOCK] = (struct mxc_pll_reg *)PLL4_BASE_ADDR,
+#endif
 };
 
 struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE;
 
 /*
- * Calculate the frequency of this pll.
+ * Calculate the frequency of PLLn.
  */
-static u32 decode_pll(struct mxc_pll_reg *pll, u32 infreq)
+static uint32_t decode_pll(struct mxc_pll_reg *pll, uint32_t infreq)
 {
-	u32 mfi, mfn, mfd, pd;
+	uint32_t ctrl, op, mfd, mfn, mfi, pdf, ret;
+	uint64_t refclk, temp;
+	int32_t mfn_abs;
 
-	mfn = __raw_readl(&pll->mfn);
-	mfd = __raw_readl(&pll->mfd) + 1;
-	mfi = __raw_readl(&pll->op);
-	pd = (mfi  & 0xF) + 1;
-	mfi = (mfi >> 4) & 0xF;
-	mfi = (mfi >= 5) ? mfi : 5;
+	ctrl = readl(&pll->ctrl);
 
-	return ((4 * (infreq / 1000) * (mfi * mfd + mfn)) / (mfd * pd)) * 1000;
+	if (ctrl & MXC_DPLLC_CTL_HFSM) {
+		mfn = __raw_readl(&pll->hfs_mfn);
+		mfd = __raw_readl(&pll->hfs_mfd);
+		op = __raw_readl(&pll->hfs_op);
+	} else {
+		mfn = __raw_readl(&pll->mfn);
+		mfd = __raw_readl(&pll->mfd);
+		op = __raw_readl(&pll->op);
+	}
+
+	mfd &= MXC_DPLLC_MFD_MFD_MASK;
+	mfn &= MXC_DPLLC_MFN_MFN_MASK;
+	pdf = op & MXC_DPLLC_OP_PDF_MASK;
+	mfi = (op & MXC_DPLLC_OP_MFI_MASK) >> MXC_DPLLC_OP_MFI_OFFSET;
+
+	/* 21.2.3 */
+	if (mfi < 5)
+		mfi = 5;
+
+	/* Sign extend */
+	if (mfn >= 0x04000000) {
+		mfn |= 0xfc000000;
+		mfn_abs = -mfn;
+	} else
+		mfn_abs = mfn;
+
+	refclk = infreq * 2;
+	if (ctrl & MXC_DPLLC_CTL_DPDCK0_2_EN)
+		refclk *= 2;
+
+	refclk /= pdf + 1;
+	temp = refclk * mfn_abs;
+	do_div(temp, mfd + 1);
+	ret = refclk * mfi;
+
+	if ((int)mfn < 0)
+		ret -= temp;
+	else
+		ret += temp;
+
+	return ret;
 }
 
 /*
@@ -99,18 +141,35 @@
 }
 
 /*
+ * Get the rate of ahb clock.
+ */
+static u32 get_ahb_clk(void)
+{
+	uint32_t freq, div, reg;
+
+	freq = get_periph_clk();
+
+	reg = __raw_readl(&mxc_ccm->cbcdr);
+	div = ((reg & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
+			MXC_CCM_CBCDR_AHB_PODF_OFFSET) + 1;
+
+	return freq / div;
+}
+
+/*
  * Get the rate of ipg clock.
  */
 static u32 get_ipg_clk(void)
 {
-	u32 ahb_podf, ipg_podf;
+	uint32_t freq, reg, div;
 
-	ahb_podf = __raw_readl(&mxc_ccm->cbcdr);
-	ipg_podf = (ahb_podf & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
-			MXC_CCM_CBCDR_IPG_PODF_OFFSET;
-	ahb_podf = (ahb_podf & MXC_CCM_CBCDR_AHB_PODF_MASK) >>
-			MXC_CCM_CBCDR_AHB_PODF_OFFSET;
-	return get_periph_clk() / ((ahb_podf + 1) * (ipg_podf + 1));
+	freq = get_ahb_clk();
+
+	reg = __raw_readl(&mxc_ccm->cbcdr);
+	div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >>
+			MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1;
+
+	return freq / div;
 }
 
 /*
@@ -237,7 +296,7 @@
 	case MXC_ARM_CLK:
 		return get_mcu_main_clk();
 	case MXC_AHB_CLK:
-		break;
+		return get_ahb_clk();
 	case MXC_IPG_CLK:
 		return get_ipg_clk();
 	case MXC_IPG_PERCLK:
@@ -274,13 +333,20 @@
 	u32 freq;
 
 	freq = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_SYS_MX5_HCLK);
-	printf("pll1: %dMHz\n", freq / 1000000);
+	printf("PLL1       %8d MHz\n", freq / 1000000);
 	freq = decode_pll(mxc_plls[PLL2_CLOCK], CONFIG_SYS_MX5_HCLK);
-	printf("pll2: %dMHz\n", freq / 1000000);
+	printf("PLL2       %8d MHz\n", freq / 1000000);
 	freq = decode_pll(mxc_plls[PLL3_CLOCK], CONFIG_SYS_MX5_HCLK);
-	printf("pll3: %dMHz\n", freq / 1000000);
-	printf("ipg clock     : %dHz\n", mxc_get_clock(MXC_IPG_CLK));
-	printf("ipg per clock : %dHz\n", mxc_get_clock(MXC_IPG_PERCLK));
+	printf("PLL3       %8d MHz\n", freq / 1000000);
+#ifdef	CONFIG_MX53
+	freq = decode_pll(mxc_plls[PLL4_CLOCK], CONFIG_SYS_MX5_HCLK);
+	printf("PLL4       %8d MHz\n", freq / 1000000);
+#endif
+
+	printf("\n");
+	printf("AHB        %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
+	printf("IPG        %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
+	printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000);
 
 	return 0;
 }
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile
index ea9f8ec..0b96b47 100644
--- a/arch/arm/cpu/armv7/omap-common/Makefile
+++ b/arch/arm/cpu/armv7/omap-common/Makefile
@@ -33,6 +33,12 @@
 
 ifdef CONFIG_SPL_BUILD
 COBJS	+= spl.o
+ifdef CONFIG_SPL_NAND_SUPPORT
+COBJS	+= spl_nand.o
+endif
+ifdef CONFIG_SPL_MMC_SUPPORT
+COBJS	+= spl_mmc.o
+endif
 endif
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
diff --git a/arch/arm/cpu/armv7/omap-common/spl.c b/arch/arm/cpu/armv7/omap-common/spl.c
index d177652..c76fea6 100644
--- a/arch/arm/cpu/armv7/omap-common/spl.c
+++ b/arch/arm/cpu/armv7/omap-common/spl.c
@@ -26,6 +26,7 @@
 #include <asm/u-boot.h>
 #include <asm/utils.h>
 #include <asm/arch/sys_proto.h>
+#include <nand.h>
 #include <mmc.h>
 #include <fat.h>
 #include <timestamp_autogenerated.h>
@@ -37,14 +38,11 @@
 
 DECLARE_GLOBAL_DATA_PTR;
 
+struct spl_image_info spl_image;
+
 /* Define global data structure pointer to it*/
 static gd_t gdata __attribute__ ((section(".data")));
 static bd_t bdata __attribute__ ((section(".data")));
-static const char *image_name;
-static u8 image_os;
-static u32 image_load_addr;
-static u32 image_entry_point;
-static u32 image_size;
 
 inline void hang(void)
 {
@@ -65,154 +63,40 @@
 	relocate_code(CONFIG_SPL_STACK, &gdata, CONFIG_SPL_TEXT_BASE);
 }
 
-#ifdef CONFIG_GENERIC_MMC
-int board_mmc_init(bd_t *bis)
-{
-	switch (omap_boot_device()) {
-	case BOOT_DEVICE_MMC1:
-		omap_mmc_init(0);
-		break;
-	case BOOT_DEVICE_MMC2:
-		omap_mmc_init(1);
-		break;
-	}
-	return 0;
-}
-#endif
-
-static void parse_image_header(const struct image_header *header)
+void spl_parse_image_header(const struct image_header *header)
 {
 	u32 header_size = sizeof(struct image_header);
 
 	if (__be32_to_cpu(header->ih_magic) == IH_MAGIC) {
-		image_size = __be32_to_cpu(header->ih_size) + header_size;
-		image_entry_point = __be32_to_cpu(header->ih_load);
+		spl_image.size = __be32_to_cpu(header->ih_size) + header_size;
+		spl_image.entry_point = __be32_to_cpu(header->ih_load);
 		/* Load including the header */
-		image_load_addr = image_entry_point - header_size;
-		image_os = header->ih_os;
-		image_name = (const char *)&header->ih_name;
+		spl_image.load_addr = spl_image.entry_point - header_size;
+		spl_image.os = header->ih_os;
+		spl_image.name = (const char *)&header->ih_name;
 		debug("spl: payload image: %s load addr: 0x%x size: %d\n",
-			image_name, image_load_addr, image_size);
+			spl_image.name, spl_image.load_addr, spl_image.size);
 	} else {
 		/* Signature not found - assume u-boot.bin */
 		printf("mkimage signature not found - ih_magic = %x\n",
 			header->ih_magic);
 		puts("Assuming u-boot.bin ..\n");
 		/* Let's assume U-Boot will not be more than 200 KB */
-		image_size = 200 * 1024;
-		image_entry_point = CONFIG_SYS_TEXT_BASE;
-		image_load_addr = CONFIG_SYS_TEXT_BASE;
-		image_os = IH_OS_U_BOOT;
-		image_name = "U-Boot";
+		spl_image.size = 200 * 1024;
+		spl_image.entry_point = CONFIG_SYS_TEXT_BASE;
+		spl_image.load_addr = CONFIG_SYS_TEXT_BASE;
+		spl_image.os = IH_OS_U_BOOT;
+		spl_image.name = "U-Boot";
 	}
 }
 
-static void mmc_load_image_raw(struct mmc *mmc)
-{
-	u32 image_size_sectors, err;
-	const struct image_header *header;
-
-	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
-						sizeof(struct image_header));
-
-	/* read image header to find the image size & load address */
-	err = mmc->block_dev.block_read(0,
-			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1,
-			(void *)header);
-
-	if (err <= 0)
-		goto end;
-
-	parse_image_header(header);
-
-	/* convert size to sectors - round up */
-	image_size_sectors = (image_size + MMCSD_SECTOR_SIZE - 1) /
-				MMCSD_SECTOR_SIZE;
-
-	/* Read the header too to avoid extra memcpy */
-	err = mmc->block_dev.block_read(0,
-			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR,
-			image_size_sectors, (void *)image_load_addr);
-
-end:
-	if (err <= 0) {
-		printf("spl: mmc blk read err - %d\n", err);
-		hang();
-	}
-}
-
-static void mmc_load_image_fat(struct mmc *mmc)
-{
-	s32 err;
-	struct image_header *header;
-
-	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
-						sizeof(struct image_header));
-
-	err = fat_register_device(&mmc->block_dev,
-				CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION);
-	if (err) {
-		printf("spl: fat register err - %d\n", err);
-		hang();
-	}
-
-	err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
-				(u8 *)header, sizeof(struct image_header));
-	if (err <= 0)
-		goto end;
-
-	parse_image_header(header);
-
-	err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
-				(u8 *)image_load_addr, 0);
-
-end:
-	if (err <= 0) {
-		printf("spl: error reading image %s, err - %d\n",
-			CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err);
-		hang();
-	}
-}
-
-static void mmc_load_image(void)
-{
-	struct mmc *mmc;
-	int err;
-	u32 boot_mode;
-
-	mmc_initialize(gd->bd);
-	/* We register only one device. So, the dev id is always 0 */
-	mmc = find_mmc_device(0);
-	if (!mmc) {
-		puts("spl: mmc device not found!!\n");
-		hang();
-	}
-
-	err = mmc_init(mmc);
-	if (err) {
-		printf("spl: mmc init failed: err - %d\n", err);
-		hang();
-	}
-
-	boot_mode = omap_boot_mode();
-	if (boot_mode == MMCSD_MODE_RAW) {
-		debug("boot mode - RAW\n");
-		mmc_load_image_raw(mmc);
-	} else if (boot_mode == MMCSD_MODE_FAT) {
-		debug("boot mode - FAT\n");
-		mmc_load_image_fat(mmc);
-	} else {
-		puts("spl: wrong MMC boot mode\n");
-		hang();
-	}
-}
-
-void jump_to_image_no_args(void)
+static void jump_to_image_no_args(void)
 {
 	typedef void (*image_entry_noargs_t)(void)__attribute__ ((noreturn));
 	image_entry_noargs_t image_entry =
-			(image_entry_noargs_t) image_entry_point;
+			(image_entry_noargs_t) spl_image.entry_point;
 
+	debug("image entry point: 0x%X\n", spl_image.entry_point);
 	image_entry();
 }
 
@@ -228,17 +112,24 @@
 	boot_device = omap_boot_device();
 	debug("boot device - %d\n", boot_device);
 	switch (boot_device) {
+#ifdef CONFIG_SPL_MMC_SUPPORT
 	case BOOT_DEVICE_MMC1:
 	case BOOT_DEVICE_MMC2:
-		mmc_load_image();
+		spl_mmc_load_image();
 		break;
+#endif
+#ifdef CONFIG_SPL_NAND_SUPPORT
+	case BOOT_DEVICE_NAND:
+		spl_nand_load_image();
+		break;
+#endif
 	default:
 		printf("SPL: Un-supported Boot Device - %d!!!\n", boot_device);
 		hang();
 		break;
 	}
 
-	switch (image_os) {
+	switch (spl_image.os) {
 	case IH_OS_U_BOOT:
 		debug("Jumping to U-Boot\n");
 		jump_to_image_no_args();
@@ -249,6 +140,7 @@
 	}
 }
 
+/* This requires UART clocks to be enabled */
 void preloader_console_init(void)
 {
 	const char *u_boot_rev = U_BOOT_VERSION;
@@ -259,7 +151,6 @@
 	gd->flags |= GD_FLG_RELOC;
 	gd->baudrate = CONFIG_BAUDRATE;
 
-	setup_clocks_for_console();
 	serial_init();		/* serial communications setup */
 
 	/* Avoid a second "U-Boot" coming from this string */
diff --git a/arch/arm/cpu/armv7/omap-common/spl_mmc.c b/arch/arm/cpu/armv7/omap-common/spl_mmc.c
new file mode 100644
index 0000000..1d1e50c
--- /dev/null
+++ b/arch/arm/cpu/armv7/omap-common/spl_mmc.c
@@ -0,0 +1,150 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Aneesh V <aneesh@ti.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 <asm/u-boot.h>
+#include <asm/utils.h>
+#include <asm/arch/sys_proto.h>
+#include <mmc.h>
+#include <fat.h>
+#include <timestamp_autogenerated.h>
+#include <version_autogenerated.h>
+#include <asm/omap_common.h>
+#include <asm/arch/mmc_host_def.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_GENERIC_MMC
+int board_mmc_init(bd_t *bis)
+{
+	switch (omap_boot_device()) {
+	case BOOT_DEVICE_MMC1:
+		omap_mmc_init(0);
+		break;
+	case BOOT_DEVICE_MMC2:
+		omap_mmc_init(1);
+		break;
+	}
+	return 0;
+}
+#endif
+
+static void mmc_load_image_raw(struct mmc *mmc)
+{
+	u32 image_size_sectors, err;
+	const struct image_header *header;
+
+	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
+						sizeof(struct image_header));
+
+	/* read image header to find the image size & load address */
+	err = mmc->block_dev.block_read(0,
+			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1,
+			(void *)header);
+
+	if (err <= 0)
+		goto end;
+
+	spl_parse_image_header(header);
+
+	/* convert size to sectors - round up */
+	image_size_sectors = (spl_image.size + MMCSD_SECTOR_SIZE - 1) /
+				MMCSD_SECTOR_SIZE;
+
+	/* Read the header too to avoid extra memcpy */
+	err = mmc->block_dev.block_read(0,
+			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR,
+			image_size_sectors, (void *)spl_image.load_addr);
+
+end:
+	if (err <= 0) {
+		printf("spl: mmc blk read err - %d\n", err);
+		hang();
+	}
+}
+
+static void mmc_load_image_fat(struct mmc *mmc)
+{
+	s32 err;
+	struct image_header *header;
+
+	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
+						sizeof(struct image_header));
+
+	err = fat_register_device(&mmc->block_dev,
+				CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION);
+	if (err) {
+		printf("spl: fat register err - %d\n", err);
+		hang();
+	}
+
+	err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
+				(u8 *)header, sizeof(struct image_header));
+	if (err <= 0)
+		goto end;
+
+	spl_parse_image_header(header);
+
+	err = file_fat_read(CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME,
+				(u8 *)spl_image.load_addr, 0);
+
+end:
+	if (err <= 0) {
+		printf("spl: error reading image %s, err - %d\n",
+			CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME, err);
+		hang();
+	}
+}
+
+void spl_mmc_load_image(void)
+{
+	struct mmc *mmc;
+	int err;
+	u32 boot_mode;
+
+	mmc_initialize(gd->bd);
+	/* We register only one device. So, the dev id is always 0 */
+	mmc = find_mmc_device(0);
+	if (!mmc) {
+		puts("spl: mmc device not found!!\n");
+		hang();
+	}
+
+	err = mmc_init(mmc);
+	if (err) {
+		printf("spl: mmc init failed: err - %d\n", err);
+		hang();
+	}
+	boot_mode = omap_boot_mode();
+	if (boot_mode == MMCSD_MODE_RAW) {
+		debug("boot mode - RAW\n");
+		mmc_load_image_raw(mmc);
+	} else if (boot_mode == MMCSD_MODE_FAT) {
+		debug("boot mode - FAT\n");
+		mmc_load_image_fat(mmc);
+	} else {
+		puts("spl: wrong MMC boot mode\n");
+		hang();
+	}
+}
diff --git a/arch/arm/cpu/armv7/omap-common/spl_nand.c b/arch/arm/cpu/armv7/omap-common/spl_nand.c
new file mode 100644
index 0000000..af02a59
--- /dev/null
+++ b/arch/arm/cpu/armv7/omap-common/spl_nand.c
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.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 <asm/u-boot.h>
+#include <asm/utils.h>
+#include <asm/arch/sys_proto.h>
+#include <nand.h>
+#include <timestamp_autogenerated.h>
+#include <version_autogenerated.h>
+#include <asm/omap_common.h>
+
+
+void spl_nand_load_image(void)
+{
+	struct image_header *header;
+	switch (omap_boot_mode()) {
+	case NAND_MODE_HW_ECC:
+		debug("spl: nand - using hw ecc\n");
+		gpmc_init();
+		nand_init();
+		break;
+	default:
+		puts("spl: ERROR: This bootmode is not implemented - hanging");
+		hang();
+	}
+
+	/*use CONFIG_SYS_TEXT_BASE as temporary storage area */
+	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE);
+
+#ifdef CONFIG_NAND_ENV_DST
+	nand_spl_load_image(CONFIG_ENV_OFFSET,
+		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+	spl_parse_image_header(header);
+	nand_spl_load_image(CONFIG_ENV_OFFSET, spl_image.size,
+		(void *)image_load_addr);
+#ifdef CONFIG_ENV_OFFSET_REDUND
+	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND,
+		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+	spl_parse_image_header(header);
+	nand_spl_load_image(CONFIG_ENV_OFFSET_REDUND, spl_image.size,
+		(void *)image_load_addr);
+#endif
+#endif
+	/* Load u-boot */
+	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+		CONFIG_SYS_NAND_PAGE_SIZE, (void *)header);
+	spl_parse_image_header(header);
+	nand_spl_load_image(CONFIG_SYS_NAND_U_BOOT_OFFS,
+		spl_image.size, (void *)spl_image.load_addr);
+	nand_deselect();
+}
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c
index 0448bc9..1b3ef69 100644
--- a/arch/arm/cpu/armv7/omap3/board.c
+++ b/arch/arm/cpu/armv7/omap3/board.c
@@ -39,6 +39,7 @@
 #include <asm/cache.h>
 #include <asm/armv7.h>
 #include <asm/arch/gpio.h>
+#include <asm/omap_common.h>
 
 /* Declarations */
 extern omap3_sysinfo sysinfo;
@@ -56,6 +57,41 @@
 
 const struct gpio_bank *const omap_gpio_bank = gpio_bank_34xx;
 
+#ifdef CONFIG_SPL_BUILD
+/*
+* We use static variables because global data is not ready yet.
+* Initialized data is available in SPL right from the beginning.
+* We would not typically need to save these parameters in regular
+* U-Boot. This is needed only in SPL at the moment.
+*/
+u32 omap3_boot_device = BOOT_DEVICE_NAND;
+
+/* auto boot mode detection is not possible for OMAP3 - hard code */
+u32 omap_boot_mode(void)
+{
+	switch (omap_boot_device()) {
+	case BOOT_DEVICE_MMC2:
+		return MMCSD_MODE_RAW;
+	case BOOT_DEVICE_MMC1:
+		return MMCSD_MODE_FAT;
+		break;
+	case BOOT_DEVICE_NAND:
+		return NAND_MODE_HW_ECC;
+		break;
+	default:
+		puts("spl: ERROR:  unknown device - can't select boot mode\n");
+		hang();
+	}
+}
+
+u32 omap_boot_device(void)
+{
+	return omap3_boot_device;
+}
+
+#endif /* CONFIG_SPL_BUILD */
+
+
 /******************************************************************************
  * Routine: delay
  * Description: spinning delay to use before udelay works
@@ -197,6 +233,10 @@
 
 	per_clocks_enable();
 
+#ifdef CONFIG_SPL_BUILD
+	preloader_console_init();
+#endif
+
 	if (!in_sdram)
 		mem_init();
 }
@@ -245,7 +285,7 @@
 {
 }
 
-#ifdef CONFIG_NAND_OMAP_GPMC
+#if defined(CONFIG_NAND_OMAP_GPMC) & !defined(CONFIG_SPL_BUILD)
 /******************************************************************************
  * OMAP3 specific command to switch between NAND HW and SW ecc
  *****************************************************************************/
@@ -273,7 +313,7 @@
 	"[hw/sw] - Switch between NAND hardware (hw) or software (sw) ecc algorithm"
 );
 
-#endif /* CONFIG_NAND_OMAP_GPMC */
+#endif /* CONFIG_NAND_OMAP_GPMC & !CONFIG_SPL_BUILD */
 
 #ifdef CONFIG_DISPLAY_BOARDINFO
 /**
@@ -410,3 +450,9 @@
 	dcache_enable();
 }
 #endif
+
+void omap_rev_string(char *omap_rev_string)
+{
+	sprintf(omap_rev_string, "OMAP3, sorry revision detection" \
+		" unimplemented");
+}
diff --git a/arch/arm/cpu/armv7/omap3/config.mk b/arch/arm/cpu/armv7/omap3/config.mk
new file mode 100644
index 0000000..b34fa64
--- /dev/null
+++ b/arch/arm/cpu/armv7/omap3/config.mk
@@ -0,0 +1,30 @@
+#
+# Copyright 2011 Linaro Limited
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# (C) Copyright 2010
+# Texas Instruments, <www.ti.com>
+#
+# Aneesh V <aneesh@ti.com>
+#
+# 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
+#
+ifdef CONFIG_SPL_BUILD
+ALL-y	+= $(OBJTREE)/MLO
+else
+ALL-y	+= $(obj)u-boot.img
+endif
diff --git a/arch/arm/cpu/armv7/omap3/lowlevel_init.S b/arch/arm/cpu/armv7/omap3/lowlevel_init.S
index 67e8ceb5..a308ebd 100644
--- a/arch/arm/cpu/armv7/omap3/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/omap3/lowlevel_init.S
@@ -35,6 +35,16 @@
 _TEXT_BASE:
 	.word	CONFIG_SYS_TEXT_BASE	/* sdram load addr from config.mk */
 
+.global save_boot_params
+save_boot_params:
+#ifdef CONFIG_SPL_BUILD
+	ldr	r4, =omap3_boot_device
+	ldr	r5, [r0, #0x4]
+	and	r5, r5, #0xff
+	str	r5, [r4]
+#endif
+	bx	lr
+
 .global omap3_gp_romcode_call
 omap3_gp_romcode_call:
 	PUSH {r4-r12, lr} @ Save all registers from ROM code!
diff --git a/arch/arm/cpu/armv7/omap3/sdrc.c b/arch/arm/cpu/armv7/omap3/sdrc.c
index 2a7970b..0dd1955 100644
--- a/arch/arm/cpu/armv7/omap3/sdrc.c
+++ b/arch/arm/cpu/armv7/omap3/sdrc.c
@@ -8,6 +8,9 @@
  * Copyright (C) 2004-2010
  * Texas Instruments Incorporated - http://www.ti.com/
  *
+ * Copyright (C) 2011
+ * Corscience GmbH & Co. KG - Simon Schwarz <schwarz@corscience.de>
+ *
  * Author :
  *     Vaibhav Hiremath <hvaibhav@ti.com>
  *
@@ -133,13 +136,40 @@
 		sdelay(0x20000);
 	}
 
+/* As long as V_MCFG and V_RFR_CTRL is not defined for all OMAP3 boards we need
+ * to prevent this to be build in non-SPL build */
+#ifdef CONFIG_SPL_BUILD
+	/* If we use a SPL there is no x-loader nor config header so we have
+	 * to do the job ourselfs
+	 */
+	if (cs == CS0) {
+		sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE;
+
+		/* General SDRC config */
+		writel(V_MCFG, &sdrc_base->cs[cs].mcfg);
+		writel(V_RFR_CTRL, &sdrc_base->cs[cs].rfr_ctrl);
+
+		/* AC timings */
+		writel(V_ACTIMA_165, &sdrc_actim_base0->ctrla);
+		writel(V_ACTIMB_165, &sdrc_actim_base0->ctrlb);
+
+		/* Initialize */
+		writel(CMD_NOP, &sdrc_base->cs[cs].manual);
+		writel(CMD_PRECHARGE, &sdrc_base->cs[cs].manual);
+		writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual);
+		writel(CMD_AUTOREFRESH, &sdrc_base->cs[cs].manual);
+
+		writel(V_MR, &sdrc_base->cs[cs].mr);
+	}
+#endif
+
 	/*
 	 * SDRC timings are set up by x-load or config header
 	 * We don't need to redo them here.
 	 * Older x-loads configure only CS0
 	 * configure CS1 to handle this ommission
 	 */
-	if (cs) {
+	if (cs == CS1) {
 		sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE;
 		sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE;
 		writel(readl(&sdrc_base->cs[CS0].mcfg),
diff --git a/arch/arm/cpu/armv7/omap3/sys_info.c b/arch/arm/cpu/armv7/omap3/sys_info.c
index bdb151d..22887ae 100644
--- a/arch/arm/cpu/armv7/omap3/sys_info.c
+++ b/arch/arm/cpu/armv7/omap3/sys_info.c
@@ -44,13 +44,13 @@
 				"UNKNOWN",
 				"UNKNOWN",
 				"3.1.2"};
-#endif /* CONFIG_DISPLAY_CPUINFO */
 
 /* this is the revision table for 37xx CPUs */
 static char *rev_s_37xx[CPU_37XX_MAX_REV] = {
 				"1.0",
 				"1.1",
 				"1.2"};
+#endif /* CONFIG_DISPLAY_CPUINFO */
 
 /*****************************************************************
  * dieid_num_r(void) - read and set die ID
diff --git a/arch/arm/cpu/armv7/omap4/board.c b/arch/arm/cpu/armv7/omap4/board.c
index 309b244..8584fdd 100644
--- a/arch/arm/cpu/armv7/omap4/board.c
+++ b/arch/arm/cpu/armv7/omap4/board.c
@@ -257,6 +257,7 @@
 	watchdog_init();
 	set_mux_conf_regs();
 #ifdef CONFIG_SPL_BUILD
+	setup_clocks_for_console();
 	preloader_console_init();
 	do_io_settings();
 #endif
diff --git a/arch/arm/include/asm/arch-armada100/armada100.h b/arch/arm/include/asm/arch-armada100/armada100.h
index d5d125a..c449d4e 100644
--- a/arch/arm/include/asm/arch-armada100/armada100.h
+++ b/arch/arm/include/asm/arch-armada100/armada100.h
@@ -41,8 +41,13 @@
 /* Functional Clock Selection Mask */
 #define APBC_FNCLKSEL(x)        (((x) & 0xf) << 4)
 
+/* Fast Ethernet Controller Clock register definition */
+#define FE_CLK_RST		0x1
+#define FE_CLK_ENA		0x8
+
 /* Register Base Addresses */
 #define ARMD1_DRAM_BASE		0xB0000000
+#define ARMD1_FEC_BASE		0xC0800000
 #define ARMD1_TIMER_BASE	0xD4014000
 #define ARMD1_APBC1_BASE	0xD4015000
 #define ARMD1_APBC2_BASE	0xD4015800
@@ -84,6 +89,59 @@
 };
 
 /*
+ * Application Subsystem Power Management
+ * Refer Datasheet Appendix A.9
+ */
+struct armd1apmu_registers {
+	u32 pcr;		/* 0x000 */
+	u32 ccr;		/* 0x004 */
+	u32 pad1;
+	u32 ccsr;		/* 0x00C */
+	u32 fc_timer;		/* 0x010 */
+	u32 pad2;
+	u32 ideal_cfg;		/* 0x018 */
+	u8 pad3[0x04C - 0x018 - 4];
+	u32 lcdcrc;		/* 0x04C */
+	u32 cciccrc;		/* 0x050 */
+	u32 sd1crc;		/* 0x054 */
+	u32 sd2crc;		/* 0x058 */
+	u32 usbcrc;		/* 0x05C */
+	u32 nfccrc;		/* 0x060 */
+	u32 dmacrc;		/* 0x064 */
+	u32 pad4;
+	u32 buscrc;		/* 0x06C */
+	u8 pad5[0x07C - 0x06C - 4];
+	u32 wake_clr;		/* 0x07C */
+	u8 pad6[0x090 - 0x07C - 4];
+	u32 core_status;	/* 0x090 */
+	u32 rfsc;		/* 0x094 */
+	u32 imr;		/* 0x098 */
+	u32 irwc;		/* 0x09C */
+	u32 isr;		/* 0x0A0 */
+	u8 pad7[0x0B0 - 0x0A0 - 4];
+	u32 mhst;		/* 0x0B0 */
+	u32 msr;		/* 0x0B4 */
+	u8 pad8[0x0C0 - 0x0B4 - 4];
+	u32 msst;		/* 0x0C0 */
+	u32 pllss;		/* 0x0C4 */
+	u32 smb;		/* 0x0C8 */
+	u32 gccrc;		/* 0x0CC */
+	u8 pad9[0x0D4 - 0x0CC - 4];
+	u32 smccrc;		/* 0x0D4 */
+	u32 pad10;
+	u32 xdcrc;		/* 0x0DC */
+	u32 sd3crc;		/* 0x0E0 */
+	u32 sd4crc;		/* 0x0E4 */
+	u8 pad11[0x0F0 - 0x0E4 - 4];
+	u32 cfcrc;		/* 0x0F0 */
+	u32 mspcrc;		/* 0x0F4 */
+	u32 cmucrc;		/* 0x0F8 */
+	u32 fecrc;		/* 0x0FC */
+	u32 pciecrc;		/* 0x100 */
+	u32 epdcrc;		/* 0x104 */
+};
+
+/*
  * APB1 Clock Reset/Control Registers
  * Refer Datasheet Appendix A.10
  */
diff --git a/arch/arm/include/asm/arch-armada100/gpio.h b/arch/arm/include/asm/arch-armada100/gpio.h
new file mode 100644
index 0000000..9e5e7b9
--- /dev/null
+++ b/arch/arm/include/asm/arch-armada100/gpio.h
@@ -0,0 +1,48 @@
+/*
+ * (C) Copyright 2011
+ * eInfochips Ltd. <www.einfochips.com>
+ * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
+ *
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef _ASM_ARCH_GPIO_H
+#define _ASM_ARCH_GPIO_H
+
+#include <asm/types.h>
+#include <asm/arch/armada100.h>
+
+#define GPIO_HIGH		1
+#define GPIO_LOW		0
+
+#define GPIO_TO_REG(gp)		(gp >> 5)
+#define GPIO_TO_BIT(gp)		(1 << (gp & 0x1F))
+#define GPIO_VAL(gp, val)	((val >> (gp & 0x1F)) & 0x01)
+
+static inline void *get_gpio_base(int bank)
+{
+	const unsigned int offset[4] = {0, 4, 8, 0x100};
+	/* gpio register bank offset - refer Appendix A.36 */
+	return (struct gpio_reg *)(ARMD1_GPIO_BASE + offset[bank]);
+}
+
+#endif /* _ASM_ARCH_GPIO_H */
diff --git a/arch/arm/include/asm/arch-armada100/mfp.h b/arch/arm/include/asm/arch-armada100/mfp.h
index d6e0494..da76b58 100644
--- a/arch/arm/include/asm/arch-armada100/mfp.h
+++ b/arch/arm/include/asm/arch-armada100/mfp.h
@@ -64,6 +64,25 @@
 #define MFP105_CI2C_SDA		(MFP_REG(0x1a4) | MFP_AF1 | MFP_DRIVE_MEDIUM)
 #define MFP106_CI2C_SCL		(MFP_REG(0x1a8) | MFP_AF1 | MFP_DRIVE_MEDIUM)
 
+/* Fast Ethernet */
+#define MFP086_ETH_TXCLK	(MFP_REG(0x158) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP087_ETH_TXEN		(MFP_REG(0x15C) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP088_ETH_TXDQ3	(MFP_REG(0x160) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP089_ETH_TXDQ2	(MFP_REG(0x164) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP090_ETH_TXDQ1	(MFP_REG(0x168) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP091_ETH_TXDQ0	(MFP_REG(0x16C) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP092_ETH_CRS		(MFP_REG(0x170) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP093_ETH_COL		(MFP_REG(0x174) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP094_ETH_RXCLK	(MFP_REG(0x178) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP095_ETH_RXER		(MFP_REG(0x17C) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP096_ETH_RXDQ3	(MFP_REG(0x180) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP097_ETH_RXDQ2	(MFP_REG(0x184) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP098_ETH_RXDQ1	(MFP_REG(0x188) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP099_ETH_RXDQ0	(MFP_REG(0x18C) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP100_ETH_MDC		(MFP_REG(0x190) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP101_ETH_MDIO		(MFP_REG(0x194) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+#define MFP103_ETH_RXDV		(MFP_REG(0x19C) | MFP_AF5 | MFP_DRIVE_MEDIUM)
+
 /* More macros can be defined here... */
 
 #define MFP_PIN_MAX	117
diff --git a/arch/arm/include/asm/arch-davinci/am1808_lowlevel.h b/arch/arm/include/asm/arch-davinci/am1808_lowlevel.h
new file mode 100644
index 0000000..0bc7f76
--- /dev/null
+++ b/arch/arm/include/asm/arch-davinci/am1808_lowlevel.h
@@ -0,0 +1,44 @@
+/*
+ * SoC-specific lowlevel code for AM1808 and similar chips
+ *
+ * Copyright (C) 2011
+ * Heiko Schocher, DENX Software Engineering, hs@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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+#ifndef __AM1808_LOWLEVEL_H
+#define __AM1808_LOWLEVEL_H
+
+/* NOR Boot Configuration Word Field Descriptions */
+#define AM1808_NORBOOT_COPY_XK(X)	((X - 1) << 8)
+#define AM1808_NORBOOT_METHOD_DIRECT	(1 << 4)
+#define AM1808_NORBOOT_16BIT		(1 << 0)
+
+#define dv_maskbits(addr, val) \
+	writel((readl(addr) & val), addr)
+
+void am1808_waitloop(unsigned long loopcnt);
+int am1808_pll_init(struct davinci_pllc_regs *reg, unsigned long pllmult);
+void am1808_lpc_transition(unsigned char pscnum, unsigned char module,
+		unsigned char domain, unsigned char state);
+int am1808_ddr_setup(unsigned int freq);
+void am1808_psc_init(void);
+void am1808_pinmux_ctl(unsigned long offset, unsigned long mask,
+	unsigned long value);
+
+#endif /* #ifndef __AM1808_LOWLEVEL_H */
diff --git a/arch/arm/include/asm/arch-davinci/ddr2_defs.h b/arch/arm/include/asm/arch-davinci/ddr2_defs.h
new file mode 100644
index 0000000..1b9430c
--- /dev/null
+++ b/arch/arm/include/asm/arch-davinci/ddr2_defs.h
@@ -0,0 +1,96 @@
+/*
+ * Copyright (C) 2011
+ * Heiko Schocher, DENX Software Engineering, hs@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
+ */
+#ifndef _DV_DDR2_DEFS_H_
+#define _DV_DDR2_DEFS_H_
+
+/*
+ * DDR2 Memory Ctrl Register structure
+ * See sprueh7d.pdf for more details.
+ */
+struct dv_ddr2_regs_ctrl {
+	unsigned char	rsvd0[4];	/* 0x00 */
+	unsigned int	sdrstat;	/* 0x04 */
+	unsigned int	sdbcr;		/* 0x08 */
+	unsigned int	sdrcr;		/* 0x0C */
+	unsigned int	sdtimr;		/* 0x10 */
+	unsigned int	sdtimr2;	/* 0x14 */
+	unsigned char	rsvd1[4];	/* 0x18 */
+	unsigned int	sdbcr2;		/* 0x1C */
+	unsigned int	pbbpr;		/* 0x20 */
+	unsigned char	rsvd2[156];	/* 0x24 */
+	unsigned int	irr;		/* 0xC0 */
+	unsigned int	imr;		/* 0xC4 */
+	unsigned int	imsr;		/* 0xC8 */
+	unsigned int	imcr;		/* 0xCC */
+	unsigned char	rsvd3[20];	/* 0xD0 */
+	unsigned int	ddrphycr;	/* 0xE4 */
+	unsigned int	ddrphycr2;	/* 0xE8 */
+	unsigned char	rsvd4[4];	/* 0xEC */
+};
+
+#define DV_DDR_PHY_PWRDNEN		0x40
+#define DV_DDR_PHY_EXT_STRBEN	0x80
+#define DV_DDR_PHY_RD_LATENCY_SHIFT	0
+
+#define DV_DDR_SDTMR1_RFC_SHIFT	25
+#define DV_DDR_SDTMR1_RP_SHIFT	22
+#define DV_DDR_SDTMR1_RCD_SHIFT	19
+#define DV_DDR_SDTMR1_WR_SHIFT	16
+#define DV_DDR_SDTMR1_RAS_SHIFT	11
+#define DV_DDR_SDTMR1_RC_SHIFT	6
+#define DV_DDR_SDTMR1_RRD_SHIFT	3
+#define DV_DDR_SDTMR1_WTR_SHIFT	0
+
+#define DV_DDR_SDTMR2_RASMAX_SHIFT	27
+#define DV_DDR_SDTMR2_XP_SHIFT	25
+#define DV_DDR_SDTMR2_XSNR_SHIFT	16
+#define DV_DDR_SDTMR2_XSRD_SHIFT	8
+#define DV_DDR_SDTMR2_RTP_SHIFT	5
+#define DV_DDR_SDTMR2_CKE_SHIFT	0
+
+#define DV_DDR_SDCR_DDR2TERM1_SHIFT	27
+#define DV_DDR_SDCR_IBANK_POS_SHIFT	26
+#define DV_DDR_SDCR_MSDRAMEN_SHIFT	25
+#define DV_DDR_SDCR_DDRDRIVE1_SHIFT	24
+#define DV_DDR_SDCR_BOOTUNLOCK_SHIFT	23
+#define DV_DDR_SDCR_DDR_DDQS_SHIFT	22
+#define DV_DDR_SDCR_DDR2EN_SHIFT	20
+#define DV_DDR_SDCR_DDRDRIVE0_SHIFT	18
+#define DV_DDR_SDCR_DDREN_SHIFT	17
+#define DV_DDR_SDCR_SDRAMEN_SHIFT	16
+#define DV_DDR_SDCR_TIMUNLOCK_SHIFT	15
+#define DV_DDR_SDCR_BUS_WIDTH_SHIFT	14
+#define DV_DDR_SDCR_CL_SHIFT		9
+#define DV_DDR_SDCR_IBANK_SHIFT	4
+#define DV_DDR_SDCR_PAGESIZE_SHIFT	0
+
+#define DV_DDR_SRCR_LPMODEN_SHIFT	31
+#define DV_DDR_SRCR_MCLKSTOPEN_SHIFT	30
+
+#define DV_DDR_BOOTUNLOCK	(1 << DV_DDR_SDCR_BOOTUNLOCK_SHIFT)
+#define DV_DDR_TIMUNLOCK	(1 << DV_DDR_SDCR_TIMUNLOCK_SHIFT)
+
+#define dv_ddr2_regs_ctrl \
+	((struct dv_ddr2_regs_ctrl *)DAVINCI_DDR_EMIF_CTRL_BASE)
+
+#endif /* _DV_DDR2_DEFS_H_ */
diff --git a/arch/arm/include/asm/arch-davinci/emac_defs.h b/arch/arm/include/asm/arch-davinci/emac_defs.h
index 4a4ee04..294a9a8 100644
--- a/arch/arm/include/asm/arch-davinci/emac_defs.h
+++ b/arch/arm/include/asm/arch-davinci/emac_defs.h
@@ -377,6 +377,12 @@
 	int	(*auto_negotiate)(int phy_addr);
 } phy_t;
 
+#define PHY_KSZ8873	(0x00221450)
+int ksz8873_is_phy_connected(int phy_addr);
+int ksz8873_get_link_speed(int phy_addr);
+int ksz8873_init_phy(int phy_addr);
+int ksz8873_auto_negotiate(int phy_addr);
+
 #define PHY_LXT972	(0x001378e2)
 int lxt972_is_phy_connected(int phy_addr);
 int lxt972_get_link_speed(int phy_addr);
diff --git a/arch/arm/include/asm/arch-davinci/gpio.h b/arch/arm/include/asm/arch-davinci/gpio.h
index 29dcccf..ef65ffb 100644
--- a/arch/arm/include/asm/arch-davinci/gpio.h
+++ b/arch/arm/include/asm/arch-davinci/gpio.h
@@ -35,6 +35,7 @@
 #define DAVINCI_GPIO_BANK23	0x01E26038
 #define DAVINCI_GPIO_BANK45	0x01E26060
 #define DAVINCI_GPIO_BANK67	0x01E26088
+#define DAVINCI_GPIO_BANK8	0x01E260B0
 #endif /* CONFIG_SOC_DA8XX */
 
 struct davinci_gpio {
@@ -62,6 +63,7 @@
 #define davinci_gpio_bank23 ((struct davinci_gpio *)DAVINCI_GPIO_BANK23)
 #define davinci_gpio_bank45 ((struct davinci_gpio *)DAVINCI_GPIO_BANK45)
 #define davinci_gpio_bank67 ((struct davinci_gpio *)DAVINCI_GPIO_BANK67)
+#define davinci_gpio_bank8 ((struct davinci_gpio *)DAVINCI_GPIO_BANK8)
 
 #define gpio_status()		gpio_info()
 #define GPIO_NAME_SIZE		20
diff --git a/arch/arm/include/asm/arch-davinci/hardware.h b/arch/arm/include/asm/arch-davinci/hardware.h
index 692d507..b6a3209 100644
--- a/arch/arm/include/asm/arch-davinci/hardware.h
+++ b/arch/arm/include/asm/arch-davinci/hardware.h
@@ -128,6 +128,7 @@
 #define DAVINCI_TIMER0_BASE			0x01c20000
 #define DAVINCI_TIMER1_BASE			0x01c21000
 #define DAVINCI_WDOG_BASE			0x01c21000
+#define DAVINCI_RTC_BASE			0x01c23000
 #define DAVINCI_PLL_CNTRL0_BASE			0x01c11000
 #define DAVINCI_PLL_CNTRL1_BASE			0x01e1a000
 #define DAVINCI_PSC0_BASE			0x01c10000
@@ -141,8 +142,11 @@
 #define DAVINCI_EMAC_WRAPPER_CNTRL_REGS_BASE	0x01e22000
 #define DAVINCI_EMAC_WRAPPER_RAM_BASE		0x01e20000
 #define DAVINCI_MDIO_CNTRL_REGS_BASE		0x01e24000
+#define DAVINCI_SYSCFG1_BASE			0x01e2c000
 #define DAVINCI_MMC_SD0_BASE			0x01c40000
 #define DAVINCI_MMC_SD1_BASE			0x01e1b000
+#define DAVINCI_TIMER2_BASE			0x01f0c000
+#define DAVINCI_TIMER3_BASE			0x01f0d000
 #define DAVINCI_ASYNC_EMIF_CNTRL_BASE		0x68000000
 #define DAVINCI_ASYNC_EMIF_DATA_CE0_BASE	0x40000000
 #define DAVINCI_ASYNC_EMIF_DATA_CE2_BASE	0x60000000
@@ -318,6 +322,11 @@
 
 #else /* CONFIG_SOC_DA8XX */
 
+#define	PSC_ENABLE		0x3
+#define	PSC_DISABLE		0x2
+#define	PSC_SYNCRESET		0x1
+#define	PSC_SWRSTDISABLE	0x0
+
 #define PSC_PSC0_MODULE_ID_CNT		16
 #define PSC_PSC1_MODULE_ID_CNT		32
 
@@ -445,6 +454,27 @@
 #define DAVINCI_SYSCFG_SUSPSRC_UART2		(1 << 20)
 #define DAVINCI_SYSCFG_SUSPSRC_TIMER0		(1 << 27)
 
+struct davinci_syscfg1_regs {
+	dv_reg	vtpio_ctl;
+	dv_reg	ddr_slew;
+	dv_reg	deepsleep;
+	dv_reg	pupd_ena;
+	dv_reg	pupd_sel;
+	dv_reg	rxactive;
+	dv_reg	pwrdwn;
+};
+
+#define davinci_syscfg1_regs \
+	((struct davinci_syscfg1_regs *)DAVINCI_SYSCFG1_BASE)
+
+#define DDR_SLEW_CMOSEN_BIT	4
+
+#define VTP_POWERDWN		(1 << 6)
+#define VTP_LOCK		(1 << 7)
+#define VTP_CLKRZ		(1 << 13)
+#define VTP_READY		(1 << 15)
+#define VTP_IOPWRDWN		(1 << 14)
+
 /* Interrupt controller */
 struct davinci_aintc_regs {
 	dv_reg	revid;
diff --git a/arch/arm/include/asm/arch-davinci/timer_defs.h b/arch/arm/include/asm/arch-davinci/timer_defs.h
new file mode 100644
index 0000000..53c961e
--- /dev/null
+++ b/arch/arm/include/asm/arch-davinci/timer_defs.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2011 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@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
+ */
+#ifndef _TIMER_DEFS_H_
+#define _TIMER_DEFS_H_
+
+struct davinci_timer {
+	u_int32_t	pid12;
+	u_int32_t	emumgt;
+	u_int32_t	na1;
+	u_int32_t	na2;
+	u_int32_t	tim12;
+	u_int32_t	tim34;
+	u_int32_t	prd12;
+	u_int32_t	prd34;
+	u_int32_t	tcr;
+	u_int32_t	tgcr;
+	u_int32_t	wdtcr;
+};
+
+#ifdef CONFIG_HW_WATCHDOG
+void davinci_hw_watchdog_enable(void);
+void davinci_hw_watchdog_reset(void);
+#endif
+#endif /* _TIMER_DEFS_H_ */
diff --git a/arch/arm/include/asm/arch-mx25/imx-regs.h b/arch/arm/include/asm/arch-mx25/imx-regs.h
index 9e30f7c..eece138 100644
--- a/arch/arm/include/asm/arch-mx25/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx25/imx-regs.h
@@ -36,7 +36,6 @@
 #ifndef __ASSEMBLY__
 #ifdef CONFIG_FEC_MXC
 extern void mx25_fec_init_pins(void);
-extern void imx_get_mac_from_fuse(unsigned char *mac);
 #endif
 
 /* Clock Control Module (CCM) registers */
@@ -351,4 +350,7 @@
 #define GPIO3_BASE_ADDR		IMX_GPIO3_BASE
 #define GPIO4_BASE_ADDR		IMX_GPIO4_BASE
 
+#define CHIP_REV_1_0		0x10
+#define CHIP_REV_1_1		0x11
+
 #endif				/* _IMX_REGS_H */
diff --git a/arch/arm/include/asm/arch-mx25/sys_proto.h b/arch/arm/include/asm/arch-mx25/sys_proto.h
new file mode 100644
index 0000000..6a01a7b0
--- /dev/null
+++ b/arch/arm/include/asm/arch-mx25/sys_proto.h
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2009
+ * Stefano Babic, DENX Software Engineering, sbabic@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
+ */
+
+#ifndef _SYS_PROTO_H_
+#define _SYS_PROTO_H_
+
+void mx25_uart1_init_pins(void);
+
+#endif
diff --git a/arch/arm/include/asm/arch-mx27/imx-regs.h b/arch/arm/include/asm/arch-mx27/imx-regs.h
index b4b2fe6..83ab216 100644
--- a/arch/arm/include/asm/arch-mx27/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx27/imx-regs.h
@@ -34,7 +34,6 @@
 
 #ifdef CONFIG_FEC_MXC
 extern void mx27_fec_init_pins(void);
-extern void imx_get_mac_from_fuse(unsigned char *mac);
 #endif /* CONFIG_FEC_MXC */
 
 #ifdef CONFIG_MXC_MMC
diff --git a/arch/arm/include/asm/arch-mx31/imx-regs.h b/arch/arm/include/asm/arch-mx31/imx-regs.h
index 2064870..0dcd9fe 100644
--- a/arch/arm/include/asm/arch-mx31/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx31/imx-regs.h
@@ -71,6 +71,8 @@
 /* Watchdog Timer (WDOG) registers */
 #define WDOG_ENABLE	(1 << 2)
 #define WDOG_WT_SHIFT	8
+#define WDOG_WDZST	(1 << 0)
+
 struct wdog_regs {
 	u16 wcr;	/* Control */
 	u16 wsr;	/* Service */
diff --git a/arch/arm/include/asm/arch-mx35/imx-regs.h b/arch/arm/include/asm/arch-mx35/imx-regs.h
index e741fb0..0c566f2 100644
--- a/arch/arm/include/asm/arch-mx35/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx35/imx-regs.h
@@ -178,8 +178,6 @@
 #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
 #include <asm/types.h>
 
-extern void imx_get_mac_from_fuse(unsigned char *mac);
-
 enum mxc_main_clocks {
 	CPU_CLK,
 	AHB_CLK,
diff --git a/arch/arm/include/asm/arch-mx5/crm_regs.h b/arch/arm/include/asm/arch-mx5/crm_regs.h
index 4ed8eb3..fcc0e36 100644
--- a/arch/arm/include/asm/arch-mx5/crm_regs.h
+++ b/arch/arm/include/asm/arch-mx5/crm_regs.h
@@ -200,4 +200,15 @@
 /* Define the bits in register CLPCR */
 #define MXC_CCM_CLPCR_BYPASS_IPU_LPM_HS                 (0x1 << 18)
 
+#define	MXC_DPLLC_CTL_HFSM				(1 << 7)
+#define	MXC_DPLLC_CTL_DPDCK0_2_EN			(1 << 12)
+
+#define	MXC_DPLLC_OP_PDF_MASK				0xf
+#define	MXC_DPLLC_OP_MFI_MASK				(0xf << 4)
+#define	MXC_DPLLC_OP_MFI_OFFSET				4
+
+#define	MXC_DPLLC_MFD_MFD_MASK				0x7ffffff
+
+#define	MXC_DPLLC_MFN_MFN_MASK				0x7ffffff
+
 #endif				/* __ARCH_ARM_MACH_MX51_CRM_REGS_H__ */
diff --git a/arch/arm/include/asm/arch-mx5/imx-regs.h b/arch/arm/include/asm/arch-mx5/imx-regs.h
index a4e680b..d069209 100644
--- a/arch/arm/include/asm/arch-mx5/imx-regs.h
+++ b/arch/arm/include/asm/arch-mx5/imx-regs.h
@@ -100,6 +100,9 @@
 #define PLL1_BASE_ADDR		(AIPS2_BASE_ADDR + 0x00080000)
 #define PLL2_BASE_ADDR		(AIPS2_BASE_ADDR + 0x00084000)
 #define PLL3_BASE_ADDR		(AIPS2_BASE_ADDR + 0x00088000)
+#ifdef	CONFIG_MX53
+#define PLL4_BASE_ADDR		(AIPS2_BASE_ADDR + 0x0008c000)
+#endif
 #define AHBMAX_BASE_ADDR	(AIPS2_BASE_ADDR + 0x00094000)
 #define IIM_BASE_ADDR		(AIPS2_BASE_ADDR + 0x00098000)
 #define CSU_BASE_ADDR		(AIPS2_BASE_ADDR + 0x0009C000)
@@ -282,8 +285,6 @@
 #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
 #include <asm/types.h>
 
-extern void imx_get_mac_from_fuse(unsigned char *mac);
-
 #define __REG(x)	(*((volatile u32 *)(x)))
 #define __REG16(x)	(*((volatile u16 *)(x)))
 #define __REG8(x)	(*((volatile u8 *)(x)))
diff --git a/arch/arm/include/asm/arch-omap3/mem.h b/arch/arm/include/asm/arch-omap3/mem.h
index f165949..8e28f77 100644
--- a/arch/arm/include/asm/arch-omap3/mem.h
+++ b/arch/arm/include/asm/arch-omap3/mem.h
@@ -128,6 +128,33 @@
 		(MICRON_XSR_165 << 0) | (MICRON_TXP_165 << 8) |	\
 		(MICRON_TWTR_165 << 16))
 
+#define MICRON_RAMTYPE			0x1
+#define MICRON_DDRTYPE			0x0
+#define MICRON_DEEPPD			0x1
+#define MICRON_B32NOT16			0x1
+#define MICRON_BANKALLOCATION	0x2
+#define MICRON_RAMSIZE			((PHYS_SDRAM_1_SIZE/(1024*1024))/2)
+#define MICRON_ADDRMUXLEGACY	0x1
+#define MICRON_CASWIDTH			0x5
+#define MICRON_RASWIDTH			0x2
+#define MICRON_LOCKSTATUS		0x0
+#define MICRON_V_MCFG ((MICRON_LOCKSTATUS << 30) | (MICRON_RASWIDTH << 24) | \
+	(MICRON_CASWIDTH << 20) | (MICRON_ADDRMUXLEGACY << 19) | \
+	(MICRON_RAMSIZE << 8) | (MICRON_BANKALLOCATION << 6) | \
+	(MICRON_B32NOT16 << 4) | (MICRON_DEEPPD << 3) | \
+	(MICRON_DDRTYPE << 2) | (MICRON_RAMTYPE))
+
+#define MICRON_ARCV				2030
+#define MICRON_ARE				0x1
+#define MICRON_V_RFR_CTRL ((MICRON_ARCV << 8) | (MICRON_ARE))
+
+#define MICRON_BL				0x2
+#define MICRON_SIL				0x0
+#define MICRON_CASL				0x3
+#define MICRON_WBST				0x0
+#define MICRON_V_MR ((MICRON_WBST << 9) | (MICRON_CASL << 4) | \
+	(MICRON_SIL << 3) | (MICRON_BL))
+
 /*
  * NUMONYX part of IGEP v2 (165MHz optimized) 6.06ns
  *   ACTIMA
@@ -171,10 +198,15 @@
 #define V_ACTIMA_165 INFINEON_V_ACTIMA_165
 #define V_ACTIMB_165 INFINEON_V_ACTIMB_165
 #endif
+
 #ifdef CONFIG_OMAP3_MICRON_DDR
 #define V_ACTIMA_165 MICRON_V_ACTIMA_165
 #define V_ACTIMB_165 MICRON_V_ACTIMB_165
+#define V_MCFG			MICRON_V_MCFG
+#define V_RFR_CTRL		MICRON_V_RFR_CTRL
+#define V_MR			MICRON_V_MR
 #endif
+
 #ifdef CONFIG_OMAP3_NUMONYX_DDR
 #define V_ACTIMA_165 NUMONYX_V_ACTIMA_165
 #define V_ACTIMB_165 NUMONYX_V_ACTIMB_165
@@ -184,6 +216,10 @@
 #error "Please choose the right DDR type in config header"
 #endif
 
+#if defined(CONFIG_SPL_BUILD) && (!defined(V_MCFG) || !defined(V_RFR_CTRL))
+#error "Please choose the right DDR type in config header"
+#endif
+
 /*
  * GPMC settings -
  * Definitions is as per the following format
diff --git a/arch/arm/include/asm/arch-omap3/omap_gpmc.h b/arch/arm/include/asm/arch-omap3/omap_gpmc.h
index bd22bce..800e4ee 100644
--- a/arch/arm/include/asm/arch-omap3/omap_gpmc.h
+++ b/arch/arm/include/asm/arch-omap3/omap_gpmc.h
@@ -80,4 +80,13 @@
 }
 #endif
 
+/* GPMC CS configuration for an SMSC LAN9221 ethernet controller */
+#define NET_LAN9221_GPMC_CONFIG1    0x00001000
+#define NET_LAN9221_GPMC_CONFIG2    0x00060700
+#define NET_LAN9221_GPMC_CONFIG3    0x00020201
+#define NET_LAN9221_GPMC_CONFIG4    0x06000700
+#define NET_LAN9221_GPMC_CONFIG5    0x0006090A
+#define NET_LAN9221_GPMC_CONFIG6    0x87030000
+#define NET_LAN9221_GPMC_CONFIG7    0x00000f6c
+
 #endif /* __ASM_ARCH_OMAP_GPMC_H */
diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h
index 995e7cb..7b60051 100644
--- a/arch/arm/include/asm/arch-omap3/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap3/sys_proto.h
@@ -71,4 +71,5 @@
 void dieid_num_r(void);
 void do_omap3_emu_romcode_call(u32 service_id, u32 parameters);
 void omap3_gp_romcode_call(u32 service_id, u32 parameter);
+void omap_rev_string(char *omap_rev_string);
 #endif
diff --git a/arch/arm/include/asm/arch-omap4/omap4.h b/arch/arm/include/asm/arch-omap4/omap4.h
index a6e1e42..fc9c555 100644
--- a/arch/arm/include/asm/arch-omap4/omap4.h
+++ b/arch/arm/include/asm/arch-omap4/omap4.h
@@ -125,6 +125,10 @@
 /* CONTROL_EFUSE_2 */
 #define CONTROL_EFUSE_2_NMOS_PMOS_PTV_CODE_1		0x00ffc000
 
+#define MMC1_PWRDNZ					(1 << 26)
+#define MMC1_PBIASLITE_PWRDNZ				(1 << 22)
+#define MMC1_PBIASLITE_VMODE				(1 << 21)
+
 #ifndef __ASSEMBLY__
 
 struct s32ktimer {
@@ -141,7 +145,9 @@
 	unsigned int control_ldosram_iva_voltage_ctrl;	/* 0x4A002320 */
 	unsigned int control_ldosram_mpu_voltage_ctrl;	/* 0x4A002324 */
 	unsigned int control_ldosram_core_voltage_ctrl;	/* 0x4A002328 */
-	unsigned int pad3[260341];
+	unsigned int pad3[260277];
+	unsigned int control_pbiaslite;			/* 0x4A100600 */
+	unsigned int pad4[63];
 	unsigned int control_efuse_1;			/* 0x4A100700 */
 	unsigned int control_efuse_2;			/* 0x4A100704 */
 };
diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h
index d3cb857..66d6b71 100644
--- a/arch/arm/include/asm/omap_common.h
+++ b/arch/arm/include/asm/omap_common.h
@@ -37,6 +37,7 @@
 void preloader_console_init(void);
 
 /* Boot device */
+#ifdef CONFIG_OMAP44XX /* OMAP4 */
 #define BOOT_DEVICE_NONE	0
 #define BOOT_DEVICE_XIP		1
 #define BOOT_DEVICE_XIPWAIT	2
@@ -44,13 +45,43 @@
 #define BOOT_DEVICE_ONE_NAND	4
 #define BOOT_DEVICE_MMC1	5
 #define BOOT_DEVICE_MMC2	6
+#elif defined(CONFIG_OMAP34XX)	/* OMAP3 */
+#define BOOT_DEVICE_NONE	0
+#define BOOT_DEVICE_XIP		1
+#define BOOT_DEVICE_NAND	2
+#define BOOT_DEVICE_ONE_NAND	3
+#define BOOT_DEVICE_MMC2	5 /*emmc*/
+#define BOOT_DEVICE_MMC1	6
+#define BOOT_DEVICE_XIPWAIT	7
+#endif
 
 /* Boot type */
 #define	MMCSD_MODE_UNDEFINED	0
 #define MMCSD_MODE_RAW		1
 #define MMCSD_MODE_FAT		2
+#define NAND_MODE_HW_ECC	3
+
+struct spl_image_info {
+	const char *name;
+	u8 os;
+	u32 load_addr;
+	u32 entry_point;
+	u32 size;
+};
+
+extern struct spl_image_info spl_image;
 
 u32 omap_boot_device(void);
 u32 omap_boot_mode(void);
 
+
+/* SPL common function s*/
+void spl_parse_image_header(const struct image_header *header);
+
+/* NAND SPL functions */
+void spl_nand_load_image(void);
+
+/* MMC SPL functions */
+void spl_mmc_load_image(void);
+
 #endif /* _OMAP_COMMON_H_ */
diff --git a/board/Marvell/gplugd/gplugd.c b/board/Marvell/gplugd/gplugd.c
index dc7d89d..b4f7f81 100644
--- a/board/Marvell/gplugd/gplugd.c
+++ b/board/Marvell/gplugd/gplugd.c
@@ -32,6 +32,13 @@
 #include <mvmfp.h>
 #include <asm/arch/mfp.h>
 #include <asm/arch/armada100.h>
+#include <asm/gpio.h>
+#include <miiphy.h>
+
+#ifdef CONFIG_ARMADA100_FEC
+#include <net.h>
+#include <netdev.h>
+#endif /* CONFIG_ARMADA100_FEC */
 
 DECLARE_GLOBAL_DATA_PTR;
 
@@ -45,6 +52,26 @@
 		/* Enable Console on UART3 */
 		MFPO8_UART3_TXD,
 		MFPO9_UART3_RXD,
+
+		/* Ethernet PHY Interface */
+		MFP086_ETH_TXCLK,
+		MFP087_ETH_TXEN,
+		MFP088_ETH_TXDQ3,
+		MFP089_ETH_TXDQ2,
+		MFP090_ETH_TXDQ1,
+		MFP091_ETH_TXDQ0,
+		MFP092_ETH_CRS,
+		MFP093_ETH_COL,
+		MFP094_ETH_RXCLK,
+		MFP095_ETH_RXER,
+		MFP096_ETH_RXDQ3,
+		MFP097_ETH_RXDQ2,
+		MFP098_ETH_RXDQ1,
+		MFP099_ETH_RXDQ0,
+		MFP100_ETH_MDC,
+		MFP101_ETH_MDIO,
+		MFP103_ETH_RXDV,
+
 		MFP_EOC		/*End of configuration*/
 	};
 	/* configure MFP's */
@@ -58,5 +85,49 @@
 	gd->bd->bi_arch_number = MACH_TYPE_SHEEVAD;
 	/* adress of boot parameters */
 	gd->bd->bi_boot_params = armd1_sdram_base(0) + 0x100;
+	/* Assert PHY_RST# */
+	gpio_direction_output(CONFIG_SYS_GPIO_PHY_RST, GPIO_LOW);
+	udelay(10);
+	/* Deassert PHY_RST# */
+	gpio_set_value(CONFIG_SYS_GPIO_PHY_RST, GPIO_HIGH);
 	return 0;
 }
+
+#ifdef CONFIG_ARMADA100_FEC
+int board_eth_init(bd_t *bis)
+{
+	struct armd1apmu_registers *apmu_regs =
+		(struct armd1apmu_registers *)ARMD1_APMU_BASE;
+
+	/* Enable clock of ethernet controller */
+	writel(FE_CLK_RST | FE_CLK_ENA, &apmu_regs->fecrc);
+
+	return armada100_fec_register(ARMD1_FEC_BASE);
+}
+
+#ifdef CONFIG_RESET_PHY_R
+/* Configure and initialize PHY chip 88E3015 */
+void reset_phy(void)
+{
+	u16 phy_adr;
+	const char *name = "armd-fec0";
+
+	if (miiphy_set_current_dev(name))
+		return;
+
+	/* command to read PHY dev address */
+	if (miiphy_read(name, 0xff, 0xff, &phy_adr)) {
+		printf("Err..%s could not read PHY dev address\n", __func__);
+		return;
+	}
+
+	/* Set Ethernet LED in TX blink mode */
+	miiphy_write(name, phy_adr, PHY_LED_MAN_REG, 0x00);
+	miiphy_write(name, phy_adr, PHY_LED_PAR_SEL_REG, PHY_LED_VAL);
+
+	/* reset the phy */
+	miiphy_reset(name, phy_adr);
+	debug("88E3015 Initialized on %s\n", name);
+}
+#endif /* CONFIG_RESET_PHY_R */
+#endif /* CONFIG_ARMADA100_FEC */
diff --git a/board/efikamx/efikamx.c b/board/efikamx/efikamx.c
index 5be1f6c..0c4e24b 100644
--- a/board/efikamx/efikamx.c
+++ b/board/efikamx/efikamx.c
@@ -62,10 +62,13 @@
 #define	EFIKAMX_BOARD_REV_13	0x3
 #define	EFIKAMX_BOARD_REV_14	0x4
 
+#define	EFIKASB_BOARD_REV_13	0x1
+#define	EFIKASB_BOARD_REV_20	0x2
+
 /*
  * Board identification
  */
-u32 get_efika_rev(void)
+u32 get_efikamx_rev(void)
 {
 	u32 rev = 0;
 	/*
@@ -97,6 +100,31 @@
 	return (~rev & 0x7) + 1;
 }
 
+inline u32 get_efikasb_rev(void)
+{
+	u32 rev = 0;
+
+	mxc_request_iomux(MX51_PIN_EIM_CS3, IOMUX_CONFIG_GPIO);
+	mxc_iomux_set_pad(MX51_PIN_EIM_CS3, PAD_CTL_100K_PU);
+	gpio_direction_input(IOMUX_TO_GPIO(MX51_PIN_EIM_CS3));
+	rev |= (!!gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_EIM_CS3))) << 0;
+
+	mxc_request_iomux(MX51_PIN_EIM_CS4, IOMUX_CONFIG_GPIO);
+	mxc_iomux_set_pad(MX51_PIN_EIM_CS4, PAD_CTL_100K_PU);
+	gpio_direction_input(IOMUX_TO_GPIO(MX51_PIN_EIM_CS4));
+	rev |= (!!gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_EIM_CS4))) << 1;
+
+	return rev;
+}
+
+inline uint32_t get_efika_rev(void)
+{
+	if (machine_is_efikamx())
+		return get_efikamx_rev();
+	else
+		return get_efikasb_rev();
+}
+
 u32 get_board_rev(void)
 {
 	return get_cpu_rev() | (get_efika_rev() << 8);
@@ -268,25 +296,36 @@
 	{MMC_SDHC2_BASE_ADDR, 1},
 };
 
+static inline uint32_t efika_mmc_cd(void)
+{
+	if (machine_is_efikamx())
+		return MX51_PIN_GPIO1_0;
+	else
+		return MX51_PIN_EIM_CS2;
+}
+
 int board_mmc_getcd(u8 *absent, struct mmc *mmc)
 {
 	struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv;
+	uint32_t cd = efika_mmc_cd();
 
 	if (cfg->esdhc_base == MMC_SDHC1_BASE_ADDR)
-		*absent = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_0));
+		*absent = gpio_get_value(IOMUX_TO_GPIO(cd));
 	else
 		*absent = gpio_get_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_8));
 
 	return 0;
 }
+
 int board_mmc_init(bd_t *bis)
 {
 	int ret;
+	uint32_t cd = efika_mmc_cd();
 
 	/* SDHC1 is used on all revisions, setup control pins first */
-	mxc_request_iomux(MX51_PIN_GPIO1_0,
+	mxc_request_iomux(cd,
 		IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
-	mxc_iomux_set_pad(MX51_PIN_GPIO1_0,
+	mxc_iomux_set_pad(cd,
 		PAD_CTL_DRV_HIGH | PAD_CTL_HYS_ENABLE |
 		PAD_CTL_PUE_KEEPER | PAD_CTL_100K_PU |
 		PAD_CTL_ODE_OPENDRAIN_NONE |
@@ -298,11 +337,12 @@
 		PAD_CTL_100K_PU | PAD_CTL_ODE_OPENDRAIN_NONE |
 		PAD_CTL_SRE_FAST);
 
-	gpio_direction_input(IOMUX_TO_GPIO(MX51_PIN_GPIO1_0));
+	gpio_direction_input(IOMUX_TO_GPIO(cd));
 	gpio_direction_input(IOMUX_TO_GPIO(MX51_PIN_GPIO1_1));
 
 	/* Internal SDHC1 IOMUX + SDHC2 IOMUX on old boards */
-	if (get_efika_rev() < EFIKAMX_BOARD_REV_12) {
+	if (machine_is_efikasb() || (machine_is_efikamx() &&
+		(get_efika_rev() < EFIKAMX_BOARD_REV_12))) {
 		/* SDHC1 IOMUX */
 		mxc_request_iomux(MX51_PIN_SD1_CMD,
 			IOMUX_CONFIG_ALT0 | IOMUX_CONFIG_SION);
@@ -414,6 +454,7 @@
 
 		ret = fsl_esdhc_initialize(bis, &esdhc_cfg[0]);
 	}
+
 	return ret;
 }
 #endif
@@ -493,27 +534,44 @@
  */
 void setup_iomux_led(void)
 {
-	/* Blue LED */
-	mxc_request_iomux(MX51_PIN_CSI1_D9, IOMUX_CONFIG_ALT3);
-	gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSI1_D9), 0);
+	if (machine_is_efikamx()) {
+		/* Blue LED */
+		mxc_request_iomux(MX51_PIN_CSI1_D9, IOMUX_CONFIG_ALT3);
+		gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSI1_D9), 0);
 
-	/* Green LED */
-	mxc_request_iomux(MX51_PIN_CSI1_VSYNC, IOMUX_CONFIG_ALT3);
-	gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSI1_VSYNC), 0);
+		/* Green LED */
+		mxc_request_iomux(MX51_PIN_CSI1_VSYNC, IOMUX_CONFIG_ALT3);
+		gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSI1_VSYNC), 0);
 
-	/* Red LED */
-	mxc_request_iomux(MX51_PIN_CSI1_HSYNC, IOMUX_CONFIG_ALT3);
-	gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSI1_HSYNC), 0);
+		/* Red LED */
+		mxc_request_iomux(MX51_PIN_CSI1_HSYNC, IOMUX_CONFIG_ALT3);
+		gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_CSI1_HSYNC), 0);
+	} else {
+		/* CAPS-LOCK LED */
+		mxc_request_iomux(MX51_PIN_EIM_CS0, IOMUX_CONFIG_GPIO);
+		gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_EIM_CS0), 0);
+
+		/* ALARM-LED LED */
+		mxc_request_iomux(MX51_PIN_GPIO1_3, IOMUX_CONFIG_GPIO);
+		gpio_direction_output(IOMUX_TO_GPIO(MX51_PIN_GPIO1_3), 0);
+	}
 }
 
 void efikamx_toggle_led(uint32_t mask)
 {
-	gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_D9),
-			mask & EFIKAMX_LED_BLUE);
-	gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_VSYNC),
-			mask & EFIKAMX_LED_GREEN);
-	gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_HSYNC),
-			mask & EFIKAMX_LED_RED);
+	if (machine_is_efikamx()) {
+		gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_D9),
+				mask & EFIKAMX_LED_BLUE);
+		gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_VSYNC),
+				mask & EFIKAMX_LED_GREEN);
+		gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_CSI1_HSYNC),
+				mask & EFIKAMX_LED_RED);
+	} else {
+		gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_EIM_CS0),
+				mask & EFIKAMX_LED_BLUE);
+		gpio_set_value(IOMUX_TO_GPIO(MX51_PIN_GPIO1_3),
+				!(mask & EFIKAMX_LED_GREEN));
+	}
 }
 
 /*
@@ -607,7 +665,6 @@
 
 int board_init(void)
 {
-	gd->bd->bi_arch_number = MACH_TYPE_MX51_EFIKAMX;
 	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
 	return 0;
@@ -629,7 +686,24 @@
 
 int checkboard(void)
 {
-	puts("Board: Efika MX\n");
+	u32 rev = get_efika_rev();
+
+	if (machine_is_efikamx()) {
+		printf("Board: Efika MX, rev1.%i\n", rev & 0xf);
+		return 0;
+	} else {
+		switch (rev) {
+		case EFIKASB_BOARD_REV_13:
+			printf("Board: Efika SB rev1.3\n");
+			break;
+		case EFIKASB_BOARD_REV_20:
+			printf("Board: Efika SB rev2.0\n");
+			break;
+		default:
+			printf("Board: Efika SB, rev Unknown\n");
+			break;
+		}
+	}
 
 	return 0;
 }
diff --git a/board/efikamx/imximage.cfg b/board/efikamx/imximage_mx.cfg
similarity index 100%
rename from board/efikamx/imximage.cfg
rename to board/efikamx/imximage_mx.cfg
diff --git a/board/efikamx/imximage_sb.cfg b/board/efikamx/imximage_sb.cfg
new file mode 100644
index 0000000..878146f
--- /dev/null
+++ b/board/efikamx/imximage_sb.cfg
@@ -0,0 +1,122 @@
+#
+# Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
+#
+# BASED ON: imx51evk
+#
+# (C) Copyright 2009
+# Stefano Babic DENX Software Engineering sbabic@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. 51 Franklin Street Fifth Floor Boston,
+# MA 02110-1301 USA
+#
+# Refer docs/README.imxmage for more details about how-to configure
+# and create imximage boot image
+#
+# The syntax is taken as close as possible with the kwbimage
+
+# Boot Device : one of
+# spi, sd (the board has no nand neither onenand)
+BOOT_FROM	spi
+
+# Device Configuration Data (DCD)
+#
+# Each entry must have the format:
+# Addr-type           Address        Value
+#
+# where:
+#	Addr-type register length (1,2 or 4 bytes)
+#	Address	  absolute address of the register
+#	value	  value to be stored in the register
+
+# Setting IOMUXC
+DATA 4 0x73fa88a0 0x200
+DATA 4 0x73fa850c 0x20c3
+DATA 4 0x73fa8510 0x20c3
+DATA 4 0x73fa883c 0x2
+DATA 4 0x73fa8848 0x2
+DATA 4 0x73fa84b8 0xe7
+DATA 4 0x73fa84bc 0x45
+DATA 4 0x73fa84c0 0x45
+DATA 4 0x73fa84c4 0x45
+DATA 4 0x73fa84c8 0x45
+DATA 4 0x73fa8820 0x0
+DATA 4 0x73fa84a4 0x5
+DATA 4 0x73fa84a8 0x5
+DATA 4 0x73fa84ac 0xe3
+DATA 4 0x73fa84b0 0xe3
+DATA 4 0x73fa84b4 0xe3
+DATA 4 0x73fa84cc 0xe3
+DATA 4 0x73fa84d0 0xe2
+
+DATA 4 0x73fa882c 0x4
+DATA 4 0x73fa88a4 0x4
+DATA 4 0x73fa88ac 0x4
+DATA 4 0x73fa88b8 0x4
+
+# Setting DDR for micron
+# 13 Rows, 10 Cols, 32 bit, SREF=4 Micron Model
+# CAS=3 BL=4
+# ESDCTL_ESDCTL0
+DATA 4 0x83fd9000 0x82a20000
+# ESDCTL_ESDCTL1
+DATA 4 0x83fd9008 0x82a20000
+# ESDCTL_ESDMISC
+DATA 4 0x83fd9010 0xcaaaf6d0
+# ESDCTL_ESDCFG0
+DATA 4 0x83fd9004 0x333574aa
+# ESDCTL_ESDCFG1
+DATA 4 0x83fd900c 0x333574aa
+
+# Init DRAM on CS0
+# ESDCTL_ESDSCR
+DATA 4 0x83fd9014 0x04008008
+DATA 4 0x83fd9014 0x0000801a
+DATA 4 0x83fd9014 0x0000801b
+DATA 4 0x83fd9014 0x00448019
+DATA 4 0x83fd9014 0x07328018
+DATA 4 0x83fd9014 0x04008008
+DATA 4 0x83fd9014 0x00008010
+DATA 4 0x83fd9014 0x00008010
+DATA 4 0x83fd9014 0x06328018
+DATA 4 0x83fd9014 0x03808019
+DATA 4 0x83fd9014 0x00408019
+DATA 4 0x83fd9014 0x00008000
+
+# Init DRAM on CS1
+DATA 4 0x83fd9014 0x0400800c
+DATA 4 0x83fd9014 0x0000801e
+DATA 4 0x83fd9014 0x0000801f
+DATA 4 0x83fd9014 0x0000801d
+DATA 4 0x83fd9014 0x0732801c
+DATA 4 0x83fd9014 0x0400800c
+DATA 4 0x83fd9014 0x00008014
+DATA 4 0x83fd9014 0x00008014
+DATA 4 0x83fd9014 0x0632801c
+DATA 4 0x83fd9014 0x0380801d
+DATA 4 0x83fd9014 0x0040801d
+DATA 4 0x83fd9014 0x00008004
+
+# Write to CTL0
+DATA 4 0x83fd9000 0xb2a20000
+# Write to CTL1
+DATA 4 0x83fd9008 0xb2a20000
+# ESDMISC
+DATA 4 0x83fd9010 0xcaaaf6d0
+#ESDCTL_ESDCDLYGD
+DATA 4 0x83fd9034 0x90000000
+DATA 4 0x83fd9014 0x00000000
diff --git a/board/freescale/mx25pdk/Makefile b/board/freescale/mx25pdk/Makefile
new file mode 100644
index 0000000..4d45ae3
--- /dev/null
+++ b/board/freescale/mx25pdk/Makefile
@@ -0,0 +1,49 @@
+#
+# Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de>
+#
+# (C) Copyright 2011 Freescale Semiconductor, Inc.
+#
+# 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 $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD).o
+
+COBJS	:= mx25pdk.o
+SOBJS	:= lowlevel_init.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS))
+SOBJS	:= $(addprefix $(obj),$(SOBJS))
+
+$(LIB):	$(obj).depend $(OBJS) $(SOBJS)
+	$(call cmd_link_o_target, $(OBJS) $(SOBJS))
+
+clean:
+	rm -f $(SOBJS) $(OBJS)
+
+distclean:	clean
+	rm -f $(LIB) core *.bak .depend
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/board/freescale/mx25pdk/imximage.cfg b/board/freescale/mx25pdk/imximage.cfg
new file mode 100644
index 0000000..f7af7ff
--- /dev/null
+++ b/board/freescale/mx25pdk/imximage.cfg
@@ -0,0 +1,73 @@
+#
+# (C) Copyright 2009
+# Stefano Babic DENX Software Engineering sbabic@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.
+#
+# Refer docs/README.imxmage for more details about how-to configure
+# and create imximage boot image
+#
+# The syntax is taken as close as possible with the kwbimage
+
+# Boot Device : one of
+# spi, sd (the board has no nand neither onenand)
+
+BOOT_FROM	sd
+
+# Device Configuration Data (DCD)
+#
+# Each entry must have the format:
+# Addr-type           Address        Value
+#
+# where:
+#	Addr-type register length (1,2 or 4 bytes)
+#	Address	  absolute address of the register
+#	value	  value to be stored in the register
+
+# EIM config-CS5 init -- CPLD
+DATA 4 0xB8002050 0x0000D843
+DATA 4 0xB8002054 0x22252521
+DATA 4 0xB8002058 0x22220A00
+
+# DDR2 init
+DATA 4 0xB8001004 0x0076E83A
+DATA 4 0xB8001010 0x00000204
+DATA 4 0xB8001000 0x92210000
+DATA 4 0x80000f00 0x12344321
+DATA 4 0xB8001000 0xB2210000
+DATA 1 0x82000000 0xda
+DATA 1 0x83000000 0xda
+DATA 1 0x81000400 0xda
+DATA 1 0x80000333 0xda
+
+DATA 4 0xB8001000 0x92210000
+DATA 1 0x80000400 0x12345678
+
+DATA 4 0xB8001000 0xA2210000
+DATA 4 0x80000000 0x87654321
+DATA 4 0x80000000 0x87654321
+
+DATA 4 0xB8001000 0xB2210000
+DATA 1 0x80000233 0xda
+DATA 1 0x81000780 0xda
+DATA 1 0x81000400 0xda
+DATA 4 0xB8001000 0x82216080
+DATA 4 0x43FAC454 0x00001000
+
+DATA 4 0x53F80008 0x20034000
+
+# Enable the clocks
+DATA 4 0x53f8000c 0x1fffffff
+DATA 4 0x53f80010 0xffffffff
+DATA 4 0x53f80014 0xfdfff
diff --git a/board/freescale/mx25pdk/lowlevel_init.S b/board/freescale/mx25pdk/lowlevel_init.S
new file mode 100644
index 0000000..6e6810f
--- /dev/null
+++ b/board/freescale/mx25pdk/lowlevel_init.S
@@ -0,0 +1,21 @@
+/*
+ * Copyright (c) 2011  Freescale Semiconductor
+ *
+ * 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.
+ */
+
+.globl lowlevel_init
+lowlevel_init:
+
+	mov	pc, lr
diff --git a/board/freescale/mx25pdk/mx25pdk.c b/board/freescale/mx25pdk/mx25pdk.c
new file mode 100644
index 0000000..4a8352f
--- /dev/null
+++ b/board/freescale/mx25pdk/mx25pdk.c
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * Author: Fabio Estevam <fabio.estevam@freescale.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.
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/imx-regs.h>
+#include <asm/arch/imx25-pinmux.h>
+#include <asm/arch/sys_proto.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+	/* dram_init must store complete ramsize in gd->ram_size */
+	gd->ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE,
+				PHYS_SDRAM_1_SIZE);
+	return 0;
+}
+
+int board_early_init_f(void)
+{
+	mx25_uart1_init_pins();
+
+	return 0;
+}
+
+int board_init(void)
+{
+	/* address of boot parameters */
+	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
+
+	return 0;
+}
+
+int checkboard(void)
+{
+	puts("Board: MX25PDK\n");
+
+	return 0;
+}
diff --git a/board/freescale/mx31ads/mx31ads.c b/board/freescale/mx31ads/mx31ads.c
index 7637c92..4dd1e63 100644
--- a/board/freescale/mx31ads/mx31ads.c
+++ b/board/freescale/mx31ads/mx31ads.c
@@ -36,12 +36,6 @@
 	return 0;
 }
 
-void dram_init_banksize(void)
-{
-	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
-	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
-}
-
 int board_early_init_f(void)
 {
 	int i;
@@ -105,7 +99,6 @@
 
 int board_init(void)
 {
-	gd->bd->bi_arch_number = MACH_TYPE_MX31ADS;	/* board id for linux */
 	gd->bd->bi_boot_params = 0x80000100;	/* adress of boot parameters */
 
 	return 0;
diff --git a/board/freescale/mx31pdk/mx31pdk.c b/board/freescale/mx31pdk/mx31pdk.c
index f6e190a..276d451 100644
--- a/board/freescale/mx31pdk/mx31pdk.c
+++ b/board/freescale/mx31pdk/mx31pdk.c
@@ -47,12 +47,6 @@
 	return 0;
 }
 
-void dram_init_banksize(void)
-{
-	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
-	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
-}
-
 int board_early_init_f(void)
 {
 	/* CS5: CPLD incl. network controller */
@@ -69,7 +63,6 @@
 
 int board_init(void)
 {
-	gd->bd->bi_arch_number = MACH_TYPE_MX31_3DS; /* board id for linux */
 	/* adress of boot parameters */
 	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
diff --git a/board/freescale/mx51evk/mx51evk.c b/board/freescale/mx51evk/mx51evk.c
index 94ea1f2..8da1ee8 100644
--- a/board/freescale/mx51evk/mx51evk.c
+++ b/board/freescale/mx51evk/mx51evk.c
@@ -403,7 +403,6 @@
 {
 	system_rev = get_cpu_rev();
 
-	gd->bd->bi_arch_number = MACH_TYPE_MX51_BABBAGE;
 	/* address of boot parameters */
 	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
diff --git a/board/freescale/mx53ard/mx53ard.c b/board/freescale/mx53ard/mx53ard.c
index 6e3360b..c89da13 100644
--- a/board/freescale/mx53ard/mx53ard.c
+++ b/board/freescale/mx53ard/mx53ard.c
@@ -278,7 +278,6 @@
 
 int board_init(void)
 {
-	gd->bd->bi_arch_number = MACH_TYPE_MX53_ARD;
 	/* address of boot parameters */
 	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
diff --git a/board/freescale/mx53evk/mx53evk.c b/board/freescale/mx53evk/mx53evk.c
index 81857ff..fd821c0 100644
--- a/board/freescale/mx53evk/mx53evk.c
+++ b/board/freescale/mx53evk/mx53evk.c
@@ -355,7 +355,6 @@
 
 int board_init(void)
 {
-	gd->bd->bi_arch_number = MACH_TYPE_MX53_EVK;
 	/* address of boot parameters */
 	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
diff --git a/board/freescale/mx53loco/mx53loco.c b/board/freescale/mx53loco/mx53loco.c
index ade1006..156f8b5 100644
--- a/board/freescale/mx53loco/mx53loco.c
+++ b/board/freescale/mx53loco/mx53loco.c
@@ -288,7 +288,6 @@
 
 int board_init(void)
 {
-	gd->bd->bi_arch_number = MACH_TYPE_MX53_LOCO;
 	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
 	return 0;
diff --git a/board/freescale/mx53smd/mx53smd.c b/board/freescale/mx53smd/mx53smd.c
index 4a7ee55..776784f 100644
--- a/board/freescale/mx53smd/mx53smd.c
+++ b/board/freescale/mx53smd/mx53smd.c
@@ -214,7 +214,6 @@
 
 int board_init(void)
 {
-	gd->bd->bi_arch_number = MACH_TYPE_MX53_SMD;
 	/* address of boot parameters */
 	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
diff --git a/board/isee/igep0020/igep0020.c b/board/isee/igep0020/igep0020.c
index 2279cc0..6a3777e 100644
--- a/board/isee/igep0020/igep0020.c
+++ b/board/isee/igep0020/igep0020.c
@@ -29,6 +29,7 @@
 #include <asm/arch/mmc_host_def.h>
 #include <asm/arch/mux.h>
 #include <asm/arch/sys_proto.h>
+#include <asm/arch/omap_gpmc.h>
 #include <asm/mach-types.h>
 #include "igep0020.h"
 
diff --git a/board/isee/igep0020/igep0020.h b/board/isee/igep0020/igep0020.h
index c08d758..3d6e15f 100644
--- a/board/isee/igep0020/igep0020.h
+++ b/board/isee/igep0020/igep0020.h
@@ -29,15 +29,6 @@
 	"ONENAND",
 };
 
-/* GPMC CS 5 connected to an SMSC LAN9221 ethernet controller */
-#define NET_LAN9221_GPMC_CONFIG1    0x00001000
-#define NET_LAN9221_GPMC_CONFIG2    0x00080701
-#define NET_LAN9221_GPMC_CONFIG3    0x00020201
-#define NET_LAN9221_GPMC_CONFIG4    0x08030703
-#define NET_LAN9221_GPMC_CONFIG5    0x00060908
-#define NET_LAN9221_GPMC_CONFIG6    0x87030000
-#define NET_LAN9221_GPMC_CONFIG7    0x00000f6c
-
 static void setup_net_chip(void);
 
 /*
diff --git a/board/karo/tx25/tx25.c b/board/karo/tx25/tx25.c
index ce75468..307ffd0 100644
--- a/board/karo/tx25/tx25.c
+++ b/board/karo/tx25/tx25.c
@@ -29,6 +29,7 @@
 #include <asm/arch/imx-regs.h>
 #include <asm/arch/imx25-pinmux.h>
 #include <asm/gpio.h>
+#include <asm/arch/sys_proto.h>
 
 static void mdelay(int n)
 {
@@ -142,8 +143,6 @@
 int board_init()
 {
 #ifdef CONFIG_MXC_UART
-	extern void mx25_uart1_init_pins(void);
-
 	mx25_uart1_init_pins();
 #endif
 	/* board id for linux */
diff --git a/board/logicpd/imx31_litekit/imx31_litekit.c b/board/logicpd/imx31_litekit/imx31_litekit.c
index 09cc9c5..7214008 100644
--- a/board/logicpd/imx31_litekit/imx31_litekit.c
+++ b/board/logicpd/imx31_litekit/imx31_litekit.c
@@ -37,12 +37,6 @@
 	return 0;
 }
 
-void dram_init_banksize(void)
-{
-	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
-	gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;
-}
-
 int board_early_init_f(void)
 {
 	__REG(CSCR_U(0)) = 0x0000cf03; /* CS0: Nor Flash */
@@ -76,7 +70,6 @@
 
 int board_init(void)
 {
-	gd->bd->bi_arch_number = MACH_TYPE_MX31LITE; /* board id for linux */
 	gd->bd->bi_boot_params = (0x80000100);	/* adress of boot parameters */
 
 	return 0;
diff --git a/board/overo/overo.c b/board/overo/overo.c
index 4bbe1b8..850dfee 100644
--- a/board/overo/overo.c
+++ b/board/overo/overo.c
@@ -36,6 +36,7 @@
 #include <asm/arch/mux.h>
 #include <asm/arch/mem.h>
 #include <asm/arch/sys_proto.h>
+#include <asm/arch/omap_gpmc.h>
 #include <asm/gpio.h>
 #include <asm/mach-types.h>
 #include "overo.h"
diff --git a/board/overo/overo.h b/board/overo/overo.h
index 68e1243..d394f90 100644
--- a/board/overo/overo.h
+++ b/board/overo/overo.h
@@ -33,15 +33,6 @@
 #endif
 };
 
-/* GPMC CS 5 connected to an SMSC LAN9221 ethernet controller */
-#define NET_LAN9221_GPMC_CONFIG1    0x00001000
-#define NET_LAN9221_GPMC_CONFIG2    0x00080701
-#define NET_LAN9221_GPMC_CONFIG3    0x00020201
-#define NET_LAN9221_GPMC_CONFIG4    0x08030703
-#define NET_LAN9221_GPMC_CONFIG5    0x00060908
-#define NET_LAN9221_GPMC_CONFIG6    0x87030000
-#define NET_LAN9221_GPMC_CONFIG7    0x00000f6c
-
 /*
  * IEN  - Input Enable
  * IDIS - Input Disable
@@ -128,7 +119,7 @@
 	MUX_VAL(CP(GPMC_NCS6),		(IEN  | PTD | DIS | M0)) /*GPMC_nCS6*/\
 	MUX_VAL(CP(GPMC_NCS7),		(IEN  | PTU | EN  | M0)) /*GPMC_nCS7*/\
 	MUX_VAL(CP(GPMC_NBE1),		(IEN  | PTD | DIS | M0)) /*GPMC_nCS3*/\
-	MUX_VAL(CP(GPMC_CLK),		(IDIS | PTU | EN  | M0)) /*GPMC_CLK*/\
+	MUX_VAL(CP(GPMC_CLK),		(IEN  | PTU | EN  | M0)) /*GPMC_CLK*/\
 	MUX_VAL(CP(GPMC_NADV_ALE),	(IDIS | PTD | DIS | M0)) /*GPMC_nADV_ALE*/\
 	MUX_VAL(CP(GPMC_NOE),		(IDIS | PTD | DIS | M0)) /*GPMC_nOE*/\
 	MUX_VAL(CP(GPMC_NWE),		(IDIS | PTD | DIS | M0)) /*GPMC_nWE*/\
diff --git a/board/syteco/zmx25/zmx25.c b/board/syteco/zmx25/zmx25.c
index 893adc6..a89ee1a 100644
--- a/board/syteco/zmx25/zmx25.c
+++ b/board/syteco/zmx25/zmx25.c
@@ -117,8 +117,6 @@
 	writel(input_select1, &inputselect->i2c3_ipp_sda_in);	/* I2C3 SDA */
 	writel(input_select2, &inputselect->i2c3_ipp_scl_in);	/* I2C3 SCL */
 
-	/* board id for linux */
-	gd->bd->bi_arch_number = MACH_TYPE_ZMX25;
 	gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
 
 	return 0;
@@ -188,9 +186,3 @@
 				PHYS_SDRAM_SIZE);
 	return 0;
 }
-
-void dram_init_banksize(void)
-{
-	gd->bd->bi_dram[0].start = PHYS_SDRAM;
-	gd->bd->bi_dram[0].size = gd->ram_size;
-}
diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c
index 533af5a..f50d113 100644
--- a/board/timll/devkit8000/devkit8000.c
+++ b/board/timll/devkit8000/devkit8000.c
@@ -128,7 +128,7 @@
 }
 #endif
 
-#ifdef CONFIG_DRIVER_DM9000
+#if defined(CONFIG_DRIVER_DM9000) & !defined(CONFIG_SPL_BUILD)
 /*
  * Routine: board_eth_init
  * Description: Setting up the Ethernet hardware.
diff --git a/board/ttcontrol/vision2/vision2.c b/board/ttcontrol/vision2/vision2.c
index 17a2558..ebca7b6 100644
--- a/board/ttcontrol/vision2/vision2.c
+++ b/board/ttcontrol/vision2/vision2.c
@@ -653,7 +653,6 @@
 
 int board_init(void)
 {
-	gd->bd->bi_arch_number = MACH_TYPE_TTC_VISION2;	/* board id for linux */
 	/* address of boot parameters */
 	gd->bd->bi_boot_params = PHYS_SDRAM_1 + 0x100;
 
diff --git a/boards.cfg b/boards.cfg
index d32ff7e..0af96f5 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -144,6 +144,8 @@
 sheevaplug                   arm         arm926ejs   -                   Marvell        kirkwood
 dockstar                     arm         arm926ejs   -                   Seagate        kirkwood
 jadecpu                      arm         arm926ejs   jadecpu             syteco         mb86r0x
+mx25pdk                      arm         arm926ejs   mx25pdk             freescale      mx25		mx25pdk:IMX_CONFIG=board/freescale/mx25pdk/imximage.cfg
+tx25                         arm         arm926ejs   tx25                karo           mx25
 zmx25                        arm         arm926ejs   zmx25               syteco         mx25
 imx27lite                    arm         arm926ejs   imx27lite           logicpd        mx27
 magnesium                    arm         arm926ejs   imx27lite           logicpd        mx27
@@ -155,7 +157,8 @@
 integratorap_cm946es         arm         arm946es    integrator          armltd         -               integratorap
 integratorcp_cm946es         arm         arm946es    integrator          armltd         -               integratorcp
 ca9x4_ct_vxp                 arm         armv7       vexpress            armltd
-efikamx                      arm         armv7       efikamx             -              mx5		efikamx:IMX_CONFIG=board/efikamx/imximage.cfg
+efikamx                      arm         armv7       efikamx             -              mx5		efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKAMX,IMX_CONFIG=board/efikamx/imximage_mx.cfg
+efikasb                      arm         armv7       efikamx             -              mx5		efikamx:MACH_TYPE=MACH_TYPE_MX51_EFIKASB,IMX_CONFIG=board/efikamx/imximage_sb.cfg
 mx51evk                      arm         armv7       mx51evk             freescale      mx5		mx51evk:IMX_CONFIG=board/freescale/mx51evk/imximage.cfg
 mx53ard                      arm         armv7       mx53ard             freescale      mx5		mx53ard:IMX_CONFIG=board/freescale/mx53ard/imximage_dd3.cfg
 mx53evk                      arm         armv7       mx53evk             freescale      mx5		mx53evk:IMX_CONFIG=board/freescale/mx53evk/imximage.cfg
diff --git a/doc/README.SPL b/doc/README.SPL
index 30624a5..d53ef9c 100644
--- a/doc/README.SPL
+++ b/doc/README.SPL
@@ -60,3 +60,5 @@
 CONFIG_SPL_SPI_SUPPORT (drivers/spi/libspi.o)
 CONFIG_SPL_FAT_SUPPORT (fs/fat/libfat.o)
 CONFIG_SPL_LIBGENERIC_SUPPORT (lib/libgeneric.o)
+CONFIG_SPL_POWER_SUPPORT (drivers/power/libpower.o)
+CONFIG_SPL_NAND_SUPPORT (drivers/mtd/nand/libnand.o)
diff --git a/doc/README.davinci b/doc/README.davinci
index 0204372..5f1bdc8 100644
--- a/doc/README.davinci
+++ b/doc/README.davinci
@@ -139,3 +139,12 @@
 7) TI DA850 EVM
 http://focus.ti.com/docs/prod/folders/print/omap-l138.html
 http://www.logicpd.com/products/development-kits/zoom-omap-l138-evm-development-kit
+
+Davinci special defines
+=======================
+
+CONFIG_SYS_DV_NOR_BOOT_CFG:	AM18xx based boards, booting in NOR Boot mode
+				need a "NOR Boot Configuration Word" stored
+				in the NOR Flash. This define adds this.
+				More Info about this, see:
+				spraba5a.pdf chapter 3.1
diff --git a/drivers/block/mxc_ata.c b/drivers/block/mxc_ata.c
index f22f4f4..35bc656 100644
--- a/drivers/block/mxc_ata.c
+++ b/drivers/block/mxc_ata.c
@@ -96,7 +96,6 @@
 #define	REG2OFF(reg)	((((uint32_t)reg) & 0x3) * 8)
 static void set_ata_bus_timing(unsigned char mode)
 {
-	uint32_t val;
 	uint32_t T = 1000000000 / mxc_get_clock(MXC_IPG_CLK);
 
 	struct mxc_ata_config_regs *ata_regs;
@@ -106,22 +105,19 @@
 		return;
 
 	/* Write TIME_OFF/ON/1/2W */
-	val =	(3 << REG2OFF(&ata_regs->time_off)) |
-		(3 << REG2OFF(&ata_regs->time_on)) |
-		(((pio_t1[mode] + T) / T) << REG2OFF(&ata_regs->time_1)) |
-		(((pio_t2_8[mode] + T) / T) << REG2OFF(&ata_regs->time_2w));
-	writel(val, &ata_regs->time_off);
+	writeb(3, &ata_regs->time_off);
+	writeb(3, &ata_regs->time_on);
+	writeb((pio_t1[mode] + T) / T, &ata_regs->time_1);
+	writeb((pio_t2_8[mode] + T) / T, &ata_regs->time_2w);
 
 	/* Write TIME_2R/AX/RDX/4 */
-	val =	(((pio_t2_8[mode] + T) / T) << REG2OFF(&ata_regs->time_2r)) |
-		(((pio_tA[mode] + T) / T + 2) << REG2OFF(&ata_regs->time_ax)) |
-		(1 << REG2OFF(&ata_regs->time_pio_rdx)) |
-		(((pio_t4[mode] + T) / T) << REG2OFF(&ata_regs->time_4));
-	writel(val, &ata_regs->time_2r);
+	writeb((pio_t2_8[mode] + T) / T, &ata_regs->time_2r);
+	writeb((pio_tA[mode] + T) / T + 2, &ata_regs->time_ax);
+	writeb(1, &ata_regs->time_pio_rdx);
+	writeb((pio_t4[mode] + T) / T, &ata_regs->time_4);
 
 	/* Write TIME_9 ; the rest of timing registers is irrelevant for PIO */
-	val =	(((pio_t9[mode] + T) / T) << REG2OFF(&ata_regs->time_9));
-	writel(val, &ata_regs->time_9);
+	writeb((pio_t9[mode] + T) / T, &ata_regs->time_9);
 }
 
 int ide_preinit(void)
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 62ec97d..beca1da 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -27,6 +27,7 @@
 
 COBJS-$(CONFIG_AT91_GPIO)	+= at91_gpio.o
 COBJS-$(CONFIG_KIRKWOOD_GPIO)	+= kw_gpio.o
+COBJS-$(CONFIG_MARVELL_GPIO)	+= mvgpio.o
 COBJS-$(CONFIG_MARVELL_MFP)	+= mvmfp.o
 COBJS-$(CONFIG_MXC_GPIO)	+= mxc_gpio.o
 COBJS-$(CONFIG_PCA953X)		+= pca953x.o
diff --git a/drivers/gpio/mvgpio.c b/drivers/gpio/mvgpio.c
new file mode 100644
index 0000000..276f206
--- /dev/null
+++ b/drivers/gpio/mvgpio.c
@@ -0,0 +1,115 @@
+/*
+ * (C) Copyright 2011
+ * eInfochips Ltd. <www.einfochips.com>
+ * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
+ *
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include "mvgpio.h"
+#include <asm/gpio.h>
+
+#ifndef MV_MAX_GPIO
+#define MV_MAX_GPIO	128
+#endif
+
+int gpio_request(int gp, const char *label)
+{
+	if (gp >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO requested %d\n", __func__, gp);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+void gpio_free(int gp)
+{
+}
+
+void gpio_toggle_value(int gp)
+{
+	gpio_set_value(gp, !gpio_get_value(gp));
+}
+
+int gpio_direction_input(int gp)
+{
+	struct gpio_reg *gpio_reg_bank;
+
+	if (gp >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO %d\n", __func__, gp);
+		return -EINVAL;
+	}
+
+	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
+	writel(GPIO_TO_BIT(gp), &gpio_reg_bank->gcdr);
+	return 0;
+}
+
+int gpio_direction_output(int gp, int value)
+{
+	struct gpio_reg *gpio_reg_bank;
+
+	if (gp >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO %d\n", __func__, gp);
+		return -EINVAL;
+	}
+
+	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
+	writel(GPIO_TO_BIT(gp), &gpio_reg_bank->gsdr);
+	gpio_set_value(gp, value);
+	return 0;
+}
+
+int gpio_get_value(int gp)
+{
+	struct gpio_reg *gpio_reg_bank;
+	u32 gp_val;
+
+	if (gp >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO %d\n", __func__, gp);
+		return -EINVAL;
+	}
+
+	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
+	gp_val = readl(&gpio_reg_bank->gplr);
+
+	return GPIO_VAL(gp, gp_val);
+}
+
+void gpio_set_value(int gp, int value)
+{
+	struct gpio_reg *gpio_reg_bank;
+
+	if (gp >= MV_MAX_GPIO) {
+		printf("%s: Invalid GPIO %d\n", __func__, gp);
+		return;
+	}
+
+	gpio_reg_bank = get_gpio_base(GPIO_TO_REG(gp));
+	if (value)
+		writel(GPIO_TO_BIT(gp),	&gpio_reg_bank->gpsr);
+	else
+		writel(GPIO_TO_BIT(gp),	&gpio_reg_bank->gpcr);
+}
diff --git a/drivers/gpio/mvgpio.h b/drivers/gpio/mvgpio.h
new file mode 100644
index 0000000..9688797
--- /dev/null
+++ b/drivers/gpio/mvgpio.h
@@ -0,0 +1,74 @@
+/*
+ * (C) Copyright 2011
+ * eInfochips Ltd. <www.einfochips.com>
+ * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
+ *
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef __MVGPIO_H__
+#define __MVGPIO_H__
+
+#include <common.h>
+
+#ifdef CONFIG_SHEEVA_88SV331xV5
+/*
+ * GPIO Register map for SHEEVA 88SV331xV5
+ */
+struct gpio_reg {
+	u32 gplr;	/* Pin Level Register - 0x0000 */
+	u32 pad0[2];
+	u32 gpdr;	/* Pin Direction Register - 0x000C */
+	u32 pad1[2];
+	u32 gpsr;	/* Pin Output Set Register - 0x0018 */
+	u32 pad2[2];
+	u32 gpcr;	/* Pin Output Clear Register - 0x0024 */
+	u32 pad3[2];
+	u32 grer;	/* Rising-Edge Detect Enable Register - 0x0030 */
+	u32 pad4[2];
+	u32 gfer;	/* Falling-Edge Detect Enable Register - 0x003C */
+	u32 pad5[2];
+	u32 gedr;	/* Edge Detect Status Register - 0x0048 */
+	u32 pad6[2];
+	u32 gsdr;	/* Bitwise Set of GPIO Direction Register - 0x0054 */
+	u32 pad7[2];
+	u32 gcdr;	/* Bitwise Clear of GPIO Direction Register - 0x0060 */
+	u32 pad8[2];
+	u32 gsrer;	/* Bitwise Set of Rising-Edge Detect Enable
+			   Register - 0x006C */
+	u32 pad9[2];
+	u32 gcrer;	/* Bitwise Clear of Rising-Edge Detect Enable
+			   Register - 0x0078 */
+	u32 pad10[2];
+	u32 gsfer;	/* Bitwise Set of Falling-Edge Detect Enable
+			   Register - 0x0084 */
+	u32 pad11[2];
+	u32 gcfer;	/* Bitwise Clear of Falling-Edge Detect Enable
+			   Register - 0x0090 */
+	u32 pad12[2];
+	u32 apmask;	/* Bitwise Mask of Edge Detect Register - 0x009C */
+};
+#else
+#error "CPU core subversion not defined"
+#endif
+
+#endif /* __MVGPIO_H__ */
diff --git a/drivers/i2c/davinci_i2c.c b/drivers/i2c/davinci_i2c.c
index eee1cbd..5e3406d 100644
--- a/drivers/i2c/davinci_i2c.c
+++ b/drivers/i2c/davinci_i2c.c
@@ -119,6 +119,11 @@
 	udelay(1000);
 }
 
+int i2c_set_bus_speed(unsigned int speed)
+{
+	i2c_init(speed, CONFIG_SYS_I2C_SLAVE);
+	return 0;
+}
 
 int i2c_probe(u_int8_t chip)
 {
diff --git a/drivers/i2c/mxc_i2c.c b/drivers/i2c/mxc_i2c.c
index ebde3c5..a805bf6 100644
--- a/drivers/i2c/mxc_i2c.c
+++ b/drivers/i2c/mxc_i2c.c
@@ -1,7 +1,15 @@
 /*
- * i2c driver for Freescale mx31
+ * i2c driver for Freescale i.MX series
  *
  * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
+ * (c) 2011 Marek Vasut <marek.vasut@gmail.com>
+ *
+ * Based on i2c-imx.c from linux kernel:
+ *  Copyright (C) 2005 Torsten Koschorrek <koschorrek at synertronixx.de>
+ *  Copyright (C) 2005 Matthias Blaschke <blaschke at synertronixx.de>
+ *  Copyright (C) 2007 RightHand Technologies, Inc.
+ *  Copyright (C) 2008 Darius Augulis <darius.augulis at teltonika.lt>
+ *
  *
  * See file CREDITS for list of people who contributed to this
  * project.
@@ -30,11 +38,13 @@
 #include <asm/arch/clock.h>
 #include <asm/arch/imx-regs.h>
 
-#define IADR	0x00
-#define IFDR	0x04
-#define I2CR	0x08
-#define I2SR	0x0c
-#define I2DR	0x10
+struct mxc_i2c_regs {
+	uint32_t	iadr;
+	uint32_t	ifdr;
+	uint32_t	i2cr;
+	uint32_t	i2sr;
+	uint32_t	i2dr;
+};
 
 #define I2CR_IEN	(1 << 7)
 #define I2CR_IIEN	(1 << 6)
@@ -68,215 +78,361 @@
 #endif
 
 #define I2C_MAX_TIMEOUT		10000
-#define I2C_MAX_RETRIES		3
 
-static u16 div[] = { 30, 32, 36, 42, 48, 52, 60, 72, 80, 88, 104, 128, 144,
-	             160, 192, 240, 288, 320, 384, 480, 576, 640, 768, 960,
-	             1152, 1280, 1536, 1920, 2304, 2560, 3072, 3840};
+static u16 i2c_clk_div[50][2] = {
+	{ 22,	0x20 }, { 24,	0x21 }, { 26,	0x22 }, { 28,	0x23 },
+	{ 30,	0x00 }, { 32,	0x24 }, { 36,	0x25 }, { 40,	0x26 },
+	{ 42,	0x03 }, { 44,	0x27 }, { 48,	0x28 }, { 52,	0x05 },
+	{ 56,	0x29 }, { 60,	0x06 }, { 64,	0x2A }, { 72,	0x2B },
+	{ 80,	0x2C }, { 88,	0x09 }, { 96,	0x2D }, { 104,	0x0A },
+	{ 112,	0x2E }, { 128,	0x2F }, { 144,	0x0C }, { 160,	0x30 },
+	{ 192,	0x31 }, { 224,	0x32 }, { 240,	0x0F }, { 256,	0x33 },
+	{ 288,	0x10 }, { 320,	0x34 }, { 384,	0x35 }, { 448,	0x36 },
+	{ 480,	0x13 }, { 512,	0x37 }, { 576,	0x14 }, { 640,	0x38 },
+	{ 768,	0x39 }, { 896,	0x3A }, { 960,	0x17 }, { 1024,	0x3B },
+	{ 1152,	0x18 }, { 1280,	0x3C }, { 1536,	0x3D }, { 1792,	0x3E },
+	{ 1920,	0x1B }, { 2048,	0x3F }, { 2304,	0x1C }, { 2560,	0x1D },
+	{ 3072,	0x1E }, { 3840,	0x1F }
+};
 
-static inline void i2c_reset(void)
+static u8 clk_idx;
+
+/*
+ * Calculate and set proper clock divider
+ */
+static void i2c_imx_set_clk(unsigned int rate)
 {
-	writew(0, I2C_BASE + I2CR);	/* Reset module */
-	writew(0, I2C_BASE + I2SR);
-	writew(I2CR_IEN, I2C_BASE + I2CR);
-}
-
-void i2c_init(int speed, int unused)
-{
-	int freq;
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+	unsigned int i2c_clk_rate;
+	unsigned int div;
 	int i;
 
 #if defined(CONFIG_MX31)
 	struct clock_control_regs *sc_regs =
 		(struct clock_control_regs *)CCM_BASE;
+
 	/* start the required I2C clock */
 	writel(readl(&sc_regs->cgr0) | (3 << I2C_CLK_OFFSET),
 		&sc_regs->cgr0);
 #endif
-	freq = mxc_get_clock(MXC_IPG_PERCLK);
 
-	for (i = 0; i < 0x1f; i++)
-		if (freq / div[i] <= speed)
-			break;
+	/* Divider value calculation */
+	i2c_clk_rate = mxc_get_clock(MXC_IPG_PERCLK);
+	div = (i2c_clk_rate + rate - 1) / rate;
+	if (div < i2c_clk_div[0][0])
+		i = 0;
+	else if (div > i2c_clk_div[ARRAY_SIZE(i2c_clk_div) - 1][0])
+		i = ARRAY_SIZE(i2c_clk_div) - 1;
+	else
+		for (i = 0; i2c_clk_div[i][0] < div; i++)
+			;
 
-	debug("%s: speed: %d\n", __func__, speed);
+	/* Store divider value */
+	clk_idx = i2c_clk_div[i][1];
+	writeb(clk_idx, &i2c_regs->ifdr);
+}
 
-	writew(i, I2C_BASE + IFDR);
+/*
+ * Reset I2C Controller
+ */
+void i2c_reset(void)
+{
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+
+	writeb(0, &i2c_regs->i2cr);	/* Reset module */
+	writeb(0, &i2c_regs->i2sr);
+}
+
+/*
+ * Init I2C Bus
+ */
+void i2c_init(int speed, int unused)
+{
+	i2c_imx_set_clk(speed);
 	i2c_reset();
 }
 
-static int wait_idle(void)
+/*
+ * Wait for bus to be busy (or free if for_busy = 0)
+ *
+ * for_busy = 1: Wait for IBB to be asserted
+ * for_busy = 0: Wait for IBB to be de-asserted
+ */
+int i2c_imx_bus_busy(int for_busy)
 {
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+	unsigned int temp;
+
 	int timeout = I2C_MAX_TIMEOUT;
 
-	while ((readw(I2C_BASE + I2SR) & I2SR_IBB) && --timeout) {
-		writew(0, I2C_BASE + I2SR);
+	while (timeout--) {
+		temp = readb(&i2c_regs->i2sr);
+
+		if (for_busy && (temp & I2SR_IBB))
+			return 0;
+		if (!for_busy && !(temp & I2SR_IBB))
+			return 0;
+
 		udelay(1);
 	}
-	return timeout ? timeout : (!(readw(I2C_BASE + I2SR) & I2SR_IBB));
+
+	return 1;
 }
 
-static int wait_busy(void)
+/*
+ * Wait for transaction to complete
+ */
+int i2c_imx_trx_complete(void)
 {
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
 	int timeout = I2C_MAX_TIMEOUT;
 
-	while (!(readw(I2C_BASE + I2SR) & I2SR_IBB) && --timeout)
-		udelay(1);
-	writew(0, I2C_BASE + I2SR); /* clear interrupt */
+	while (timeout--) {
+		if (readb(&i2c_regs->i2sr) & I2SR_IIF) {
+			writeb(0, &i2c_regs->i2sr);
+			return 0;
+		}
 
-	return timeout;
-}
-
-static int wait_complete(void)
-{
-	int timeout = I2C_MAX_TIMEOUT;
-
-	while ((!(readw(I2C_BASE + I2SR) & I2SR_ICF)) && (--timeout)) {
-		writew(0, I2C_BASE + I2SR);
 		udelay(1);
 	}
-	udelay(200);
 
-	writew(0, I2C_BASE + I2SR);	/* clear interrupt */
-
-	return timeout;
+	return 1;
 }
 
-
-static int tx_byte(u8 byte)
+/*
+ * Check if the transaction was ACKed
+ */
+int i2c_imx_acked(void)
 {
-	writew(byte, I2C_BASE + I2DR);
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
 
-	if (!wait_complete() || readw(I2C_BASE + I2SR) & I2SR_RX_NO_AK)
-		return -1;
+	return readb(&i2c_regs->i2sr) & I2SR_RX_NO_AK;
+}
+
+/*
+ * Start the controller
+ */
+int i2c_imx_start(void)
+{
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+	unsigned int temp = 0;
+	int result;
+
+	writeb(clk_idx, &i2c_regs->ifdr);
+
+	/* Enable I2C controller */
+	writeb(0, &i2c_regs->i2sr);
+	writeb(I2CR_IEN, &i2c_regs->i2cr);
+
+	/* Wait controller to be stable */
+	udelay(50);
+
+	/* Start I2C transaction */
+	temp = readb(&i2c_regs->i2cr);
+	temp |= I2CR_MSTA;
+	writeb(temp, &i2c_regs->i2cr);
+
+	result = i2c_imx_bus_busy(1);
+	if (result)
+		return result;
+
+	temp |= I2CR_MTX | I2CR_TX_NO_AK;
+	writeb(temp, &i2c_regs->i2cr);
+
 	return 0;
 }
 
-static int rx_byte(int last)
+/*
+ * Stop the controller
+ */
+void i2c_imx_stop(void)
 {
-	if (!wait_complete())
-		return -1;
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+	unsigned int temp = 0;
 
-	if (last)
-		writew(I2CR_IEN, I2C_BASE + I2CR);
+	/* Stop I2C transaction */
+	temp = readb(&i2c_regs->i2cr);
+	temp |= ~(I2CR_MSTA | I2CR_MTX);
+	writeb(temp, &i2c_regs->i2cr);
 
-	return readw(I2C_BASE + I2DR);
+	i2c_imx_bus_busy(0);
+
+	/* Disable I2C controller */
+	writeb(0, &i2c_regs->i2cr);
 }
 
-int i2c_probe(uchar chip)
+/*
+ * Set chip address and access mode
+ *
+ * read = 1: READ access
+ * read = 0: WRITE access
+ */
+int i2c_imx_set_chip_addr(uchar chip, int read)
 {
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
 	int ret;
 
-	writew(0, I2C_BASE + I2CR); /* Reset module */
-	writew(I2CR_IEN, I2C_BASE + I2CR);
+	writeb((chip << 1) | read, &i2c_regs->i2dr);
 
-	writew(I2CR_IEN |  I2CR_MSTA | I2CR_MTX, I2C_BASE + I2CR);
-	ret = tx_byte(chip << 1);
-	writew(I2CR_IEN | I2CR_MTX, I2C_BASE + I2CR);
+	ret = i2c_imx_trx_complete();
+	if (ret)
+		return ret;
+
+	ret = i2c_imx_acked();
+	if (ret)
+		return ret;
 
 	return ret;
 }
 
-static int i2c_addr(uchar chip, uint addr, int alen)
+/*
+ * Write register address
+ */
+int i2c_imx_set_reg_addr(uint addr, int alen)
 {
-	int i, retry = 0;
-	for (retry = 0; retry < 3; retry++) {
-		if (wait_idle())
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+	int ret;
+	int i;
+
+	for (i = 0; i < (8 * alen); i += 8) {
+		writeb((addr >> i) & 0xff, &i2c_regs->i2dr);
+
+		ret = i2c_imx_trx_complete();
+		if (ret)
 			break;
-		i2c_reset();
-		for (i = 0; i < I2C_MAX_TIMEOUT; i++)
-			udelay(1);
-	}
-	if (retry >= I2C_MAX_RETRIES) {
-		debug("%s:bus is busy(%x)\n",
-		       __func__, readw(I2C_BASE + I2SR));
-		return -1;
-	}
-	writew(I2CR_IEN | I2CR_MSTA | I2CR_MTX, I2C_BASE + I2CR);
 
-	if (!wait_busy()) {
-		debug("%s:trigger start fail(%x)\n",
-		       __func__, readw(I2C_BASE + I2SR));
-		return -1;
+		ret = i2c_imx_acked();
+		if (ret)
+			break;
 	}
 
-	if (tx_byte(chip << 1) || (readw(I2C_BASE + I2SR) & I2SR_RX_NO_AK)) {
-		debug("%s:chip address cycle fail(%x)\n",
-		       __func__, readw(I2C_BASE + I2SR));
-		return -1;
-	}
-	while (alen--)
-		if (tx_byte((addr >> (alen * 8)) & 0xff) ||
-		    (readw(I2C_BASE + I2SR) & I2SR_RX_NO_AK)) {
-			debug("%s:device address cycle fail(%x)\n",
-			       __func__, readw(I2C_BASE + I2SR));
-			return -1;
-		}
-	return 0;
+	return ret;
 }
 
-int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
+/*
+ * Try if a chip add given address responds (probe the chip)
+ */
+int i2c_probe(uchar chip)
 {
-	int timeout = I2C_MAX_TIMEOUT;
 	int ret;
 
-	debug("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",
-		__func__, chip, addr, alen, len);
+	ret = i2c_imx_start();
+	if (ret)
+		return ret;
 
-	if (i2c_addr(chip, addr, alen)) {
-		printf("i2c_addr failed\n");
-		return -1;
-	}
+	ret = i2c_imx_set_chip_addr(chip, 0);
+	if (ret)
+		return ret;
 
-	writew(I2CR_IEN | I2CR_MSTA | I2CR_MTX | I2CR_RSTA, I2C_BASE + I2CR);
+	i2c_imx_stop();
 
-	if (tx_byte(chip << 1 | 1))
-		return -1;
-
-	writew(I2CR_IEN | I2CR_MSTA |
-		((len == 1) ? I2CR_TX_NO_AK : 0),
-		I2C_BASE + I2CR);
-
-	ret = readw(I2C_BASE + I2DR);
-
-	while (len--) {
-		ret = rx_byte(len == 0);
-		if (ret  < 0)
-			return -1;
-		*buf++ = ret;
-		if (len <= 1)
-			writew(I2CR_IEN | I2CR_MSTA |
-				I2CR_TX_NO_AK,
-				I2C_BASE + I2CR);
-	}
-
-	writew(I2CR_IEN, I2C_BASE + I2CR);
-
-	while (readw(I2C_BASE + I2SR) & I2SR_IBB && --timeout)
-		udelay(1);
-
-	return 0;
+	return ret;
 }
 
+/*
+ * Read data from I2C device
+ */
+int i2c_read(uchar chip, uint addr, int alen, uchar *buf, int len)
+{
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+	int ret;
+	unsigned int temp;
+	int i;
+
+	ret = i2c_imx_start();
+	if (ret)
+		return ret;
+
+	/* write slave address */
+	ret = i2c_imx_set_chip_addr(chip, 0);
+	if (ret)
+		return ret;
+
+	ret = i2c_imx_set_reg_addr(addr, alen);
+	if (ret)
+		return ret;
+
+	temp = readb(&i2c_regs->i2cr);
+	temp |= I2CR_RSTA;
+	writeb(temp, &i2c_regs->i2cr);
+
+	ret = i2c_imx_set_chip_addr(chip, 1);
+	if (ret)
+		return ret;
+
+	/* setup bus to read data */
+	temp = readb(&i2c_regs->i2cr);
+	temp &= ~(I2CR_MTX | I2CR_TX_NO_AK);
+	if (len == 1)
+		temp |= I2CR_TX_NO_AK;
+	writeb(temp, &i2c_regs->i2cr);
+	readb(&i2c_regs->i2dr);
+
+	/* read data */
+	for (i = 0; i < len; i++) {
+		ret = i2c_imx_trx_complete();
+		if (ret)
+			return ret;
+
+		/*
+		 * It must generate STOP before read I2DR to prevent
+		 * controller from generating another clock cycle
+		 */
+		if (i == (len - 1)) {
+			temp = readb(&i2c_regs->i2cr);
+			temp &= ~(I2CR_MSTA | I2CR_MTX);
+			writeb(temp, &i2c_regs->i2cr);
+			i2c_imx_bus_busy(0);
+		} else if (i == (len - 2)) {
+			temp = readb(&i2c_regs->i2cr);
+			temp |= I2CR_TX_NO_AK;
+			writeb(temp, &i2c_regs->i2cr);
+		}
+
+		buf[i] = readb(&i2c_regs->i2dr);
+	}
+
+	i2c_imx_stop();
+
+	return ret;
+}
+
+/*
+ * Write data to I2C device
+ */
 int i2c_write(uchar chip, uint addr, int alen, uchar *buf, int len)
 {
-	int timeout = I2C_MAX_TIMEOUT;
-	debug("%s chip: 0x%02x addr: 0x%04x alen: %d len: %d\n",
-		__func__, chip, addr, alen, len);
+	struct mxc_i2c_regs *i2c_regs = (struct mxc_i2c_regs *)I2C_BASE;
+	int ret;
+	int i;
 
-	if (i2c_addr(chip, addr, alen))
-		return -1;
+	ret = i2c_imx_start();
+	if (ret)
+		return ret;
 
-	while (len--)
-		if (tx_byte(*buf++))
-			return -1;
+	/* write slave address */
+	ret = i2c_imx_set_chip_addr(chip, 0);
+	if (ret)
+		return ret;
 
-	writew(I2CR_IEN, I2C_BASE + I2CR);
+	ret = i2c_imx_set_reg_addr(addr, alen);
+	if (ret)
+		return ret;
 
-	while (readw(I2C_BASE + I2SR) & I2SR_IBB && --timeout)
-		udelay(1);
+	for (i = 0; i < len; i++) {
+		writeb(buf[i], &i2c_regs->i2dr);
 
-	return 0;
+		ret = i2c_imx_trx_complete();
+		if (ret)
+			return ret;
+
+		ret = i2c_imx_acked();
+		if (ret)
+			return ret;
+	}
+
+	i2c_imx_stop();
+
+	return ret;
 }
-
 #endif /* CONFIG_HARD_I2C */
diff --git a/drivers/misc/fsl_pmic.c b/drivers/misc/fsl_pmic.c
index ef80ad9..23255a5 100644
--- a/drivers/misc/fsl_pmic.c
+++ b/drivers/misc/fsl_pmic.c
@@ -230,6 +230,6 @@
 U_BOOT_CMD(
 	pmic,	CONFIG_SYS_MAXARGS, 1, do_pmic,
 	"Freescale PMIC (Atlas)",
-	"dump [numregs] dump registers\n"
+	"dump [numregs] - dump registers\n"
 	"pmic write <reg> <value> - write register"
 );
diff --git a/drivers/mmc/omap_hsmmc.c b/drivers/mmc/omap_hsmmc.c
index ef12ecd..5d4cf51 100644
--- a/drivers/mmc/omap_hsmmc.c
+++ b/drivers/mmc/omap_hsmmc.c
@@ -28,6 +28,7 @@
 #include <part.h>
 #include <i2c.h>
 #include <twl4030.h>
+#include <twl6030.h>
 #include <asm/io.h>
 #include <asm/arch/mmc_host_def.h>
 #include <asm/arch/sys_proto.h>
@@ -38,7 +39,27 @@
 static int mmc_read_data(hsmmc_t *mmc_base, char *buf, unsigned int size);
 static int mmc_write_data(hsmmc_t *mmc_base, const char *buf, unsigned int siz);
 static struct mmc hsmmc_dev[2];
-unsigned char mmc_board_init(hsmmc_t *mmc_base)
+
+#if defined(CONFIG_OMAP44XX) && defined(CONFIG_TWL6030_POWER)
+static void omap4_vmmc_pbias_config(struct mmc *mmc)
+{
+	u32 value = 0;
+	struct omap4_sys_ctrl_regs *const ctrl =
+		(struct omap4_sys_ctrl_regs *)SYSCTRL_GENERAL_CORE_BASE;
+
+
+	value = readl(&ctrl->control_pbiaslite);
+	value &= ~(MMC1_PBIASLITE_PWRDNZ | MMC1_PWRDNZ);
+	writel(value, &ctrl->control_pbiaslite);
+	/* set VMMC to 3V */
+	twl6030_power_mmc_init();
+	value = readl(&ctrl->control_pbiaslite);
+	value |= MMC1_PBIASLITE_VMODE | MMC1_PBIASLITE_PWRDNZ | MMC1_PWRDNZ;
+	writel(value, &ctrl->control_pbiaslite);
+}
+#endif
+
+unsigned char mmc_board_init(struct mmc *mmc)
 {
 #if defined(CONFIG_TWL4030_POWER)
 	twl4030_power_mmc_init();
@@ -67,7 +88,11 @@
 		&prcm_base->iclken1_core);
 #endif
 
-/* TODO add appropriate OMAP4 init - none currently necessary */
+#if defined(CONFIG_OMAP44XX) && defined(CONFIG_TWL6030_POWER)
+	/* PBIAS config needed for MMC1 only */
+	if (mmc->block_dev.dev == 0)
+		omap4_vmmc_pbias_config(mmc);
+#endif
 
 	return 0;
 }
@@ -108,7 +133,7 @@
 	unsigned int dsor;
 	ulong start;
 
-	mmc_board_init(mmc_base);
+	mmc_board_init(mmc);
 
 	writel(readl(&mmc_base->sysconfig) | MMC_SOFTRESET,
 		&mmc_base->sysconfig);
@@ -461,7 +486,8 @@
 		return 1;
 	}
 	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34 | MMC_VDD_165_195;
-	mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS;
+	mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS_52MHz | MMC_MODE_HS |
+				MMC_MODE_HC;
 
 	mmc->f_min = 400000;
 	mmc->f_max = 52000000;
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 8b598f6..b6a7886 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -26,12 +26,18 @@
 LIB	:= $(obj)libnand.o
 
 ifdef CONFIG_CMD_NAND
+ifdef CONFIG_SPL_BUILD
+ifdef CONFIG_SPL_NAND_SIMPLE
+COBJS-y += nand_spl_simple.o
+endif
+else
 COBJS-y += nand.o
-COBJS-y += nand_base.o
 COBJS-y += nand_bbt.o
-COBJS-y += nand_ecc.o
 COBJS-y += nand_ids.o
 COBJS-y += nand_util.o
+endif
+COBJS-y += nand_ecc.o
+COBJS-y += nand_base.o
 
 COBJS-$(CONFIG_NAND_ATMEL) += atmel_nand.o
 COBJS-$(CONFIG_DRIVER_NAND_BFIN) += bfin_nand.o
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index 1a95a91..e7dfcb1 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -213,7 +213,7 @@
  *
  * Default read function for 8bit buswith
  */
-static void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
+void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len)
 {
 	int i;
 	struct nand_chip *chip = mtd->priv;
@@ -269,7 +269,7 @@
  *
  * Default read function for 16bit buswith
  */
-static void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
+void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len)
 {
 	int i;
 	struct nand_chip *chip = mtd->priv;
diff --git a/drivers/mtd/nand/nand_spl_simple.c b/drivers/mtd/nand/nand_spl_simple.c
new file mode 100644
index 0000000..71491d4
--- /dev/null
+++ b/drivers/mtd/nand/nand_spl_simple.c
@@ -0,0 +1,245 @@
+/*
+ * (C) Copyright 2006-2008
+ * Stefan Roese, DENX Software Engineering, sr@denx.de.
+ *
+ * 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 <nand.h>
+#include <asm/io.h>
+
+static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS;
+static nand_info_t mtd;
+static struct nand_chip nand_chip;
+
+#if (CONFIG_SYS_NAND_PAGE_SIZE <= 512)
+/*
+ * NAND command for small page NAND devices (512)
+ */
+static int nand_command(int block, int page, uint32_t offs,
+	u8 cmd)
+{
+	struct nand_chip *this = mtd.priv;
+	int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
+
+	while (!this->dev_ready(&mtd))
+		;
+
+	/* Begin command latch cycle */
+	this->cmd_ctrl(&mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
+	/* Set ALE and clear CLE to start address cycle */
+	/* Column address */
+	this->cmd_ctrl(&mtd, offs, NAND_CTRL_ALE | NAND_CTRL_CHANGE);
+	this->cmd_ctrl(&mtd, page_addr & 0xff, NAND_CTRL_ALE); /* A[16:9] */
+	this->cmd_ctrl(&mtd, (page_addr >> 8) & 0xff,
+		       NAND_CTRL_ALE); /* A[24:17] */
+#ifdef CONFIG_SYS_NAND_4_ADDR_CYCLE
+	/* One more address cycle for devices > 32MiB */
+	this->cmd_ctrl(&mtd, (page_addr >> 16) & 0x0f,
+		       NAND_CTRL_ALE); /* A[28:25] */
+#endif
+	/* Latch in address */
+	this->cmd_ctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+
+	/*
+	 * Wait a while for the data to be ready
+	 */
+	while (!this->dev_ready(&mtd))
+		;
+
+	return 0;
+}
+#else
+/*
+ * NAND command for large page NAND devices (2k)
+ */
+static int nand_command(int block, int page, uint32_t offs,
+	u8 cmd)
+{
+	struct nand_chip *this = mtd.priv;
+	int page_addr = page + block * CONFIG_SYS_NAND_PAGE_COUNT;
+	void (*hwctrl)(struct mtd_info *mtd, int cmd,
+			unsigned int ctrl) = this->cmd_ctrl;
+
+	while (!this->dev_ready(&mtd))
+		;
+
+	/* Emulate NAND_CMD_READOOB */
+	if (cmd == NAND_CMD_READOOB) {
+		offs += CONFIG_SYS_NAND_PAGE_SIZE;
+		cmd = NAND_CMD_READ0;
+	}
+
+	/* Shift the offset from byte addressing to word addressing. */
+	if (this->options & NAND_BUSWIDTH_16)
+		offs >>= 1;
+
+	/* Begin command latch cycle */
+	hwctrl(&mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
+	/* Set ALE and clear CLE to start address cycle */
+	/* Column address */
+	hwctrl(&mtd, offs & 0xff,
+		       NAND_CTRL_ALE | NAND_CTRL_CHANGE); /* A[7:0] */
+	hwctrl(&mtd, (offs >> 8) & 0xff, NAND_CTRL_ALE); /* A[11:9] */
+	/* Row address */
+	hwctrl(&mtd, (page_addr & 0xff), NAND_CTRL_ALE); /* A[19:12] */
+	hwctrl(&mtd, ((page_addr >> 8) & 0xff),
+		       NAND_CTRL_ALE); /* A[27:20] */
+#ifdef CONFIG_SYS_NAND_5_ADDR_CYCLE
+	/* One more address cycle for devices > 128MiB */
+	hwctrl(&mtd, (page_addr >> 16) & 0x0f,
+		       NAND_CTRL_ALE); /* A[31:28] */
+#endif
+	/* Latch in address */
+	hwctrl(&mtd, NAND_CMD_READSTART,
+		       NAND_CTRL_CLE | NAND_CTRL_CHANGE);
+	hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+
+	/*
+	 * Wait a while for the data to be ready
+	 */
+	while (!this->dev_ready(&mtd))
+		;
+
+	return 0;
+}
+#endif
+
+static int nand_is_bad_block(int block)
+{
+	struct nand_chip *this = mtd.priv;
+
+	nand_command(block, 0, CONFIG_SYS_NAND_BAD_BLOCK_POS,
+		NAND_CMD_READOOB);
+
+	/*
+	 * Read one byte (or two if it's a 16 bit chip).
+	 */
+	if (this->options & NAND_BUSWIDTH_16) {
+		if (readw(this->IO_ADDR_R) != 0xffff)
+			return 1;
+	} else {
+		if (readb(this->IO_ADDR_R) != 0xff)
+			return 1;
+	}
+
+	return 0;
+}
+
+static int nand_read_page(int block, int page, void *dst)
+{
+	struct nand_chip *this = mtd.priv;
+	u_char *ecc_calc;
+	u_char *ecc_code;
+	u_char *oob_data;
+	int i;
+	int eccsize = CONFIG_SYS_NAND_ECCSIZE;
+	int eccbytes = CONFIG_SYS_NAND_ECCBYTES;
+	int eccsteps = CONFIG_SYS_NAND_ECCSTEPS;
+	uint8_t *p = dst;
+	int stat;
+
+	nand_command(block, page, 0, NAND_CMD_READ0);
+
+	/* No malloc available for now, just use some temporary locations
+	 * in SDRAM
+	 */
+	ecc_calc = (u_char *)(CONFIG_SYS_SDRAM_BASE + 0x10000);
+	ecc_code = ecc_calc + 0x100;
+	oob_data = ecc_calc + 0x200;
+
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		this->ecc.hwctl(&mtd, NAND_ECC_READ);
+		this->read_buf(&mtd, p, eccsize);
+		this->ecc.calculate(&mtd, p, &ecc_calc[i]);
+	}
+	this->read_buf(&mtd, oob_data, CONFIG_SYS_NAND_OOBSIZE);
+
+	/* Pick the ECC bytes out of the oob data */
+	for (i = 0; i < CONFIG_SYS_NAND_ECCTOTAL; i++)
+		ecc_code[i] = oob_data[nand_ecc_pos[i]];
+
+	eccsteps = CONFIG_SYS_NAND_ECCSTEPS;
+	p = dst;
+
+	for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		/* No chance to do something with the possible error message
+		 * from correct_data(). We just hope that all possible errors
+		 * are corrected by this routine.
+		 */
+		stat = this->ecc.correct(&mtd, p, &ecc_code[i], &ecc_calc[i]);
+	}
+
+	return 0;
+}
+
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst)
+{
+	unsigned int block, lastblock;
+	unsigned int page;
+
+	/*
+	 * offs has to be aligned to a page address!
+	 */
+	block = offs / CONFIG_SYS_NAND_BLOCK_SIZE;
+	lastblock = (offs + size - 1) / CONFIG_SYS_NAND_BLOCK_SIZE;
+	page = (offs % CONFIG_SYS_NAND_BLOCK_SIZE) / CONFIG_SYS_NAND_PAGE_SIZE;
+
+	while (block <= lastblock) {
+		if (!nand_is_bad_block(block)) {
+			/*
+			 * Skip bad blocks
+			 */
+			while (page < CONFIG_SYS_NAND_PAGE_COUNT) {
+				nand_read_page(block, page, dst);
+				dst += CONFIG_SYS_NAND_PAGE_SIZE;
+				page++;
+			}
+
+			page = 0;
+		} else {
+			lastblock++;
+		}
+
+		block++;
+	}
+
+	return 0;
+}
+
+/* nand_init() - initialize data to make nand usable by SPL */
+void nand_init(void)
+{
+	/*
+	 * Init board specific nand support
+	 */
+	mtd.priv = &nand_chip;
+	nand_chip.IO_ADDR_R = nand_chip.IO_ADDR_W =
+		(void  __iomem *)CONFIG_SYS_NAND_BASE;
+	nand_chip.options = 0;
+	board_nand_init(&nand_chip);
+
+	if (nand_chip.select_chip)
+		nand_chip.select_chip(&mtd, 0);
+}
+
+/* Unselect after operation */
+void nand_deselect(void)
+{
+	if (nand_chip.select_chip)
+		nand_chip.select_chip(&mtd, -1);
+}
diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c
index 99b9cef..5bbec48 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -61,6 +61,14 @@
 		writeb(cmd, this->IO_ADDR_W);
 }
 
+#ifdef CONFIG_SPL_BUILD
+/* Check wait pin as dev ready indicator */
+int omap_spl_dev_ready(struct mtd_info *mtd)
+{
+	return gpmc_cfg->status & (1 << 8);
+}
+#endif
+
 /*
  * omap_hwecc_init - Initialize the Hardware ECC for NAND flash in
  *                   GPMC controller
@@ -224,6 +232,7 @@
 	}
 }
 
+#ifndef CONFIG_SPL_BUILD
 /*
  * omap_nand_switch_ecc - switch the ECC operation b/w h/w ecc and s/w ecc.
  * The default is to come up on s/w ecc
@@ -280,6 +289,7 @@
 
 	nand->options &= ~NAND_OWN_BUFFERS;
 }
+#endif /* CONFIG_SPL_BUILD */
 
 /*
  * Board-specific NAND initialization. The following members of the
@@ -338,7 +348,24 @@
 
 	nand->chip_delay = 100;
 	/* Default ECC mode */
+#ifndef CONFIG_SPL_BUILD
 	nand->ecc.mode = NAND_ECC_SOFT;
+#else
+	nand->ecc.mode = NAND_ECC_HW;
+	nand->ecc.layout = &hw_nand_oob;
+	nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
+	nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
+	nand->ecc.hwctl = omap_enable_hwecc;
+	nand->ecc.correct = omap_correct_data;
+	nand->ecc.calculate = omap_calculate_ecc;
+	omap_hwecc_init(nand);
+
+	if (nand->options & NAND_BUSWIDTH_16)
+		nand->read_buf = nand_read_buf16;
+	else
+		nand->read_buf = nand_read_buf;
+	nand->dev_ready = omap_spl_dev_ready;
+#endif
 
 	return 0;
 }
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 819b197..34b4322 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -28,6 +28,7 @@
 COBJS-$(CONFIG_DRIVER_3C589) += 3c589.o
 COBJS-$(CONFIG_PPC4xx_EMAC) += 4xx_enet.o
 COBJS-$(CONFIG_ALTERA_TSE) += altera_tse.o
+COBJS-$(CONFIG_ARMADA100_FEC) += armada100_fec.o
 COBJS-$(CONFIG_DRIVER_AT91EMAC) += at91_emac.o
 COBJS-$(CONFIG_DRIVER_AX88180) += ax88180.o
 COBJS-$(CONFIG_BCM570x) += bcm570x.o
diff --git a/drivers/net/armada100_fec.c b/drivers/net/armada100_fec.c
new file mode 100644
index 0000000..fbf9763
--- /dev/null
+++ b/drivers/net/armada100_fec.c
@@ -0,0 +1,736 @@
+/*
+ * (C) Copyright 2011
+ * eInfochips Ltd. <www.einfochips.com>
+ * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
+ *
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.com>
+ * Contributor: Mahavir Jain <mjain@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#include <common.h>
+#include <net.h>
+#include <malloc.h>
+#include <miiphy.h>
+#include <netdev.h>
+#include <asm/types.h>
+#include <asm/byteorder.h>
+#include <linux/err.h>
+#include <linux/mii.h>
+#include <asm/io.h>
+#include <asm/arch/armada100.h>
+#include "armada100_fec.h"
+
+#define  PHY_ADR_REQ     0xFF	/* Magic number to read/write PHY address */
+
+#ifdef DEBUG
+static int eth_dump_regs(struct eth_device *dev)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	unsigned int i = 0;
+
+	printf("\noffset: phy_adr, value: 0x%x\n", readl(&regs->phyadr));
+	printf("offset: smi, value: 0x%x\n", readl(&regs->smi));
+	for (i = 0x400; i <= 0x4e4; i += 4)
+		printf("offset: 0x%x, value: 0x%x\n",
+			i, readl(ARMD1_FEC_BASE + i));
+	return 0;
+}
+#endif
+
+static int armdfec_phy_timeout(u32 *reg, u32 flag, int cond)
+{
+	u32 timeout = PHY_WAIT_ITERATIONS;
+	u32 reg_val;
+
+	while (--timeout) {
+		reg_val = readl(reg);
+		if (cond && (reg_val & flag))
+			break;
+		else if (!cond && !(reg_val & flag))
+			break;
+		udelay(PHY_WAIT_MICRO_SECONDS);
+	}
+	return !timeout;
+}
+
+static int smi_reg_read(const char *devname, u8 phy_addr, u8 phy_reg,
+			u16 *value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	u32 val;
+
+	if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) {
+		val = readl(&regs->phyadr);
+		*value = val & 0x1f;
+		return 0;
+	}
+
+	/* check parameters */
+	if (phy_addr > PHY_MASK) {
+		printf("ARMD100 FEC: (%s) Invalid phy address: 0x%X\n",
+				__func__, phy_addr);
+		return -EINVAL;
+	}
+	if (phy_reg > PHY_MASK) {
+		printf("ARMD100 FEC: (%s) Invalid register offset: 0x%X\n",
+				__func__, phy_reg);
+		return -EINVAL;
+	}
+
+	/* wait for the SMI register to become available */
+	if (armdfec_phy_timeout(&regs->smi, SMI_BUSY, FALSE)) {
+		printf("ARMD100 FEC: (%s) PHY busy timeout\n",	__func__);
+		return -1;
+	}
+
+	writel((phy_addr << 16) | (phy_reg << 21) | SMI_OP_R, &regs->smi);
+
+	/* now wait for the data to be valid */
+	if (armdfec_phy_timeout(&regs->smi, SMI_R_VALID, TRUE)) {
+		val = readl(&regs->smi);
+		printf("ARMD100 FEC: (%s) PHY Read timeout, val=0x%x\n",
+				__func__, val);
+		return -1;
+	}
+	val = readl(&regs->smi);
+	*value = val & 0xffff;
+
+	return 0;
+}
+
+static int smi_reg_write(const char *devname,
+	 u8 phy_addr, u8 phy_reg, u16 value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+
+	if (phy_addr == PHY_ADR_REQ && phy_reg == PHY_ADR_REQ) {
+		clrsetbits_le32(&regs->phyadr, 0x1f, value & 0x1f);
+		return 0;
+	}
+
+	/* check parameters */
+	if (phy_addr > PHY_MASK) {
+		printf("ARMD100 FEC: (%s) Invalid phy address\n", __func__);
+		return -EINVAL;
+	}
+	if (phy_reg > PHY_MASK) {
+		printf("ARMD100 FEC: (%s) Invalid register offset\n", __func__);
+		return -EINVAL;
+	}
+
+	/* wait for the SMI register to become available */
+	if (armdfec_phy_timeout(&regs->smi, SMI_BUSY, FALSE)) {
+		printf("ARMD100 FEC: (%s) PHY busy timeout\n",	__func__);
+		return -1;
+	}
+
+	writel((phy_addr << 16) | (phy_reg << 21) | SMI_OP_W | (value & 0xffff),
+			&regs->smi);
+	return 0;
+}
+
+/*
+ * Abort any transmit and receive operations and put DMA
+ * in idle state. AT and AR bits are cleared upon entering
+ * in IDLE state. So poll those bits to verify operation.
+ */
+static void abortdma(struct eth_device *dev)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	int delay;
+	int maxretries = 40;
+	u32 tmp;
+
+	while (--maxretries) {
+		writel(SDMA_CMD_AR | SDMA_CMD_AT, &regs->sdma_cmd);
+		udelay(100);
+
+		delay = 10;
+		while (--delay) {
+			tmp = readl(&regs->sdma_cmd);
+			if (!(tmp & (SDMA_CMD_AR | SDMA_CMD_AT)))
+				break;
+			udelay(10);
+		}
+		if (delay)
+			break;
+	}
+
+	if (!maxretries)
+		printf("ARMD100 FEC: (%s) DMA Stuck\n", __func__);
+}
+
+static inline u32 nibble_swapping_32_bit(u32 x)
+{
+	return ((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4);
+}
+
+static inline u32 nibble_swapping_16_bit(u32 x)
+{
+	return ((x & 0x0000f0f0) >> 4) | ((x & 0x00000f0f) << 4);
+}
+
+static inline u32 flip_4_bits(u32 x)
+{
+	return ((x & 0x01) << 3) | ((x & 0x002) << 1)
+		| ((x & 0x04) >> 1) | ((x & 0x008) >> 3);
+}
+
+/*
+ * This function will calculate the hash function of the address.
+ * depends on the hash mode and hash size.
+ * Inputs
+ * mach             - the 2 most significant bytes of the MAC address.
+ * macl             - the 4 least significant bytes of the MAC address.
+ * Outputs
+ * return the calculated entry.
+ */
+static u32 hash_function(u32 mach, u32 macl)
+{
+	u32 hashresult;
+	u32 addrh;
+	u32 addrl;
+	u32 addr0;
+	u32 addr1;
+	u32 addr2;
+	u32 addr3;
+	u32 addrhswapped;
+	u32 addrlswapped;
+
+	addrh = nibble_swapping_16_bit(mach);
+	addrl = nibble_swapping_32_bit(macl);
+
+	addrhswapped = flip_4_bits(addrh & 0xf)
+		+ ((flip_4_bits((addrh >> 4) & 0xf)) << 4)
+		+ ((flip_4_bits((addrh >> 8) & 0xf)) << 8)
+		+ ((flip_4_bits((addrh >> 12) & 0xf)) << 12);
+
+	addrlswapped = flip_4_bits(addrl & 0xf)
+		+ ((flip_4_bits((addrl >> 4) & 0xf)) << 4)
+		+ ((flip_4_bits((addrl >> 8) & 0xf)) << 8)
+		+ ((flip_4_bits((addrl >> 12) & 0xf)) << 12)
+		+ ((flip_4_bits((addrl >> 16) & 0xf)) << 16)
+		+ ((flip_4_bits((addrl >> 20) & 0xf)) << 20)
+		+ ((flip_4_bits((addrl >> 24) & 0xf)) << 24)
+		+ ((flip_4_bits((addrl >> 28) & 0xf)) << 28);
+
+	addrh = addrhswapped;
+	addrl = addrlswapped;
+
+	addr0 = (addrl >> 2) & 0x03f;
+	addr1 = (addrl & 0x003) | (((addrl >> 8) & 0x7f) << 2);
+	addr2 = (addrl >> 15) & 0x1ff;
+	addr3 = ((addrl >> 24) & 0x0ff) | ((addrh & 1) << 8);
+
+	hashresult = (addr0 << 9) | (addr1 ^ addr2 ^ addr3);
+	hashresult = hashresult & 0x07ff;
+	return hashresult;
+}
+
+/*
+ * This function will add an entry to the address table.
+ * depends on the hash mode and hash size that was initialized.
+ * Inputs
+ * mach - the 2 most significant bytes of the MAC address.
+ * macl - the 4 least significant bytes of the MAC address.
+ * skip - if 1, skip this address.
+ * rd   - the RD field in the address table.
+ * Outputs
+ * address table entry is added.
+ * 0 if success.
+ * -ENOSPC if table full
+ */
+static int add_del_hash_entry(struct armdfec_device *darmdfec, u32 mach,
+			      u32 macl, u32 rd, u32 skip, int del)
+{
+	struct addr_table_entry_t *entry, *start;
+	u32 newhi;
+	u32 newlo;
+	u32 i;
+
+	newlo = (((mach >> 4) & 0xf) << 15)
+		| (((mach >> 0) & 0xf) << 11)
+		| (((mach >> 12) & 0xf) << 7)
+		| (((mach >> 8) & 0xf) << 3)
+		| (((macl >> 20) & 0x1) << 31)
+		| (((macl >> 16) & 0xf) << 27)
+		| (((macl >> 28) & 0xf) << 23)
+		| (((macl >> 24) & 0xf) << 19)
+		| (skip << HTESKIP) | (rd << HTERDBIT)
+		| HTEVALID;
+
+	newhi = (((macl >> 4) & 0xf) << 15)
+		| (((macl >> 0) & 0xf) << 11)
+		| (((macl >> 12) & 0xf) << 7)
+		| (((macl >> 8) & 0xf) << 3)
+		| (((macl >> 21) & 0x7) << 0);
+
+	/*
+	 * Pick the appropriate table, start scanning for free/reusable
+	 * entries at the index obtained by hashing the specified MAC address
+	 */
+	start = (struct addr_table_entry_t *)(darmdfec->htpr);
+	entry = start + hash_function(mach, macl);
+	for (i = 0; i < HOP_NUMBER; i++) {
+		if (!(entry->lo & HTEVALID)) {
+			break;
+		} else {
+			/* if same address put in same position */
+			if (((entry->lo & 0xfffffff8) == (newlo & 0xfffffff8))
+					&& (entry->hi == newhi))
+				break;
+		}
+		if (entry == start + 0x7ff)
+			entry = start;
+		else
+			entry++;
+	}
+
+	if (((entry->lo & 0xfffffff8) != (newlo & 0xfffffff8)) &&
+		(entry->hi != newhi) && del)
+		return 0;
+
+	if (i == HOP_NUMBER) {
+		if (!del) {
+			printf("ARMD100 FEC: (%s) table section is full\n",
+					__func__);
+			return -ENOSPC;
+		} else {
+			return 0;
+		}
+	}
+
+	/*
+	 * Update the selected entry
+	 */
+	if (del) {
+		entry->hi = 0;
+		entry->lo = 0;
+	} else {
+		entry->hi = newhi;
+		entry->lo = newlo;
+	}
+
+	return 0;
+}
+
+/*
+ *  Create an addressTable entry from MAC address info
+ *  found in the specifed net_device struct
+ *
+ *  Input : pointer to ethernet interface network device structure
+ *  Output : N/A
+ */
+static void update_hash_table_mac_address(struct armdfec_device *darmdfec,
+					  u8 *oaddr, u8 *addr)
+{
+	u32 mach;
+	u32 macl;
+
+	/* Delete old entry */
+	if (oaddr) {
+		mach = (oaddr[0] << 8) | oaddr[1];
+		macl = (oaddr[2] << 24) | (oaddr[3] << 16) |
+			(oaddr[4] << 8) | oaddr[5];
+		add_del_hash_entry(darmdfec, mach, macl, 1, 0, HASH_DELETE);
+	}
+
+	/* Add new entry */
+	mach = (addr[0] << 8) | addr[1];
+	macl = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];
+	add_del_hash_entry(darmdfec, mach, macl, 1, 0, HASH_ADD);
+}
+
+/* Address Table Initialization */
+static void init_hashtable(struct eth_device *dev)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	memset(darmdfec->htpr, 0, HASH_ADDR_TABLE_SIZE);
+	writel((u32)darmdfec->htpr, &regs->htpr);
+}
+
+/*
+ * This detects PHY chip from address 0-31 by reading PHY status
+ * registers. PHY chip can be connected at any of this address.
+ */
+static int ethernet_phy_detect(struct eth_device *dev)
+{
+	u32 val;
+	u16 tmp, mii_status;
+	u8 addr;
+
+	for (addr = 0; addr < 32; addr++) {
+		if (miiphy_read(dev->name, addr, MII_BMSR, &mii_status)	!= 0)
+			/* try next phy */
+			continue;
+
+		/* invalid MII status. More validation required here... */
+		if (mii_status == 0 || mii_status == 0xffff)
+			/* try next phy */
+			continue;
+
+		if (miiphy_read(dev->name, addr, MII_PHYSID1, &tmp) != 0)
+			/* try next phy */
+			continue;
+
+		val = tmp << 16;
+		if (miiphy_read(dev->name, addr, MII_PHYSID2, &tmp) != 0)
+			/* try next phy */
+			continue;
+
+		val |= tmp;
+
+		if ((val & 0xfffffff0) != 0)
+			return addr;
+	}
+	return -1;
+}
+
+static void armdfec_init_rx_desc_ring(struct armdfec_device *darmdfec)
+{
+	struct rx_desc *p_rx_desc;
+	int i;
+
+	/* initialize the Rx descriptors ring */
+	p_rx_desc = darmdfec->p_rxdesc;
+	for (i = 0; i < RINGSZ; i++) {
+		p_rx_desc->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT;
+		p_rx_desc->buf_size = PKTSIZE_ALIGN;
+		p_rx_desc->byte_cnt = 0;
+		p_rx_desc->buf_ptr = darmdfec->p_rxbuf + i * PKTSIZE_ALIGN;
+		if (i == (RINGSZ - 1)) {
+			p_rx_desc->nxtdesc_p = darmdfec->p_rxdesc;
+		} else {
+			p_rx_desc->nxtdesc_p = (struct rx_desc *)
+			    ((u32)p_rx_desc + ARMDFEC_RXQ_DESC_ALIGNED_SIZE);
+			p_rx_desc = p_rx_desc->nxtdesc_p;
+		}
+	}
+	darmdfec->p_rxdesc_curr = darmdfec->p_rxdesc;
+}
+
+static int armdfec_init(struct eth_device *dev, bd_t *bd)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	int phy_adr;
+
+	armdfec_init_rx_desc_ring(darmdfec);
+
+	/* Disable interrupts */
+	writel(0, &regs->im);
+	writel(0, &regs->ic);
+	/* Write to ICR to clear interrupts. */
+	writel(0, &regs->iwc);
+
+	/*
+	 * Abort any transmit and receive operations and put DMA
+	 * in idle state.
+	 */
+	abortdma(dev);
+
+	/* Initialize address hash table */
+	init_hashtable(dev);
+
+	/* SDMA configuration */
+	writel(SDCR_BSZ8 |	/* Burst size = 32 bytes */
+		SDCR_RIFB |	/* Rx interrupt on frame */
+		SDCR_BLMT |	/* Little endian transmit */
+		SDCR_BLMR |	/* Little endian receive */
+		SDCR_RC_MAX_RETRANS,	/* Max retransmit count */
+		&regs->sdma_conf);
+	/* Port Configuration */
+	writel(PCR_HS, &regs->pconf);	/* Hash size is 1/2kb */
+
+	/* Set extended port configuration */
+	writel(PCXR_2BSM |		/* Two byte suffix aligns IP hdr */
+		PCXR_DSCP_EN |		/* Enable DSCP in IP */
+		PCXR_MFL_1536 |		/* Set MTU = 1536 */
+		PCXR_FLP |		/* do not force link pass */
+		PCXR_TX_HIGH_PRI,	/* Transmit - high priority queue */
+		&regs->pconf_ext);
+
+	update_hash_table_mac_address(darmdfec, NULL, dev->enetaddr);
+
+	/* Update TX and RX queue descriptor register */
+	writel((u32)darmdfec->p_txdesc, &regs->txcdp[TXQ]);
+	writel((u32)darmdfec->p_rxdesc, &regs->rxfdp[RXQ]);
+	writel((u32)darmdfec->p_rxdesc_curr, &regs->rxcdp[RXQ]);
+
+	/* Enable Interrupts */
+	writel(ALL_INTS, &regs->im);
+
+	/* Enable Ethernet Port */
+	setbits_le32(&regs->pconf, PCR_EN);
+
+	/* Enable RX DMA engine */
+	setbits_le32(&regs->sdma_cmd, SDMA_CMD_ERD);
+
+#ifdef DEBUG
+	eth_dump_regs(dev);
+#endif
+
+#if (defined(CONFIG_MII) || defined(CONFIG_CMD_MII))
+
+#if defined(CONFIG_PHY_BASE_ADR)
+	miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ, CONFIG_PHY_BASE_ADR);
+#else
+	/* Search phy address from range 0-31 */
+	phy_adr = ethernet_phy_detect(dev);
+	if (phy_adr < 0) {
+		printf("ARMD100 FEC: PHY not detected at address range 0-31\n");
+		return -1;
+	} else {
+		debug("ARMD100 FEC: PHY detected at addr %d\n", phy_adr);
+		miiphy_write(dev->name, PHY_ADR_REQ, PHY_ADR_REQ, phy_adr);
+	}
+#endif
+
+#if defined(CONFIG_SYS_FAULT_ECHO_LINK_DOWN)
+	/* Wait up to 5s for the link status */
+	for (i = 0; i < 5; i++) {
+		u16 phy_adr;
+
+		miiphy_read(dev->name, 0xFF, 0xFF, &phy_adr);
+		/* Return if we get link up */
+		if (miiphy_link(dev->name, phy_adr))
+			return 0;
+		udelay(1000000);
+	}
+
+	printf("ARMD100 FEC: No link on %s\n", dev->name);
+	return -1;
+#endif
+#endif
+	return 0;
+}
+
+static void armdfec_halt(struct eth_device *dev)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+
+	/* Stop RX DMA */
+	clrbits_le32(&regs->sdma_cmd, SDMA_CMD_ERD);
+
+	/*
+	 * Abort any transmit and receive operations and put DMA
+	 * in idle state.
+	 */
+	abortdma(dev);
+
+	/* Disable interrupts */
+	writel(0, &regs->im);
+	writel(0, &regs->ic);
+	writel(0, &regs->iwc);
+
+	/* Disable Port */
+	clrbits_le32(&regs->pconf, PCR_EN);
+}
+
+static int armdfec_send(struct eth_device *dev, volatile void *dataptr,
+		    int datasize)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct armdfec_reg *regs = darmdfec->regs;
+	struct tx_desc *p_txdesc = darmdfec->p_txdesc;
+	void *p = (void *)dataptr;
+	int retry = PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS;
+	u32 cmd_sts;
+
+	/* Copy buffer if it's misaligned */
+	if ((u32)dataptr & 0x07) {
+		if (datasize > PKTSIZE_ALIGN) {
+			printf("ARMD100 FEC: Non-aligned data too large (%d)\n",
+					datasize);
+			return -1;
+		}
+		memcpy(darmdfec->p_aligned_txbuf, p, datasize);
+		p = darmdfec->p_aligned_txbuf;
+	}
+
+	p_txdesc->cmd_sts = TX_ZERO_PADDING | TX_GEN_CRC;
+	p_txdesc->cmd_sts |= TX_FIRST_DESC | TX_LAST_DESC;
+	p_txdesc->cmd_sts |= BUF_OWNED_BY_DMA;
+	p_txdesc->cmd_sts |= TX_EN_INT;
+	p_txdesc->buf_ptr = p;
+	p_txdesc->byte_cnt = datasize;
+
+	/* Apply send command using high priority TX queue */
+	writel((u32)p_txdesc, &regs->txcdp[TXQ]);
+	writel(SDMA_CMD_TXDL | SDMA_CMD_TXDH | SDMA_CMD_ERD, &regs->sdma_cmd);
+
+	/*
+	 * wait for packet xmit completion
+	 */
+	cmd_sts = readl(&p_txdesc->cmd_sts);
+	while (cmd_sts & BUF_OWNED_BY_DMA) {
+		/* return fail if error is detected */
+		if ((cmd_sts & (TX_ERROR | TX_LAST_DESC)) ==
+			(TX_ERROR | TX_LAST_DESC)) {
+			printf("ARMD100 FEC: (%s) in xmit packet\n", __func__);
+			return -1;
+		}
+		cmd_sts = readl(&p_txdesc->cmd_sts);
+		if (!(retry--)) {
+			printf("ARMD100 FEC: (%s) xmit packet timeout!\n",
+					__func__);
+			return -1;
+		}
+	}
+
+	return 0;
+}
+
+static int armdfec_recv(struct eth_device *dev)
+{
+	struct armdfec_device *darmdfec = to_darmdfec(dev);
+	struct rx_desc *p_rxdesc_curr = darmdfec->p_rxdesc_curr;
+	u32 cmd_sts;
+	u32 timeout = 0;
+
+	/* wait untill rx packet available or timeout */
+	do {
+		if (timeout < PHY_WAIT_ITERATIONS * PHY_WAIT_MICRO_SECONDS) {
+			timeout++;
+		} else {
+			debug("ARMD100 FEC: %s time out...\n", __func__);
+			return -1;
+		}
+	} while (readl(&p_rxdesc_curr->cmd_sts) & BUF_OWNED_BY_DMA);
+
+	if (p_rxdesc_curr->byte_cnt != 0) {
+		debug("ARMD100 FEC: %s: Received %d byte Packet @ 0x%x"
+				"(cmd_sts= %08x)\n", __func__,
+				(u32)p_rxdesc_curr->byte_cnt,
+				(u32)p_rxdesc_curr->buf_ptr,
+				(u32)p_rxdesc_curr->cmd_sts);
+	}
+
+	/*
+	 * In case received a packet without first/last bits on
+	 * OR the error summary bit is on,
+	 * the packets needs to be dropeed.
+	 */
+	cmd_sts = readl(&p_rxdesc_curr->cmd_sts);
+
+	if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
+			(RX_FIRST_DESC | RX_LAST_DESC)) {
+		printf("ARMD100 FEC: (%s) Dropping packet spread on"
+			" multiple descriptors\n", __func__);
+	} else if (cmd_sts & RX_ERROR) {
+		printf("ARMD100 FEC: (%s) Dropping packet with errors\n",
+				__func__);
+	} else {
+		/* !!! call higher layer processing */
+		debug("ARMD100 FEC: (%s) Sending Received packet to"
+			" upper layer (NetReceive)\n", __func__);
+
+		/*
+		 * let the upper layer handle the packet, subtract offset
+		 * as two dummy bytes are added in received buffer see
+		 * PORT_CONFIG_EXT register bit TWO_Byte_Stuff_Mode bit.
+		 */
+		NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET),
+			   (int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET));
+	}
+	/*
+	 * free these descriptors and point next in the ring
+	 */
+	p_rxdesc_curr->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT;
+	p_rxdesc_curr->buf_size = PKTSIZE_ALIGN;
+	p_rxdesc_curr->byte_cnt = 0;
+
+	writel((u32)p_rxdesc_curr->nxtdesc_p, (u32)&darmdfec->p_rxdesc_curr);
+
+	return 0;
+}
+
+int armada100_fec_register(unsigned long base_addr)
+{
+	struct armdfec_device *darmdfec;
+	struct eth_device *dev;
+
+	darmdfec = malloc(sizeof(struct armdfec_device));
+	if (!darmdfec)
+		goto error;
+
+	memset(darmdfec, 0, sizeof(struct armdfec_device));
+
+	darmdfec->htpr = memalign(8, HASH_ADDR_TABLE_SIZE);
+	if (!darmdfec->htpr)
+		goto error1;
+
+	darmdfec->p_rxdesc = memalign(PKTALIGN,
+			ARMDFEC_RXQ_DESC_ALIGNED_SIZE * RINGSZ + 1);
+
+	if (!darmdfec->p_rxdesc)
+		goto error1;
+
+	darmdfec->p_rxbuf = memalign(PKTALIGN, RINGSZ * PKTSIZE_ALIGN + 1);
+	if (!darmdfec->p_rxbuf)
+		goto error1;
+
+	darmdfec->p_aligned_txbuf = memalign(8, PKTSIZE_ALIGN);
+	if (!darmdfec->p_aligned_txbuf)
+		goto error1;
+
+	darmdfec->p_txdesc = memalign(PKTALIGN, sizeof(struct tx_desc) + 1);
+	if (!darmdfec->p_txdesc)
+		goto error1;
+
+	dev = &darmdfec->dev;
+	/* Assign ARMADA100 Fast Ethernet Controller Base Address */
+	darmdfec->regs = (void *)base_addr;
+
+	/* must be less than NAMESIZE (16) */
+	strcpy(dev->name, "armd-fec0");
+
+	dev->init = armdfec_init;
+	dev->halt = armdfec_halt;
+	dev->send = armdfec_send;
+	dev->recv = armdfec_recv;
+
+	eth_register(dev);
+
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
+	miiphy_register(dev->name, smi_reg_read, smi_reg_write);
+#endif
+	return 0;
+
+error1:
+	free(darmdfec->p_aligned_txbuf);
+	free(darmdfec->p_rxbuf);
+	free(darmdfec->p_rxdesc);
+	free(darmdfec->htpr);
+error:
+	free(darmdfec);
+	printf("AMD100 FEC: (%s) Failed to allocate memory\n", __func__);
+	return -1;
+}
diff --git a/drivers/net/armada100_fec.h b/drivers/net/armada100_fec.h
new file mode 100644
index 0000000..e2df4fc
--- /dev/null
+++ b/drivers/net/armada100_fec.h
@@ -0,0 +1,232 @@
+/*
+ * (C) Copyright 2011
+ * eInfochips Ltd. <www.einfochips.com>
+ * Written-by: Ajay Bhargav <ajay.bhargav@einfochips.com>
+ *
+ * (C) Copyright 2010
+ * Marvell Semiconductor <www.marvell.com>
+ * Contributor: Mahavir Jain <mjain@marvell.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., 51 Franklin Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA
+ */
+
+#ifndef __ARMADA100_FEC_H__
+#define __ARMADA100_FEC_H__
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#define PORT_NUM		0x0
+
+/* RX & TX descriptor command */
+#define BUF_OWNED_BY_DMA        (1<<31)
+
+/* RX descriptor status */
+#define RX_EN_INT               (1<<23)
+#define RX_FIRST_DESC           (1<<17)
+#define RX_LAST_DESC            (1<<16)
+#define RX_ERROR                (1<<15)
+
+/* TX descriptor command */
+#define TX_EN_INT               (1<<23)
+#define TX_GEN_CRC              (1<<22)
+#define TX_ZERO_PADDING         (1<<18)
+#define TX_FIRST_DESC           (1<<17)
+#define TX_LAST_DESC            (1<<16)
+#define TX_ERROR                (1<<15)
+
+/* smi register */
+#define SMI_BUSY                (1<<28)	/* 0 - Write, 1 - Read  */
+#define SMI_R_VALID             (1<<27)	/* 0 - Write, 1 - Read  */
+#define SMI_OP_W                (0<<26)	/* Write operation      */
+#define SMI_OP_R                (1<<26)	/* Read operation */
+
+#define HASH_ADD                0
+#define HASH_DELETE             1
+#define HASH_ADDR_TABLE_SIZE    0x4000	/* 16K (1/2K address - PCR_HS == 1) */
+#define HOP_NUMBER              12
+
+#define PHY_WAIT_ITERATIONS     1000	/* 1000 iterations * 10uS = 10mS max */
+#define PHY_WAIT_MICRO_SECONDS  10
+
+#define ETH_HW_IP_ALIGN         2	/* hw aligns IP header */
+#define ETH_EXTRA_HEADER        (6+6+2+4)
+					/* dest+src addr+protocol id+crc */
+#define MAX_PKT_SIZE            1536
+
+
+/* Bit definitions of the SDMA Config Reg */
+#define SDCR_BSZ_OFF            12
+#define SDCR_BSZ8               (3<<SDCR_BSZ_OFF)
+#define SDCR_BSZ4               (2<<SDCR_BSZ_OFF)
+#define SDCR_BSZ2               (1<<SDCR_BSZ_OFF)
+#define SDCR_BSZ1               (0<<SDCR_BSZ_OFF)
+#define SDCR_BLMR               (1<<6)
+#define SDCR_BLMT               (1<<7)
+#define SDCR_RIFB               (1<<9)
+#define SDCR_RC_OFF             2
+#define SDCR_RC_MAX_RETRANS     (0xf << SDCR_RC_OFF)
+
+/* SDMA_CMD */
+#define SDMA_CMD_AT             (1<<31)
+#define SDMA_CMD_TXDL           (1<<24)
+#define SDMA_CMD_TXDH           (1<<23)
+#define SDMA_CMD_AR             (1<<15)
+#define SDMA_CMD_ERD            (1<<7)
+
+
+/* Bit definitions of the Port Config Reg */
+#define PCR_HS                  (1<<12)
+#define PCR_EN                  (1<<7)
+#define PCR_PM                  (1<<0)
+
+/* Bit definitions of the Port Config Extend Reg */
+#define PCXR_2BSM               (1<<28)
+#define PCXR_DSCP_EN            (1<<21)
+#define PCXR_MFL_1518           (0<<14)
+#define PCXR_MFL_1536           (1<<14)
+#define PCXR_MFL_2048           (2<<14)
+#define PCXR_MFL_64K            (3<<14)
+#define PCXR_FLP                (1<<11)
+#define PCXR_PRIO_TX_OFF        3
+#define PCXR_TX_HIGH_PRI        (7<<PCXR_PRIO_TX_OFF)
+
+/*
+ *  * Bit definitions of the Interrupt Cause Reg
+ *   * and Interrupt MASK Reg is the same
+ *    */
+#define ICR_RXBUF               (1<<0)
+#define ICR_TXBUF_H             (1<<2)
+#define ICR_TXBUF_L             (1<<3)
+#define ICR_TXEND_H             (1<<6)
+#define ICR_TXEND_L             (1<<7)
+#define ICR_RXERR               (1<<8)
+#define ICR_TXERR_H             (1<<10)
+#define ICR_TXERR_L             (1<<11)
+#define ICR_TX_UDR              (1<<13)
+#define ICR_MII_CH              (1<<28)
+
+#define ALL_INTS (ICR_TXBUF_H  | ICR_TXBUF_L  | ICR_TX_UDR |\
+				ICR_TXERR_H  | ICR_TXERR_L |\
+				ICR_TXEND_H  | ICR_TXEND_L |\
+				ICR_RXBUF | ICR_RXERR  | ICR_MII_CH)
+
+#define PHY_MASK               0x0000001f
+
+#define to_darmdfec(_kd) container_of(_kd, struct armdfec_device, dev)
+/* Size of a Tx/Rx descriptor used in chain list data structure */
+#define ARMDFEC_RXQ_DESC_ALIGNED_SIZE \
+	(((sizeof(struct rx_desc) / PKTALIGN) + 1) * PKTALIGN)
+
+#define RX_BUF_OFFSET		0x2
+#define RXQ			0x0	/* RX Queue 0 */
+#define TXQ			0x1	/* TX Queue 1 */
+
+struct addr_table_entry_t {
+	u32 lo;
+	u32 hi;
+};
+
+/* Bit fields of a Hash Table Entry */
+enum hash_table_entry {
+	HTEVALID = 1,
+	HTESKIP = 2,
+	HTERD = 4,
+	HTERDBIT = 2
+};
+
+struct tx_desc {
+	u32 cmd_sts;		/* Command/status field */
+	u16 reserved;
+	u16 byte_cnt;		/* buffer byte count */
+	u8 *buf_ptr;		/* pointer to buffer for this descriptor */
+	struct tx_desc *nextdesc_p;	/* Pointer to next descriptor */
+};
+
+struct rx_desc {
+	u32 cmd_sts;		/* Descriptor command status */
+	u16 byte_cnt;		/* Descriptor buffer byte count */
+	u16 buf_size;		/* Buffer size */
+	u8 *buf_ptr;		/* Descriptor buffer pointer */
+	struct rx_desc *nxtdesc_p;	/* Next descriptor pointer */
+};
+
+/*
+ * Armada100 Fast Ethernet controller Registers
+ * Refer Datasheet Appendix A.22
+ */
+struct armdfec_reg {
+	u32 phyadr;			/* PHY Address */
+	u32 pad1[3];
+	u32 smi;			/* SMI */
+	u32 pad2[0xFB];
+	u32 pconf;			/* Port configuration */
+	u32 pad3;
+	u32 pconf_ext;			/* Port configuration extend */
+	u32 pad4;
+	u32 pcmd;			/* Port Command */
+	u32 pad5;
+	u32 pstatus;			/* Port Status */
+	u32 pad6;
+	u32 spar;			/* Serial Parameters */
+	u32 pad7;
+	u32 htpr;			/* Hash table pointer */
+	u32 pad8;
+	u32 fcsal;			/* Flow control source address low */
+	u32 pad9;
+	u32 fcsah;			/* Flow control source address high */
+	u32 pad10;
+	u32 sdma_conf;			/* SDMA configuration */
+	u32 pad11;
+	u32 sdma_cmd;			/* SDMA command */
+	u32 pad12;
+	u32 ic;				/* Interrupt cause */
+	u32 iwc;			/* Interrupt write to clear */
+	u32 im;				/* Interrupt mask */
+	u32 pad13;
+	u32 *eth_idscpp[4];		/* Eth0 IP Differentiated Services Code
+					   Point to Priority 0 Low */
+	u32 eth_vlan_p;			/* Eth0 VLAN Priority Tag to Priority */
+	u32 pad14[3];
+	struct rx_desc *rxfdp[4];	/* Ethernet First Rx Descriptor
+					   Pointer */
+	u32 pad15[4];
+	struct rx_desc *rxcdp[4];	/* Ethernet Current Rx Descriptor
+					   Pointer */
+	u32 pad16[0x0C];
+	struct tx_desc *txcdp[2];	/* Ethernet Current Tx Descriptor
+					   Pointer */
+};
+
+struct armdfec_device {
+	struct eth_device dev;
+	struct armdfec_reg *regs;
+	struct tx_desc *p_txdesc;
+	struct rx_desc *p_rxdesc;
+	struct rx_desc *p_rxdesc_curr;
+	u8 *p_rxbuf;
+	u8 *p_aligned_txbuf;
+	u8 *htpr;		/* hash pointer */
+};
+
+#endif /* __ARMADA100_FEC_H__ */
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index c0b8929..a8905b8 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -680,6 +680,9 @@
 
 	davinci_eth_mdio_enable();
 
+	/* let the EMAC detect the PHYs */
+	udelay(5000);
+
 	for (i = 0; i < 256; i++) {
 		if (readl(&adap_mdio->ALIVE))
 			break;
@@ -711,6 +714,13 @@
 	phy_id |= tmp & 0x0000ffff;
 
 	switch (phy_id) {
+	case PHY_KSZ8873:
+		sprintf(phy.name, "KSZ8873 @ 0x%02x", active_phy_addr);
+		phy.init = ksz8873_init_phy;
+		phy.is_phy_connected = ksz8873_is_phy_connected;
+		phy.get_link_speed = ksz8873_get_link_speed;
+		phy.auto_negotiate = ksz8873_auto_negotiate;
+		break;
 		case PHY_LXT972:
 			sprintf(phy.name, "LXT972 @ 0x%02x", active_phy_addr);
 			phy.init = lxt972_init_phy;
@@ -740,7 +750,7 @@
 			phy.auto_negotiate = gen_auto_negotiate;
 	}
 
-	printf("Ethernet PHY: %s\n", phy.name);
+	debug("Ethernet PHY: %s\n", phy.name);
 
 	miiphy_register(phy.name, davinci_mii_phy_read, davinci_mii_phy_write);
 	return(1);
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index ab90afa..cfe2176 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -38,6 +38,10 @@
 #error "CONFIG_MII has to be defined!"
 #endif
 
+#ifndef	CONFIG_FEC_XCV_TYPE
+#define	CONFIG_FEC_XCV_TYPE	MII100
+#endif
+
 #undef DEBUG
 
 struct nbuf {
@@ -47,18 +51,6 @@
 	uint8_t head[16];	/**< MAC header(6 + 6 + 2) + 2(aligned) */
 };
 
-struct fec_priv gfec = {
-	.eth       = (struct ethernet_regs *)IMX_FEC_BASE,
-	.xcv_type  = MII100,
-	.rbd_base  = NULL,
-	.rbd_index = 0,
-	.tbd_base  = NULL,
-	.tbd_index = 0,
-	.bd        = NULL,
-	.rdb_ptr   = NULL,
-	.base_ptr  = NULL,
-};
-
 /*
  * MII-interface related functions
  */
@@ -67,6 +59,7 @@
 {
 	struct eth_device *edev = eth_get_dev_by_name(dev);
 	struct fec_priv *fec = (struct fec_priv *)edev->priv;
+	struct ethernet_regs *eth = fec->eth;
 
 	uint32_t reg;		/* convenient holder for the PHY register */
 	uint32_t phy;		/* convenient holder for the PHY */
@@ -76,18 +69,18 @@
 	 * reading from any PHY's register is done by properly
 	 * programming the FEC's MII data register.
 	 */
-	writel(FEC_IEVENT_MII, &fec->eth->ievent);
+	writel(FEC_IEVENT_MII, &eth->ievent);
 	reg = regAddr << FEC_MII_DATA_RA_SHIFT;
 	phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
 
 	writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_RD | FEC_MII_DATA_TA |
-			phy | reg, &fec->eth->mii_data);
+			phy | reg, &eth->mii_data);
 
 	/*
 	 * wait for the related interrupt
 	 */
 	start = get_timer(0);
-	while (!(readl(&fec->eth->ievent) & FEC_IEVENT_MII)) {
+	while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
 		if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
 			printf("Read MDIO failed...\n");
 			return -1;
@@ -97,12 +90,12 @@
 	/*
 	 * clear mii interrupt bit
 	 */
-	writel(FEC_IEVENT_MII, &fec->eth->ievent);
+	writel(FEC_IEVENT_MII, &eth->ievent);
 
 	/*
 	 * it's now safe to read the PHY's register
 	 */
-	*retVal = readl(&fec->eth->mii_data);
+	*retVal = readl(&eth->mii_data);
 	debug("fec_miiphy_read: phy: %02x reg:%02x val:%#x\n", phyAddr,
 			regAddr, *retVal);
 	return 0;
@@ -117,13 +110,14 @@
 	writel((((imx_get_fecclk() / 1000000) + 2) / 5) << 1,
 			&fec->eth->mii_speed);
 	debug("fec_init: mii_speed %#lx\n",
-			fec->eth->mii_speed);
+			readl(&fec->eth->mii_speed));
 }
 static int fec_miiphy_write(const char *dev, uint8_t phyAddr, uint8_t regAddr,
 		uint16_t data)
 {
 	struct eth_device *edev = eth_get_dev_by_name(dev);
 	struct fec_priv *fec = (struct fec_priv *)edev->priv;
+	struct ethernet_regs *eth = fec->eth;
 
 	uint32_t reg;		/* convenient holder for the PHY register */
 	uint32_t phy;		/* convenient holder for the PHY */
@@ -133,13 +127,13 @@
 	phy = phyAddr << FEC_MII_DATA_PA_SHIFT;
 
 	writel(FEC_MII_DATA_ST | FEC_MII_DATA_OP_WR |
-		FEC_MII_DATA_TA | phy | reg | data, &fec->eth->mii_data);
+		FEC_MII_DATA_TA | phy | reg | data, &eth->mii_data);
 
 	/*
 	 * wait for the MII interrupt
 	 */
 	start = get_timer(0);
-	while (!(readl(&fec->eth->ievent) & FEC_IEVENT_MII)) {
+	while (!(readl(&eth->ievent) & FEC_IEVENT_MII)) {
 		if (get_timer(start) > (CONFIG_SYS_HZ / 1000)) {
 			printf("Write MDIO failed...\n");
 			return -1;
@@ -149,7 +143,7 @@
 	/*
 	 * clear MII interrupt bit
 	 */
-	writel(FEC_IEVENT_MII, &fec->eth->ievent);
+	writel(FEC_IEVENT_MII, &eth->ievent);
 	debug("fec_miiphy_write: phy: %02x reg:%02x val:%#x\n", phyAddr,
 			regAddr, data);
 
@@ -158,33 +152,40 @@
 
 static int miiphy_restart_aneg(struct eth_device *dev)
 {
+	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+	int ret = 0;
+
 	/*
 	 * Wake up from sleep if necessary
 	 * Reset PHY, then delay 300ns
 	 */
 #ifdef CONFIG_MX27
-	miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, MII_DCOUNTER, 0x00FF);
+	miiphy_write(dev->name, fec->phy_id, MII_DCOUNTER, 0x00FF);
 #endif
-	miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, MII_BMCR,
+	miiphy_write(dev->name, fec->phy_id, MII_BMCR,
 			BMCR_RESET);
 	udelay(1000);
 
 	/*
 	 * Set the auto-negotiation advertisement register bits
 	 */
-	miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, MII_ADVERTISE,
+	miiphy_write(dev->name, fec->phy_id, MII_ADVERTISE,
 			LPA_100FULL | LPA_100HALF | LPA_10FULL |
 			LPA_10HALF | PHY_ANLPAR_PSB_802_3);
-	miiphy_write(dev->name, CONFIG_FEC_MXC_PHYADDR, MII_BMCR,
+	miiphy_write(dev->name, fec->phy_id, MII_BMCR,
 			BMCR_ANENABLE | BMCR_ANRESTART);
 
-	return 0;
+	if (fec->mii_postcall)
+		ret = fec->mii_postcall(fec->phy_id);
+
+	return ret;
 }
 
 static int miiphy_wait_aneg(struct eth_device *dev)
 {
 	uint32_t start;
 	uint16_t status;
+	struct fec_priv *fec = (struct fec_priv *)dev->priv;
 
 	/*
 	 * Wait for AN completion
@@ -196,7 +197,7 @@
 			return -1;
 		}
 
-		if (miiphy_read(dev->name, CONFIG_FEC_MXC_PHYADDR,
+		if (miiphy_read(dev->name, fec->phy_id,
 					MII_BMSR, &status)) {
 			printf("%s: Autonegotiation failed. status: 0x%04x\n",
 					dev->name, status);
@@ -384,8 +385,8 @@
 #endif
 
 	miiphy_wait_aneg(edev);
-	miiphy_speed(edev->name, CONFIG_FEC_MXC_PHYADDR);
-	miiphy_duplex(edev->name, CONFIG_FEC_MXC_PHYADDR);
+	miiphy_speed(edev->name, fec->phy_id);
+	miiphy_duplex(edev->name, fec->phy_id);
 
 	/*
 	 * Enable SmartDMA receive task
@@ -400,6 +401,9 @@
 {
 	uint32_t base;
 	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+	uint32_t mib_ptr = (uint32_t)&fec->eth->rmon_t_drop;
+	uint32_t rcntrl;
+	int i;
 
 	/* Initialize MAC address */
 	fec_set_hwaddr(dev);
@@ -442,19 +446,21 @@
 	/*
 	 * Set FEC-Lite receive control register(R_CNTRL):
 	 */
-	if (fec->xcv_type == SEVENWIRE) {
-		/*
-		 * Frame length=1518; 7-wire mode
-		 */
-		writel(0x05ee0020, &fec->eth->r_cntrl);	/* FIXME 0x05ee0000 */
-	} else {
-		/*
-		 * Frame length=1518; MII mode;
-		 */
-		writel(0x05ee0024, &fec->eth->r_cntrl);	/* FIXME 0x05ee0004 */
 
+	/* Start with frame length = 1518, common for all modes. */
+	rcntrl = PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT;
+	if (fec->xcv_type == SEVENWIRE)
+		rcntrl |= FEC_RCNTRL_FCE;
+	else if (fec->xcv_type == RMII)
+		rcntrl |= FEC_RCNTRL_RMII;
+	else	/* MII mode */
+		rcntrl |= FEC_RCNTRL_FCE | FEC_RCNTRL_MII_MODE;
+
+	writel(rcntrl, &fec->eth->r_cntrl);
+
+	if (fec->xcv_type == MII10 || fec->xcv_type == MII100)
 		fec_mii_setspeed(fec);
-	}
+
 	/*
 	 * Set Opcode/Pause Duration Register
 	 */
@@ -468,9 +474,8 @@
 
 
 	/* clear MIB RAM */
-	long *mib_ptr = (long *)(IMX_FEC_BASE + 0x200);
-	while (mib_ptr <= (long *)(IMX_FEC_BASE + 0x2FC))
-		*mib_ptr++ = 0;
+	for (i = mib_ptr; i <= mib_ptr + 0xfc; i += 4)
+		writel(0, i);
 
 	/* FIFO receive start register */
 	writel(0x520, &fec->eth->r_fstart);
@@ -504,7 +509,7 @@
  */
 static void fec_halt(struct eth_device *dev)
 {
-	struct fec_priv *fec = &gfec;
+	struct fec_priv *fec = (struct fec_priv *)dev->priv;
 	int counter = 0xffff;
 
 	/*
@@ -685,19 +690,32 @@
 	return len;
 }
 
-static int fec_probe(bd_t *bd)
+static int fec_probe(bd_t *bd, int dev_id, int phy_id, uint32_t base_addr)
 {
 	struct eth_device *edev;
-	struct fec_priv *fec = &gfec;
+	struct fec_priv *fec;
 	unsigned char ethaddr[6];
+	uint32_t start;
+	int ret = 0;
 
 	/* create and fill edev struct */
 	edev = (struct eth_device *)malloc(sizeof(struct eth_device));
 	if (!edev) {
-		puts("fec_mxc: not enough malloc memory\n");
-		return -ENOMEM;
+		puts("fec_mxc: not enough malloc memory for eth_device\n");
+		ret = -ENOMEM;
+		goto err1;
 	}
+
+	fec = (struct fec_priv *)malloc(sizeof(struct fec_priv));
+	if (!fec) {
+		puts("fec_mxc: not enough malloc memory for fec_priv\n");
+		ret = -ENOMEM;
+		goto err2;
+	}
+
 	memset(edev, 0, sizeof(*edev));
+	memset(fec, 0, sizeof(*fec));
+
 	edev->priv = fec;
 	edev->init = fec_init;
 	edev->send = fec_send;
@@ -705,15 +723,21 @@
 	edev->halt = fec_halt;
 	edev->write_hwaddr = fec_set_hwaddr;
 
-	fec->eth = (struct ethernet_regs *)IMX_FEC_BASE;
+	fec->eth = (struct ethernet_regs *)base_addr;
 	fec->bd = bd;
 
-	fec->xcv_type = MII100;
+	fec->xcv_type = CONFIG_FEC_XCV_TYPE;
 
 	/* Reset chip. */
 	writel(readl(&fec->eth->ecntrl) | FEC_ECNTRL_RESET, &fec->eth->ecntrl);
-	while (readl(&fec->eth->ecntrl) & 1)
+	start = get_timer(0);
+	while (readl(&fec->eth->ecntrl) & FEC_ECNTRL_RESET) {
+		if (get_timer(start) > (CONFIG_SYS_HZ * 5)) {
+			printf("FEC MXC: Timeout reseting chip\n");
+			goto err3;
+		}
 		udelay(10);
+	}
 
 	/*
 	 * Set interrupt mask register
@@ -731,29 +755,63 @@
 	/*
 	 * Frame length=1518; MII mode;
 	 */
-	writel(0x05ee0024, &fec->eth->r_cntrl);	/* FIXME 0x05ee0004 */
+	writel((PKTSIZE << FEC_RCNTRL_MAX_FL_SHIFT) | FEC_RCNTRL_FCE |
+		FEC_RCNTRL_MII_MODE, &fec->eth->r_cntrl);
 	fec_mii_setspeed(fec);
 
-	sprintf(edev->name, "FEC");
+	if (dev_id == -1) {
+		sprintf(edev->name, "FEC");
+		fec->dev_id = 0;
+	} else {
+		sprintf(edev->name, "FEC%i", dev_id);
+		fec->dev_id = dev_id;
+	}
+	fec->phy_id = phy_id;
 
 	miiphy_register(edev->name, fec_miiphy_read, fec_miiphy_write);
 
 	eth_register(edev);
 
 	if (fec_get_hwaddr(edev, ethaddr) == 0) {
-		printf("got MAC address from fuse: %pM\n", ethaddr);
+		debug("got MAC address from fuse: %pM\n", ethaddr);
 		memcpy(edev->enetaddr, ethaddr, 6);
 	}
 
-	return 0;
+	return ret;
+
+err3:
+	free(fec);
+err2:
+	free(edev);
+err1:
+	return ret;
 }
 
+#ifndef	CONFIG_FEC_MXC_MULTI
 int fecmxc_initialize(bd_t *bd)
 {
 	int lout = 1;
 
 	debug("eth_init: fec_probe(bd)\n");
-	lout = fec_probe(bd);
+	lout = fec_probe(bd, -1, CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE);
 
 	return lout;
 }
+#endif
+
+int fecmxc_initialize_multi(bd_t *bd, int dev_id, int phy_id, uint32_t addr)
+{
+	int lout = 1;
+
+	debug("eth_init: fec_probe(bd, %i, %i) @ %08x\n", dev_id, phy_id, addr);
+	lout = fec_probe(bd, dev_id, phy_id, addr);
+
+	return lout;
+}
+
+int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int))
+{
+	struct fec_priv *fec = (struct fec_priv *)dev->priv;
+	fec->mii_postcall = cb;
+	return 0;
+}
diff --git a/drivers/net/fec_mxc.h b/drivers/net/fec_mxc.h
index 1ba5161..8b26645 100644
--- a/drivers/net/fec_mxc.h
+++ b/drivers/net/fec_mxc.h
@@ -32,6 +32,8 @@
 #ifndef __FEC_MXC_H
 #define __FEC_MXC_H
 
+void imx_get_mac_from_fuse(unsigned char *mac);
+
 /**
  * Layout description of the FEC
  */
@@ -194,6 +196,7 @@
 #define FEC_RCNTRL_PROM			0x00000008
 #define FEC_RCNTRL_BC_REJ		0x00000010
 #define FEC_RCNTRL_FCE			0x00000020
+#define FEC_RCNTRL_RMII			0x00000100
 
 #define FEC_TCNTRL_GTS			0x00000001
 #define FEC_TCNTRL_HBC			0x00000002
@@ -257,7 +260,8 @@
 enum xceiver_type {
 	SEVENWIRE,	/* 7-wire       */
 	MII10,		/* MII 10Mbps   */
-	MII100		/* MII 100Mbps  */
+	MII100,		/* MII 100Mbps  */
+	RMII		/* RMII */
 };
 
 /**
@@ -273,6 +277,9 @@
 	bd_t *bd;
 	void *rdb_ptr;
 	void *base_ptr;
+	int dev_id;
+	int phy_id;
+	int (*mii_postcall)(int);
 };
 
 /**
diff --git a/drivers/power/twl6030.c b/drivers/power/twl6030.c
index fef57b4..c5a0038 100644
--- a/drivers/power/twl6030.c
+++ b/drivers/power/twl6030.c
@@ -182,6 +182,13 @@
 	return;
 }
 
+void twl6030_power_mmc_init()
+{
+	/* set voltage to 3.0 and turnon for APP */
+	twl6030_i2c_write_u8(TWL6030_CHIP_PM, 0x15, VMMC_CFG_VOLTATE);
+	twl6030_i2c_write_u8(TWL6030_CHIP_PM, 0x21, VMMC_CFG_STATE);
+}
+
 void twl6030_usb_device_settings()
 {
 	u8 data = 0;
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index ca27745..df440c6 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -30,6 +30,7 @@
 COBJS-$(CONFIG_RTC_AT91SAM9_RTT) += at91sam9_rtt.o
 COBJS-$(CONFIG_RTC_BFIN) += bfin_rtc.o
 COBJS-y += date.o
+COBJS-$(CONFIG_RTC_DAVINCI) += davinci.o
 COBJS-$(CONFIG_RTC_DS12887) += ds12887.o
 COBJS-$(CONFIG_RTC_DS1302) += ds1302.o
 COBJS-$(CONFIG_RTC_DS1306) += ds1306.o
diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c
new file mode 100644
index 0000000..8436cbf
--- /dev/null
+++ b/drivers/rtc/davinci.c
@@ -0,0 +1,125 @@
+/*
+ * (C) Copyright 2011 DENX Software Engineering GmbH
+ * Heiko Schocher <hs@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 <command.h>
+#include <rtc.h>
+#include <asm/io.h>
+#include <asm/arch/hardware.h>
+
+#if defined(CONFIG_CMD_DATE)
+struct davinci_rtc {
+	u_int32_t	second;
+	u_int32_t	minutes;
+	u_int32_t	hours;
+	u_int32_t	day;
+	u_int32_t	month; /* 0x10 */
+	u_int32_t	year;
+	u_int32_t	dotw;
+	u_int32_t	resv1;
+	u_int32_t	alarmsecond; /* 0x20 */
+	u_int32_t	alarmminute;
+	u_int32_t	alarmhour;
+	u_int32_t	alarmday;
+	u_int32_t	alarmmonth; /* 0x30 */
+	u_int32_t	alarmyear;
+	u_int32_t	resv2[2];
+	u_int32_t	ctrl; /* 0x40 */
+	u_int32_t	status;
+	u_int32_t	irq;
+};
+
+#define RTC_STATE_BUSY	0x01
+#define RTC_STATE_RUN	0x02
+
+#define davinci_rtc_base ((struct davinci_rtc *)DAVINCI_RTC_BASE)
+
+int rtc_get(struct rtc_time *tmp)
+{
+	struct davinci_rtc *rtc = davinci_rtc_base;
+	unsigned long sec, min, hour, mday, wday, mon_cent, year;
+	unsigned long status;
+
+	status = readl(&rtc->status);
+	if ((status & RTC_STATE_RUN) != RTC_STATE_RUN) {
+		printf("RTC doesn't run\n");
+		return -1;
+	}
+	if ((status & RTC_STATE_BUSY) == RTC_STATE_BUSY)
+		udelay(20);
+
+	sec	= readl(&rtc->second);
+	min	= readl(&rtc->minutes);
+	hour	= readl(&rtc->hours);
+	mday	= readl(&rtc->day);
+	wday	= readl(&rtc->dotw);
+	mon_cent = readl(&rtc->month);
+	year	= readl(&rtc->year);
+
+	debug("Get RTC year: %02lx mon/cent: %02lx mday: %02lx wday: %02lx "
+		"hr: %02lx min: %02lx sec: %02lx\n",
+		year, mon_cent, mday, wday,
+		hour, min, sec);
+
+	tmp->tm_sec  = bcd2bin(sec  & 0x7F);
+	tmp->tm_min  = bcd2bin(min  & 0x7F);
+	tmp->tm_hour = bcd2bin(hour & 0x3F);
+	tmp->tm_mday = bcd2bin(mday & 0x3F);
+	tmp->tm_mon  = bcd2bin(mon_cent & 0x1F);
+	tmp->tm_year = bcd2bin(year) + 2000;
+	tmp->tm_wday = bcd2bin(wday & 0x07);
+	tmp->tm_yday = 0;
+	tmp->tm_isdst = 0;
+
+	debug("Get DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+
+	return 0;
+}
+
+int rtc_set(struct rtc_time *tmp)
+{
+	struct davinci_rtc *rtc = davinci_rtc_base;
+
+	debug("Set DATE: %4d-%02d-%02d (wday=%d)  TIME: %2d:%02d:%02d\n",
+		tmp->tm_year, tmp->tm_mon, tmp->tm_mday, tmp->tm_wday,
+		tmp->tm_hour, tmp->tm_min, tmp->tm_sec);
+	writel(bin2bcd(tmp->tm_year % 100), &rtc->year);
+	writel(bin2bcd(tmp->tm_mon), &rtc->month);
+
+	writel(bin2bcd(tmp->tm_wday), &rtc->dotw);
+	writel(bin2bcd(tmp->tm_mday), &rtc->day);
+	writel(bin2bcd(tmp->tm_hour), &rtc->hours);
+	writel(bin2bcd(tmp->tm_min), &rtc->minutes);
+	writel(bin2bcd(tmp->tm_sec), &rtc->second);
+	return 0;
+}
+
+void rtc_reset(void)
+{
+	struct davinci_rtc *rtc = davinci_rtc_base;
+
+	/* run RTC counter */
+	writel(0x01, &rtc->ctrl);
+}
+#endif
diff --git a/include/configs/devkit8000.h b/include/configs/devkit8000.h
index 710092d..fbcbdb3 100644
--- a/include/configs/devkit8000.h
+++ b/include/configs/devkit8000.h
@@ -181,7 +181,7 @@
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"loadaddr=0x82000000\0" \
-	"console=ttyS2,115200n8\0" \
+	"console=ttyO2,115200n8\0" \
 	"mmcdev=0\0" \
 	"vram=12M\0" \
 	"dvimode=1024x768MR-16@60\0" \
@@ -308,4 +308,50 @@
 		                                         CONFIG_SYS_INIT_RAM_SIZE - \
 		                                         GENERATED_GBL_DATA_SIZE)
 
+/* SRAM config */
+#define CONFIG_SYS_SRAM_START              0x40200000
+#define CONFIG_SYS_SRAM_SIZE               0x10000
+
+/* Defines for SPL */
+#define CONFIG_SPL
+#define CONFIG_SPL_NAND_SIMPLE
+
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBDISK_SUPPORT
+#define CONFIG_SPL_I2C_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_POWER_SUPPORT
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_LDSCRIPT		"$(CPUDIR)/omap-common/u-boot-spl.lds"
+
+#define CONFIG_SPL_TEXT_BASE		0x40200000 /*CONFIG_SYS_SRAM_START*/
+#define CONFIG_SPL_MAX_SIZE		0xB400  /* 45 K */
+#define CONFIG_SPL_STACK		LOW_LEVEL_SRAM_STACK
+
+#define CONFIG_SPL_BSS_START_ADDR	0x80000000 /*CONFIG_SYS_SDRAM_BASE*/
+#define CONFIG_SPL_BSS_MAX_SIZE		0x80000
+
+/* NAND boot config */
+#define CONFIG_SYS_NAND_PAGE_COUNT	64
+#define CONFIG_SYS_NAND_PAGE_SIZE	2048
+#define CONFIG_SYS_NAND_OOBSIZE		64
+#define CONFIG_SYS_NAND_BLOCK_SIZE	(128*1024)
+#define CONFIG_SYS_NAND_BAD_BLOCK_POS	0
+#define CONFIG_SYS_NAND_ECCPOS		{2, 3, 4, 5, 6, 7, 8, 9,\
+						10, 11, 12, 13}
+
+#define CONFIG_SYS_NAND_ECCSIZE		512
+#define CONFIG_SYS_NAND_ECCBYTES	3
+
+#define CONFIG_SYS_NAND_ECCSTEPS	(CONFIG_SYS_NAND_PAGE_SIZE / \
+						CONFIG_SYS_NAND_ECCSIZE)
+#define CONFIG_SYS_NAND_ECCTOTAL       (CONFIG_SYS_NAND_ECCBYTES * \
+						CONFIG_SYS_NAND_ECCSTEPS)
+
+#define CONFIG_SYS_NAND_U_BOOT_START   CONFIG_SYS_TEXT_BASE
+
+#define CONFIG_SYS_NAND_U_BOOT_OFFS	0x80000
+#define CONFIG_SYS_NAND_U_BOOT_SIZE	0x200000
+
 #endif /* __CONFIG_H */
diff --git a/include/configs/efikamx.h b/include/configs/efikamx.h
index b90e342..54f48e4 100644
--- a/include/configs/efikamx.h
+++ b/include/configs/efikamx.h
@@ -31,6 +31,10 @@
  */
 /* An i.MX51 CPU */
 #define CONFIG_MX51
+
+#define	machine_is_efikamx()	(CONFIG_MACH_TYPE == MACH_TYPE_MX51_EFIKAMX)
+#define	machine_is_efikasb()	(CONFIG_MACH_TYPE == MACH_TYPE_MX51_EFIKASB)
+
 #include <asm/arch/imx-regs.h>
 
 #define CONFIG_SYS_MX5_HCLK		24000000
@@ -230,6 +234,6 @@
 	(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
 
 #define CONFIG_SYS_DDR_CLKSEL		0
-#define CONFIG_SYS_CLKTL_CBCDR		0x59E35100
+#define CONFIG_SYS_CLKTL_CBCDR		0x59E35145
 
 #endif
diff --git a/include/configs/gplugd.h b/include/configs/gplugd.h
index cc14f49..5f72163 100644
--- a/include/configs/gplugd.h
+++ b/include/configs/gplugd.h
@@ -62,8 +62,34 @@
 #define CONFIG_CMD_I2C
 #define CONFIG_CMD_AUTOSCRIPT
 #undef CONFIG_CMD_FPGA
-#undef CONFIG_CMD_NET
-#undef CONFIG_CMD_NFS
+
+/* Disable DCACHE */
+#define CONFIG_SYS_DCACHE_OFF
+
+/* Network configuration */
+#ifdef CONFIG_CMD_NET
+#define CONFIG_CMD_PING
+#define CONFIG_NET_MULTI
+#define CONFIG_ARMADA100_FEC
+
+/* DHCP Support */
+#define CONFIG_CMD_DHCP
+#define CONFIG_BOOTP_DHCP_REQUEST_DELAY		50000
+#endif /* CONFIG_CMD_NET */
+
+/* GPIO Support */
+#define CONFIG_MARVELL_GPIO
+
+/* PHY configuration */
+#define CONFIG_MII
+#define CONFIG_CMD_MII
+#define CONFIG_RESET_PHY_R
+/* 88E3015 register definition */
+#define PHY_LED_PAR_SEL_REG		22
+#define PHY_LED_MAN_REG			25
+#define PHY_LED_VAL			0x5b	/* LINK LED1, ACT LED2 */
+/* GPIO Configuration for PHY */
+#define CONFIG_SYS_GPIO_PHY_RST		104	/* GPIO104 */
 
 /*
  * mv-common.h should be defined after CMD configs since it used them
diff --git a/include/configs/imx31_litekit.h b/include/configs/imx31_litekit.h
index b7f1cb3..5e976bc 100644
--- a/include/configs/imx31_litekit.h
+++ b/include/configs/imx31_litekit.h
@@ -41,6 +41,8 @@
 
 #define CONFIG_SYS_TEXT_BASE	0xa0000000
 
+#define CONFIG_MACH_TYPE	MACH_TYPE_MX31LITE
+
 /* Temporarily disabled */
 #if 0
 #define CONFIG_OF_LIBFDT		1
@@ -150,7 +152,7 @@
 #define PHYS_SDRAM_1_SIZE	(128 * 1024 * 1024)
 #define CONFIG_BOARD_EARLY_INIT_F
 
-#define CONFIG_SYS_SDRAM_BASE		CSD0_BASE
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
 #define CONFIG_SYS_INIT_RAM_ADDR	IRAM_BASE_ADDR
 #define CONFIG_SYS_INIT_RAM_SIZE		IRAM_SIZE
 #define CONFIG_SYS_GBL_DATA_OFFSET	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
diff --git a/include/configs/mx25pdk.h b/include/configs/mx25pdk.h
new file mode 100644
index 0000000..0afae24
--- /dev/null
+++ b/include/configs/mx25pdk.h
@@ -0,0 +1,108 @@
+/*
+ * (C) Copyright 2011 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/* High Level Configuration Options */
+
+#define CONFIG_MX25_CLK32		32768	/* OSC32K frequency */
+#define CONFIG_SYS_HZ			1000
+#define CONFIG_SYS_TEXT_BASE		0x81200000
+
+#define CONFIG_DISPLAY_CPUINFO
+#define CONFIG_DISPLAY_BOARDINFO
+
+#define CONFIG_CMDLINE_TAG		/* enable passing of ATAGs */
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_INITRD_TAG
+
+#define CONFIG_MACH_TYPE	MACH_TYPE_MX25_3DS
+
+/* Size of malloc() pool */
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + 2 * 1024 * 1024)
+
+/* Physical Memory Map */
+
+#define CONFIG_NR_DRAM_BANKS	1
+#define PHYS_SDRAM_1		0x80000000
+#define PHYS_SDRAM_1_SIZE	(64 * 1024 * 1024)
+
+#define CONFIG_BOARD_EARLY_INIT_F
+
+#define CONFIG_SYS_SDRAM_BASE		PHYS_SDRAM_1
+#define CONFIG_SYS_INIT_SP_ADDR		(CONFIG_SYS_SDRAM_BASE + 0x1000 - \
+						GENERATED_GBL_DATA_SIZE)
+
+/* Memory Test */
+#define CONFIG_SYS_MEMTEST_START	(PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE/2)
+#define CONFIG_SYS_MEMTEST_END		(PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)
+
+/* Stack sizes */
+#define CONFIG_STACKSIZE	(128 * 1024)	/* regular stack */
+
+/* Serial Info */
+#define CONFIG_MXC_UART
+#define CONFIG_SYS_MX25_UART1
+#define CONFIG_CONS_INDEX	1	/* use UART0 for console */
+#define CONFIG_BAUDRATE		115200	/* Default baud rate */
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+/* No NOR flash present */
+#define CONFIG_ENV_OFFSET      (6 * 64 * 1024)
+#define CONFIG_ENV_SIZE        (8 * 1024)
+#define CONFIG_ENV_IS_NOWHERE
+
+#define CONFIG_SYS_NO_FLASH
+#define CONFIG_SYS_64BIT_VSPRINTF
+
+/* U-Boot general configuration */
+#define CONFIG_SYS_PROMPT	"MX25PDK U-Boot > "
+#define CONFIG_AUTO_COMPLETE
+#define CONFIG_SYS_CBSIZE	256	/* Console I/O Buffer Size  */
+/* Print buffer sz */
+#define CONFIG_SYS_PBSIZE	(CONFIG_SYS_CBSIZE + \
+		sizeof(CONFIG_SYS_PROMPT) + 16)
+#define CONFIG_SYS_MAXARGS	16	/* max number of command args */
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE	CONFIG_SYS_CBSIZE
+#define CONFIG_CMDLINE_EDITING
+#define CONFIG_SYS_LONGHELP
+
+/* U-Boot commands */
+#include <config_cmd_default.h>
+#define CONFIG_CMD_CACHE
+
+/* Ethernet */
+#define CONFIG_FEC_MXC
+#define CONFIG_FEC_MXC_PHYADDR		0x1f
+#define CONFIG_MII
+#define CONFIG_CMD_NET
+#define CONFIG_NET_MULTI
+#define CONFIG_ENV_OVERWRITE
+
+#define CONFIG_BOOTDELAY	3
+
+#define CONFIG_LOADADDR		0x81000000	/* loadaddr env var */
+#define CONFIG_SYS_LOAD_ADDR	CONFIG_LOADADDR
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"script=boot.scr\0" \
+	"uimage=uImage\0" \
+	"netargs=setenv bootargs console=ttymxc0,${baudrate} " \
+		"root=/dev/nfs " \
+		"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
+	"bootcmd=run netargs; dhcp ${uimage}; bootm\0" \
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/mx31ads.h b/include/configs/mx31ads.h
index adb2ee1..0bea858 100644
--- a/include/configs/mx31ads.h
+++ b/include/configs/mx31ads.h
@@ -35,6 +35,8 @@
 
 #define CONFIG_SYS_TEXT_BASE		0xA0000000
 
+#define CONFIG_MACH_TYPE	MACH_TYPE_MX31ADS
+
 /*
  * Disabled for now due to build problems under Debian and a significant increase
  * in the final file size: 144260 vs. 109536 Bytes.
diff --git a/include/configs/mx31pdk.h b/include/configs/mx31pdk.h
index 1a5bdd1..cd156d8 100644
--- a/include/configs/mx31pdk.h
+++ b/include/configs/mx31pdk.h
@@ -45,6 +45,8 @@
 #define CONFIG_SETUP_MEMORY_TAGS
 #define CONFIG_INITRD_TAG
 
+#define CONFIG_MACH_TYPE	MACH_TYPE_MX31_3DS
+
 #if defined(CONFIG_NAND_U_BOOT) && !defined(CONFIG_NAND_SPL)
 #define CONFIG_SKIP_LOWLEVEL_INIT
 #endif
@@ -124,7 +126,7 @@
  * Miscellaneous configurable options
  */
 #define CONFIG_SYS_LONGHELP	/* undef to save memory */
-#define CONFIG_SYS_PROMPT	"uboot> "
+#define CONFIG_SYS_PROMPT	"MX31PDK U-Boot > "
 #define CONFIG_SYS_CBSIZE	256	/* Console I/O Buffer Size */
 /* Print Buffer Size */
 #define CONFIG_SYS_PBSIZE	(CONFIG_SYS_CBSIZE + \
diff --git a/include/configs/mx51evk.h b/include/configs/mx51evk.h
index 7d05dc8..d62a4f2 100644
--- a/include/configs/mx51evk.h
+++ b/include/configs/mx51evk.h
@@ -48,6 +48,7 @@
 
 #define CONFIG_OF_LIBFDT		1
 
+#define CONFIG_MACH_TYPE	MACH_TYPE_MX51_BABBAGE
 /*
  * Size of malloc() pool
  */
diff --git a/include/configs/mx53ard.h b/include/configs/mx53ard.h
index c0b8d6a..26fc219 100644
--- a/include/configs/mx53ard.h
+++ b/include/configs/mx53ard.h
@@ -29,6 +29,8 @@
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_DISPLAY_BOARDINFO
 
+#define CONFIG_MACH_TYPE	MACH_TYPE_MX53_ARD
+
 #include <asm/arch/imx-regs.h>
 
 #define CONFIG_CMDLINE_TAG			/* enable passing of ATAGs */
diff --git a/include/configs/mx53evk.h b/include/configs/mx53evk.h
index 7fb1d9a..b127b06 100644
--- a/include/configs/mx53evk.h
+++ b/include/configs/mx53evk.h
@@ -29,6 +29,8 @@
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_DISPLAY_BOARDINFO
 
+#define CONFIG_MACH_TYPE	MACH_TYPE_MX53_EVK
+
 #include <asm/arch/imx-regs.h>
 
 #define CONFIG_CMDLINE_TAG		1	/* enable passing of ATAGs */
diff --git a/include/configs/mx53loco.h b/include/configs/mx53loco.h
index cfb38a5..4091703 100644
--- a/include/configs/mx53loco.h
+++ b/include/configs/mx53loco.h
@@ -30,6 +30,8 @@
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_DISPLAY_BOARDINFO
 
+#define CONFIG_MACH_TYPE	MACH_TYPE_MX53_LOCO
+
 #include <asm/arch/imx-regs.h>
 
 #define CONFIG_CMDLINE_TAG
diff --git a/include/configs/mx53smd.h b/include/configs/mx53smd.h
index 49f8c6e..261f0bc 100644
--- a/include/configs/mx53smd.h
+++ b/include/configs/mx53smd.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (C) 2011 Freescale Semiconductor, Inc.
  *
- * Configuration settings for the MX53-SMDFreescale board.
+ * Configuration settings for the MX53SMD Freescale board.
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
@@ -29,6 +29,8 @@
 #define CONFIG_DISPLAY_CPUINFO
 #define CONFIG_DISPLAY_BOARDINFO
 
+#define CONFIG_MACH_TYPE	MACH_TYPE_MX53_SMD
+
 #include <asm/arch/imx-regs.h>
 
 #define CONFIG_CMDLINE_TAG			/* enable passing of ATAGs */
diff --git a/include/configs/omap3_evm.h b/include/configs/omap3_evm.h
index fdc861d..7af30c2 100644
--- a/include/configs/omap3_evm.h
+++ b/include/configs/omap3_evm.h
@@ -200,7 +200,7 @@
 	"loadaddr=0x82000000\0" \
 	"usbtty=cdc_acm\0" \
 	"mmcdev=0\0" \
-	"console=ttyS2,115200n8\0" \
+	"console=ttyO0,115200n8\0" \
 	"mmcargs=setenv bootargs console=${console} " \
 		"root=/dev/mmcblk0p2 rw " \
 		"rootfstype=ext3 rootwait\0" \
diff --git a/include/configs/omap4_common.h b/include/configs/omap4_common.h
index d8ac8c0..228eac5 100644
--- a/include/configs/omap4_common.h
+++ b/include/configs/omap4_common.h
@@ -98,7 +98,9 @@
 #define CONFIG_I2C_MULTI_BUS		1
 
 /* TWL6030 */
+#ifndef CONFIG_SPL_BUILD
 #define CONFIG_TWL6030_POWER		1
+#endif
 
 /* MMC */
 #define CONFIG_GENERIC_MMC		1
diff --git a/include/configs/omap4_sdp4430.h b/include/configs/omap4_sdp4430.h
index 39d7154..9e03291 100644
--- a/include/configs/omap4_sdp4430.h
+++ b/include/configs/omap4_sdp4430.h
@@ -37,7 +37,9 @@
 #include <configs/omap4_common.h>
 
 /* Battery Charger */
+#ifndef CONFIG_SPL_BUILD
 #define CONFIG_CMD_BAT			1
+#endif
 
 /* ENV related config options */
 #define CONFIG_ENV_IS_IN_MMC		1
diff --git a/include/configs/vision2.h b/include/configs/vision2.h
index b5c7357..d95c0ba 100644
--- a/include/configs/vision2.h
+++ b/include/configs/vision2.h
@@ -41,6 +41,8 @@
 #define CONFIG_INITRD_TAG
 #define BOARD_LATE_INIT
 
+#define CONFIG_MACH_TYPE	MACH_TYPE_TTC_VISION2
+
 /*
  * Size of malloc() pool
  */
diff --git a/include/configs/zmx25.h b/include/configs/zmx25.h
index 374c88a..ab7f30f 100644
--- a/include/configs/zmx25.h
+++ b/include/configs/zmx25.h
@@ -32,6 +32,7 @@
 #define CONFIG_SYS_HZ			1000
 #define CONFIG_SYS_TEXT_BASE		0xA0000000
 
+#define CONFIG_MACH_TYPE	MACH_TYPE_ZMX25
 /*
  * Environment settings
  */
diff --git a/include/nand.h b/include/nand.h
index 8d94b5c..b4140794 100644
--- a/include/nand.h
+++ b/include/nand.h
@@ -132,6 +132,12 @@
 int nand_unlock( nand_info_t *meminfo, ulong start, ulong length );
 int nand_get_lock_status(nand_info_t *meminfo, loff_t offset);
 
+int nand_spl_load_image(uint32_t offs, unsigned int size, void *dst);
+void nand_deselect(void);
+
+void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len);
+void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);
+
 #ifdef CONFIG_SYS_NAND_SELECT_DEVICE
 void board_nand_select_device(struct nand_chip *nand, int chip);
 #endif
diff --git a/include/netdev.h b/include/netdev.h
index 96c7b9b..480453e 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -61,8 +61,8 @@
 int eth_3com_initialize (bd_t * bis);
 int ethoc_initialize(u8 dev_num, int base_addr);
 int fec_initialize (bd_t *bis);
-int fecmxc_initialize (bd_t *bis);
 int fecmxc_initialize(bd_t *bis);
+int fecmxc_initialize_multi(bd_t *bis, int dev_id, int phy_id, uint32_t addr);
 int ftgmac100_initialize(bd_t *bits);
 int ftmac100_initialize(bd_t *bits);
 int greth_initialize(bd_t *bis);
@@ -94,6 +94,7 @@
 int tsi108_eth_initialize(bd_t *bis);
 int uec_standard_init(bd_t *bis);
 int uli526x_initialize(bd_t *bis);
+int armada100_fec_register(unsigned long base_addr);
 int xilinx_emaclite_initialize (bd_t *bis, int base_addr);
 
 /* Boards with PCI network controllers can call this from their board_eth_init()
@@ -185,4 +186,9 @@
 int mv88e61xx_switch_initialize(struct mv88e61xx_config *swconfig);
 #endif /* CONFIG_MV88E61XX_SWITCH */
 
+/*
+ * Allow FEC to fine-tune MII configuration on boards which require this.
+ */
+int fecmxc_register_mii_postcall(struct eth_device *dev, int (*cb)(int));
+
 #endif /* _NETDEV_H_ */
diff --git a/include/twl6030.h b/include/twl6030.h
index 6ed68a0..a9fcadb 100644
--- a/include/twl6030.h
+++ b/include/twl6030.h
@@ -33,6 +33,8 @@
 #define TWL6030_CHIP_PWM	0x49
 
 /* Slave Address 0x48 */
+#define VMMC_CFG_STATE		0x9A
+#define VMMC_CFG_VOLTATE	0x9B
 #define VUSB_CFG_STATE		0xA2
 
 #define MISC1			0xE4
@@ -130,3 +132,4 @@
 void twl6030_stop_usb_charging(void);
 int twl6030_get_battery_voltage(void);
 int twl6030_get_battery_current(void);
+void twl6030_power_mmc_init(void);
diff --git a/nand_spl/board/freescale/mx31pdk/Makefile b/nand_spl/board/freescale/mx31pdk/Makefile
index e6ec10a..87784d2 100644
--- a/nand_spl/board/freescale/mx31pdk/Makefile
+++ b/nand_spl/board/freescale/mx31pdk/Makefile
@@ -1,7 +1,7 @@
 CONFIG_NAND_SPL	= y
+PAD_TO	:= 2048
 
 include $(TOPDIR)/config.mk
-include $(TOPDIR)/nand_spl/board/$(BOARDDIR)/config.mk
 
 nandobj	:= $(OBJTREE)/nand_spl/
 
diff --git a/nand_spl/board/freescale/mx31pdk/config.mk b/nand_spl/board/freescale/mx31pdk/config.mk
deleted file mode 100644
index 68afbf1..0000000
--- a/nand_spl/board/freescale/mx31pdk/config.mk
+++ /dev/null
@@ -1 +0,0 @@
-PAD_TO	:= 2048
diff --git a/spl/Makefile b/spl/Makefile
index 95ecce1..b44e84d 100644
--- a/spl/Makefile
+++ b/spl/Makefile
@@ -46,6 +46,8 @@
 LIBS-$(CONFIG_SPL_SPI_SUPPORT) += drivers/spi/libspi.o
 LIBS-$(CONFIG_SPL_FAT_SUPPORT) += fs/fat/libfat.o
 LIBS-$(CONFIG_SPL_LIBGENERIC_SUPPORT) += lib/libgeneric.o
+LIBS-$(CONFIG_SPL_POWER_SUPPORT) += drivers/power/libpower.o
+LIBS-$(CONFIG_SPL_NAND_SUPPORT) += drivers/mtd/nand/libnand.o
 
 ifeq ($(SOC),omap3)
 LIBS-y += $(CPUDIR)/omap-common/libomap-common.o