Patchwork [U-Boot,SPEAr,Fixes,08/11] spear/spl: Cleanup spear SPL

login
register
mail settings
Submitter Vipin Kumar
Date Nov. 2, 2012, 5:39 p.m.
Message ID <1ed54a41d4b953a193b749ffb0e7aeffc6d66094.1351877185.git.vipin.kumar@st.com>
Download mbox | patch
Permalink /patch/196731/
State New
Delegated to: Vipin Kumar
Headers show

Comments

Vipin Kumar - Nov. 2, 2012, 5:39 p.m.
This patch cleans up the spear SPL support. The modifications include

- Move mpmc register programing values to board dir
   MPMC register programming values are dependent on DDR timings which in turn
   depend a lot on the placement of DDR chip on the board. It makes more sense
   to keep these register init values in board
- Add SPEAR to the CONFIG_DDR namespace
   Add SPEAR to the CONFIG_DDR namespace to make it exclusive to SPEAr platfroms
   only
- Add hardware configurations for spear600 spl support
- Avoid console operations during spl
   The spl runs in the environment provided by boot code. The Boot code may or
   may not initialize UART (padmux, clock etc). This mandates the SPL to initialize
   UART to dump information
   SPEAr SPL as a policy initializes only the system and ddr
- Do not copy the header arbitrarily
   The current logic is copying the header at 64 bytes before the load address.
   This can lead to unpredictable results as that memory is reserved to be
   bss/rw area
   Modify the logic to use a local structure for image header
- Rename spear600.c to spl-spear600.c
- Use the smi_init routine from smi driver
- Perform Data CRC check on relocated image
   image_check_dcrc accepts a header pointer as an argument and performs a data
   crc check based on the assumption that the image data is placed immediately
   after the header. The SPEAr SPL support performs the data verification after
   relocation to RAM has taken place. There are at least following two benefits
   of doing so
   * It is faster in Normal booting cases It also leads to a basic DDR test
   * because the code gets copied to the recently
     initialized DDR and it works like a read-write test for RAM before the
     control is actually transfered to u-boot
- Implement independent routines for get_socrev()
- Rename register bitmask definitions
- Simplify lds file
- Use ENTRY/ENDPROC macros and clear bss

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 arch/arm/cpu/arm926ejs/spear/Makefile              |   6 +-
 arch/arm/cpu/arm926ejs/spear/spear600.c            | 232 ---------------------
 arch/arm/cpu/arm926ejs/spear/spl-spear3xx.c        |  35 ++++
 arch/arm/cpu/arm926ejs/spear/spl-spear600.c        |  98 +++++++++
 arch/arm/cpu/arm926ejs/spear/spl.c                 | 140 ++++---------
 arch/arm/cpu/arm926ejs/spear/spl_boot.c            |  84 +++-----
 arch/arm/cpu/arm926ejs/spear/start.S               |  58 +++---
 arch/arm/cpu/arm926ejs/spear/u-boot-spl.lds        |  65 ++----
 arch/arm/include/asm/arch-spear/generic.h          |  88 ++++++--
 arch/arm/include/asm/arch-spear/misc.h             | 191 +++++------------
 arch/arm/include/asm/arch-spear/spear600.h         |  13 ++
 arch/arm/include/asm/arch-spear/syscntl.h          |  21 +-
 board/st/spear/config.mk                           |   6 +
 board/st/spear/ddr/Makefile                        |  57 +++++
 .../ddr/spear600_mt47h128m8_3_266_cl5_async.c      |   3 +-
 .../spear/ddr/spear600_mt47h32m16_333_cl5_psync.c  |   8 +-
 .../ddr/spear600_mt47h32m16_37e_166_cl4_sync.c     |   3 +-
 .../ddr/spear600_mt47h64m16_3_333_cl5_psync.c      |   8 +-
 board/st/spear/spear600evb.c                       |  91 ++++++++
 include/configs/spear600.h                         |  11 +
 spl/Makefile                                       |   4 +
 21 files changed, 578 insertions(+), 644 deletions(-)
 delete mode 100644 arch/arm/cpu/arm926ejs/spear/spear600.c
 create mode 100644 arch/arm/cpu/arm926ejs/spear/spl-spear3xx.c
 create mode 100644 arch/arm/cpu/arm926ejs/spear/spl-spear600.c
 create mode 100644 board/st/spear/ddr/Makefile
 rename arch/arm/cpu/arm926ejs/spear/spr600_mt47h128m8_3_266_cl5_async.c => board/st/spear/ddr/spear600_mt47h128m8_3_266_cl5_async.c (95%)
 rename arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_333_cl5_psync.c => board/st/spear/ddr/spear600_mt47h32m16_333_cl5_psync.c (91%)
 rename arch/arm/cpu/arm926ejs/spear/spr600_mt47h32m16_37e_166_cl4_sync.c => board/st/spear/ddr/spear600_mt47h32m16_37e_166_cl4_sync.c (95%)
 rename arch/arm/cpu/arm926ejs/spear/spr600_mt47h64m16_3_333_cl5_psync.c => board/st/spear/ddr/spear600_mt47h64m16_3_333_cl5_psync.c (91%)

Patch

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