diff --git a/arch/arm/cpu/arm926ejs/davinci/reset.c b/arch/arm/cpu/arm926ejs/davinci/reset.c
index 968fb035c89..80f1ce9d318 100644
--- a/arch/arm/cpu/arm926ejs/davinci/reset.c
+++ b/arch/arm/cpu/arm926ejs/davinci/reset.c
@@ -16,7 +16,7 @@
 void reset_cpu(unsigned long a)
 {
 	struct davinci_timer *const wdttimer =
-		(struct davinci_timer *)DAVINCI_TIMER1_BASE;
+		(struct davinci_timer *)DAVINCI_WDOG_BASE;
 	writel(0x08, &wdttimer->tgcr);
 	writel(readl(&wdttimer->tgcr) | 0x03, &wdttimer->tgcr);
 	writel(0, &wdttimer->tim12);
diff --git a/arch/arm/cpu/armv7/am33xx/Makefile b/arch/arm/cpu/armv7/am33xx/Makefile
index 74875b32558..70c443edbbb 100644
--- a/arch/arm/cpu/armv7/am33xx/Makefile
+++ b/arch/arm/cpu/armv7/am33xx/Makefile
@@ -18,10 +18,12 @@ LIB	= $(obj)lib$(SOC).o
 
 COBJS	+= clock.o
 COBJS	+= sys_info.o
+COBJS	+= mem.o
 COBJS	+= ddr.o
 COBJS	+= emif4.o
 COBJS	+= board.o
 COBJS	+= mux.o
+COBJS-$(CONFIG_NAND_OMAP_GPMC)	+= elm.o
 
 SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
 OBJS	:= $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS))
diff --git a/arch/arm/cpu/armv7/am33xx/board.c b/arch/arm/cpu/armv7/am33xx/board.c
index da5bc731852..ab313265d0c 100644
--- a/arch/arm/cpu/armv7/am33xx/board.c
+++ b/arch/arm/cpu/armv7/am33xx/board.c
@@ -25,6 +25,7 @@
 #include <asm/arch/ddr_defs.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/gpio.h>
+#include <asm/arch/mem.h>
 #include <asm/arch/mmc_host_def.h>
 #include <asm/arch/sys_proto.h>
 #include <asm/io.h>
diff --git a/arch/arm/cpu/armv7/am33xx/clock.c b/arch/arm/cpu/armv7/am33xx/clock.c
index 0b4cb4e529e..d7d98d1111e 100644
--- a/arch/arm/cpu/armv7/am33xx/clock.c
+++ b/arch/arm/cpu/armv7/am33xx/clock.c
@@ -151,6 +151,16 @@ static void enable_per_clocks(void)
 		;
 #endif /* CONFIG_SERIAL6 */
 
+	/* GPMC */
+	writel(PRCM_MOD_EN, &cmper->gpmcclkctrl);
+	while (readl(&cmper->gpmcclkctrl) != PRCM_MOD_EN)
+		;
+
+	/* ELM */
+	writel(PRCM_MOD_EN, &cmper->elmclkctrl);
+	while (readl(&cmper->elmclkctrl) != PRCM_MOD_EN)
+		;
+
 	/* MMC0*/
 	writel(PRCM_MOD_EN, &cmper->mmc0clkctrl);
 	while (readl(&cmper->mmc0clkctrl) != PRCM_MOD_EN)
diff --git a/arch/arm/cpu/armv7/am33xx/elm.c b/arch/arm/cpu/armv7/am33xx/elm.c
new file mode 100644
index 00000000000..9eed23d75af
--- /dev/null
+++ b/arch/arm/cpu/armv7/am33xx/elm.c
@@ -0,0 +1,212 @@
+/*
+ * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com>
+ * Mansoor Ahamed <mansoor.ahamed@ti.com>
+ *
+ * BCH Error Location Module (ELM) support.
+ *
+ * NOTE:
+ * 1. Supports only continuous mode. Dont see need for page mode in uboot
+ * 2. Supports only syndrome polynomial 0. i.e. poly local variable is
+ *    always set to ELM_DEFAULT_POLY. Dont see need for other polynomial
+ *    sets in uboot
+ *
+ * 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/io.h>
+#include <asm/errno.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/omap_gpmc.h>
+#include <asm/arch/elm.h>
+
+#define ELM_DEFAULT_POLY (0)
+
+struct elm *elm_cfg;
+
+/**
+ * elm_load_syndromes - Load BCH syndromes based on nibble selection
+ * @syndrome: BCH syndrome
+ * @nibbles:
+ * @poly: Syndrome Polynomial set to use
+ *
+ * Load BCH syndromes based on nibble selection
+ */
+static void elm_load_syndromes(u8 *syndrome, u32 nibbles, u8 poly)
+{
+	u32 *ptr;
+	u32 val;
+
+	/* reg 0 */
+	ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[0];
+	val = syndrome[0] | (syndrome[1] << 8) | (syndrome[2] << 16) |
+				(syndrome[3] << 24);
+	writel(val, ptr);
+	/* reg 1 */
+	ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[1];
+	val = syndrome[4] | (syndrome[5] << 8) | (syndrome[6] << 16) |
+				(syndrome[7] << 24);
+	writel(val, ptr);
+
+	/* BCH 8-bit with 26 nibbles (4*8=32) */
+	if (nibbles > 13) {
+		/* reg 2 */
+		ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[2];
+		val = syndrome[8] | (syndrome[9] << 8) | (syndrome[10] << 16) |
+				(syndrome[11] << 24);
+		writel(val, ptr);
+		/* reg 3 */
+		ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[3];
+		val = syndrome[12] | (syndrome[13] << 8) |
+			(syndrome[14] << 16) | (syndrome[15] << 24);
+		writel(val, ptr);
+	}
+
+	/* BCH 16-bit with 52 nibbles (7*8=56) */
+	if (nibbles > 26) {
+		/* reg 4 */
+		ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[4];
+		val = syndrome[16] | (syndrome[17] << 8) |
+			(syndrome[18] << 16) | (syndrome[19] << 24);
+		writel(val, ptr);
+
+		/* reg 5 */
+		ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[5];
+		val = syndrome[20] | (syndrome[21] << 8) |
+			(syndrome[22] << 16) | (syndrome[23] << 24);
+		writel(val, ptr);
+
+		/* reg 6 */
+		ptr = &elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6];
+		val = syndrome[24] | (syndrome[25] << 8) |
+			(syndrome[26] << 16) | (syndrome[27] << 24);
+		writel(val, ptr);
+	}
+}
+
+/**
+ * elm_check_errors - Check for BCH errors and return error locations
+ * @syndrome: BCH syndrome
+ * @nibbles:
+ * @error_count: Returns number of errrors in the syndrome
+ * @error_locations: Returns error locations (in decimal) in this array
+ *
+ * Check the provided syndrome for BCH errors and return error count
+ * and locations in the array passed. Returns -1 if error is not correctable,
+ * else returns 0
+ */
+int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
+		u32 *error_locations)
+{
+	u8 poly = ELM_DEFAULT_POLY;
+	s8 i;
+	u32 location_status;
+
+	elm_load_syndromes(syndrome, nibbles, poly);
+
+	/* start processing */
+	writel((readl(&elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6])
+				| ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID),
+		&elm_cfg->syndrome_fragments[poly].syndrome_fragment_x[6]);
+
+	/* wait for processing to complete */
+	while ((readl(&elm_cfg->irqstatus) & (0x1 << poly)) != 0x1)
+		;
+	/* clear status */
+	writel((readl(&elm_cfg->irqstatus) | (0x1 << poly)),
+			&elm_cfg->irqstatus);
+
+	/* check if correctable */
+	location_status = readl(&elm_cfg->error_location[poly].location_status);
+	if (!(location_status & ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK))
+		return -1;
+
+	/* get error count */
+	*error_count = readl(&elm_cfg->error_location[poly].location_status) &
+					ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK;
+
+	for (i = 0; i < *error_count; i++) {
+		error_locations[i] =
+			readl(&elm_cfg->error_location[poly].error_location_x[i]);
+	}
+
+	return 0;
+}
+
+
+/**
+ * elm_config - Configure ELM module
+ * @level: 4 / 8 / 16 bit BCH
+ *
+ * Configure ELM module based on BCH level.
+ * Set mode as continuous mode.
+ * Currently we are using only syndrome 0 and syndromes 1 to 6 are not used.
+ * Also, the mode is set only for syndrome 0
+ */
+int elm_config(enum bch_level level)
+{
+	u32 val;
+	u8 poly = ELM_DEFAULT_POLY;
+	u32 buffer_size = 0x7FF;
+
+	/* config size and level */
+	val = (u32)(level) & ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK;
+	val |= ((buffer_size << ELM_LOCATION_CONFIG_ECC_SIZE_POS) &
+				ELM_LOCATION_CONFIG_ECC_SIZE_MASK);
+	writel(val, &elm_cfg->location_config);
+
+	/* config continous mode */
+	/* enable interrupt generation for syndrome polynomial set */
+	writel((readl(&elm_cfg->irqenable) | (0x1 << poly)),
+			&elm_cfg->irqenable);
+	/* set continuous mode for the syndrome polynomial set */
+	writel((readl(&elm_cfg->page_ctrl) & ~(0x1 << poly)),
+			&elm_cfg->page_ctrl);
+
+	return 0;
+}
+
+/**
+ * elm_reset - Do a soft reset of ELM
+ *
+ * Perform a soft reset of ELM and return after reset is done.
+ */
+void elm_reset(void)
+{
+	/* initiate reset */
+	writel((readl(&elm_cfg->sysconfig) | ELM_SYSCONFIG_SOFTRESET),
+				&elm_cfg->sysconfig);
+
+	/* wait for reset complete and normal operation */
+	while ((readl(&elm_cfg->sysstatus) & ELM_SYSSTATUS_RESETDONE) !=
+		ELM_SYSSTATUS_RESETDONE)
+		;
+}
+
+/**
+ * elm_init - Initialize ELM module
+ *
+ * Initialize ELM support. Currently it does only base address init
+ * and ELM reset.
+ */
+void elm_init(void)
+{
+	elm_cfg = (struct elm *)ELM_BASE;
+	elm_reset();
+}
diff --git a/arch/arm/cpu/armv7/am33xx/mem.c b/arch/arm/cpu/armv7/am33xx/mem.c
new file mode 100644
index 00000000000..b8f54abae2f
--- /dev/null
+++ b/arch/arm/cpu/armv7/am33xx/mem.c
@@ -0,0 +1,101 @@
+/*
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author :
+ *     Mansoor Ahamed <mansoor.ahamed@ti.com>
+ *
+ * Initial Code from:
+ *     Manikandan Pillai <mani.pillai@ti.com>
+ *     Richard Woodruff <r-woodruff2@ti.com>
+ *     Syed Mohammed Khasim <khasim@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
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/sys_proto.h>
+#include <command.h>
+
+struct gpmc *gpmc_cfg;
+
+#if defined(CONFIG_CMD_NAND)
+static const u32 gpmc_m_nand[GPMC_MAX_REG] = {
+	M_NAND_GPMC_CONFIG1,
+	M_NAND_GPMC_CONFIG2,
+	M_NAND_GPMC_CONFIG3,
+	M_NAND_GPMC_CONFIG4,
+	M_NAND_GPMC_CONFIG5,
+	M_NAND_GPMC_CONFIG6, 0
+};
+#endif
+
+
+void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
+			u32 size)
+{
+	writel(0, &cs->config7);
+	sdelay(1000);
+	/* Delay for settling */
+	writel(gpmc_config[0], &cs->config1);
+	writel(gpmc_config[1], &cs->config2);
+	writel(gpmc_config[2], &cs->config3);
+	writel(gpmc_config[3], &cs->config4);
+	writel(gpmc_config[4], &cs->config5);
+	writel(gpmc_config[5], &cs->config6);
+	/* Enable the config */
+	writel((((size & 0xF) << 8) | ((base >> 24) & 0x3F) |
+		(1 << 6)), &cs->config7);
+	sdelay(2000);
+}
+
+/*****************************************************
+ * gpmc_init(): init gpmc bus
+ * Init GPMC for x16, MuxMode (SDRAM in x32).
+ * This code can only be executed from SRAM or SDRAM.
+ *****************************************************/
+void gpmc_init(void)
+{
+	/* putting a blanket check on GPMC based on ZeBu for now */
+	gpmc_cfg = (struct gpmc *)GPMC_BASE;
+
+#ifdef CONFIG_CMD_NAND
+	const u32 *gpmc_config = NULL;
+	u32 base = 0;
+	u32 size = 0;
+#endif
+	/* global settings */
+	writel(0x00000008, &gpmc_cfg->sysconfig);
+	writel(0x00000100, &gpmc_cfg->irqstatus);
+	writel(0x00000200, &gpmc_cfg->irqenable);
+	writel(0x00000012, &gpmc_cfg->config);
+	/*
+	 * Disable the GPMC0 config set by ROM code
+	 */
+	writel(0, &gpmc_cfg->cs[0].config7);
+	sdelay(1000);
+
+#ifdef CONFIG_CMD_NAND
+	gpmc_config = gpmc_m_nand;
+
+	base = PISMO1_NAND_BASE;
+	size = PISMO1_NAND_SIZE;
+	enable_gpmc_cs_config(gpmc_config, &gpmc_cfg->cs[0], base, size);
+#endif
+}
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile
index 1f2fa027c8f..0efc80ddeb4 100644
--- a/arch/arm/cpu/armv7/omap-common/Makefile
+++ b/arch/arm/cpu/armv7/omap-common/Makefile
@@ -25,9 +25,8 @@ include $(TOPDIR)/config.mk
 
 LIB	= $(obj)libomap-common.o
 
-SOBJS	:= reset.o
-
-COBJS	:= timer.o
+COBJS	:= reset.o
+COBJS	+= timer.o
 COBJS	+= utils.o
 
 ifneq ($(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c
index 0f19141cc23..2b584e0a537 100644
--- a/arch/arm/cpu/armv7/omap-common/boot-common.c
+++ b/arch/arm/cpu/armv7/omap-common/boot-common.c
@@ -21,6 +21,7 @@
 #include <asm/omap_common.h>
 #include <asm/arch/omap.h>
 #include <asm/arch/mmc_host_def.h>
+#include <asm/arch/sys_proto.h>
 
 /*
  * This is used to verify if the configuration header
diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c
index 30dcf1b0b04..88253cf8ce3 100644
--- a/arch/arm/cpu/armv7/omap-common/emif-common.c
+++ b/arch/arm/cpu/armv7/omap-common/emif-common.c
@@ -33,6 +33,8 @@
 #include <asm/utils.h>
 #include <linux/compiler.h>
 
+static int emif1_enabled = -1, emif2_enabled = -1;
+
 void set_lpmode_selfrefresh(u32 base)
 {
 	struct emif_reg_struct *emif = (struct emif_reg_struct *)base;
@@ -1109,6 +1111,7 @@ void emif_post_init_config(u32 base)
 void dmm_init(u32 base)
 {
 	const struct dmm_lisa_map_regs *lisa_map_regs;
+	u32 i, section, valid;
 
 #ifdef CONFIG_SYS_EMIF_PRECALCULATED_TIMING_REGS
 	emif_get_dmm_regs(&lisa_map_regs);
@@ -1216,6 +1219,29 @@ void dmm_init(u32 base)
 		writel(lisa_map_regs->dmm_lisa_map_0,
 			&hw_lisa_map_regs->dmm_lisa_map_0);
 	}
+
+	/*
+	 * EMIF should be configured only when
+	 * memory is mapped on it. Using emif1_enabled
+	 * and emif2_enabled variables for this.
+	 */
+	emif1_enabled = 0;
+	emif2_enabled = 0;
+	for (i = 0; i < 4; i++) {
+		section	= __raw_readl(DMM_BASE + i*4);
+		valid = (section & EMIF_SDRC_MAP_MASK) >>
+			(EMIF_SDRC_MAP_SHIFT);
+		if (valid == 3) {
+			emif1_enabled = 1;
+			emif2_enabled = 1;
+			break;
+		} else if (valid == 1) {
+			emif1_enabled = 1;
+		} else if (valid == 2) {
+			emif2_enabled = 1;
+		}
+	}
+
 }
 
 /*
@@ -1255,15 +1281,20 @@ void sdram_init(void)
 			writel(CM_DLL_CTRL_NO_OVERRIDE, &prcm->cm_dll_ctrl);
 	}
 
-	do_sdram_init(EMIF1_BASE);
-	do_sdram_init(EMIF2_BASE);
-
 	if (!in_sdram)
 		dmm_init(DMM_BASE);
 
+	if (emif1_enabled)
+		do_sdram_init(EMIF1_BASE);
+
+	if (emif2_enabled)
+		do_sdram_init(EMIF2_BASE);
+
 	if (!(in_sdram || warm_reset())) {
-		emif_post_init_config(EMIF1_BASE);
-		emif_post_init_config(EMIF2_BASE);
+		if (emif1_enabled)
+			emif_post_init_config(EMIF1_BASE);
+		if (emif2_enabled)
+			emif_post_init_config(EMIF2_BASE);
 	}
 
 	/* for the shadow registers to take effect */
diff --git a/arch/arm/cpu/armv7/omap3/board.c b/arch/arm/cpu/armv7/omap3/board.c
index f3cd81ad988..89c587e3108 100644
--- a/arch/arm/cpu/armv7/omap3/board.c
+++ b/arch/arm/cpu/armv7/omap3/board.c
@@ -478,7 +478,7 @@ void omap3_outer_cache_disable(void)
 	 */
 	omap3_update_aux_cr(0, 0x2);
 }
-#endif
+#endif /* !CONFIG_SYS_L2CACHE_OFF */
 
 #ifndef CONFIG_SYS_DCACHE_OFF
 void enable_caches(void)
@@ -486,4 +486,4 @@ void enable_caches(void)
 	/* Enable D-cache. I-cache is already enabled in start.S */
 	dcache_enable();
 }
-#endif
+#endif /* !CONFIG_SYS_DCACHE_OFF */
diff --git a/arch/arm/cpu/armv7/omap3/mem.c b/arch/arm/cpu/armv7/omap3/mem.c
index 2fe5ac7c394..d04a5a10d75 100644
--- a/arch/arm/cpu/armv7/omap3/mem.c
+++ b/arch/arm/cpu/armv7/omap3/mem.c
@@ -42,14 +42,7 @@ static const u32 gpmc_m_nand[GPMC_MAX_REG] = {
 	M_NAND_GPMC_CONFIG5,
 	M_NAND_GPMC_CONFIG6, 0
 };
-
-#if defined(CONFIG_ENV_IS_IN_NAND)
-#define GPMC_CS 0
-#else
-#define GPMC_CS 1
-#endif
-
-#endif
+#endif /* CONFIG_CMD_NAND */
 
 #if defined(CONFIG_CMD_ONENAND)
 static const u32 gpmc_onenand[GPMC_MAX_REG] = {
@@ -60,14 +53,7 @@ static const u32 gpmc_onenand[GPMC_MAX_REG] = {
 	ONENAND_GPMC_CONFIG5,
 	ONENAND_GPMC_CONFIG6, 0
 };
-
-#if defined(CONFIG_ENV_IS_IN_ONENAND)
-#define GPMC_CS 0
-#else
-#define GPMC_CS 1
-#endif
-
-#endif
+#endif /* CONFIG_CMD_ONENAND */
 
 /********************************************************
  *  mem_ok() - test used to see if timings are correct
diff --git a/arch/arm/cpu/armv7/omap3/sdrc.c b/arch/arm/cpu/armv7/omap3/sdrc.c
index f6d9b97bb4d..e32bf118b18 100644
--- a/arch/arm/cpu/armv7/omap3/sdrc.c
+++ b/arch/arm/cpu/armv7/omap3/sdrc.c
@@ -113,18 +113,18 @@ u32 get_sdr_cs_offset(u32 cs)
  *  - Test CS to make sure it's OK for use
  */
 static void write_sdrc_timings(u32 cs, struct sdrc_actim *sdrc_actim_base,
-		u32 mcfg, u32 ctrla, u32 ctrlb, u32 rfr_ctrl, u32 mr)
+			struct board_sdrc_timings *timings)
 {
 	/* Setup timings we got from the board. */
-	writel(mcfg, &sdrc_base->cs[cs].mcfg);
-	writel(ctrla, &sdrc_actim_base->ctrla);
-	writel(ctrlb, &sdrc_actim_base->ctrlb);
-	writel(rfr_ctrl, &sdrc_base->cs[cs].rfr_ctrl);
+	writel(timings->mcfg, &sdrc_base->cs[cs].mcfg);
+	writel(timings->ctrla, &sdrc_actim_base->ctrla);
+	writel(timings->ctrlb, &sdrc_actim_base->ctrlb);
+	writel(timings->rfr_ctrl, &sdrc_base->cs[cs].rfr_ctrl);
 	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(mr, &sdrc_base->cs[cs].mr);
+	writel(timings->mr, &sdrc_base->cs[cs].mr);
 
 	/*
 	 * Test ram in this bank
@@ -143,7 +143,7 @@ static void write_sdrc_timings(u32 cs, struct sdrc_actim *sdrc_actim_base,
 void do_sdrc_init(u32 cs, u32 early)
 {
 	struct sdrc_actim *sdrc_actim_base0, *sdrc_actim_base1;
-	u32 mcfg, ctrla, ctrlb, rfr_ctrl, mr;
+	struct board_sdrc_timings timings;
 
 	sdrc_actim_base0 = (struct sdrc_actim *)SDRC_ACTIM_CTRL0_BASE;
 	sdrc_actim_base1 = (struct sdrc_actim *)SDRC_ACTIM_CTRL1_BASE;
@@ -158,7 +158,7 @@ void do_sdrc_init(u32 cs, u32 early)
 	 * setup CS1.
 	 */
 #ifdef CONFIG_SPL_BUILD
-	get_board_mem_timings(&mcfg, &ctrla, &ctrlb, &rfr_ctrl, &mr);
+	get_board_mem_timings(&timings);
 #endif
 	if (early) {
 		/* reset sdrc controller */
@@ -177,11 +177,9 @@ void do_sdrc_init(u32 cs, u32 early)
 		writel(ENADLL | DLLPHASE_90, &sdrc_base->dlla_ctrl);
 		sdelay(0x20000);
 #ifdef CONFIG_SPL_BUILD
-		write_sdrc_timings(CS0, sdrc_actim_base0, mcfg, ctrla, ctrlb,
-				rfr_ctrl, mr);
+		write_sdrc_timings(CS0, sdrc_actim_base0, &timings);
 		make_cs1_contiguous();
-		write_sdrc_timings(CS1, sdrc_actim_base1, mcfg, ctrla, ctrlb,
-				rfr_ctrl, mr);
+		write_sdrc_timings(CS1, sdrc_actim_base1, &timings);
 #endif
 
 	}
@@ -193,14 +191,12 @@ void do_sdrc_init(u32 cs, u32 early)
 	 * so we may be asked now to setup CS1.
 	 */
 	if (cs == CS1) {
-		mcfg = readl(&sdrc_base->cs[CS0].mcfg),
-		rfr_ctrl = readl(&sdrc_base->cs[CS0].rfr_ctrl);
-		ctrla = readl(&sdrc_actim_base0->ctrla),
-		ctrlb = readl(&sdrc_actim_base0->ctrlb);
-		mr = readl(&sdrc_base->cs[CS0].mr);
-		write_sdrc_timings(cs, sdrc_actim_base1, mcfg, ctrla, ctrlb,
-				rfr_ctrl, mr);
-
+		timings.mcfg = readl(&sdrc_base->cs[CS0].mcfg),
+		timings.rfr_ctrl = readl(&sdrc_base->cs[CS0].rfr_ctrl);
+		timings.ctrla = readl(&sdrc_actim_base0->ctrla);
+		timings.ctrlb = readl(&sdrc_actim_base0->ctrlb);
+		timings.mr = readl(&sdrc_base->cs[CS0].mr);
+		write_sdrc_timings(cs, sdrc_actim_base1, &timings);
 	}
 }
 
diff --git a/arch/arm/cpu/armv7/omap4/clocks.c b/arch/arm/cpu/armv7/omap4/clocks.c
index 5bd0a88fdeb..12c58033d26 100644
--- a/arch/arm/cpu/armv7/omap4/clocks.c
+++ b/arch/arm/cpu/armv7/omap4/clocks.c
@@ -44,7 +44,7 @@
  */
 #define printf(fmt, args...)
 #define puts(s)
-#endif
+#endif /* !CONFIG_SPL_BUILD */
 
 struct omap4_prcm_regs *const prcm = (struct omap4_prcm_regs *)0x4A004100;
 
diff --git a/arch/arm/cpu/armv7/omap4/hwinit.c b/arch/arm/cpu/armv7/omap4/hwinit.c
index 2c34e48f428..f4123aaffca 100644
--- a/arch/arm/cpu/armv7/omap4/hwinit.c
+++ b/arch/arm/cpu/armv7/omap4/hwinit.c
@@ -116,7 +116,7 @@ void do_io_settings(void)
 	if ((omap4_rev < OMAP4460_ES1_0) || !readl(&ctrl->control_efuse_2))
 		writel(CONTROL_EFUSE_2_OVERRIDE, &ctrl->control_efuse_2);
 }
-#endif
+#endif /* CONFIG_SPL_BUILD */
 
 /* dummy fuction for omap4 */
 void config_data_eye_leveling_samples(u32 emif_base)
@@ -182,4 +182,4 @@ void v7_outer_cache_disable(void)
 {
 	set_pl310_ctrl_reg(0);
 }
-#endif
+#endif /* !CONFIG_SYS_L2CACHE_OFF */
diff --git a/arch/arm/include/asm/arch-am33xx/cpu.h b/arch/arm/include/asm/arch-am33xx/cpu.h
index d6c038e3aec..16e8a80700a 100644
--- a/arch/arm/include/asm/arch-am33xx/cpu.h
+++ b/arch/arm/include/asm/arch-am33xx/cpu.h
@@ -60,6 +60,59 @@
 
 #ifndef __KERNEL_STRICT_NAMES
 #ifndef __ASSEMBLY__
+struct gpmc_cs {
+	u32 config1;		/* 0x00 */
+	u32 config2;		/* 0x04 */
+	u32 config3;		/* 0x08 */
+	u32 config4;		/* 0x0C */
+	u32 config5;		/* 0x10 */
+	u32 config6;		/* 0x14 */
+	u32 config7;		/* 0x18 */
+	u32 nand_cmd;		/* 0x1C */
+	u32 nand_adr;		/* 0x20 */
+	u32 nand_dat;		/* 0x24 */
+	u8 res[8];		/* blow up to 0x30 byte */
+};
+
+struct bch_res_0_3 {
+	u32 bch_result_x[4];
+};
+
+struct gpmc {
+	u8 res1[0x10];
+	u32 sysconfig;		/* 0x10 */
+	u8 res2[0x4];
+	u32 irqstatus;		/* 0x18 */
+	u32 irqenable;		/* 0x1C */
+	u8 res3[0x20];
+	u32 timeout_control;	/* 0x40 */
+	u8 res4[0xC];
+	u32 config;		/* 0x50 */
+	u32 status;		/* 0x54 */
+	u8 res5[0x8];		/* 0x58 */
+	struct gpmc_cs cs[8];	/* 0x60, 0x90, .. */
+	u8 res6[0x14];		/* 0x1E0 */
+	u32 ecc_config;		/* 0x1F4 */
+	u32 ecc_control;	/* 0x1F8 */
+	u32 ecc_size_config;	/* 0x1FC */
+	u32 ecc1_result;	/* 0x200 */
+	u32 ecc2_result;	/* 0x204 */
+	u32 ecc3_result;	/* 0x208 */
+	u32 ecc4_result;	/* 0x20C */
+	u32 ecc5_result;	/* 0x210 */
+	u32 ecc6_result;	/* 0x214 */
+	u32 ecc7_result;	/* 0x218 */
+	u32 ecc8_result;	/* 0x21C */
+	u32 ecc9_result;	/* 0x220 */
+	u8 res7[12];		/* 0x224 */
+	u32 testmomde_ctrl;	/* 0x230 */
+	u8 res8[12];		/* 0x234 */
+	struct bch_res_0_3 bch_result_0_3[2];	/* 0x240 */
+};
+
+/* Used for board specific gpmc initialization */
+extern struct gpmc *gpmc_cfg;
+
 /* Encapsulating core pll registers */
 struct cm_wkuppll {
 	unsigned int wkclkstctrl;	/* offset 0x00 */
diff --git a/arch/arm/include/asm/arch-am33xx/elm.h b/arch/arm/include/asm/arch-am33xx/elm.h
new file mode 100644
index 00000000000..e80f7d48e4a
--- /dev/null
+++ b/arch/arm/include/asm/arch-am33xx/elm.h
@@ -0,0 +1,93 @@
+/*
+ * (C) Copyright 2010-2011 Texas Instruments, <www.ti.com>
+ * Mansoor Ahamed <mansoor.ahamed@ti.com>
+ *
+ * Derived from work done by Rohit Choraria <rohitkc@ti.com> for omap3
+ *
+ * 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 __ASM_ARCH_ELM_H
+#define __ASM_ARCH_ELM_H
+/*
+ * ELM Module Registers
+ */
+
+/* ELM registers bit fields */
+#define ELM_SYSCONFIG_SOFTRESET_MASK			(0x2)
+#define ELM_SYSCONFIG_SOFTRESET			(0x2)
+#define ELM_SYSSTATUS_RESETDONE_MASK			(0x1)
+#define ELM_SYSSTATUS_RESETDONE			(0x1)
+#define ELM_LOCATION_CONFIG_ECC_BCH_LEVEL_MASK		(0x3)
+#define ELM_LOCATION_CONFIG_ECC_SIZE_MASK		(0x7FF0000)
+#define ELM_LOCATION_CONFIG_ECC_SIZE_POS		(16)
+#define ELM_SYNDROME_FRAGMENT_6_SYNDROME_VALID		(0x00010000)
+#define ELM_LOCATION_STATUS_ECC_CORRECTABLE_MASK	(0x100)
+#define ELM_LOCATION_STATUS_ECC_NB_ERRORS_MASK		(0x1F)
+
+#ifndef __ASSEMBLY__
+
+enum bch_level {
+	BCH_4_BIT = 0,
+	BCH_8_BIT,
+	BCH_16_BIT
+};
+
+
+/* BCH syndrome registers */
+struct syndrome {
+	u32 syndrome_fragment_x[7];	/* 0x400, 0x404.... 0x418 */
+	u8 res1[36];			/* 0x41c */
+};
+
+/* BCH error status & location register */
+struct location {
+	u32 location_status;		/* 0x800 */
+	u8 res1[124];			/* 0x804 */
+	u32 error_location_x[16];	/* 0x880.... */
+	u8 res2[64];			/* 0x8c0 */
+};
+
+/* BCH ELM register map - do not try to allocate memmory for this structure.
+ * We have used plenty of reserved variables to fill the slots in the ELM
+ * register memory map.
+ * Directly initialize the struct pointer to ELM base address.
+ */
+struct elm {
+	u32 rev;				/* 0x000 */
+	u8 res1[12];				/* 0x004 */
+	u32 sysconfig;				/* 0x010 */
+	u32 sysstatus;				/* 0x014 */
+	u32 irqstatus;				/* 0x018 */
+	u32 irqenable;				/* 0x01c */
+	u32 location_config;			/* 0x020 */
+	u8 res2[92];				/* 0x024 */
+	u32 page_ctrl;				/* 0x080 */
+	u8 res3[892];				/* 0x084 */
+	struct  syndrome syndrome_fragments[8]; /* 0x400 */
+	u8 res4[512];				/* 0x600 */
+	struct location  error_location[8];	/* 0x800 */
+};
+
+int elm_check_error(u8 *syndrome, u32 nibbles, u32 *error_count,
+		u32 *error_locations);
+int elm_config(enum bch_level level);
+void elm_reset(void);
+void elm_init(void);
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_ARCH_ELM_H */
diff --git a/arch/arm/include/asm/arch-am33xx/hardware.h b/arch/arm/include/asm/arch-am33xx/hardware.h
index 24ab365ea31..6dd3296907a 100644
--- a/arch/arm/include/asm/arch-am33xx/hardware.h
+++ b/arch/arm/include/asm/arch-am33xx/hardware.h
@@ -80,6 +80,9 @@
 #define DDRPHY_0_CONFIG_BASE		(CTRL_BASE + 0x1400)
 #define DDRPHY_CONFIG_BASE		DDRPHY_0_CONFIG_BASE
 
+/* GPMC Base address */
+#define GPMC_BASE			0x50000000
+
 /* CPSW Config space */
 #define AM335X_CPSW_BASE		0x4A100000
 #define AM335X_CPSW_MDIO_BASE		0x4A101000
diff --git a/arch/arm/include/asm/arch-am33xx/mem.h b/arch/arm/include/asm/arch-am33xx/mem.h
new file mode 100644
index 00000000000..c3bf74e629b
--- /dev/null
+++ b/arch/arm/include/asm/arch-am33xx/mem.h
@@ -0,0 +1,83 @@
+/*
+ * (C) Copyright 2006-2008
+ * Texas Instruments, <www.ti.com>
+ *
+ * Author
+ *		Mansoor Ahamed <mansoor.ahamed@ti.com>
+ *
+ * Initial Code from:
+ *		Richard Woodruff <r-woodruff2@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
+ */
+
+#ifndef _MEM_H_
+#define _MEM_H_
+
+/*
+ * GPMC settings -
+ * Definitions is as per the following format
+ * #define <PART>_GPMC_CONFIG<x> <value>
+ * Where:
+ * PART is the part name e.g. STNOR - Intel Strata Flash
+ * x is GPMC config registers from 1 to 6 (there will be 6 macros)
+ * Value is corresponding value
+ *
+ * For every valid PRCM configuration there should be only one definition of
+ * the same. if values are independent of the board, this definition will be
+ * present in this file if values are dependent on the board, then this should
+ * go into corresponding mem-boardName.h file
+ *
+ * Currently valid part Names are (PART):
+ * M_NAND - Micron NAND
+ */
+#define GPMC_SIZE_256M		0x0
+#define GPMC_SIZE_128M		0x8
+#define GPMC_SIZE_64M		0xC
+#define GPMC_SIZE_32M		0xE
+#define GPMC_SIZE_16M		0xF
+
+#define M_NAND_GPMC_CONFIG1	0x00000800
+#define M_NAND_GPMC_CONFIG2	0x001e1e00
+#define M_NAND_GPMC_CONFIG3	0x001e1e00
+#define M_NAND_GPMC_CONFIG4	0x16051807
+#define M_NAND_GPMC_CONFIG5	0x00151e1e
+#define M_NAND_GPMC_CONFIG6	0x16000f80
+#define M_NAND_GPMC_CONFIG7	0x00000008
+
+/* max number of GPMC Chip Selects */
+#define GPMC_MAX_CS		8
+/* max number of GPMC regs */
+#define GPMC_MAX_REG		7
+
+#define PISMO1_NOR		1
+#define PISMO1_NAND		2
+#define PISMO2_CS0		3
+#define PISMO2_CS1		4
+#define PISMO1_ONENAND		5
+#define DBG_MPDB		6
+#define PISMO2_NAND_CS0		7
+#define PISMO2_NAND_CS1		8
+
+/* make it readable for the gpmc_init */
+#define PISMO1_NOR_BASE	FLASH_BASE
+#define PISMO1_NAND_BASE	CONFIG_SYS_NAND_BASE
+#define PISMO1_NAND_SIZE	GPMC_SIZE_256M
+
+#endif /* endif _MEM_H_ */
diff --git a/arch/arm/include/asm/arch-am33xx/omap_gpmc.h b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
new file mode 100644
index 00000000000..572f9d0b27c
--- /dev/null
+++ b/arch/arm/include/asm/arch-am33xx/omap_gpmc.h
@@ -0,0 +1,120 @@
+/*
+ * (C) Copyright 2004-2008 Texas Instruments, <www.ti.com>
+ * Rohit Choraria <rohitkc@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
+ */
+#ifndef __ASM_ARCH_OMAP_GPMC_H
+#define __ASM_ARCH_OMAP_GPMC_H
+
+#define GPMC_BUF_EMPTY	0
+#define GPMC_BUF_FULL	1
+
+#define ECCCLEAR	(0x1 << 8)
+#define ECCRESULTREG1	(0x1 << 0)
+#define ECCSIZE512BYTE	0xFF
+#define ECCSIZE1	(ECCSIZE512BYTE << 22)
+#define ECCSIZE0	(ECCSIZE512BYTE << 12)
+#define ECCSIZE0SEL	(0x000 << 0)
+
+/* Generic ECC Layouts */
+/* Large Page x8 NAND device Layout */
+#ifdef GPMC_NAND_ECC_LP_x8_LAYOUT
+#define GPMC_NAND_HW_ECC_LAYOUT {\
+	.eccbytes = 12,\
+	.eccpos = {1, 2, 3, 4, 5, 6, 7, 8,\
+		9, 10, 11, 12},\
+	.oobfree = {\
+		{.offset = 13,\
+		 .length = 51 } } \
+}
+#endif
+
+/* Large Page x16 NAND device Layout */
+#ifdef GPMC_NAND_ECC_LP_x16_LAYOUT
+#define GPMC_NAND_HW_ECC_LAYOUT {\
+	.eccbytes = 12,\
+	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9,\
+		10, 11, 12, 13},\
+	.oobfree = {\
+		{.offset = 14,\
+		 .length = 50 } } \
+}
+#endif
+
+/* Small Page x8 NAND device Layout */
+#ifdef GPMC_NAND_ECC_SP_x8_LAYOUT
+#define GPMC_NAND_HW_ECC_LAYOUT {\
+	.eccbytes = 3,\
+	.eccpos = {1, 2, 3},\
+	.oobfree = {\
+		{.offset = 4,\
+		 .length = 12 } } \
+}
+#endif
+
+/* Small Page x16 NAND device Layout */
+#ifdef GPMC_NAND_ECC_SP_x16_LAYOUT
+#define GPMC_NAND_HW_ECC_LAYOUT {\
+	.eccbytes = 3,\
+	.eccpos = {2, 3, 4},\
+	.oobfree = {\
+		{.offset = 5,\
+		 .length = 11 } } \
+}
+#endif
+
+#define GPMC_NAND_HW_BCH4_ECC_LAYOUT {\
+	.eccbytes = 32,\
+	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
+				16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
+				28, 29, 30, 31, 32, 33},\
+	.oobfree = {\
+		{.offset = 34,\
+		 .length = 30 } } \
+}
+
+#define GPMC_NAND_HW_BCH8_ECC_LAYOUT {\
+	.eccbytes = 56,\
+	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
+				16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
+				28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\
+				40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\
+				52, 53, 54, 55, 56, 57},\
+	.oobfree = {\
+		{.offset = 58,\
+		 .length = 6 } } \
+}
+
+#define GPMC_NAND_HW_BCH16_ECC_LAYOUT {\
+	.eccbytes = 104,\
+	.eccpos = {2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,\
+				16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,\
+				28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39,\
+				40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,\
+				52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,\
+				64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,\
+				76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87,\
+				88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,\
+				100, 101, 102, 103, 104, 105},\
+	.oobfree = {\
+		{.offset = 106,\
+		 .length = 8 } } \
+}
+#endif /* __ASM_ARCH_OMAP_GPMC_H */
diff --git a/arch/arm/include/asm/arch-am33xx/sys_proto.h b/arch/arm/include/asm/arch-am33xx/sys_proto.h
index 9cf35e02578..588d8de82fb 100644
--- a/arch/arm/include/asm/arch-am33xx/sys_proto.h
+++ b/arch/arm/include/asm/arch-am33xx/sys_proto.h
@@ -33,4 +33,7 @@ u32 get_device_type(void);
 void setup_clocks_for_console(void);
 void ddr_pll_config(unsigned int ddrpll_M);
 
+void sdelay(unsigned long);
+void gpmc_init(void);
+void omap_nand_switch_ecc(int);
 #endif
diff --git a/arch/arm/include/asm/arch-omap3/sys_proto.h b/arch/arm/include/asm/arch-omap3/sys_proto.h
index 9e52b12aa29..d60f2addb2a 100644
--- a/arch/arm/include/asm/arch-omap3/sys_proto.h
+++ b/arch/arm/include/asm/arch-omap3/sys_proto.h
@@ -32,6 +32,15 @@ struct emu_hal_params {
 	u32 param1;
 };
 
+/* Board SDRC timing values */
+struct board_sdrc_timings {
+	u32 mcfg;
+	u32 ctrla;
+	u32 ctrlb;
+	u32 rfr_ctrl;
+	u32 mr;
+};
+
 void prcm_init(void);
 void per_clocks_enable(void);
 void ehci_clocks_enable(void);
@@ -39,8 +48,8 @@ void ehci_clocks_enable(void);
 void memif_init(void);
 void sdrc_init(void);
 void do_sdrc_init(u32, u32);
-void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
-		u32 *mr);
+
+void get_board_mem_timings(struct board_sdrc_timings *timings);
 void identify_nand_chip(int *mfr, int *id);
 void emif4_init(void);
 void gpmc_init(void);
diff --git a/arch/arm/include/asm/omap_gpio.h b/arch/arm/include/asm/omap_gpio.h
index 516cc4260c1..1ebfa8694f6 100644
--- a/arch/arm/include/asm/omap_gpio.h
+++ b/arch/arm/include/asm/omap_gpio.h
@@ -49,4 +49,11 @@ extern const struct gpio_bank *const omap_gpio_bank;
 
 #define METHOD_GPIO_24XX	4
 
+/**
+ * Check if gpio is valid.
+ *
+ * @param gpio	GPIO number
+ * @return 1 if ok, 0 on error
+ */
+int gpio_is_valid(int gpio);
 #endif /* _GPIO_H_ */
diff --git a/board/corscience/tricorder/tricorder.c b/board/corscience/tricorder/tricorder.c
index aaff2e868ba..56fe495277e 100644
--- a/board/corscience/tricorder/tricorder.c
+++ b/board/corscience/tricorder/tricorder.c
@@ -91,15 +91,14 @@ int board_mmc_init(bd_t *bis)
  * provides the timing values back to the function that configures
  * the memory.  We have either one or two banks of 128MB DDR.
  */
-void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
-				u32 *mr)
+void get_board_mem_timings(struct board_sdrc_timings *timings)
 {
 	/* General SDRC config */
-	*mcfg = MICRON_V_MCFG_165(128 << 20);
-	*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+	timings->mcfg = MICRON_V_MCFG_165(128 << 20);
+	timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
 
 	/* AC timings */
-	*ctrla = MICRON_V_ACTIMA_165;
-	*ctrlb = MICRON_V_ACTIMB_165;
-	*mr = MICRON_V_MR_165;
+	timings->ctrla = MICRON_V_ACTIMA_165;
+	timings->ctrlb = MICRON_V_ACTIMB_165;
+	timings->mr = MICRON_V_MR_165;
 }
diff --git a/board/isee/igep0020/igep0020.c b/board/isee/igep0020/igep0020.c
index a8257a3005f..a0f2aa3e4e2 100644
--- a/board/isee/igep0020/igep0020.c
+++ b/board/isee/igep0020/igep0020.c
@@ -72,27 +72,26 @@ void omap_rev_string(void)
  * Description: If we use SPL then there is no x-loader nor config header
  * so we have to setup the DDR timings ourself on both banks.
  */
-void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
-		u32 *mr)
+void get_board_mem_timings(struct board_sdrc_timings *timings)
 {
-	*mr = MICRON_V_MR_165;
+	timings->mr = MICRON_V_MR_165;
 #ifdef CONFIG_BOOT_NAND
-	*mcfg = MICRON_V_MCFG_200(256 << 20);
-	*ctrla = MICRON_V_ACTIMA_200;
-	*ctrlb = MICRON_V_ACTIMB_200;
-	*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
+	timings->mcfg = MICRON_V_MCFG_200(256 << 20);
+	timings->ctrla = MICRON_V_ACTIMA_200;
+	timings->ctrlb = MICRON_V_ACTIMB_200;
+	timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
 #else
 	if (get_cpu_family() == CPU_OMAP34XX) {
-		*mcfg = NUMONYX_V_MCFG_165(256 << 20);
-		*ctrla = NUMONYX_V_ACTIMA_165;
-		*ctrlb = NUMONYX_V_ACTIMB_165;
-		*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+		timings->mcfg = NUMONYX_V_MCFG_165(256 << 20);
+		timings->ctrla = NUMONYX_V_ACTIMA_165;
+		timings->ctrlb = NUMONYX_V_ACTIMB_165;
+		timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
 
 	} else {
-		*mcfg = NUMONYX_V_MCFG_200(256 << 20);
-		*ctrla = NUMONYX_V_ACTIMA_200;
-		*ctrlb = NUMONYX_V_ACTIMB_200;
-		*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
+		timings->mcfg = NUMONYX_V_MCFG_200(256 << 20);
+		timings->ctrla = NUMONYX_V_ACTIMA_200;
+		timings->ctrlb = NUMONYX_V_ACTIMB_200;
+		timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
 	}
 #endif
 }
diff --git a/board/isee/igep0030/igep0030.c b/board/isee/igep0030/igep0030.c
index 107cb7f8e05..a41e752b820 100644
--- a/board/isee/igep0030/igep0030.c
+++ b/board/isee/igep0030/igep0030.c
@@ -59,27 +59,26 @@ void omap_rev_string(void)
  * Description: If we use SPL then there is no x-loader nor config header
  * so we have to setup the DDR timings ourself on both banks.
  */
-void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
-			   u32 *mr)
+void get_board_mem_timings(struct board_sdrc_timings *timings)
 {
-	*mr = MICRON_V_MR_165;
+	timings->mr = MICRON_V_MR_165;
 #ifdef CONFIG_BOOT_NAND
-	*mcfg = MICRON_V_MCFG_200(256 << 20);
-	*ctrla = MICRON_V_ACTIMA_200;
-	*ctrlb = MICRON_V_ACTIMB_200;
-	*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
+	timings->mcfg = MICRON_V_MCFG_200(256 << 20);
+	timings->ctrla = MICRON_V_ACTIMA_200;
+	timings->ctrlb = MICRON_V_ACTIMB_200;
+	timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
 #else
 	if (get_cpu_family() == CPU_OMAP34XX) {
-		*mcfg = NUMONYX_V_MCFG_165(256 << 20);
-		*ctrla = NUMONYX_V_ACTIMA_165;
-		*ctrlb = NUMONYX_V_ACTIMB_165;
-		*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+		timings->mcfg = NUMONYX_V_MCFG_165(256 << 20);
+		timings->ctrla = NUMONYX_V_ACTIMA_165;
+		timings->ctrlb = NUMONYX_V_ACTIMB_165;
+		timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
 
 	} else {
-		*mcfg = NUMONYX_V_MCFG_200(256 << 20);
-		*ctrla = NUMONYX_V_ACTIMA_200;
-		*ctrlb = NUMONYX_V_ACTIMB_200;
-		*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
+		timings->mcfg = NUMONYX_V_MCFG_200(256 << 20);
+		timings->ctrla = NUMONYX_V_ACTIMA_200;
+		timings->ctrlb = NUMONYX_V_ACTIMB_200;
+		timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
 	}
 #endif
 }
diff --git a/board/overo/overo.c b/board/overo/overo.c
index c6d50a07aca..fdf46a2aae9 100644
--- a/board/overo/overo.c
+++ b/board/overo/overo.c
@@ -147,34 +147,33 @@ int get_board_revision(void)
  * Description: If we use SPL then there is no x-loader nor config header
  * so we have to setup the DDR timings ourself on both banks.
  */
-void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
-		u32 *mr)
+void get_board_mem_timings(struct board_sdrc_timings *timings)
 {
-	*mr = MICRON_V_MR_165;
+	timings->mr = MICRON_V_MR_165;
 	switch (get_board_revision()) {
 	case REVISION_0: /* Micron 1286MB/256MB, 1/2 banks of 128MB */
-		*mcfg = MICRON_V_MCFG_165(128 << 20);
-		*ctrla = MICRON_V_ACTIMA_165;
-		*ctrlb = MICRON_V_ACTIMB_165;
-		*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+		timings->mcfg = MICRON_V_MCFG_165(128 << 20);
+		timings->ctrla = MICRON_V_ACTIMA_165;
+		timings->ctrlb = MICRON_V_ACTIMB_165;
+		timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
 		break;
 	case REVISION_1: /* Micron 256MB/512MB, 1/2 banks of 256MB */
-		*mcfg = MICRON_V_MCFG_165(256 << 20);
-		*ctrla = MICRON_V_ACTIMA_165;
-		*ctrlb = MICRON_V_ACTIMB_165;
-		*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+		timings->mcfg = MICRON_V_MCFG_165(256 << 20);
+		timings->ctrla = MICRON_V_ACTIMA_165;
+		timings->ctrlb = MICRON_V_ACTIMB_165;
+		timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
 		break;
 	case REVISION_2: /* Hynix 256MB/512MB, 1/2 banks of 256MB */
-		*mcfg = HYNIX_V_MCFG_165(256 << 20);
-		*ctrla = HYNIX_V_ACTIMA_165;
-		*ctrlb = HYNIX_V_ACTIMB_165;
-		*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+		timings->mcfg = HYNIX_V_MCFG_165(256 << 20);
+		timings->ctrla = HYNIX_V_ACTIMA_165;
+		timings->ctrlb = HYNIX_V_ACTIMB_165;
+		timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
 		break;
 	default:
-		*mcfg = MICRON_V_MCFG_165(128 << 20);
-		*ctrla = MICRON_V_ACTIMA_165;
-		*ctrlb = MICRON_V_ACTIMB_165;
-		*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+		timings->mcfg = MICRON_V_MCFG_165(128 << 20);
+		timings->ctrla = MICRON_V_ACTIMA_165;
+		timings->ctrlb = MICRON_V_ACTIMB_165;
+		timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
 	}
 }
 #endif
diff --git a/board/technexion/twister/twister.c b/board/technexion/twister/twister.c
index 1471559909d..c9eea9b3045 100644
--- a/board/technexion/twister/twister.c
+++ b/board/technexion/twister/twister.c
@@ -98,9 +98,12 @@ int board_init(void)
 	return 0;
 }
 
+#ifndef CONFIG_SPL_BUILD
 int misc_init_r(void)
 {
 	char *eth_addr;
+	struct tam3517_module_info info;
+	int ret;
 
 	dieid_num_r();
 
@@ -108,12 +111,13 @@ int misc_init_r(void)
 	if (eth_addr)
 		return 0;
 
-#ifndef CONFIG_SPL_BUILD
-	TAM3517_READ_MAC_FROM_EEPROM;
-#endif
+	TAM3517_READ_EEPROM(&info, ret);
+	if (!ret)
+		TAM3517_READ_MAC_FROM_EEPROM(&info);
 
 	return 0;
 }
+#endif
 
 /*
  * Routine: set_muxconf_regs
diff --git a/board/teejet/mt_ventoux/mt_ventoux.c b/board/teejet/mt_ventoux/mt_ventoux.c
index 9622a81280c..c516c75a006 100644
--- a/board/teejet/mt_ventoux/mt_ventoux.c
+++ b/board/teejet/mt_ventoux/mt_ventoux.c
@@ -73,10 +73,10 @@ static struct {
 
 static struct panel_config lcd_cfg[] = {
 	{
-	.timing_h       = PANEL_TIMING_H(4, 8, 41),
-	.timing_v       = PANEL_TIMING_V(2, 4, 10),
-	.pol_freq       = 0x00000000, /* Pol Freq */
-	.divisor        = 0x0001000d, /* 33Mhz Pixel Clock */
+	.timing_h       = PANEL_TIMING_H(40, 5, 2),
+	.timing_v       = PANEL_TIMING_V(8, 8, 2),
+	.pol_freq       = 0x00003000, /* Pol Freq */
+	.divisor        = 0x00010033, /* 9 Mhz Pixel Clock */
 	.panel_type     = 0x01, /* TFT */
 	.data_lines     = 0x03, /* 24 Bit RGB */
 	.load_mode      = 0x02, /* Frame Mode */
@@ -258,21 +258,26 @@ int board_init(void)
 	return 0;
 }
 
+#ifndef CONFIG_SPL_BUILD
 int misc_init_r(void)
 {
 	char *eth_addr;
+	struct tam3517_module_info info;
+	int ret;
 
+	TAM3517_READ_EEPROM(&info, ret);
 	dieid_num_r();
 
-	eth_addr = getenv("ethaddr");
-	if (eth_addr)
+	if (ret)
 		return 0;
+	eth_addr = getenv("ethaddr");
+	if (!eth_addr)
+		TAM3517_READ_MAC_FROM_EEPROM(&info);
 
-#ifndef CONFIG_SPL_BUILD
-	TAM3517_READ_MAC_FROM_EEPROM;
-#endif
+	TAM3517_PRINT_SOM_INFO(&info);
 	return 0;
 }
+#endif
 
 /*
  * Routine: set_muxconf_regs
diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c
index f0eca54c9e9..ed4229e258d 100644
--- a/board/ti/am335x/board.c
+++ b/board/ti/am335x/board.c
@@ -44,7 +44,7 @@ static struct uart_sys *uart_base = (struct uart_sys *)DEFAULT_UART_BASE;
 
 /* MII mode defines */
 #define MII_MODE_ENABLE		0x0
-#define RGMII_MODE_ENABLE	0xA
+#define RGMII_MODE_ENABLE	0x3A
 
 /* GPIO that controls power to DDR on EVM-SK */
 #define GPIO_DDR_VTT_EN		7
@@ -318,6 +318,8 @@ int board_init(void)
 
 	gd->bd->bi_boot_params = PHYS_DRAM_1 + 0x100;
 
+	gpmc_init();
+
 	return 0;
 }
 
diff --git a/board/ti/am335x/mux.c b/board/ti/am335x/mux.c
index 8437ef515af..02837082cb8 100644
--- a/board/ti/am335x/mux.c
+++ b/board/ti/am335x/mux.c
@@ -171,6 +171,25 @@ static struct module_pin_mux mii1_pin_mux[] = {
 	{-1},
 };
 
+static struct module_pin_mux nand_pin_mux[] = {
+	{OFFSET(gpmc_ad0), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD0 */
+	{OFFSET(gpmc_ad1), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD1 */
+	{OFFSET(gpmc_ad2), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD2 */
+	{OFFSET(gpmc_ad3), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD3 */
+	{OFFSET(gpmc_ad4), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD4 */
+	{OFFSET(gpmc_ad5), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD5 */
+	{OFFSET(gpmc_ad6), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD6 */
+	{OFFSET(gpmc_ad7), (MODE(0) | PULLUP_EN | RXACTIVE)},	/* NAND AD7 */
+	{OFFSET(gpmc_wait0), (MODE(0) | RXACTIVE | PULLUP_EN)}, /* NAND WAIT */
+	{OFFSET(gpmc_wpn), (MODE(7) | PULLUP_EN | RXACTIVE)},	/* NAND_WPN */
+	{OFFSET(gpmc_csn0), (MODE(0) | PULLUDEN)},	/* NAND_CS0 */
+	{OFFSET(gpmc_advn_ale), (MODE(0) | PULLUDEN)}, /* NAND_ADV_ALE */
+	{OFFSET(gpmc_oen_ren), (MODE(0) | PULLUDEN)},	/* NAND_OE */
+	{OFFSET(gpmc_wen), (MODE(0) | PULLUDEN)},	/* NAND_WEN */
+	{OFFSET(gpmc_be0n_cle), (MODE(0) | PULLUDEN)},	/* NAND_BE_CLE */
+	{-1},
+};
+
 void enable_uart0_pin_mux(void)
 {
 	configure_module_pin_mux(uart0_pin_mux);
@@ -257,6 +276,9 @@ void enable_board_pin_mux(struct am335x_baseboard_id *header)
 		/* In profile #2 i2c1 and spi0 conflict. */
 		if (profile & ~PROFILE_2)
 			configure_module_pin_mux(i2c1_pin_mux);
+		/* Profiles 2 & 3 don't have NAND */
+		if (profile & ~(PROFILE_2 | PROFILE_3))
+			configure_module_pin_mux(nand_pin_mux);
 		else if (profile == PROFILE_2) {
 			configure_module_pin_mux(mmc1_pin_mux);
 			configure_module_pin_mux(spi0_pin_mux);
diff --git a/board/ti/beagle/beagle.c b/board/ti/beagle/beagle.c
index f20ebed4524..b829a792b2c 100644
--- a/board/ti/beagle/beagle.c
+++ b/board/ti/beagle/beagle.c
@@ -144,8 +144,7 @@ static int get_board_revision(void)
  * Description: If we use SPL then there is no x-loader nor config header
  * so we have to setup the DDR timings ourself on both banks.
  */
-void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
-		u32 *mr)
+void get_board_mem_timings(struct board_sdrc_timings *timings)
 {
 	int pop_mfr, pop_id;
 
@@ -156,29 +155,29 @@ void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
 	 */
 	identify_nand_chip(&pop_mfr, &pop_id);
 
-	*mr = MICRON_V_MR_165;
+	timings->mr = MICRON_V_MR_165;
 	switch (get_board_revision()) {
 	case REVISION_C4:
 		if (pop_mfr == NAND_MFR_STMICRO && pop_id == 0xba) {
 			/* 512MB DDR */
-			*mcfg = NUMONYX_V_MCFG_165(512 << 20);
-			*ctrla = NUMONYX_V_ACTIMA_165;
-			*ctrlb = NUMONYX_V_ACTIMB_165;
-			*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+			timings->mcfg = NUMONYX_V_MCFG_165(512 << 20);
+			timings->ctrla = NUMONYX_V_ACTIMA_165;
+			timings->ctrlb = NUMONYX_V_ACTIMB_165;
+			timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
 			break;
 		} else if (pop_mfr == NAND_MFR_MICRON && pop_id == 0xba) {
 			/* Beagleboard Rev C4, 512MB Nand/256MB DDR*/
-			*mcfg = MICRON_V_MCFG_165(128 << 20);
-			*ctrla = MICRON_V_ACTIMA_165;
-			*ctrlb = MICRON_V_ACTIMB_165;
-			*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+			timings->mcfg = MICRON_V_MCFG_165(128 << 20);
+			timings->ctrla = MICRON_V_ACTIMA_165;
+			timings->ctrlb = MICRON_V_ACTIMB_165;
+			timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
 			break;
 		} else if (pop_mfr == NAND_MFR_MICRON && pop_id == 0xbc) {
 			/* Beagleboard Rev C5, 256MB DDR */
-			*mcfg = MICRON_V_MCFG_200(256 << 20);
-			*ctrla = MICRON_V_ACTIMA_200;
-			*ctrlb = MICRON_V_ACTIMB_200;
-			*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
+			timings->mcfg = MICRON_V_MCFG_200(256 << 20);
+			timings->ctrla = MICRON_V_ACTIMA_200;
+			timings->ctrlb = MICRON_V_ACTIMB_200;
+			timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
 			break;
 		}
 	case REVISION_XM_A:
@@ -186,24 +185,24 @@ void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
 	case REVISION_XM_C:
 		if (pop_mfr == 0) {
 			/* 256MB DDR */
-			*mcfg = MICRON_V_MCFG_200(256 << 20);
-			*ctrla = MICRON_V_ACTIMA_200;
-			*ctrlb = MICRON_V_ACTIMB_200;
-			*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
+			timings->mcfg = MICRON_V_MCFG_200(256 << 20);
+			timings->ctrla = MICRON_V_ACTIMA_200;
+			timings->ctrlb = MICRON_V_ACTIMB_200;
+			timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_200MHz;
 		} else {
 			/* 512MB DDR */
-			*mcfg = NUMONYX_V_MCFG_165(512 << 20);
-			*ctrla = NUMONYX_V_ACTIMA_165;
-			*ctrlb = NUMONYX_V_ACTIMB_165;
-			*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+			timings->mcfg = NUMONYX_V_MCFG_165(512 << 20);
+			timings->ctrla = NUMONYX_V_ACTIMA_165;
+			timings->ctrlb = NUMONYX_V_ACTIMB_165;
+			timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
 		}
 		break;
 	default:
 		/* Assume 128MB and Micron/165MHz timings to be safe */
-		*mcfg = MICRON_V_MCFG_165(128 << 20);
-		*ctrla = MICRON_V_ACTIMA_165;
-		*ctrlb = MICRON_V_ACTIMB_165;
-		*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+		timings->mcfg = MICRON_V_MCFG_165(128 << 20);
+		timings->ctrla = MICRON_V_ACTIMA_165;
+		timings->ctrlb = MICRON_V_ACTIMB_165;
+		timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
 	}
 }
 #endif
diff --git a/board/ti/evm/evm.c b/board/ti/evm/evm.c
index 61fc7b55310..8a3aa0c5bfd 100644
--- a/board/ti/evm/evm.c
+++ b/board/ti/evm/evm.c
@@ -128,8 +128,7 @@ int board_init(void)
  * provides the timing values back to the function that configures
  * the memory.
  */
-void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
-		u32 *mr)
+void get_board_mem_timings(struct board_sdrc_timings *timings)
 {
 	int pop_mfr, pop_id;
 
@@ -142,17 +141,17 @@ void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
 
 	if (pop_mfr == NAND_MFR_HYNIX && pop_id == 0xbc) {
 		/* 256MB DDR */
-		*mcfg = HYNIX_V_MCFG_200(256 << 20);
-		*ctrla = HYNIX_V_ACTIMA_200;
-		*ctrlb = HYNIX_V_ACTIMB_200;
+		timings->mcfg = HYNIX_V_MCFG_200(256 << 20);
+		timings->ctrla = HYNIX_V_ACTIMA_200;
+		timings->ctrlb = HYNIX_V_ACTIMB_200;
 	} else {
 		/* 128MB DDR */
-		*mcfg = MICRON_V_MCFG_165(128 << 20);
-		*ctrla = MICRON_V_ACTIMA_165;
-		*ctrlb = MICRON_V_ACTIMB_165;
+		timings->mcfg = MICRON_V_MCFG_165(128 << 20);
+		timings->ctrla = MICRON_V_ACTIMA_165;
+		timings->ctrlb = MICRON_V_ACTIMB_165;
 	}
-	*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
-	*mr = MICRON_V_MR_165;
+	timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+	timings->mr = MICRON_V_MR_165;
 }
 #endif
 
diff --git a/board/timll/devkit8000/devkit8000.c b/board/timll/devkit8000/devkit8000.c
index 35f5e15fc24..85685ee7c05 100644
--- a/board/timll/devkit8000/devkit8000.c
+++ b/board/timll/devkit8000/devkit8000.c
@@ -188,16 +188,15 @@ int spl_start_uboot(void)
  * provides the timing values back to the function that configures
  * the memory.  We have either one or two banks of 128MB DDR.
  */
-void get_board_mem_timings(u32 *mcfg, u32 *ctrla, u32 *ctrlb, u32 *rfr_ctrl,
-		u32 *mr)
+void get_board_mem_timings(struct board_sdrc_timings *timings)
 {
 	/* General SDRC config */
-	*mcfg = MICRON_V_MCFG_165(128 << 20);
-	*rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
+	timings->mcfg = MICRON_V_MCFG_165(128 << 20);
+	timings->rfr_ctrl = SDP_3430_SDRC_RFR_CTRL_165MHz;
 
 	/* AC timings */
-	*ctrla = MICRON_V_ACTIMA_165;
-	*ctrlb = MICRON_V_ACTIMB_165;
+	timings->ctrla = MICRON_V_ACTIMA_165;
+	timings->ctrlb = MICRON_V_ACTIMB_165;
 
-	*mr = MICRON_V_MR_165;
+	timings->mr = MICRON_V_MR_165;
 }
diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c
index fc89f2a42b1..a30d7f0603e 100644
--- a/drivers/gpio/omap_gpio.c
+++ b/drivers/gpio/omap_gpio.c
@@ -53,18 +53,14 @@ static inline int get_gpio_index(int gpio)
 	return gpio & 0x1f;
 }
 
-static inline int gpio_valid(int gpio)
+int gpio_is_valid(int gpio)
 {
-	if (gpio < 0)
-		return -1;
-	if (gpio < 192)
-		return 0;
-	return -1;
+	return (gpio >= 0) && (gpio < 192);
 }
 
 static int check_gpio(int gpio)
 {
-	if (gpio_valid(gpio) < 0) {
+	if (!gpio_is_valid(gpio)) {
 		printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
 		return -1;
 	}
diff --git a/drivers/i2c/omap24xx_i2c.c b/drivers/i2c/omap24xx_i2c.c
index af454f901c7..54e9b1586fb 100644
--- a/drivers/i2c/omap24xx_i2c.c
+++ b/drivers/i2c/omap24xx_i2c.c
@@ -31,7 +31,7 @@ DECLARE_GLOBAL_DATA_PTR;
 
 #define I2C_TIMEOUT	1000
 
-static void wait_for_bb(void);
+static int wait_for_bb(void);
 static u16 wait_for_pin(void);
 static void flush_fifo(void);
 
@@ -159,7 +159,8 @@ static int i2c_read_byte(u8 devaddr, u16 regoffset, u8 alen, u8 *value)
 	u16 w;
 
 	/* wait until bus not busy */
-	wait_for_bb();
+	if (wait_for_bb())
+		return 1;
 
 	/* one byte only */
 	writew(alen, &i2c_base->cnt);
@@ -263,7 +264,8 @@ int i2c_probe(uchar chip)
 		return res;
 
 	/* wait until bus not busy */
-	wait_for_bb();
+	if (wait_for_bb())
+		return res;
 
 	/* try to read one byte */
 	writew(1, &i2c_base->cnt);
@@ -282,7 +284,10 @@ int i2c_probe(uchar chip)
 			res = 1;
 			writew(0xff, &i2c_base->stat);
 			writew (readw (&i2c_base->con) | I2C_CON_STP, &i2c_base->con);
-			wait_for_bb ();
+
+			if (wait_for_bb())
+				res = 1;
+
 			break;
 		}
 		if (status & I2C_STAT_ARDY) {
@@ -355,7 +360,8 @@ int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
 	}
 
 	/* wait until bus not busy */
-	wait_for_bb();
+	if (wait_for_bb())
+		return 1;
 
 	/* start address phase - will write regoffset + len bytes data */
 	/* TODO consider case when !CONFIG_OMAP243X/34XX/44XX */
@@ -399,7 +405,7 @@ write_exit:
 	return i2c_error;
 }
 
-static void wait_for_bb(void)
+static int wait_for_bb(void)
 {
 	int timeout = I2C_TIMEOUT;
 	u16 stat;
@@ -413,8 +419,10 @@ static void wait_for_bb(void)
 	if (timeout <= 0) {
 		printf("timed out in wait_for_bb: I2C_STAT=%x\n",
 			readw(&i2c_base->stat));
+		return 1;
 	}
 	writew(0xFFFF, &i2c_base->stat);	 /* clear delayed stuff*/
+	return 0;
 }
 
 static u16 wait_for_pin(void)
diff --git a/drivers/mtd/nand/Makefile b/drivers/mtd/nand/Makefile
index 28e52bd08ea..2c3812c3bab 100644
--- a/drivers/mtd/nand/Makefile
+++ b/drivers/mtd/nand/Makefile
@@ -33,6 +33,7 @@ ifdef CONFIG_SPL_NAND_DRIVERS
 NORMAL_DRIVERS=y
 endif
 
+COBJS-$(CONFIG_SPL_NAND_AM33XX_BCH) += am335x_spl_bch.o
 COBJS-$(CONFIG_SPL_NAND_SIMPLE) += nand_spl_simple.o
 COBJS-$(CONFIG_SPL_NAND_LOAD) += nand_spl_load.o
 COBJS-$(CONFIG_SPL_NAND_ECC) += nand_ecc.o
@@ -78,10 +79,6 @@ COBJS-$(CONFIG_TEGRA_NAND) += tegra_nand.o
 COBJS-$(CONFIG_NAND_OMAP_GPMC) += omap_gpmc.o
 COBJS-$(CONFIG_NAND_PLAT) += nand_plat.o
 
-else  # minimal SPL drivers
-
-COBJS-$(CONFIG_NAND_FSL_ELBC) += fsl_elbc_spl.o
-
 endif # drivers
 endif # nand
 
diff --git a/drivers/mtd/nand/am335x_spl_bch.c b/drivers/mtd/nand/am335x_spl_bch.c
new file mode 100644
index 00000000000..b84528ba3b5
--- /dev/null
+++ b/drivers/mtd/nand/am335x_spl_bch.c
@@ -0,0 +1,238 @@
+/*
+ * (C) Copyright 2012
+ * Konstantin Kozhevnikov, Cogent Embedded
+ *
+ * based on nand_spl_simple code
+ *
+ * (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.
+ */
+
+#include <common.h>
+#include <nand.h>
+#include <asm/io.h>
+#include <linux/mtd/nand_ecc.h>
+
+static int nand_ecc_pos[] = CONFIG_SYS_NAND_ECCPOS;
+static nand_info_t mtd;
+static struct nand_chip nand_chip;
+
+#define ECCSTEPS	(CONFIG_SYS_NAND_PAGE_SIZE / \
+					CONFIG_SYS_NAND_ECCSIZE)
+#define ECCTOTAL	(ECCSTEPS * CONFIG_SYS_NAND_ECCBYTES)
+
+
+/*
+ * 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;
+	}
+
+	/* Begin command latch cycle */
+	hwctrl(&mtd, cmd, NAND_CTRL_CLE | NAND_CTRL_CHANGE);
+
+	if (cmd == NAND_CMD_RESET) {
+		hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+		while (!this->dev_ready(&mtd))
+			;
+		return 0;
+	}
+
+	/* Shift the offset from byte addressing to word addressing. */
+	if (this->options & NAND_BUSWIDTH_16)
+		offs >>= 1;
+
+	/* 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
+	hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+
+	if (cmd == NAND_CMD_READ0) {
+		/* 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))
+			;
+	} else if (cmd == NAND_CMD_RNDOUT) {
+		hwctrl(&mtd, NAND_CMD_RNDOUTSTART, NAND_CTRL_CLE |
+					NAND_CTRL_CHANGE);
+		hwctrl(&mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE);
+	}
+
+	return 0;
+}
+
+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[ECCTOTAL];
+	u_char ecc_code[ECCTOTAL];
+	u_char oob_data[CONFIG_SYS_NAND_OOBSIZE];
+	int i;
+	int eccsize = CONFIG_SYS_NAND_ECCSIZE;
+	int eccbytes = CONFIG_SYS_NAND_ECCBYTES;
+	int eccsteps = ECCSTEPS;
+	uint8_t *p = dst;
+	uint32_t data_pos = 0;
+	uint8_t *oob = &oob_data[0] + nand_ecc_pos[0];
+	uint32_t oob_pos = eccsize * eccsteps + nand_ecc_pos[0];
+
+	nand_command(block, page, 0, NAND_CMD_READ0);
+
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		this->ecc.hwctl(&mtd, NAND_ECC_READ);
+		nand_command(block, page, data_pos, NAND_CMD_RNDOUT);
+
+		this->read_buf(&mtd, p, eccsize);
+
+		nand_command(block, page, oob_pos, NAND_CMD_RNDOUT);
+
+		this->read_buf(&mtd, oob, eccbytes);
+		this->ecc.calculate(&mtd, p, &ecc_calc[i]);
+
+		data_pos += eccsize;
+		oob_pos += eccbytes;
+		oob += eccbytes;
+	}
+
+	/* Pick the ECC bytes out of the oob data */
+	for (i = 0; i < ECCTOTAL; i++)
+		ecc_code[i] = oob_data[nand_ecc_pos[i]];
+
+	eccsteps = 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.
+		 */
+		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;
+	board_nand_init(&nand_chip);
+
+	if (nand_chip.select_chip)
+		nand_chip.select_chip(&mtd, 0);
+
+	/* NAND chip may require reset after power-on */
+	nand_command(0, 0, 0, NAND_CMD_RESET);
+}
+
+/* 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 f1469d11050..cee394ece4b 100644
--- a/drivers/mtd/nand/omap_gpmc.c
+++ b/drivers/mtd/nand/omap_gpmc.c
@@ -29,6 +29,9 @@
 #include <linux/mtd/nand_ecc.h>
 #include <linux/compiler.h>
 #include <nand.h>
+#ifdef CONFIG_AM33XX
+#include <asm/arch/elm.h>
+#endif
 
 static uint8_t cs;
 static __maybe_unused struct nand_ecclayout hw_nand_oob =
@@ -234,6 +237,370 @@ static void __maybe_unused omap_enable_hwecc(struct mtd_info *mtd, int32_t mode)
 	}
 }
 
+/*
+ * BCH8 support (needs ELM and thus AM33xx-only)
+ */
+#ifdef CONFIG_AM33XX
+struct nand_bch_priv {
+	uint8_t mode;
+	uint8_t type;
+	uint8_t nibbles;
+};
+
+/* bch types */
+#define ECC_BCH4	0
+#define ECC_BCH8	1
+#define ECC_BCH16	2
+
+/* BCH nibbles for diff bch levels */
+#define NAND_ECC_HW_BCH ((uint8_t)(NAND_ECC_HW_OOB_FIRST) + 1)
+#define ECC_BCH4_NIBBLES	13
+#define ECC_BCH8_NIBBLES	26
+#define ECC_BCH16_NIBBLES	52
+
+static struct nand_ecclayout hw_bch8_nand_oob = GPMC_NAND_HW_BCH8_ECC_LAYOUT;
+
+static struct nand_bch_priv bch_priv = {
+	.mode = NAND_ECC_HW_BCH,
+	.type = ECC_BCH8,
+	.nibbles = ECC_BCH8_NIBBLES
+};
+
+/*
+ * omap_read_bch8_result - Read BCH result for BCH8 level
+ *
+ * @mtd:	MTD device structure
+ * @big_endian:	When set read register 3 first
+ * @ecc_code:	Read syndrome from BCH result registers
+ */
+static void omap_read_bch8_result(struct mtd_info *mtd, uint8_t big_endian,
+				uint8_t *ecc_code)
+{
+	uint32_t *ptr;
+	int8_t i = 0, j;
+
+	if (big_endian) {
+		ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[3];
+		ecc_code[i++] = readl(ptr) & 0xFF;
+		ptr--;
+		for (j = 0; j < 3; j++) {
+			ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
+			ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
+			ecc_code[i++] = (readl(ptr) >>  8) & 0xFF;
+			ecc_code[i++] = readl(ptr) & 0xFF;
+			ptr--;
+		}
+	} else {
+		ptr = &gpmc_cfg->bch_result_0_3[0].bch_result_x[0];
+		for (j = 0; j < 3; j++) {
+			ecc_code[i++] = readl(ptr) & 0xFF;
+			ecc_code[i++] = (readl(ptr) >>  8) & 0xFF;
+			ecc_code[i++] = (readl(ptr) >> 16) & 0xFF;
+			ecc_code[i++] = (readl(ptr) >> 24) & 0xFF;
+			ptr++;
+		}
+		ecc_code[i++] = readl(ptr) & 0xFF;
+		ecc_code[i++] = 0;	/* 14th byte is always zero */
+	}
+}
+
+/*
+ * omap_ecc_disable - Disable H/W ECC calculation
+ *
+ * @mtd:	MTD device structure
+ *
+ */
+static void omap_ecc_disable(struct mtd_info *mtd)
+{
+	writel((readl(&gpmc_cfg->ecc_config) & ~0x1),
+		&gpmc_cfg->ecc_config);
+}
+
+/*
+ * omap_rotate_ecc_bch - Rotate the syndrome bytes
+ *
+ * @mtd:	MTD device structure
+ * @calc_ecc:	ECC read from ECC registers
+ * @syndrome:	Rotated syndrome will be retuned in this array
+ *
+ */
+static void omap_rotate_ecc_bch(struct mtd_info *mtd, uint8_t *calc_ecc,
+		uint8_t *syndrome)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct nand_bch_priv *bch = chip->priv;
+	uint8_t n_bytes = 0;
+	int8_t i, j;
+
+	switch (bch->type) {
+	case ECC_BCH4:
+		n_bytes = 8;
+		break;
+
+	case ECC_BCH16:
+		n_bytes = 28;
+		break;
+
+	case ECC_BCH8:
+	default:
+		n_bytes = 13;
+		break;
+	}
+
+	for (i = 0, j = (n_bytes-1); i < n_bytes; i++, j--)
+		syndrome[i] =  calc_ecc[j];
+}
+
+/*
+ *  omap_calculate_ecc_bch - Read BCH ECC result
+ *
+ *  @mtd:	MTD structure
+ *  @dat:	unused
+ *  @ecc_code:	ecc_code buffer
+ */
+static int omap_calculate_ecc_bch(struct mtd_info *mtd, const uint8_t *dat,
+				uint8_t *ecc_code)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct nand_bch_priv *bch = chip->priv;
+	uint8_t big_endian = 1;
+	int8_t ret = 0;
+
+	if (bch->type == ECC_BCH8)
+		omap_read_bch8_result(mtd, big_endian, ecc_code);
+	else /* BCH4 and BCH16 currently not supported */
+		ret = -1;
+
+	/*
+	 * Stop reading anymore ECC vals and clear old results
+	 * enable will be called if more reads are required
+	 */
+	omap_ecc_disable(mtd);
+
+	return ret;
+}
+
+/*
+ * omap_fix_errors_bch - Correct bch error in the data
+ *
+ * @mtd:	MTD device structure
+ * @data:	Data read from flash
+ * @error_count:Number of errors in data
+ * @error_loc:	Locations of errors in the data
+ *
+ */
+static void omap_fix_errors_bch(struct mtd_info *mtd, uint8_t *data,
+		uint32_t error_count, uint32_t *error_loc)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct nand_bch_priv *bch = chip->priv;
+	uint8_t count = 0;
+	uint32_t error_byte_pos;
+	uint32_t error_bit_mask;
+	uint32_t last_bit = (bch->nibbles * 4) - 1;
+
+	/* Flip all bits as specified by the error location array. */
+	/* FOR( each found error location flip the bit ) */
+	for (count = 0; count < error_count; count++) {
+		if (error_loc[count] > last_bit) {
+			/* Remove the ECC spare bits from correction. */
+			error_loc[count] -= (last_bit + 1);
+			/* Offset bit in data region */
+			error_byte_pos = ((512 * 8) -
+					(error_loc[count]) - 1) / 8;
+			/* Error Bit mask */
+			error_bit_mask = 0x1 << (error_loc[count] % 8);
+			/* Toggle the error bit to make the correction. */
+			data[error_byte_pos] ^= error_bit_mask;
+		}
+	}
+}
+
+/*
+ * omap_correct_data_bch - Compares the ecc read from nand spare area
+ * with ECC registers values and corrects one bit error if it has occured
+ *
+ * @mtd:	MTD device structure
+ * @dat:	page data
+ * @read_ecc:	ecc read from nand flash (ignored)
+ * @calc_ecc:	ecc read from ECC registers
+ *
+ * @return 0 if data is OK or corrected, else returns -1
+ */
+static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat,
+				uint8_t *read_ecc, uint8_t *calc_ecc)
+{
+	struct nand_chip *chip = mtd->priv;
+	struct nand_bch_priv *bch = chip->priv;
+	uint8_t syndrome[28];
+	uint32_t error_count = 0;
+	uint32_t error_loc[8];
+	uint32_t i, ecc_flag;
+
+	ecc_flag = 0;
+	for (i = 0; i < chip->ecc.bytes; i++)
+		if (read_ecc[i] != 0xff)
+			ecc_flag = 1;
+
+	if (!ecc_flag)
+		return 0;
+
+	elm_reset();
+	elm_config((enum bch_level)(bch->type));
+
+	/*
+	 * while reading ECC result we read it in big endian.
+	 * Hence while loading to ELM we have rotate to get the right endian.
+	 */
+	omap_rotate_ecc_bch(mtd, calc_ecc, syndrome);
+
+	/* use elm module to check for errors */
+	if (elm_check_error(syndrome, bch->nibbles, &error_count,
+				error_loc) != 0) {
+		printf("ECC: uncorrectable.\n");
+		return -1;
+	}
+
+	/* correct bch error */
+	if (error_count > 0)
+		omap_fix_errors_bch(mtd, dat, error_count, error_loc);
+
+	return 0;
+}
+/*
+ * omap_hwecc_init_bch - Initialize the BCH Hardware ECC for NAND flash in
+ *				GPMC controller
+ * @mtd:       MTD device structure
+ * @mode:	Read/Write mode
+ */
+static void omap_hwecc_init_bch(struct nand_chip *chip, int32_t mode)
+{
+	uint32_t val, dev_width = (chip->options & NAND_BUSWIDTH_16) >> 1;
+	uint32_t unused_length = 0;
+	struct nand_bch_priv *bch = chip->priv;
+
+	switch (bch->nibbles) {
+	case ECC_BCH4_NIBBLES:
+		unused_length = 3;
+		break;
+	case ECC_BCH8_NIBBLES:
+		unused_length = 2;
+		break;
+	case ECC_BCH16_NIBBLES:
+		unused_length = 0;
+		break;
+	}
+
+	/* Clear the ecc result registers, select ecc reg as 1 */
+	writel(ECCCLEAR | ECCRESULTREG1, &gpmc_cfg->ecc_control);
+
+	switch (mode) {
+	case NAND_ECC_WRITE:
+		/* eccsize1 config */
+		val = ((unused_length + bch->nibbles) << 22);
+		break;
+
+	case NAND_ECC_READ:
+	default:
+		/* by default eccsize0 selected for ecc1resultsize */
+		/* eccsize0 config */
+		val  = (bch->nibbles << 12);
+		/* eccsize1 config */
+		val |= (unused_length << 22);
+		break;
+	}
+	/* ecc size configuration */
+	writel(val, &gpmc_cfg->ecc_size_config);
+	/* by default 512bytes sector page is selected */
+	/* set bch mode */
+	val  = (1 << 16);
+	/* bch4 / bch8 / bch16 */
+	val |= (bch->type << 12);
+	/* set wrap mode to 1 */
+	val |= (1 << 8);
+	val |= (dev_width << 7);
+	val |= (cs << 1);
+	writel(val, &gpmc_cfg->ecc_config);
+}
+
+/*
+ * omap_enable_ecc_bch- This function enables the bch h/w ecc functionality
+ * @mtd:        MTD device structure
+ * @mode:       Read/Write mode
+ *
+ */
+static void omap_enable_ecc_bch(struct mtd_info *mtd, int32_t mode)
+{
+	struct nand_chip *chip = mtd->priv;
+
+	omap_hwecc_init_bch(chip, mode);
+	/* enable ecc */
+	writel((readl(&gpmc_cfg->ecc_config) | 0x1), &gpmc_cfg->ecc_config);
+}
+
+/**
+ * omap_read_page_bch - hardware ecc based page read function
+ * @mtd:	mtd info structure
+ * @chip:	nand chip info structure
+ * @buf:	buffer to store read data
+ * @page:	page number to read
+ *
+ */
+static int omap_read_page_bch(struct mtd_info *mtd, struct nand_chip *chip,
+				uint8_t *buf, int page)
+{
+	int i, eccsize = chip->ecc.size;
+	int eccbytes = chip->ecc.bytes;
+	int eccsteps = chip->ecc.steps;
+	uint8_t *p = buf;
+	uint8_t *ecc_calc = chip->buffers->ecccalc;
+	uint8_t *ecc_code = chip->buffers->ecccode;
+	uint32_t *eccpos = chip->ecc.layout->eccpos;
+	uint8_t *oob = chip->oob_poi;
+	uint32_t data_pos;
+	uint32_t oob_pos;
+
+	data_pos = 0;
+	/* oob area start */
+	oob_pos = (eccsize * eccsteps) + chip->ecc.layout->eccpos[0];
+	oob += chip->ecc.layout->eccpos[0];
+
+	for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize,
+				oob += eccbytes) {
+		chip->ecc.hwctl(mtd, NAND_ECC_READ);
+		/* read data */
+		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, data_pos, page);
+		chip->read_buf(mtd, p, eccsize);
+
+		/* read respective ecc from oob area */
+		chip->cmdfunc(mtd, NAND_CMD_RNDOUT, oob_pos, page);
+		chip->read_buf(mtd, oob, eccbytes);
+		/* read syndrome */
+		chip->ecc.calculate(mtd, p, &ecc_calc[i]);
+
+		data_pos += eccsize;
+		oob_pos += eccbytes;
+	}
+
+	for (i = 0; i < chip->ecc.total; i++)
+		ecc_code[i] = chip->oob_poi[eccpos[i]];
+
+	eccsteps = chip->ecc.steps;
+	p = buf;
+
+	for (i = 0 ; eccsteps; eccsteps--, i += eccbytes, p += eccsize) {
+		int stat;
+
+		stat = chip->ecc.correct(mtd, p, &ecc_code[i], &ecc_calc[i]);
+		if (stat < 0)
+			mtd->ecc_stats.failed++;
+		else
+			mtd->ecc_stats.corrected += stat;
+	}
+	return 0;
+}
+#endif /* CONFIG_AM33XX */
+
 #ifndef CONFIG_SPL_BUILD
 /*
  * omap_nand_switch_ecc - switch the ECC operation b/w h/w ecc and s/w ecc.
@@ -269,7 +636,7 @@ void omap_nand_switch_ecc(int32_t hardware)
 	nand->ecc.calculate = NULL;
 
 	/* Setup the ecc configurations again */
-	if (hardware) {
+	if (hardware == 1) {
 		nand->ecc.mode = NAND_ECC_HW;
 		nand->ecc.layout = &hw_nand_oob;
 		nand->ecc.size = 512;
@@ -279,6 +646,19 @@ void omap_nand_switch_ecc(int32_t hardware)
 		nand->ecc.calculate = omap_calculate_ecc;
 		omap_hwecc_init(nand);
 		printf("HW ECC selected\n");
+#ifdef CONFIG_AM33XX
+	} else if (hardware == 2) {
+		nand->ecc.mode = NAND_ECC_HW;
+		nand->ecc.layout = &hw_bch8_nand_oob;
+		nand->ecc.size = 512;
+		nand->ecc.bytes = 14;
+		nand->ecc.read_page = omap_read_page_bch;
+		nand->ecc.hwctl = omap_enable_ecc_bch;
+		nand->ecc.correct = omap_correct_data_bch;
+		nand->ecc.calculate = omap_calculate_ecc_bch;
+		omap_hwecc_init_bch(nand, NAND_ECC_READ);
+		printf("HW BCH8 selected\n");
+#endif
 	} else {
 		nand->ecc.mode = NAND_ECC_SOFT;
 		/* Use mtd default settings */
@@ -350,7 +730,27 @@ int board_nand_init(struct nand_chip *nand)
 		nand->options |= NAND_BUSWIDTH_16;
 
 	nand->chip_delay = 100;
+
+#ifdef CONFIG_AM33XX
+	/* required in case of BCH */
+	elm_init();
+
+	/* BCH info that will be correct for SPL or overridden otherwise. */
+	nand->priv = &bch_priv;
+#endif
+
 	/* Default ECC mode */
+#ifdef CONFIG_AM33XX
+	nand->ecc.mode = NAND_ECC_HW;
+	nand->ecc.layout = &hw_bch8_nand_oob;
+	nand->ecc.size = CONFIG_SYS_NAND_ECCSIZE;
+	nand->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
+	nand->ecc.hwctl = omap_enable_ecc_bch;
+	nand->ecc.correct = omap_correct_data_bch;
+	nand->ecc.calculate = omap_calculate_ecc_bch;
+	nand->ecc.read_page = omap_read_page_bch;
+	omap_hwecc_init_bch(nand, NAND_ECC_READ);
+#else
 #if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_NAND_SOFTECC)
 	nand->ecc.mode = NAND_ECC_SOFT;
 #else
@@ -363,6 +763,7 @@ int board_nand_init(struct nand_chip *nand)
 	nand->ecc.calculate = omap_calculate_ecc;
 	omap_hwecc_init(nand);
 #endif
+#endif
 
 #ifdef CONFIG_SPL_BUILD
 	if (nand->options & NAND_BUSWIDTH_16)
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index af3d8593eb6..db04795dfc9 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -920,7 +920,10 @@ static int cpsw_phy_init(struct eth_device *dev, struct cpsw_slave *slave)
 			SUPPORTED_100baseT_Full |
 			SUPPORTED_1000baseT_Full);
 
-	phydev = phy_connect(priv->bus, 0, dev, slave->data->phy_if);
+	phydev = phy_connect(priv->bus,
+			CONFIG_PHY_ADDR,
+			dev,
+			slave->data->phy_if);
 
 	phydev->supported &= supported;
 	phydev->advertising = phydev->supported;
diff --git a/drivers/power/twl6035.c b/drivers/power/twl6035.c
index 624c09e85dc..d3de698cde7 100644
--- a/drivers/power/twl6035.c
+++ b/drivers/power/twl6035.c
@@ -50,16 +50,25 @@ void twl6035_init_settings(void)
 	return;
 }
 
-void twl6035_mmc1_poweron_ldo(void)
+int twl6035_mmc1_poweron_ldo(void)
 {
 	u8 val = 0;
 
 	/* set LDO9 TWL6035 to 3V */
 	val = 0x2b; /* (3 -.9)*28 +1 */
-	palmas_write_u8(0x48, LDO9_VOLTAGE, val);
+
+	if (palmas_write_u8(0x48, LDO9_VOLTAGE, val)) {
+		printf("twl6035: could not set LDO9 voltage.\n");
+		return 1;
+	}
 
 	/* TURN ON LDO9 */
 	val = LDO_ON | LDO_MODE_SLEEP | LDO_MODE_ACTIVE;
-	palmas_write_u8(0x48, LDO9_CTRL, val);
-	return;
+
+	if (palmas_write_u8(0x48, LDO9_CTRL, val)) {
+		printf("twl6035: could not turn on LDO9.\n");
+		return 1;
+	}
+
+	return 0;
 }
diff --git a/drivers/spi/omap3_spi.c b/drivers/spi/omap3_spi.c
index 6791a7e0ec7..344d5b8a7e2 100644
--- a/drivers/spi/omap3_spi.c
+++ b/drivers/spi/omap3_spi.c
@@ -57,6 +57,20 @@ static void spi_reset(struct omap3_spi_slave *ds)
 	writel(OMAP3_MCSPI_WAKEUPENABLE_WKEN, &ds->regs->wakeupenable);
 }
 
+static void omap3_spi_write_chconf(struct omap3_spi_slave *ds, int val)
+{
+	writel(val, &ds->regs->channel[ds->slave.cs].chconf);
+	/* Flash post writes to make immediate effect */
+	readl(&ds->regs->channel[ds->slave.cs].chconf);
+}
+
+static void omap3_spi_set_enable(struct omap3_spi_slave *ds, int enable)
+{
+	writel(enable, &ds->regs->channel[ds->slave.cs].chctrl);
+        /* Flash post writes to make immediate effect */
+	readl(&ds->regs->channel[ds->slave.cs].chctrl);
+}
+
 void spi_init()
 {
 	/* do nothing */
@@ -212,7 +226,7 @@ int spi_claim_bus(struct spi_slave *slave)
 	/* Transmit & receive mode */
 	conf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
 
-	writel(conf, &ds->regs->channel[ds->slave.cs].chconf);
+	omap3_spi_write_chconf(ds,conf);
 
 	return 0;
 }
@@ -233,14 +247,13 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp,
 	int timeout = SPI_WAIT_TIMEOUT;
 	int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
 
-	if (flags & SPI_XFER_BEGIN)
-		writel(OMAP3_MCSPI_CHCTRL_EN,
-		       &ds->regs->channel[ds->slave.cs].chctrl);
+	/* Enable the channel */
+	omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
 
 	chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
 	chconf |= OMAP3_MCSPI_CHCONF_TRM_TX_ONLY;
 	chconf |= OMAP3_MCSPI_CHCONF_FORCE;
-	writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
+	omap3_spi_write_chconf(ds,chconf);
 
 	for (i = 0; i < len; i++) {
 		/* wait till TX register is empty (TXS == 1) */
@@ -256,15 +269,17 @@ int omap3_spi_write(struct spi_slave *slave, unsigned int len, const u8 *txp,
 		writel(txp[i], &ds->regs->channel[ds->slave.cs].tx);
 	}
 
+        /* wait to finish of transfer */
+        while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
+                         OMAP3_MCSPI_CHSTAT_EOT));
+
+	/* Disable the channel otherwise the next immediate RX will get affected */
+	omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
+
 	if (flags & SPI_XFER_END) {
-		/* wait to finish of transfer */
-		while (!(readl(&ds->regs->channel[ds->slave.cs].chstat) &
-			 OMAP3_MCSPI_CHSTAT_EOT));
 
 		chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
-		writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
-
-		writel(0, &ds->regs->channel[ds->slave.cs].chctrl);
+		omap3_spi_write_chconf(ds,chconf);
 	}
 	return 0;
 }
@@ -277,14 +292,13 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
 	int timeout = SPI_WAIT_TIMEOUT;
 	int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
 
-	if (flags & SPI_XFER_BEGIN)
-		writel(OMAP3_MCSPI_CHCTRL_EN,
-		       &ds->regs->channel[ds->slave.cs].chctrl);
+	/* Enable the channel */
+	omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
 
 	chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
 	chconf |= OMAP3_MCSPI_CHCONF_TRM_RX_ONLY;
 	chconf |= OMAP3_MCSPI_CHCONF_FORCE;
-	writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
+	omap3_spi_write_chconf(ds,chconf);
 
 	writel(0, &ds->regs->channel[ds->slave.cs].tx);
 
@@ -298,15 +312,18 @@ int omap3_spi_read(struct spi_slave *slave, unsigned int len, u8 *rxp,
 				return -1;
 			}
 		}
+
+		/* Disable the channel to prevent furher receiving */
+		if(i == (len - 1))
+			omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
+
 		/* Read the data */
 		rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx);
 	}
 
 	if (flags & SPI_XFER_END) {
 		chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
-		writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
-
-		writel(0, &ds->regs->channel[ds->slave.cs].chctrl);
+		omap3_spi_write_chconf(ds,chconf);
 	}
 
 	return 0;
@@ -323,14 +340,12 @@ int omap3_spi_txrx(struct spi_slave *slave,
 	int i=0;
 
 	/*Enable SPI channel*/
-	if (flags & SPI_XFER_BEGIN)
-		writel(OMAP3_MCSPI_CHCTRL_EN,
-		       &ds->regs->channel[ds->slave.cs].chctrl);
+	omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
 
 	/*set TRANSMIT-RECEIVE Mode*/
 	chconf &= ~OMAP3_MCSPI_CHCONF_TRM_MASK;
 	chconf |= OMAP3_MCSPI_CHCONF_FORCE;
-	writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
+	omap3_spi_write_chconf(ds,chconf);
 
 	/*Shift in and out 1 byte at time*/
 	for (i=0; i < len; i++){
@@ -359,13 +374,13 @@ int omap3_spi_txrx(struct spi_slave *slave,
 		/* Read the data */
 		rxp[i] = readl(&ds->regs->channel[ds->slave.cs].rx);
 	}
+	/* Disable the channel */
+        omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
 
 	/*if transfer must be terminated disable the channel*/
 	if (flags & SPI_XFER_END) {
 		chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
-		writel(chconf, &ds->regs->channel[ds->slave.cs].chconf);
-
-		writel(0, &ds->regs->channel[ds->slave.cs].chctrl);
+		omap3_spi_write_chconf(ds,chconf);
 	}
 
 	return 0;
@@ -389,17 +404,14 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
 		int chconf = readl(&ds->regs->channel[ds->slave.cs].chconf);
 
 		if (flags & SPI_XFER_BEGIN) {
-			writel(OMAP3_MCSPI_CHCTRL_EN,
-			       &ds->regs->channel[ds->slave.cs].chctrl);
+			omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_EN);
 			chconf |= OMAP3_MCSPI_CHCONF_FORCE;
-			writel(chconf,
-			       &ds->regs->channel[ds->slave.cs].chconf);
+			omap3_spi_write_chconf(ds,chconf);
 		}
 		if (flags & SPI_XFER_END) {
 			chconf &= ~OMAP3_MCSPI_CHCONF_FORCE;
-			writel(chconf,
-			       &ds->regs->channel[ds->slave.cs].chconf);
-			writel(0, &ds->regs->channel[ds->slave.cs].chctrl);
+			omap3_spi_write_chconf(ds,chconf);
+			omap3_spi_set_enable(ds,OMAP3_MCSPI_CHCTRL_DIS);
 		}
 		ret = 0;
 	} else {
diff --git a/drivers/spi/omap3_spi.h b/drivers/spi/omap3_spi.h
index bffa43cb6c7..5e00208c5dc 100644
--- a/drivers/spi/omap3_spi.h
+++ b/drivers/spi/omap3_spi.h
@@ -99,6 +99,7 @@ struct mcspi {
 #define OMAP3_MCSPI_CHSTAT_EOT		(1 << 2)
 
 #define OMAP3_MCSPI_CHCTRL_EN		(1 << 0)
+#define OMAP3_MCSPI_CHCTRL_DIS		(0 << 0)
 
 #define OMAP3_MCSPI_WAKEUPENABLE_WKEN	(1 << 0)
 
diff --git a/include/configs/am335x_evm.h b/include/configs/am335x_evm.h
index ab9549b93b8..72459d859d1 100644
--- a/include/configs/am335x_evm.h
+++ b/include/configs/am335x_evm.h
@@ -240,6 +240,38 @@
 #define CONFIG_SYS_SPI_U_BOOT_SIZE	0x40000
 #define CONFIG_SPL_LDSCRIPT		"$(CPUDIR)/omap-common/u-boot-spl.lds"
 
+#define CONFIG_SPL_BOARD_INIT
+#define CONFIG_SPL_NAND_AM33XX_BCH
+#define CONFIG_SPL_NAND_SUPPORT
+#define CONFIG_SPL_NAND_BASE
+#define CONFIG_SPL_NAND_DRIVERS
+#define CONFIG_SPL_NAND_ECC
+#define CONFIG_SYS_NAND_5_ADDR_CYCLE
+#define CONFIG_SYS_NAND_PAGE_COUNT	(CONFIG_SYS_NAND_BLOCK_SIZE / \
+					 CONFIG_SYS_NAND_PAGE_SIZE)
+#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	NAND_LARGE_BADBLOCK_POS
+#define CONFIG_SYS_NAND_ECCPOS		{ 2, 3, 4, 5, 6, 7, 8, 9, \
+					 10, 11, 12, 13, 14, 15, 16, 17, \
+					 18, 19, 20, 21, 22, 23, 24, 25, \
+					 26, 27, 28, 29, 30, 31, 32, 33, \
+					 34, 35, 36, 37, 38, 39, 40, 41, \
+					 42, 43, 44, 45, 46, 47, 48, 49, \
+					 50, 51, 52, 53, 54, 55, 56, 57, }
+
+#define CONFIG_SYS_NAND_ECCSIZE		512
+#define CONFIG_SYS_NAND_ECCBYTES	14
+
+#define CONFIG_SYS_NAND_ECCSTEPS	4
+#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
+
 /*
  * 1MB into the SDRAM to allow for SPL's bss at the beginning of SDRAM
  * 64 bytes before this address should be set aside for u-boot.img's
@@ -299,6 +331,24 @@
 #define CONFIG_NET_MULTI
 #define CONFIG_PHY_GIGE
 #define CONFIG_PHYLIB
+#define CONFIG_PHY_ADDR			0
 #define CONFIG_PHY_SMSC
 
+#define CONFIG_NAND
+/* NAND support */
+#ifdef CONFIG_NAND
+#define CONFIG_CMD_NAND
+#define CONFIG_NAND_OMAP_GPMC
+#define GPMC_NAND_ECC_LP_x16_LAYOUT	1
+#define CONFIG_SYS_NAND_BASE		(0x08000000)	/* physical address */
+							/* to access nand at */
+							/* CS0 */
+#define CONFIG_SYS_MAX_NAND_DEVICE	1		/* Max number of NAND
+							   devices */
+#undef CONFIG_ENV_IS_NOWHERE
+#define CONFIG_ENV_IS_IN_NAND
+#define CONFIG_ENV_OFFSET		0x260000 /* environment starts here */
+#define CONFIG_SYS_ENV_SECT_SIZE	(128 << 10)	/* 128 KiB */
+#endif
+
 #endif	/* ! __CONFIG_AM335X_EVM_H */
diff --git a/include/configs/cm_t35.h b/include/configs/cm_t35.h
index 568ae8e0972..433b447ff9b 100644
--- a/include/configs/cm_t35.h
+++ b/include/configs/cm_t35.h
@@ -188,6 +188,7 @@
 
 /* Environment information */
 #define CONFIG_BOOTDELAY		10
+#define CONFIG_ZERO_BOOTDELAY_CHECK
 
 #define CONFIG_EXTRA_ENV_SETTINGS \
 	"loadaddr=0x82000000\0" \
@@ -282,7 +283,6 @@
  */
 #define CONFIG_NR_DRAM_BANKS	1	/* CS1 is never populated */
 #define PHYS_SDRAM_1		OMAP34XX_SDRC_CS0
-#define PHYS_SDRAM_1_SIZE	(32 << 20)	/* at least 32 MiB */
 
 /*-----------------------------------------------------------------------
  * FLASH and environment organization
diff --git a/include/configs/dig297.h b/include/configs/dig297.h
index dda758269a8..721b91c4df9 100644
--- a/include/configs/dig297.h
+++ b/include/configs/dig297.h
@@ -263,7 +263,6 @@
  */
 #define CONFIG_NR_DRAM_BANKS	2	/* CS1 may or may not be populated */
 #define PHYS_SDRAM_1		OMAP34XX_SDRC_CS0
-#define PHYS_SDRAM_1_SIZE	(32 << 20)	/* at least 32 MiB */
 #define PHYS_SDRAM_2		OMAP34XX_SDRC_CS1
 
 /*-----------------------------------------------------------------------
diff --git a/include/configs/igep00x0.h b/include/configs/igep00x0.h
index be7937d70ea..43dd06e2467 100644
--- a/include/configs/igep00x0.h
+++ b/include/configs/igep00x0.h
@@ -236,7 +236,6 @@
  */
 #define CONFIG_NR_DRAM_BANKS	2	/* CS1 may or may not be populated */
 #define PHYS_SDRAM_1		OMAP34XX_SDRC_CS0
-#define PHYS_SDRAM_1_SIZE	(32 << 20)	/* at least 32 meg */
 #define PHYS_SDRAM_2		OMAP34XX_SDRC_CS1
 
 /*
diff --git a/include/configs/mcx.h b/include/configs/mcx.h
index e304c994171..185faa7ef18 100644
--- a/include/configs/mcx.h
+++ b/include/configs/mcx.h
@@ -322,7 +322,6 @@
  */
 #define CONFIG_NR_DRAM_BANKS	2	/* CS1 may or may not be populated */
 #define PHYS_SDRAM_1		OMAP34XX_SDRC_CS0
-#define PHYS_SDRAM_1_SIZE	(32 << 20)	/* at least 32 MiB */
 #define PHYS_SDRAM_2		OMAP34XX_SDRC_CS1
 
 /*
diff --git a/include/configs/omap3_beagle.h b/include/configs/omap3_beagle.h
index 12d65f2c4e7..d0daa455e52 100644
--- a/include/configs/omap3_beagle.h
+++ b/include/configs/omap3_beagle.h
@@ -285,7 +285,7 @@
 		"else run userbutton_nonxm; fi;\0" \
 	"userbutton_xm=gpio input 4;\0" \
 	"userbutton_nonxm=gpio input 7;\0"
-/* "run userbutton" will return 1 (false) if is pressed and 0 (false) if not */
+/* "run userbutton" will return 1 (false) if pressed and 0 (true) if not */
 #define CONFIG_BOOTCOMMAND \
 	"mmc dev ${mmcdev}; if mmc rescan; then " \
 		"if run userbutton; then " \
diff --git a/include/configs/omap3_mvblx.h b/include/configs/omap3_mvblx.h
index 67af314652a..09a0b2f7192 100644
--- a/include/configs/omap3_mvblx.h
+++ b/include/configs/omap3_mvblx.h
@@ -251,7 +251,6 @@
  */
 #define CONFIG_NR_DRAM_BANKS	1
 #define PHYS_SDRAM_1		OMAP34XX_SDRC_CS0
-#define PHYS_SDRAM_1_SIZE	(32 << 20)	/* at least 32 MiB */
 #define PHYS_SDRAM_2		OMAP34XX_SDRC_CS1
 
 #define CONFIG_ENV_IS_NOWHERE	1
diff --git a/include/configs/omap3_pandora.h b/include/configs/omap3_pandora.h
index 8a8a5d1cc03..217f306c019 100644
--- a/include/configs/omap3_pandora.h
+++ b/include/configs/omap3_pandora.h
@@ -221,7 +221,6 @@
  */
 #define CONFIG_NR_DRAM_BANKS	2	/* CS1 may or may not be populated */
 #define PHYS_SDRAM_1		OMAP34XX_SDRC_CS0
-#define PHYS_SDRAM_1_SIZE	(32 << 20)	/* at least 32 MiB */
 #define PHYS_SDRAM_2		OMAP34XX_SDRC_CS1
 
 #define CONFIG_SYS_TEXT_BASE		0x80008000
diff --git a/include/configs/omap3_sdp3430.h b/include/configs/omap3_sdp3430.h
index 2a890c9c7e8..b02ec850b7d 100644
--- a/include/configs/omap3_sdp3430.h
+++ b/include/configs/omap3_sdp3430.h
@@ -303,7 +303,6 @@
  */
 #define CONFIG_NR_DRAM_BANKS	2	/* CS1 may or may not be populated */
 #define PHYS_SDRAM_1		OMAP34XX_SDRC_CS0
-#define PHYS_SDRAM_1_SIZE	(32 << 20) /* at least 32 meg */
 #define PHYS_SDRAM_2		OMAP34XX_SDRC_CS1
 
 /*--------------------------------------------------------------------------*/
diff --git a/include/configs/omap3_zoom1.h b/include/configs/omap3_zoom1.h
index e152055a64e..ee4cbd75c1b 100644
--- a/include/configs/omap3_zoom1.h
+++ b/include/configs/omap3_zoom1.h
@@ -252,7 +252,6 @@
  */
 #define CONFIG_NR_DRAM_BANKS	2	/* CS1 may or may not be populated */
 #define PHYS_SDRAM_1		OMAP34XX_SDRC_CS0
-#define PHYS_SDRAM_1_SIZE	(32 << 20)	/* at least 32 MiB */
 #define PHYS_SDRAM_2		OMAP34XX_SDRC_CS1
 
 /*-----------------------------------------------------------------------
diff --git a/include/configs/omap3_zoom2.h b/include/configs/omap3_zoom2.h
index d6814248ed1..a6b48a80ce4 100644
--- a/include/configs/omap3_zoom2.h
+++ b/include/configs/omap3_zoom2.h
@@ -221,7 +221,6 @@
  */
 #define CONFIG_NR_DRAM_BANKS	2	/* CS1 may or may not be populated */
 #define PHYS_SDRAM_1		OMAP34XX_SDRC_CS0
-#define PHYS_SDRAM_1_SIZE	(32 << 20)	/* at least 32 MiB */
 #define PHYS_SDRAM_2		OMAP34XX_SDRC_CS1
 
 /*-----------------------------------------------------------------------
diff --git a/include/configs/tam3517-common.h b/include/configs/tam3517-common.h
index ee73c277b95..9f1fb9feef8 100644
--- a/include/configs/tam3517-common.h
+++ b/include/configs/tam3517-common.h
@@ -189,7 +189,6 @@
  */
 #define CONFIG_NR_DRAM_BANKS	2	/* CS1 may or may not be populated */
 #define PHYS_SDRAM_1		OMAP34XX_SDRC_CS0
-#define PHYS_SDRAM_1_SIZE	(32 << 20)	/* at least 32 MiB */
 #define PHYS_SDRAM_2		OMAP34XX_SDRC_CS1
 
 /*
@@ -358,7 +357,6 @@
  * I2C EEPROM
  */
 #if !(defined(__KERNEL_STRICT_NAMES) || defined(__ASSEMBLY__))
-
 /*
  * The I2C EEPROM on the TAM3517 contains
  * mac address and production data
@@ -384,24 +382,29 @@ struct tam3517_module_info {
 	unsigned char _rev[100];
 };
 
-#define TAM3517_READ_MAC_FROM_EEPROM	\
-do {					\
-	struct tam3517_module_info info;\
-	char buf[80], ethname[20];	\
-	int i;				\
+#define TAM3517_READ_EEPROM(info, ret) \
+do {								\
 	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);	\
 	if (eeprom_read(CONFIG_SYS_I2C_EEPROM_ADDR, 0,		\
-			(void *)&info, sizeof(info)))		\
-		break;						\
+		(void *)info, sizeof(*info)))			\
+		ret = 1;					\
+	else							\
+		ret = 0;					\
+} while (0)
+
+#define TAM3517_READ_MAC_FROM_EEPROM(info)			\
+do {								\
+	char buf[80], ethname[20];				\
+	int i;							\
 	memset(buf, 0, sizeof(buf));				\
-	for (i = 0 ; i < ARRAY_SIZE(info.eth_addr); i++) {	\
+	for (i = 0 ; i < ARRAY_SIZE((info)->eth_addr); i++) {	\
 		sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",	\
-			info.eth_addr[i][5],			\
-			info.eth_addr[i][4],			\
-			info.eth_addr[i][3],			\
-			info.eth_addr[i][2],			\
-			info.eth_addr[i][1],			\
-			info.eth_addr[i][0]);			\
+			(info)->eth_addr[i][5],			\
+			(info)->eth_addr[i][4],			\
+			(info)->eth_addr[i][3],			\
+			(info)->eth_addr[i][2],			\
+			(info)->eth_addr[i][1],			\
+			(info)->eth_addr[i][0]);			\
 								\
 		if (i)						\
 			sprintf(ethname, "eth%daddr", i);	\
@@ -411,6 +414,30 @@ do {					\
 		setenv(ethname, buf);				\
 	}							\
 } while (0)
+
+/* The following macros are taken from Technexion's documentation */
+#define TAM3517_sequence_number(info) \
+	((info)->sequence_number % 0x1000000000000LL)
+#define TAM3517_week_of_year(info) (((info)->sequence_number >> 48) % 0x100)
+#define TAM3517_year(info) ((info)->sequence_number >> 56)
+#define TAM3517_revision_fixed(info) ((info)->revision % 0x100)
+#define TAM3517_revision_major(info) (((info)->revision >> 8) % 0x100)
+#define TAM3517_revision_tn(info) ((info)->revision >> 16)
+
+#define TAM3517_PRINT_SOM_INFO(info)				\
+do {								\
+	printf("Vendor:%s\n", (info)->customer);		\
+	printf("SOM:   %s\n", (info)->product);			\
+	printf("SeqNr: %02llu%02llu%012llu\n",			\
+		TAM3517_year(info),				\
+		TAM3517_week_of_year(info),			\
+		TAM3517_sequence_number(info));			\
+	printf("Rev:   TN%u %u.%u\n",				\
+		TAM3517_revision_tn(info),			\
+		TAM3517_revision_major(info),			\
+		TAM3517_revision_fixed(info));			\
+} while (0)
+
 #endif
 
 #endif /* __TAM3517_H */
diff --git a/include/configs/tricorder.h b/include/configs/tricorder.h
index be0d2ec3c7c..bcb0350b8c7 100644
--- a/include/configs/tricorder.h
+++ b/include/configs/tricorder.h
@@ -247,7 +247,6 @@
 /*  Physical Memory Map  */
 #define CONFIG_NR_DRAM_BANKS		2 /* CS1 may or may not be populated */
 #define PHYS_SDRAM_1			OMAP34XX_SDRC_CS0
-#define PHYS_SDRAM_1_SIZE		(128 << 20)	/* at least 128 MiB */
 #define PHYS_SDRAM_2			OMAP34XX_SDRC_CS1
 
 /* NAND and environment organization  */
diff --git a/include/twl6035.h b/include/twl6035.h
index e21ddbaf22f..ce74348d443 100644
--- a/include/twl6035.h
+++ b/include/twl6035.h
@@ -39,4 +39,4 @@
 int twl6035_i2c_write_u8(u8 chip_no, u8 val, u8 reg);
 int twl6035_i2c_read_u8(u8 chip_no, u8 *val, u8 reg);
 void twl6035_init_settings(void);
-void twl6035_mmc1_poweron_ldo(void);
+int twl6035_mmc1_poweron_ldo(void);