diff --git a/arch/arm/cpu/arm926ejs/spear/Makefile b/arch/arm/cpu/arm926ejs/spear/Makefile
index 939f372..3fe7e26 100644
--- a/arch/arm/cpu/arm926ejs/spear/Makefile
+++ b/arch/arm/cpu/arm926ejs/spear/Makefile
@@ -33,11 +33,7 @@ COBJS-$(CONFIG_ST_EMI) += emi.o
 
 ifdef CONFIG_SPL_BUILD
 COBJS-y	+= spl.o spl_boot.o
-COBJS-$(CONFIG_SPEAR600) += spear600.o
-COBJS-$(CONFIG_DDR_MT47H64M16) += spr600_mt47h64m16_3_333_cl5_psync.o
-COBJS-$(CONFIG_DDR_MT47H32M16) += spr600_mt47h32m16_333_cl5_psync.o
-COBJS-$(CONFIG_DDR_MT47H32M16) += spr600_mt47h32m16_37e_166_cl4_sync.o
-COBJS-$(CONFIG_DDR_MT47H128M8) += spr600_mt47h128m8_3_266_cl5_async.o
+COBJS-$(CONFIG_SOC_SPEAR600) += spl-spear600.o
 endif
 
 SRCS	:= $(START:.o=.S) $(COBJS-y:.o=.c)
diff --git a/arch/arm/cpu/arm926ejs/spear/spear600.c b/arch/arm/cpu/arm926ejs/spear/spear600.c
deleted file mode 100644
index bd8cb7a..0000000
--- a/arch/arm/cpu/arm926ejs/spear/spear600.c
+++ /dev/null
@@ -1,232 +0,0 @@
-/*
- * (C) Copyright 2000-2009
- * Viresh Kumar, ST Microelectronics, viresh.kumar@st.com
- * Vipin Kumar, ST Microelectronics, vipin.kumar@st.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/hardware.h>
-#include <asm/io.h>
-#include <asm/arch/misc.h>
-#include <asm/arch/generic.h>
-
-#define FALSE				0
-#define TRUE				(!FALSE)
-
-static void sel_1v8(void)
-{
-	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
-	u32 ddr1v8, ddr2v5;
-
-	ddr2v5 = readl(&misc_p->ddr_2v5_compensation);
-	ddr2v5 &= 0x8080ffc0;
-	ddr2v5 |= 0x78000003;
-	writel(ddr2v5, &misc_p->ddr_2v5_compensation);
-
-	ddr1v8 = readl(&misc_p->ddr_1v8_compensation);
-	ddr1v8 &= 0x8080ffc0;
-	ddr1v8 |= 0x78000010;
-	writel(ddr1v8, &misc_p->ddr_1v8_compensation);
-
-	while (!(readl(&misc_p->ddr_1v8_compensation) & DDR_COMP_ACCURATE))
-		;
-}
-
-static void sel_2v5(void)
-{
-	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
-	u32 ddr1v8, ddr2v5;
-
-	ddr1v8 = readl(&misc_p->ddr_1v8_compensation);
-	ddr1v8 &= 0x8080ffc0;
-	ddr1v8 |= 0x78000003;
-	writel(ddr1v8, &misc_p->ddr_1v8_compensation);
-
-	ddr2v5 = readl(&misc_p->ddr_2v5_compensation);
-	ddr2v5 &= 0x8080ffc0;
-	ddr2v5 |= 0x78000010;
-	writel(ddr2v5, &misc_p->ddr_2v5_compensation);
-
-	while (!(readl(&misc_p->ddr_2v5_compensation) & DDR_COMP_ACCURATE))
-		;
-}
-
-/*
- * plat_ddr_init:
- */
-void plat_ddr_init(void)
-{
-	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
-	u32 ddrpad;
-	u32 core3v3, ddr1v8, ddr2v5;
-
-	/* DDR pad register configurations */
-	ddrpad = readl(&misc_p->ddr_pad);
-	ddrpad &= ~DDR_PAD_CNF_MSK;
-
-#if (CONFIG_DDR_HCLK)
-	ddrpad |= 0xEAAB;
-#elif (CONFIG_DDR_2HCLK)
-	ddrpad |= 0xEAAD;
-#elif (CONFIG_DDR_PLL2)
-	ddrpad |= 0xEAAD;
-#endif
-	writel(ddrpad, &misc_p->ddr_pad);
-
-	/* Compensation register configurations */
-	core3v3 = readl(&misc_p->core_3v3_compensation);
-	core3v3 &= 0x8080ffe0;
-	core3v3 |= 0x78000002;
-	writel(core3v3, &misc_p->core_3v3_compensation);
-
-	ddr1v8 = readl(&misc_p->ddr_1v8_compensation);
-	ddr1v8 &= 0x8080ffc0;
-	ddr1v8 |= 0x78000004;
-	writel(ddr1v8, &misc_p->ddr_1v8_compensation);
-
-	ddr2v5 = readl(&misc_p->ddr_2v5_compensation);
-	ddr2v5 &= 0x8080ffc0;
-	ddr2v5 |= 0x78000004;
-	writel(ddr2v5, &misc_p->ddr_2v5_compensation);
-
-	if ((readl(&misc_p->ddr_pad) & DDR_PAD_SW_CONF) == DDR_PAD_SW_CONF) {
-		/* Software memory configuration */
-		if (readl(&misc_p->ddr_pad) & DDR_PAD_SSTL_SEL)
-			sel_1v8();
-		else
-			sel_2v5();
-	} else {
-		/* Hardware memory configuration */
-		if (readl(&misc_p->ddr_pad) & DDR_PAD_DRAM_TYPE)
-			sel_1v8();
-		else
-			sel_2v5();
-	}
-}
-
-/*
- * soc_init:
- */
-void soc_init(void)
-{
-	/* Nothing to be done for SPEAr600 */
-}
-
-/*
- * xxx_boot_selected:
- *
- * return TRUE if the particular booting option is selected
- * return FALSE otherwise
- */
-static u32 read_bootstrap(void)
-{
-	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
-
-	return readl(&misc_p->auto_cfg_reg) & MISC_BOOTSTRAPMASK;
-}
-
-int snor_boot_selected(void)
-{
-	u32 bootstrap = read_bootstrap();
-
-	if (SNOR_BOOT_SUPPORTED) {
-		/* Check whether SNOR boot is selected */
-		if ((bootstrap & MISC_ONLYSNORBOOT) == MISC_ONLYSNORBOOT)
-			return TRUE;
-
-		if ((bootstrap & MISC_NORNANDBOOT) == MISC_NORNAND8BOOT)
-			return TRUE;
-
-		if ((bootstrap & MISC_NORNANDBOOT) == MISC_NORNAND16BOOT)
-			return TRUE;
-	}
-
-	return FALSE;
-}
-
-int nand_boot_selected(void)
-{
-	u32 bootstrap = read_bootstrap();
-
-	if (NAND_BOOT_SUPPORTED) {
-		/* Check whether NAND boot is selected */
-		if ((bootstrap & MISC_NORNANDBOOT) == MISC_NORNAND8BOOT)
-			return TRUE;
-
-		if ((bootstrap & MISC_NORNANDBOOT) == MISC_NORNAND16BOOT)
-			return TRUE;
-	}
-
-	return FALSE;
-}
-
-int pnor_boot_selected(void)
-{
-	/* Parallel NOR boot is not selected in any SPEAr600 revision */
-	return FALSE;
-}
-
-int usb_boot_selected(void)
-{
-	u32 bootstrap = read_bootstrap();
-
-	if (USB_BOOT_SUPPORTED) {
-		/* Check whether USB boot is selected */
-		if (!(bootstrap & MISC_USBBOOT))
-			return TRUE;
-	}
-
-	return FALSE;
-}
-
-int tftp_boot_selected(void)
-{
-	/* TFTP boot is not selected in any SPEAr600 revision */
-	return FALSE;
-}
-
-int uart_boot_selected(void)
-{
-	/* UART boot is not selected in any SPEAr600 revision */
-	return FALSE;
-}
-
-int spi_boot_selected(void)
-{
-	/* SPI boot is not selected in any SPEAr600 revision */
-	return FALSE;
-}
-
-int i2c_boot_selected(void)
-{
-	/* I2C boot is not selected in any SPEAr600 revision */
-	return FALSE;
-}
-
-int mmc_boot_selected(void)
-{
-	return FALSE;
-}
-
-void plat_late_init(void)
-{
-	spear_late_init();
-}
diff --git a/arch/arm/cpu/arm926ejs/spear/spl-spear3xx.c b/arch/arm/cpu/arm926ejs/spear/spl-spear3xx.c
new file mode 100644
index 0000000..7e2bc98
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/spear/spl-spear3xx.c
@@ -0,0 +1,35 @@
+/*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Microelectronics, vipin.kumar@st.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>
+
+int get_socrev(void)
+{
+#if defined(CONFIG_SOC_SPEAR300)
+	return SOC_SPEAR300;
+#elif defined(CONFIG_SOC_SPEAR310)
+	return SOC_SPEAR310;
+#elif defined(CONFIG_SOC_SPEAR320)
+	return SOC_SPEAR320;
+#endif
+}
diff --git a/arch/arm/cpu/arm926ejs/spear/spl-spear600.c b/arch/arm/cpu/arm926ejs/spear/spl-spear600.c
new file mode 100644
index 0000000..5813656
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/spear/spl-spear600.c
@@ -0,0 +1,98 @@
+/*
+ * (C) Copyright 2000-2009
+ * Viresh Kumar, ST Microelectronics, viresh.kumar@st.com
+ * Vipin Kumar, ST Microelectronics, vipin.kumar@st.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/hardware.h>
+#include <asm/io.h>
+#include <asm/arch/misc.h>
+#include <asm/arch/generic.h>
+
+#define FALSE				0
+#define TRUE				(!FALSE)
+
+int get_socrev(void)
+{
+	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+	u32 soc_id = readl(&misc_p->soc_core_id);
+	u32 pri_socid = (soc_id >> MISC_PRISOCID_SHFT) & 0xFF;
+	u32 sec_socid = (soc_id >> MISC_SECSOCID_SHFT) & 0xFF;
+
+	if ((pri_socid == 'B') && (sec_socid == 'B'))
+		return SOC_SPEAR600_BB;
+	else if ((pri_socid == 'B') && (sec_socid == 'C'))
+		return SOC_SPEAR600_BC;
+	else if ((pri_socid == 'B') && (sec_socid == 'D'))
+		return SOC_SPEAR600_BD;
+	else if (soc_id == 0)
+		return SOC_SPEAR600_BA;
+	else
+		return SOC_SPEAR_NA;
+}
+
+/*
+ * soc_init:
+ */
+void soc_init(void)
+{
+	/* Nothing to be done for SPEAr600 */
+}
+
+u32 getboottype(void)
+{
+	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+	u32 bootstrap = readl(&misc_p->auto_cfg_reg) & MISC_BOOTSTRAPMASK;
+	u32 bootmask = 0;
+
+	if (SNOR_BOOT_SUPPORTED) {
+		/* Check whether SNOR boot is selected */
+		if ((bootstrap & MISC_ONLYSNORBOOT) == MISC_ONLYSNORBOOT)
+			bootmask |= BOOT_TYPE_SMI;
+
+		if ((bootstrap & MISC_NORNANDBOOT) == MISC_NORNAND8BOOT)
+			bootmask |= BOOT_TYPE_SMI;
+
+		if ((bootstrap & MISC_NORNANDBOOT) == MISC_NORNAND16BOOT)
+			bootmask |= BOOT_TYPE_SMI;
+	}
+
+	if (NAND_BOOT_SUPPORTED) {
+		/* Check whether NAND boot is selected */
+		if ((bootstrap & MISC_NORNANDBOOT) == MISC_NORNAND8BOOT)
+			bootmask |= BOOT_TYPE_NAND;
+
+		if ((bootstrap & MISC_NORNANDBOOT) == MISC_NORNAND16BOOT)
+			bootmask |= BOOT_TYPE_NAND;
+	}
+
+	if (USBD_BOOT_SUPPORTED) {
+		/* Check whether USB boot is selected */
+		if (!(bootstrap & MISC_USBBOOT))
+			bootmask |= BOOT_TYPE_USBD;
+	}
+
+	if (!bootmask)
+		bootmask |= BOOT_TYPE_UNSUPPORTED;
+
+	return bootmask;
+}
diff --git a/arch/arm/cpu/arm926ejs/spear/spl.c b/arch/arm/cpu/arm926ejs/spear/spl.c
index 16ab82d..4203150 100644
--- a/arch/arm/cpu/arm926ejs/spear/spl.c
+++ b/arch/arm/cpu/arm926ejs/spear/spl.c
@@ -33,7 +33,6 @@
 
 inline void hang(void)
 {
-	serial_puts("### ERROR ### Please RESET the board ###\n");
 	for (;;)
 		;
 }
@@ -44,27 +43,27 @@ static void ddr_clock_init(void)
 	u32 clkenb, ddrpll;
 
 	clkenb = readl(&misc_p->periph1_clken);
-	clkenb &= ~PERIPH_MPMCMSK;
-	clkenb |= PERIPH_MPMC_WE;
+	clkenb &= ~MISC_MPMCMSK;
+	clkenb |= MISC_MPMCWE;
 
 	/* Intentionally done twice */
 	writel(clkenb, &misc_p->periph1_clken);
 	writel(clkenb, &misc_p->periph1_clken);
 
 	ddrpll = readl(&misc_p->pll_ctr_reg);
-	ddrpll &= ~MEM_CLK_SEL_MSK;
-#if (CONFIG_DDR_HCLK)
-	ddrpll |= MEM_CLK_HCLK;
-#elif (CONFIG_DDR_2HCLK)
-	ddrpll |= MEM_CLK_2HCLK;
-#elif (CONFIG_DDR_PLL2)
-	ddrpll |= MEM_CLK_PLL2;
+	ddrpll &= ~MISC_DDRCLK_MSK;
+#if defined(CONFIG_SPEAR_DDR_HCLK)
+	ddrpll |= MISC_DDRCLK_HCLK;
+#elif defined(CONFIG_SPEAR_DDR_2HCLK)
+	ddrpll |= MISC_DDRCLK_2HCLK;
+#elif defined(CONFIG_SPEAR_DDR_PLL2)
+	ddrpll |= MISC_DDRCLK_PLL2;
 #else
-#error "please define one of CONFIG_DDR_(HCLK|2HCLK|PLL2)"
+#error "please define one of CONFIG_SPEAR_DDR_(HCLK|2HCLK|PLL2)"
 #endif
 	writel(ddrpll, &misc_p->pll_ctr_reg);
 
-	writel(readl(&misc_p->periph1_clken) | PERIPH_MPMC_EN,
+	writel(readl(&misc_p->periph1_clken) | MISC_MPMCENB,
 			&misc_p->periph1_clken);
 }
 
@@ -89,16 +88,13 @@ static void mpmc_init_values(void)
 		;
 }
 
-static void mpmc_init(void)
+static void ddr_init(void)
 {
 	/* Clock related settings for DDR */
 	ddr_clock_init();
 
-	/*
-	 * DDR pad register bits are different for different SoCs
-	 * Compensation values are also handled separately
-	 */
-	plat_ddr_init();
+	/* Borad related low level initializations */
+	board_ddr_init();
 
 	/* Initialize mpmc register values */
 	mpmc_init_values();
@@ -109,13 +105,13 @@ static void pll_init(void)
 	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
 
 	/* Initialize PLLs */
-	writel(FREQ_332, &misc_p->pll1_frq);
+	writel(MISC_FREQ_332, &misc_p->pll1_frq);
 	writel(0x1C0A, &misc_p->pll1_cntl);
 	writel(0x1C0E, &misc_p->pll1_cntl);
 	writel(0x1C06, &misc_p->pll1_cntl);
 	writel(0x1C0E, &misc_p->pll1_cntl);
 
-	writel(FREQ_332, &misc_p->pll2_frq);
+	writel(MISC_FREQ_332, &misc_p->pll2_frq);
 	writel(0x1C0A, &misc_p->pll2_cntl);
 	writel(0x1C0E, &misc_p->pll2_cntl);
 	writel(0x1C06, &misc_p->pll2_cntl);
@@ -135,113 +131,51 @@ static void sys_init(void)
 		(struct syscntl_regs *)CONFIG_SPEAR_SYSCNTLBASE;
 
 	/* Set system state to SLOW */
-	writel(SLOW, &syscntl_p->scctrl);
-	writel(PLL_TIM << 3, &syscntl_p->scpllctrl);
+	writel(SYSCNTL_REQ_SLOW, &syscntl_p->scctrl);
+	writel(SYSCNTL_PLL_TIM << 3, &syscntl_p->scpllctrl);
 
 	/* Initialize PLLs */
 	pll_init();
 
-	/*
-	 * Ethernet configuration
-	 * To be done only if the tftp boot is not selected already
-	 * Boot code ensures the correct configuration in tftp booting
-	 */
-	if (!tftp_boot_selected())
-		mac_init();
-
-	writel(RTC_DISABLE | PLLTIMEEN, &misc_p->periph_clk_cfg);
+	writel(MISC_RTC_DISABLE | MISC_PLLTIMEEN, &misc_p->periph_clk_cfg);
 	writel(0x555, &misc_p->amba_clk_cfg);
 
-	writel(NORMAL, &syscntl_p->scctrl);
+	writel(SYSCNTL_REQ_NORMAL, &syscntl_p->scctrl);
 
 	/* Wait for system to switch to normal mode */
-	while (((readl(&syscntl_p->scctrl) >> MODE_SHIFT) & MODE_MASK)
-		!= NORMAL)
+	while ((readl(&syscntl_p->scctrl) & SYSCNTL_STATE_MASK) !=
+			SYSCNTL_STATE_NORMAL)
 		;
 }
 
-/*
- * get_socrev
- *
- * Get SoC Revision.
- * @return SOC_SPEARXXX
- */
-int get_socrev(void)
+static void spear_icm_init(void)
 {
-#if defined(CONFIG_SOC_SPEAR600)
 	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
-	u32 soc_id = readl(&misc_p->soc_core_id);
-	u32 pri_socid = (soc_id >> SOC_PRI_SHFT) & 0xFF;
-	u32 sec_socid = (soc_id >> SOC_SEC_SHFT) & 0xFF;
-
-	if ((pri_socid == 'B') && (sec_socid == 'B'))
-		return SOC_SPEAR600_BB;
-	else if ((pri_socid == 'B') && (sec_socid == 'C'))
-		return SOC_SPEAR600_BC;
-	else if ((pri_socid == 'B') && (sec_socid == 'D'))
-		return SOC_SPEAR600_BD;
-	else if (soc_id == 0)
-		return SOC_SPEAR600_BA;
-	else
-		return SOC_SPEAR_NA;
-#elif defined(CONFIG_SOC_SPEAR300)
-	return SOC_SPEAR300;
-#elif defined(CONFIG_SOC_SPEAR310)
-	return SOC_SPEAR310;
-#elif defined(CONFIG_SOC_SPEAR320)
-	return SOC_SPEAR320;
-#endif
+
+	writel(0x80000007, &misc_p->arb_icm_ml1);
+	writel(0x80000007, &misc_p->arb_icm_ml2);
+	writel(0x80000007, &misc_p->arb_icm_ml3);
+	writel(0x80000007, &misc_p->arb_icm_ml4);
+	writel(0x80000007, &misc_p->arb_icm_ml5);
+	writel(0x80000007, &misc_p->arb_icm_ml6);
+	writel(0x80000007, &misc_p->arb_icm_ml7);
+	writel(0x80000007, &misc_p->arb_icm_ml8);
+	writel(0x80000007, &misc_p->arb_icm_ml9);
 }
 
 void lowlevel_init(void)
 {
 	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
-	const char *u_boot_rev = U_BOOT_VERSION;
 
 	/* Initialize PLLs */
 	sys_init();
 
-	/* Initialize UART */
-	serial_init();
-
-	/* Print U-Boot SPL version string */
-	serial_puts("\nU-Boot SPL ");
-	/* Avoid a second "U-Boot" coming from this string */
-	u_boot_rev = &u_boot_rev[7];
-	serial_puts(u_boot_rev);
-	serial_puts(" (");
-	serial_puts(U_BOOT_DATE);
-	serial_puts(" - ");
-	serial_puts(U_BOOT_TIME);
-	serial_puts(")\n");
-
-#if defined(CONFIG_OS_BOOT)
-	writel(readl(&misc_p->periph1_clken) | PERIPH_UART1,
-			&misc_p->periph1_clken);
-#endif
-
 	/* Enable IPs (release reset) */
-	writel(PERIPH_RST_ALL, &misc_p->periph1_rst);
+	writel(MISC_PERIPH_RST_ALL, &misc_p->periph1_rst);
 
 	/* Initialize MPMC */
-	serial_puts("Configure DDR\n");
-	mpmc_init();
-
-	/* SoC specific initialization */
-	soc_init();
-}
-
-void spear_late_init(void)
-{
-	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+	ddr_init();
 
-	writel(0x80000007, &misc_p->arb_icm_ml1);
-	writel(0x80000007, &misc_p->arb_icm_ml2);
-	writel(0x80000007, &misc_p->arb_icm_ml3);
-	writel(0x80000007, &misc_p->arb_icm_ml4);
-	writel(0x80000007, &misc_p->arb_icm_ml5);
-	writel(0x80000007, &misc_p->arb_icm_ml6);
-	writel(0x80000007, &misc_p->arb_icm_ml7);
-	writel(0x80000007, &misc_p->arb_icm_ml8);
-	writel(0x80000007, &misc_p->arb_icm_ml9);
+	/* Initialize Interconnect Matrix */
+	spear_icm_init();
 }
diff --git a/arch/arm/cpu/arm926ejs/spear/spl_boot.c b/arch/arm/cpu/arm926ejs/spear/spl_boot.c
index c67774d..9742135 100644
--- a/arch/arm/cpu/arm926ejs/spear/spl_boot.c
+++ b/arch/arm/cpu/arm926ejs/spear/spl_boot.c
@@ -31,63 +31,40 @@
 #include <asm/arch/hardware.h>
 #include <asm/arch/generic.h>
 
-static const char kernel_name[] = "Linux";
-static const char loader_name[] = "U-Boot";
+uint32_t crc32(uint32_t, const unsigned char *, uint);
 
-int image_check_header(image_header_t *hdr, const char *name)
+int image_check_header(image_header_t *hdr)
 {
-	if (image_check_magic(hdr) &&
-	    (!strncmp(image_get_name(hdr), name, strlen(name))) &&
-	    image_check_hcrc(hdr)) {
+	if (image_check_magic(hdr) && image_check_hcrc(hdr))
 		return 1;
-	}
+
 	return 0;
 }
 
 int image_check_data(image_header_t *hdr)
 {
-	if (image_check_dcrc(hdr))
-		return 1;
+	ulong data = image_get_load(hdr);
+	ulong len = image_get_data_size(hdr);
+	ulong dcrc = crc32(0, (unsigned char *)data, len);
 
-	return 0;
+	return (dcrc == image_get_dcrc(hdr));
 }
 
-/*
- * SNOR (Serial NOR flash) related functions
- */
-void snor_init(void)
+static int snor_image_load(u8 *load_addr, void (**image_p)(void))
 {
-	struct smi_regs *const smicntl =
-		(struct smi_regs * const)CONFIG_SYS_SMI_BASE;
+	image_header_t header;
 
-	/* Setting the fast mode values. SMI working at 166/4 = 41.5 MHz */
-	writel(HOLD1 | FAST_MODE | BANK_EN | DSEL_TIME | PRESCAL4,
-	       &smicntl->smi_cr1);
-}
+	memcpy(&header, load_addr, sizeof(image_header_t));
 
-static int snor_image_load(u8 *load_addr, void (**image_p)(void),
-			   const char *image_name)
-{
-	image_header_t *header;
+	if (image_check_header(&header)) {
+		/* Copy the image to load address */
+		memcpy((void *)image_get_load(&header),
+		       load_addr + sizeof(image_header_t),
+		       image_get_data_size(&header));
 
-	/*
-	 * Since calculating the crc in the SNOR flash does not
-	 * work, we copy the image to the destination address
-	 * minus the header size. And point the header to this
-	 * new destination. This will not work for address 0
-	 * of course.
-	 */
-	header = (image_header_t *)load_addr;
-	memcpy((ulong *)(image_get_load(header) - sizeof(image_header_t)),
-	       (const ulong *)load_addr,
-	       image_get_data_size(header) + sizeof(image_header_t));
-	header = (image_header_t *)(image_get_load(header) -
-				    sizeof(image_header_t));
-
-	if (image_check_header(header, image_name)) {
-		if (image_check_data(header)) {
+		if (image_check_data(&header)) {
 			/* Jump to boot image */
-			*image_p = (void *)image_get_load(header);
+			*image_p = (void (*)(void))image_get_load(&header);
 			return 1;
 		}
 	}
@@ -102,6 +79,12 @@ static void boot_image(void (*image)(void))
 	(*funcp)();
 }
 
+static void __def_board_lowlevel_late_init(void)
+{
+}
+void board_lowlevel_late_init(void)
+	__attribute__((weak, alias("__def_board_lowlevel_late_init")));
+
 /*
  * spl_boot:
  *
@@ -114,7 +97,7 @@ u32 spl_boot(void)
 	void (*image)(void);
 
 #ifdef CONFIG_SPEAR_USBTTY
-	plat_late_init();
+	board_lowlevel_late_init();
 	return 1;
 #endif
 
@@ -126,17 +109,14 @@ u32 spl_boot(void)
 
 	if (SNOR_BOOT_SUPPORTED && snor_boot_selected()) {
 		/* SNOR-SMI initialization */
-		snor_init();
+		smi_init();
 
-		serial_puts("Booting via SNOR\n");
 		/* Serial NOR booting */
-		if (1 == snor_image_load((u8 *)CONFIG_SYS_UBOOT_BASE,
-					    &image, loader_name)) {
+		if (snor_image_load((u8 *)CONFIG_SYS_SNOR_BOOT_BASE, &image)) {
 			/* Platform related late initialasations */
-			plat_late_init();
+			board_lowlevel_late_init();
 
 			/* Jump to boot image */
-			serial_puts("Jumping to U-Boot\n");
 			boot_image(image);
 			return 1;
 		}
@@ -178,18 +158,18 @@ u32 spl_boot(void)
 	 * the following booting scenarios
 	 */
 
-	if (USB_BOOT_SUPPORTED && usb_boot_selected()) {
-		plat_late_init();
+	if (USBD_BOOT_SUPPORTED && usbd_boot_selected()) {
+		board_lowlevel_late_init();
 		return 1;
 	}
 
 	if (TFTP_BOOT_SUPPORTED && tftp_boot_selected()) {
-		plat_late_init();
+		board_lowlevel_late_init();
 		return 1;
 	}
 
 	if (UART_BOOT_SUPPORTED && uart_boot_selected()) {
-		plat_late_init();
+		board_lowlevel_late_init();
 		return 1;
 	}
 
diff --git a/arch/arm/cpu/arm926ejs/spear/start.S b/arch/arm/cpu/arm926ejs/spear/start.S
index a103c0f..26368b3 100644
--- a/arch/arm/cpu/arm926ejs/spear/start.S
+++ b/arch/arm/cpu/arm926ejs/spear/start.S
@@ -31,30 +31,12 @@
  */
 
 
+#include <asm-offsets.h>
 #include <config.h>
+#include <asm/system.h>
+#include <linux/linkage.h>
 
-.globl _start
-_start:
-	b	reset
-	ldr	pc, _undefined_instruction
-	ldr	pc, _software_interrupt
-	ldr	pc, _prefetch_abort
-	ldr	pc, _data_abort
-	ldr	pc, _not_used
-	ldr	pc, _irq
-	ldr	pc, _fiq
-
-_undefined_instruction:
-_software_interrupt:
-_prefetch_abort:
-_data_abort:
-_not_used:
-_irq:
-_fiq:
-	.word infinite_loop
-
-infinite_loop:
-	b	infinite_loop
+.syntax	unified
 
 /*
  *************************************************************************
@@ -69,17 +51,28 @@ infinite_loop:
  *************************************************************************
  */
 
-/*
- * the actual reset code
- */
-
-reset:
+.globl _start
+_start:
 /*
  * Xloader has to return back to BootROM in a few cases.
  * eg. Ethernet boot, UART boot, USB boot
  * Saving registers for returning back
  */
-	stmdb	sp!, {r0-r12,r14}
+	push	{r0-r12, r14}
+
+	/* Relocate data if needed and Clear BSS */
+	ldr	r0, =__bss_start
+	ldr	r1, =__bss_end
+	mov	r2, #0x00000000		/* clear			    */
+
+clbss_l:
+	cmp	r0, r1			/* clear loop... */
+	bhs	clbss_e			/* if reached end of bss, exit */
+	str	r2, [r0]
+	add	r0, r0, #4
+	b	clbss_l
+clbss_e:
+
 	bl	cpu_init_crit
 /*
  * Clearing bss area is not done in Xloader.
@@ -87,7 +80,7 @@ reset:
  * bss is assumed to be uninitialized.
  */
 	bl	spl_boot
-	ldmia	sp!, {r0-r12,pc}
+	pop	{r0-r12, pc}
 
 /*
  *************************************************************************
@@ -99,7 +92,7 @@ reset:
  *
  *************************************************************************
  */
-cpu_init_crit:
+ENTRY(cpu_init_crit)
 	/*
 	 * flush v4 I/D caches
 	 */
@@ -117,6 +110,7 @@ cpu_init_crit:
 	/*
 	 * Go setup Memory and board specific bits prior to relocation.
 	 */
-	stmdb	sp!, {lr}
+	push	{lr}
 	bl	lowlevel_init	/* go setup pll,mux,memory */
-	ldmia	sp!, {pc}
+	pop	{pc}
+ENDPROC(cpu_init_crit)
diff --git a/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds b/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds
index f3bd5e7..43af464 100644
--- a/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds
+++ b/arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds
@@ -1,4 +1,7 @@
 /*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Microelectronics, <vipin.kumar@st.com>
+ *
  * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
  * on behalf of DENX Software Engineering GmbH
  *
@@ -30,59 +33,21 @@
 OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
 OUTPUT_ARCH(arm)
 ENTRY(_start)
-SECTIONS
+
+MEMORY
 {
-	. = 0x00000000;
+	xloader : ORIGIN = 0xD2800B00, LENGTH = 0x1500
+}
 
-	. = ALIGN(4);
-	.text	:
+SECTIONS
+{
+	.text :
 	{
 		arch/arm/cpu/arm926ejs/spear/start.o	(.text)
-		*(.text)
-	}
-
-	. = ALIGN(4);
-	.rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
-
-	. = ALIGN(4);
-	.data : {
-		*(.data)
-	}
-
-	. = ALIGN(4);
-
-	.u_boot_list : {
-		#include <u-boot.lst>
-	}
-
-	. = ALIGN(4);
-
-	.rel.dyn : {
-		__rel_dyn_start = .;
-		*(.rel*)
-		__rel_dyn_end = .;
-	}
-
-	.dynsym : {
-		__dynsym_start = .;
-		*(.dynsym)
-	}
-
-	.bss : {
-		. = ALIGN(4);
-		__bss_start = .;
-		*(.bss*)
-		. = ALIGN(4);
-		__bss_end__ = .;
-	}
-
-	_end = .;
+		*(.text); . = ALIGN(4);
+	} > xloader
 
-	/DISCARD/ : { *(.dynstr*) }
-	/DISCARD/ : { *(.dynsym*) }
-	/DISCARD/ : { *(.dynamic*) }
-	/DISCARD/ : { *(.hash*) }
-	/DISCARD/ : { *(.plt*) }
-	/DISCARD/ : { *(.interp*) }
-	/DISCARD/ : { *(.gnu*) }
+	.rodata : { *(.rodata*); . = ALIGN(4); } > xloader
+	.data : { *(.data*); . = ALIGN(4); } > xloader
+	.bss : { __bss_start = .; *(.bss*); . = ALIGN(4); __bss_end = .;} > xloader
 }
diff --git a/arch/arm/include/asm/arch-spear/generic.h b/arch/arm/include/asm/arch-spear/generic.h
index 062571c..68a775e 100644
--- a/arch/arm/include/asm/arch-spear/generic.h
+++ b/arch/arm/include/asm/arch-spear/generic.h
@@ -27,21 +27,85 @@
 /* Routines exported from baord */
 extern void setfreq(unsigned int, unsigned int);
 extern unsigned int setfreq_sz;
+extern void board_ddr_init(void);
+extern void board_lowlevel_late_init(void);
 
-void spear_late_init(void);
-void plat_late_init(void);
+extern u32 mpmc_conf_vals[];
 
-int snor_boot_selected(void);
-int nand_boot_selected(void);
-int pnor_boot_selected(void);
-int usb_boot_selected(void);
-int uart_boot_selected(void);
-int tftp_boot_selected(void);
-int i2c_boot_selected(void);
-int spi_boot_selected(void);
-int mmc_boot_selected(void);
+/*
+ * All SoCs should support a generic routine getboottype() which returns a
+ * bitmask with one or more of the following bits set. This is a generic routine
+ * which can be used on any SoC
+ */
+#define BOOT_TYPE_BYPASS	(1 << 1)
+#define BOOT_TYPE_SMI		(1 << 2)
+#define BOOT_TYPE_NAND		(1 << 3)
+#define BOOT_TYPE_RESERVED	(1 << 4)
+#define BOOT_TYPE_I2C		(1 << 5)
+#define BOOT_TYPE_SPI		(1 << 6)
+#define BOOT_TYPE_USBD		(1 << 7)
+#define BOOT_TYPE_TFTP		(1 << 8)
+#define BOOT_TYPE_PCIE		(1 << 9)
+#define BOOT_TYPE_UART		(1 << 10)
+#define BOOT_TYPE_MMC		(1 << 11)
+#define BOOT_TYPE_PNOR8		(1 << 12)
+#define BOOT_TYPE_PNOR16	(1 << 13)
+#define BOOT_TYPE_PNOR32	(1 << 14)
+#define BOOT_TYPE_UNSUPPORTED	(1 << 31)
 
-extern u32 mpmc_conf_vals[];
+extern u32 getboottype(void);
+
+/* xxx_boot_selected */
+#define boot_bypass_selected()	\
+		(getboottype() & BOOT_TYPE_BYPASS)
+#define usbd_boot_selected()	\
+		(getboottype() & BOOT_TYPE_USBD)
+#define snor_boot_selected()	\
+		(getboottype() & BOOT_TYPE_SMI)
+#define nand_boot_selected()	\
+		(getboottype() & BOOT_TYPE_NAND)
+#define pnor8_boot_selected()	\
+		(getboottype() & BOOT_TYPE_PNOR8)
+#define pnor16_boot_selected()	\
+		(getboottype() & BOOT_TYPE_PNOR16)
+#define pnor32_boot_selected()	\
+		(getboottype() & BOOT_TYPE_PNOR32)
+#define pnor_boot_selected()	\
+		(pnor8_boot_selected() || \
+		pnor16_boot_selected() || \
+		pnor32_boot_selected())
+#define tftp_boot_selected()	\
+		(getboottype() & BOOT_TYPE_TFTP)
+#define uart_boot_selected()	\
+		(getboottype() & BOOT_TYPE_UART)
+#define spi_boot_selected()	\
+		(getboottype() & BOOT_TYPE_SPI)
+#define i2c_boot_selected()	\
+		(getboottype() & BOOT_TYPE_I2C)
+#define pcie_boot_selected()	\
+		(getboottype() & BOOT_TYPE_PCIE)
+#define mmc_boot_selected()	\
+		(getboottype() & BOOT_TYPE_MMC)
+
+/* Revision definitions */
+/*
+ * The definitons have started from
+ * 101 for SPEAr6xx
+ * 201 for SPEAr3xx
+ */
+#define SOC_SPEAR_NA		0
+#define SOC_SPEAR600_AA		101
+#define SOC_SPEAR600_AB		102
+#define SOC_SPEAR600_BA		103
+#define SOC_SPEAR600_BB		104
+#define SOC_SPEAR600_BC		105
+#define SOC_SPEAR600_BD		106
+
+#define SOC_SPEAR300		201
+#define SOC_SPEAR310		202
+#define SOC_SPEAR320		203
+
+extern int get_socrev(void);
 
 /* HW mac id in i2c memory definitions */
 #define MAGIC_OFF	0x0
diff --git a/arch/arm/include/asm/arch-spear/misc.h b/arch/arm/include/asm/arch-spear/misc.h
index 2696203..bb97650 100644
--- a/arch/arm/include/asm/arch-spear/misc.h
+++ b/arch/arm/include/asm/arch-spear/misc.h
@@ -101,38 +101,7 @@ struct misc_regs {
 	u32 ras_gpp2_out;	/* 0x800C */
 };
 
-/* SYNTH_CLK value*/
-#define SYNTH23			0x00020003
-
-/* PLLx_FRQ value */
-#if defined(CONFIG_ARCH_SPEAR3XX)
-#define FREQ_332		0xA600010C
-#define FREQ_266		0x8500010C
-#elif defined(CONFIG_ARCH_SPEAR6XX)
-#define FREQ_332		0xA600010F
-#define FREQ_266		0x8500010F
-#endif
-
-/* PLL_CTR_REG   */
-#define MEM_CLK_SEL_MSK		0x70000000
-#define MEM_CLK_HCLK		0x00000000
-#define MEM_CLK_2HCLK		0x10000000
-#define MEM_CLK_PLL2		0x30000000
-
-#define EXPI_CLK_CFG_LOW_COMPR	0x2000
-#define EXPI_CLK_CFG_CLK_EN	0x0400
-#define EXPI_CLK_CFG_RST	0x0200
-#define EXPI_CLK_SYNT_EN	0x0010
-#define EXPI_CLK_CFG_SEL_PLL2	0x0004
-#define EXPI_CLK_CFG_INT_CLK_EN	0x0001
-
-#define PLL2_CNTL_6UA		0x1c00
-#define PLL2_CNTL_SAMPLE	0x0008
-#define PLL2_CNTL_ENABLE	0x0004
-#define PLL2_CNTL_RESETN	0x0002
-#define PLL2_CNTL_LOCK		0x0001
-
-/* AUTO_CFG_REG value */
+/* auto_cfg_reg value */
 #define MISC_SOCCFGMSK                  0x0000003F
 #define MISC_SOCCFG30                   0x0000000C
 #define MISC_SOCCFG31                   0x0000000D
@@ -144,26 +113,34 @@ struct misc_regs {
 #define MISC_NORNAND16BOOT		0x00090000
 #define MISC_USBBOOT			0x00080000
 
-/* PERIPH_CLK_CFG value */
+/* pllX_frq value */
+#if defined(CONFIG_ARCH_SPEAR3XX)
+#define MISC_FREQ_332		0xA600010C
+#define MISC_FREQ_266		0x8500010C
+#elif defined(CONFIG_ARCH_SPEAR6XX)
+#define MISC_FREQ_332		0xA600010F
+#define MISC_FREQ_266		0x8500010F
+#endif
+
+/* pll_ctr_reg */
+#define MISC_DDRCLK_MSK			0x70000000
+#define MISC_DDRCLK_HCLK		0x00000000
+#define MISC_DDRCLK_2HCLK		0x10000000
+#define MISC_DDRCLK_PLL2		0x30000000
+
+/* periph_clk_cfg */
 #define MISC_GPT3SYNTH			0x00000400
 #define MISC_GPT4SYNTH			0x00000800
+#define MISC_RTC_DISABLE		0x00000080
 #define MISC_UART48M			0x00000000
 #define MISC_UARTCLKMSK			0x00000010
+#define MISC_PLLTIMEEN			0x00000002
 
-/* PRSC_CLK_CFG value */
-/*
- * Fout = Fin / (2^(N+1) * (M + 1))
- */
-#define MISC_PRSC_N_1			0x00001000
-#define MISC_PRSC_M_9			0x00000009
-#define MISC_PRSC_N_4			0x00004000
-#define MISC_PRSC_M_399			0x0000018F
-#define MISC_PRSC_N_6			0x00006000
-#define MISC_PRSC_M_2593		0x00000A21
-#define MISC_PRSC_M_124			0x0000007C
-#define MISC_PRSC_CFG			(MISC_PRSC_N_1 | MISC_PRSC_M_9)
-
-/* PERIPH1_CLKEN, PERIPH1_RST value */
+/* periph1_clken, periph1_rst */
+#define MISC_MPMCMSK			0x60000000
+#define MISC_MPMCWE			0x40000000
+#define MISC_MPMCENB			0x20000000
+#define MISC_USBHENB			0x02000000
 #define MISC_USBDENB			0x01000000
 #define MISC_ETHENB			0x00800000
 #define MISC_SMIENB			0x00200000
@@ -174,106 +151,38 @@ struct misc_regs {
 #define MISC_I2CENB			0x00000080
 #define MISC_SSP2ENB			0x00000070
 #define MISC_UART0ENB			0x00000008
+#define MISC_PERIPH_RST_ALL		0x00000004
 
-/*   PERIPH_CLK_CFG   */
-#define  XTALTIMEEN		0x00000001
-#define  PLLTIMEEN		0x00000002
-#define  CLCDCLK_SYNTH		0x00000000
-#define  CLCDCLK_48MHZ		0x00000004
-#define  CLCDCLK_EXT		0x00000008
-#define  UARTCLK_MASK		(0x1 << 4)
-#define  UARTCLK_48MHZ		0x00000000
-#define  UARTCLK_SYNTH		0x00000010
-#define  IRDACLK_48MHZ		0x00000000
-#define  IRDACLK_SYNTH		0x00000020
-#define  IRDACLK_EXT		0x00000040
-#define  RTC_DISABLE		0x00000080
-#define  GPT1CLK_48MHZ		0x00000000
-#define  GPT1CLK_SYNTH		0x00000100
-#define  GPT2CLK_48MHZ		0x00000000
-#define  GPT2CLK_SYNTH		0x00000200
-#define  GPT3CLK_48MHZ		0x00000000
-#define  GPT3CLK_SYNTH		0x00000400
-#define  GPT4CLK_48MHZ		0x00000000
-#define  GPT4CLK_SYNTH		0x00000800
-#define  GPT5CLK_48MHZ		0x00000000
-#define  GPT5CLK_SYNTH		0x00001000
-#define  GPT1_FREEZE		0x00002000
-#define  GPT2_FREEZE		0x00004000
-#define  GPT3_FREEZE		0x00008000
-#define  GPT4_FREEZE		0x00010000
-#define  GPT5_FREEZE		0x00020000
-
-/*  PERIPH1_CLKEN bits  */
-#define PERIPH_ARM1_WE		0x00000001
-#define PERIPH_ARM1		0x00000002
-#define PERIPH_ARM2		0x00000004
-#define PERIPH_UART1		0x00000008
-#define PERIPH_UART2		0x00000010
-#define PERIPH_SSP1		0x00000020
-#define PERIPH_SSP2		0x00000040
-#define PERIPH_I2C		0x00000080
-#define PERIPH_JPEG		0x00000100
-#define PERIPH_FSMC		0x00000200
-#define PERIPH_FIRDA		0x00000400
-#define PERIPH_GPT4		0x00000800
-#define PERIPH_GPT5		0x00001000
-#define PERIPH_GPIO4		0x00002000
-#define PERIPH_SSP3		0x00004000
-#define PERIPH_ADC		0x00008000
-#define PERIPH_GPT3		0x00010000
-#define PERIPH_RTC		0x00020000
-#define PERIPH_GPIO3		0x00040000
-#define PERIPH_DMA		0x00080000
-#define PERIPH_ROM		0x00100000
-#define PERIPH_SMI		0x00200000
-#define PERIPH_CLCD		0x00400000
-#define PERIPH_GMAC		0x00800000
-#define PERIPH_USBD		0x01000000
-#define PERIPH_USBH1		0x02000000
-#define PERIPH_USBH2		0x04000000
-#define PERIPH_MPMC		0x08000000
-#define PERIPH_RAMW		0x10000000
-#define PERIPH_MPMC_EN		0x20000000
-#define PERIPH_MPMC_WE		0x40000000
-#define PERIPH_MPMCMSK		0x60000000
-
-#define PERIPH_CLK_ALL		0x0FFFFFF8
-#define PERIPH_RST_ALL		0x00000004
-
-/* DDR_PAD values */
-#define DDR_PAD_CNF_MSK		0x0000ffff
-#define DDR_PAD_SW_CONF		0x00060000
-#define DDR_PAD_SSTL_SEL	0x00000001
-#define DDR_PAD_DRAM_TYPE	0x00008000
-
-/* DDR_COMP values */
-#define DDR_COMP_ACCURATE	0x00000010
-
-/* SoC revision stuff */
-#define SOC_PRI_SHFT		16
-#define SOC_SEC_SHFT		8
+/* soc_core_id */
+#define MISC_PRISOCID_SHFT		16
+#define MISC_SECSOCID_SHFT		8
 
-/* Revision definitions */
-#define SOC_SPEAR_NA		0
+/* synth_clk */
+#define MISC_SYNTH23			0x00020003
 
+/* prsc_clk_cfg */
 /*
- * The definitons have started from
- * 101 for SPEAr6xx
- * 201 for SPEAr3xx
- * 301 for SPEAr13xx
+ * Fout = Fin / (2^(N+1) * (M + 1))
  */
-#define SOC_SPEAR600_AA		101
-#define SOC_SPEAR600_AB		102
-#define SOC_SPEAR600_BA		103
-#define SOC_SPEAR600_BB		104
-#define SOC_SPEAR600_BC		105
-#define SOC_SPEAR600_BD		106
+#define MISC_PRSC_N_1			0x00001000
+#define MISC_PRSC_M_9			0x00000009
+#define MISC_PRSC_N_4			0x00004000
+#define MISC_PRSC_M_399			0x0000018F
+#define MISC_PRSC_N_6			0x00006000
+#define MISC_PRSC_M_2593		0x00000A21
+#define MISC_PRSC_M_124			0x0000007C
+#define MISC_PRSC_CFG			(MISC_PRSC_N_1 | MISC_PRSC_M_9)
+
+/* amem_cfg_ctrl */
+#define MISC_AMEM_CLKENB		0x00000001
 
-#define SOC_SPEAR300		201
-#define SOC_SPEAR310		202
-#define SOC_SPEAR320		203
+/* ddr_compensation */
+#define MISC_DDR_COMP_ACCURATE		0x00000010
 
-extern int get_socrev(void);
+/* ddr_pad */
+#define MISC_DDR_PAD_CNF_MSK		0x0000ffff
+#define MISC_DDR_PAD_SW_CONF		0x00060000
+#define MISC_DDR_PAD_SSTL_SEL		0x00000001
+#define MISC_DDR_PAD_DRAM_TYPE		0x00008000
 
 #endif
diff --git a/arch/arm/include/asm/arch-spear/spear600.h b/arch/arm/include/asm/arch-spear/spear600.h
index c8b0047..dd4f531 100644
--- a/arch/arm/include/asm/arch-spear/spear600.h
+++ b/arch/arm/include/asm/arch-spear/spear600.h
@@ -32,7 +32,10 @@
 #define CONFIG_SYS_PLUG_BASE			0xE1200000
 #define CONFIG_SYS_UHC0_EHCI_BASE		0xE1800000
 #define CONFIG_SYS_SMI_BASE			0xFC000000
+
 #define CONFIG_SPEAR_MPMCBASE			0xFC600000
+#define CONFIG_SPEAR_MPMCREGS			100
+
 #define CONFIG_SPEAR_TIMERBASE			0xFC800000
 #define CONFIG_SPEAR_SYSCNTLBASE		0xFCA00000
 #define CONFIG_SPEAR_MISCBASE			0xFCA80000
@@ -42,4 +45,14 @@
 #define CONFIG_SYS_NAND_CLE			(1 << 16)
 #define CONFIG_SYS_NAND_ALE			(1 << 17)
 
+#define SNOR_BOOT_SUPPORTED			1
+#define NAND_BOOT_SUPPORTED			1
+#define PNOR_BOOT_SUPPORTED			0
+#define USBD_BOOT_SUPPORTED			1
+#define TFTP_BOOT_SUPPORTED			0
+#define UART_BOOT_SUPPORTED			0
+#define MMC_BOOT_SUPPORTED			0
+#define SPI_BOOT_SUPPORTED			0
+#define I2C_BOOT_SUPPORTED			0
+
 #endif
diff --git a/arch/arm/include/asm/arch-spear/syscntl.h b/arch/arm/include/asm/arch-spear/syscntl.h
index 2393d89..f55ce92 100644
--- a/arch/arm/include/asm/arch-spear/syscntl.h
+++ b/arch/arm/include/asm/arch-spear/syscntl.h
@@ -21,8 +21,8 @@
  * MA 02111-1307 USA
  */
 
-#ifndef __SYSCTRL_H
-#define __SYSCTRL_H
+#ifndef ASM_ARCH_SPEAR_SYSCTRL_H
+#define ASM_ARCH_SPEAR_SYSCTRL_H
 
 struct syscntl_regs {
 	u32 scctrl;
@@ -40,13 +40,16 @@ struct syscntl_regs {
 	const u32 scperstat;
 };
 
-#define MODE_SHIFT          0x00000003
+#define SYSCNTL_STATE_MASK		(0x07 << 3)
+#define SYSCNTL_STATE_NORMAL		(0x04 << 3)
+#define SYSCNTL_STATE_SLOW		(0x02 << 3)
+#define SYSCNTL_STATE_DOZE		(0x01 << 3)
+#define SYSCNTL_STATE_SLEEP		(0x00 << 3)
+#define SYSCNTL_REQ_NORMAL		(0x04 << 0)
+#define SYSCNTL_REQ_SLOW		(0x02 << 0)
+#define SYSCNTL_REQ_DOZE		(0x01 << 0)
+#define SYSCNTL_REQ_SLEEP		(0x00 << 0)
 
-#define NORMAL              0x00000004
-#define SLOW                0x00000002
-#define DOZE                0x00000001
-#define SLEEP               0x00000000
-
-#define PLL_TIM             0x01FFFFFF
+#define SYSCNTL_PLL_TIM			0x01FFFFFF
 
 #endif
diff --git a/board/st/spear/config.mk b/board/st/spear/config.mk
index 9533c5f..971d60a 100644
--- a/board/st/spear/config.mk
+++ b/board/st/spear/config.mk
@@ -21,4 +21,10 @@
 # MA 02111-1307 USA
 #
 
+ifndef CONFIG_SPL_BUILD
 ALL-y += $(obj)u-boot.img
+
+ifdef CONFIG_MACH_SPEAR600EVB
+ALL-y += $(obj)spl/u-boot-spl.img
+endif
+endif
diff --git a/board/st/spear/ddr/Makefile b/board/st/spear/ddr/Makefile
new file mode 100644
index 0000000..9f1c627
--- /dev/null
+++ b/board/st/spear/ddr/Makefile
@@ -0,0 +1,57 @@
+#
+# (C) Copyright 2012
+# Vipin Kumar, ST Microelectronics, vipin.kumar@st.com
+#
+# (C) Copyright 2000-2004
+# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	= $(obj)lib$(BOARD)ddr.o
+
+SOBJS-y	:=
+COBJS-y	:=
+
+ifdef CONFIG_SPL_BUILD
+COBJS-$(CONFIG_DDR_MT47H64M16) += spear600_mt47h64m16_3_333_cl5_psync.o
+COBJS-$(CONFIG_DDR_MT47H32M16) += spear600_mt47h32m16_333_cl5_psync.o
+COBJS-$(CONFIG_DDR_MT47H32M16) += spear600_mt47h32m16_37e_166_cl4_sync.o
+COBJS-$(CONFIG_DDR_MT47H128M8) += spear600_mt47h128m8_3_266_cl5_async.o
+endif
+
+COBJS	:= $(sort $(COBJS-y))
+SOBJS	:= $(sort $(SOBJS-y))
+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))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c b/board/st/spear/ddr/spear600_mt47h128m8_3_266_cl5_async.c
similarity index 95%
rename from arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c
rename to board/st/spear/ddr/spear600_mt47h128m8_3_266_cl5_async.c
index 5edc115..abaa7b6 100644
--- a/arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c
+++ b/board/st/spear/ddr/spear600_mt47h128m8_3_266_cl5_async.c
@@ -22,8 +22,9 @@
  */
 
 #include <common.h>
+#include <asm/arch/hardware.h>
 
-#if (CONFIG_DDR_PLL2)
+#if defined(CONFIG_ARCH_SPEAR6XX) && defined(CONFIG_SPEAR_DDR_PLL2)
 
 const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = {
 	0x00000001,
diff --git a/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c b/board/st/spear/ddr/spear600_mt47h32m16_333_cl5_psync.c
similarity index 91%
rename from arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c
rename to board/st/spear/ddr/spear600_mt47h32m16_333_cl5_psync.c
index 616b861..65e7371 100644
--- a/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c
+++ b/board/st/spear/ddr/spear600_mt47h32m16_333_cl5_psync.c
@@ -22,14 +22,16 @@
  */
 
 #include <common.h>
+#include <asm/arch/hardware.h>
 
-#if (CONFIG_DDR_PLL2 || CONFIG_DDR_2HCLK)
+#if defined(CONFIG_ARCH_SPEAR6XX) && \
+	(defined(CONFIG_SPEAR_DDR_PLL2) || defined(CONFIG_SPEAR_DDR_2HCLK))
 
 const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = {
-#if (CONFIG_DDR_PLL2)
+#if defined(CONFIG_SPEAR_DDR_PLL2)
 	0x00000001,
 	0x00000000,
-#elif (CONFIG_DDR_2HCLK)
+#elif defined(CONFIG_SPEAR_DDR_2HCLK)
 	0x02020201,
 	0x02020202,
 #endif
diff --git a/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c b/board/st/spear/ddr/spear600_mt47h32m16_37e_166_cl4_sync.c
similarity index 95%
rename from arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c
rename to board/st/spear/ddr/spear600_mt47h32m16_37e_166_cl4_sync.c
index b89f77d..1e4e0d9 100644
--- a/arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c
+++ b/board/st/spear/ddr/spear600_mt47h32m16_37e_166_cl4_sync.c
@@ -22,8 +22,9 @@
  */
 
 #include <common.h>
+#include <asm/arch/hardware.h>
 
-#if (CONFIG_DDR_HCLK)
+#if defined(CONFIG_ARCH_SPEAR6XX) && defined(CONFIG_SPEAR_DDR_HCLK)
 
 const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = {
 	0x03030301,
diff --git a/arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c b/board/st/spear/ddr/spear600_mt47h64m16_3_333_cl5_psync.c
similarity index 91%
rename from arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c
rename to board/st/spear/ddr/spear600_mt47h64m16_3_333_cl5_psync.c
index 0c39cd1..81cd706 100644
--- a/arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c
+++ b/board/st/spear/ddr/spear600_mt47h64m16_3_333_cl5_psync.c
@@ -22,14 +22,16 @@
  */
 
 #include <common.h>
+#include <asm/arch/hardware.h>
 
-#if (CONFIG_DDR_PLL2 || CONFIG_DDR_2HCLK)
+#if defined(CONFIG_ARCH_SPEAR6XX) && \
+	(defined(CONFIG_SPEAR_DDR_PLL2) || defined(CONFIG_SPEAR_DDR_2HCLK))
 
 const u32 mpmc_conf_vals[CONFIG_SPEAR_MPMCREGS] = {
-#if (CONFIG_DDR_PLL2)
+#if defined(CONFIG_SPEAR_DDR_PLL2)
 	0x00000001,
 	0x00000000,
-#elif (CONFIG_DDR_2HCLK)
+#elif defined(CONFIG_SPEAR_DDR_2HCLK)
 	0x02020201,
 	0x02020202,
 #endif
diff --git a/board/st/spear/spear600evb.c b/board/st/spear/spear600evb.c
index b5901e6..17828a3 100644
--- a/board/st/spear/spear600evb.c
+++ b/board/st/spear/spear600evb.c
@@ -79,3 +79,94 @@ int board_eth_init(bd_t *bis)
 	return ret;
 }
 #endif
+
+#if defined(CONFIG_SPL_BUILD)
+static void sel_1v8(void)
+{
+	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+	u32 ddr1v8, ddr2v5;
+
+	ddr2v5 = readl(&misc_p->ddr_2v5_compensation);
+	ddr2v5 &= 0x8080ffc0;
+	ddr2v5 |= 0x78000003;
+	writel(ddr2v5, &misc_p->ddr_2v5_compensation);
+
+	ddr1v8 = readl(&misc_p->ddr_1v8_compensation);
+	ddr1v8 &= 0x8080ffc0;
+	ddr1v8 |= 0x78000010;
+	writel(ddr1v8, &misc_p->ddr_1v8_compensation);
+
+	while (!(readl(&misc_p->ddr_1v8_compensation) & MISC_DDR_COMP_ACCURATE))
+		;
+}
+
+static void sel_2v5(void)
+{
+	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+	u32 ddr1v8, ddr2v5;
+
+	ddr1v8 = readl(&misc_p->ddr_1v8_compensation);
+	ddr1v8 &= 0x8080ffc0;
+	ddr1v8 |= 0x78000003;
+	writel(ddr1v8, &misc_p->ddr_1v8_compensation);
+
+	ddr2v5 = readl(&misc_p->ddr_2v5_compensation);
+	ddr2v5 &= 0x8080ffc0;
+	ddr2v5 |= 0x78000010;
+	writel(ddr2v5, &misc_p->ddr_2v5_compensation);
+
+	while (!(readl(&misc_p->ddr_2v5_compensation) & MISC_DDR_COMP_ACCURATE))
+		;
+}
+
+void board_ddr_init(void)
+{
+	struct misc_regs *misc_p = (struct misc_regs *)CONFIG_SPEAR_MISCBASE;
+	u32 ddrpad;
+	u32 core3v3, ddr1v8, ddr2v5;
+
+	/* DDR pad register configurations */
+	ddrpad = readl(&misc_p->ddr_pad);
+	ddrpad &= ~MISC_DDR_PAD_CNF_MSK;
+
+#if defined(CONFIG_SPEAR_DDR_HCLK)
+	ddrpad |= 0xEAAB;
+#elif defined(CONFIG_SPEAR_DDR_2HCLK)
+	ddrpad |= 0xEAAD;
+#elif defined(CONFIG_SPEAR_DDR_PLL2)
+	ddrpad |= 0xEAAD;
+#endif
+	writel(ddrpad, &misc_p->ddr_pad);
+
+	/* Compensation register configurations */
+	core3v3 = readl(&misc_p->core_3v3_compensation);
+	core3v3 &= 0x8080ffe0;
+	core3v3 |= 0x78000002;
+	writel(core3v3, &misc_p->core_3v3_compensation);
+
+	ddr1v8 = readl(&misc_p->ddr_1v8_compensation);
+	ddr1v8 &= 0x8080ffc0;
+	ddr1v8 |= 0x78000004;
+	writel(ddr1v8, &misc_p->ddr_1v8_compensation);
+
+	ddr2v5 = readl(&misc_p->ddr_2v5_compensation);
+	ddr2v5 &= 0x8080ffc0;
+	ddr2v5 |= 0x78000004;
+	writel(ddr2v5, &misc_p->ddr_2v5_compensation);
+
+	if ((readl(&misc_p->ddr_pad) & MISC_DDR_PAD_SW_CONF) ==
+			MISC_DDR_PAD_SW_CONF) {
+		/* Software memory configuration */
+		if (readl(&misc_p->ddr_pad) & MISC_DDR_PAD_SSTL_SEL)
+			sel_1v8();
+		else
+			sel_2v5();
+	} else {
+		/* Hardware memory configuration */
+		if (readl(&misc_p->ddr_pad) & MISC_DDR_PAD_DRAM_TYPE)
+			sel_1v8();
+		else
+			sel_2v5();
+	}
+}
+#endif
diff --git a/include/configs/spear600.h b/include/configs/spear600.h
index e64f26d..dfe8196 100644
--- a/include/configs/spear600.h
+++ b/include/configs/spear600.h
@@ -54,5 +54,16 @@
 #define CONFIG_SYS_INIT_SP_ADDR			(0xD2800000 + 0x2000 - \
 						GENERATED_GBL_DATA_SIZE)
 
+/* SPL configurations */
+#if defined(CONFIG_SPL)
+	#define CONFIG_SPL_NO_CPU_SUPPORT_CODE
+	#define CONFIG_SPL_LIBCOMMON_SUPPORT
+	#define CONFIG_SPL_LIBGENERIC_SUPPORT
+	#define CONFIG_SPL_MTD_SUPPORT
+	#define CONFIG_SPL_START_S_PATH	"arch/arm/cpu/arm926ejs/spear"
+	#define CONFIG_SPL_LDSCRIPT	\
+		"arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds"
+#endif
+
 #include <configs/spear.h>
 #endif /* __CONFIG_SPEAR600_H */
diff --git a/spl/Makefile b/spl/Makefile
index 20a943c..e38467a 100644
--- a/spl/Makefile
+++ b/spl/Makefile
@@ -61,6 +61,10 @@ LIBS-$(CONFIG_SPL_NET_SUPPORT) += net/libnet.o
 LIBS-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/libnet.o
 LIBS-$(CONFIG_SPL_ETH_SUPPORT) += drivers/net/phy/libphy.o
 
+ifeq ($(BOARD),spear)
+LIBS-y += board/$(BOARDDIR)/ddr/lib$(BOARD)ddr.o
+endif
+
 ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP34XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX),)
 LIBS-y += $(CPUDIR)/omap-common/libomap-common.o
 endif
