Patchwork [U-Boot,SPEAr,Enhancement,8/9] spear/spl: Add support to boot from Parallel NOR device

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

Comments

Vipin Kumar - Nov. 2, 2012, 5:39 p.m.
Parallel NOR boot is supported by all spear3xx devices. This patch adds the
support to the generic spear spl framework.

Signed-off-by: Vipin Kumar <vipin.kumar@st.com>
---
 arch/arm/cpu/arm926ejs/spear/spl_boot.c    | 79 +++++++++++++++++++++++++++++-
 arch/arm/include/asm/arch-spear/generic.h  |  6 ---
 arch/arm/include/asm/arch-spear/spl_pnor.h | 34 +++++++++++++
 include/configs/spear600-evb.h             |  1 +
 4 files changed, 113 insertions(+), 7 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-spear/spl_pnor.h

Patch

diff --git a/arch/arm/cpu/arm926ejs/spear/spl_boot.c b/arch/arm/cpu/arm926ejs/spear/spl_boot.c
index 497aefc..7364ee0 100644
--- a/arch/arm/cpu/arm926ejs/spear/spl_boot.c
+++ b/arch/arm/cpu/arm926ejs/spear/spl_boot.c
@@ -31,6 +31,7 @@ 
 #include <asm/arch/hardware.h>
 #include <asm/arch/generic.h>
 #include <asm/arch/spl_nand.h>
+#include <asm/arch/spl_pnor.h>
 
 uint32_t crc32(uint32_t, const unsigned char *, uint);
 
@@ -102,6 +103,59 @@  static int nand_image_load(u32 blkstart, void (**image_p)(void))
 	return 0;
 }
 
+static void pnorcopy(void *dest, const void *src, size_t len,
+		pnor_width_t width)
+{
+	const u32 *src_32 = src;
+	const u16 *src_16 = src;
+	const u8 *src_8 = src;
+	u32 *dest_32 = dest;
+	u16 *dest_16 = dest;
+	u8 *dest_8 = dest;
+	int i;
+
+	switch (width) {
+	case PNOR_WIDTH_32:
+		for (i = 0; i < len >> 2; i++)
+			*dest_32++ = *src_32++;
+		break;
+	case PNOR_WIDTH_16:
+		for (i = 0; i < len >> 1; i++)
+			*dest_16++ = *src_16++;
+		break;
+	case PNOR_WIDTH_8:
+	default:
+		for (i = 0; i < len; i++)
+			*dest_8++ = *src_8++;
+		break;
+	}
+}
+
+static int pnor_image_load(const void *load_addr, void (**image_p)(void),
+		pnor_width_t width)
+{
+	image_header_t header;
+	u32 numbytes;
+
+	pnorcopy((void *)&header, load_addr, sizeof(header), width);
+
+	if (image_check_header(&header)) {
+		numbytes = image_get_data_size(&header);
+
+		/* Copy the image to load address */
+		pnorcopy((void *)image_get_load(&header),
+				load_addr + sizeof(header), numbytes, width);
+
+		if (image_check_data(&header)) {
+			/* Jump to boot image */
+			*image_p = (void (*)(void))image_get_load(&header);
+			return 1;
+		}
+	}
+
+	return 0;
+}
+
 static void boot_image(void (*image)(void))
 {
 	void (*funcp)(void) __noreturn = (void *)image;
@@ -109,6 +163,13 @@  static void boot_image(void (*image)(void))
 	(*funcp)();
 }
 
+static pnor_width_t __def_get_pnor_width(void)
+{
+	return PNOR_WIDTH_SEARCH;
+}
+pnor_width_t get_pnor_width(void)
+	__attribute__((weak, alias("__def_get_pnor_width")));
+
 static void __def_board_lowlevel_late_init(void)
 {
 }
@@ -170,7 +231,23 @@  u32 spl_boot(void)
 
 	if (PNOR_BOOT_SUPPORTED && pnor_boot_selected()) {
 		/* PNOR booting */
-		/* Not ported from XLoader to SPL yet */
+		/* PNOR initialization */
+		pnor_width_t width = get_pnor_width();
+
+		if (width == PNOR_WIDTH_SEARCH)
+			width = PNOR_WIDTH_8;
+
+		/* NAND booting */
+		if (pnor_image_load((const void *)CONFIG_SYS_PNOR_BOOT_BASE,
+					&image, width)) {
+			/* Platform related late initialasations */
+			board_lowlevel_late_init();
+
+			/* Jump to boot image */
+			boot_image(image);
+			return 1;
+		}
+
 		return 0;
 	}
 
diff --git a/arch/arm/include/asm/arch-spear/generic.h b/arch/arm/include/asm/arch-spear/generic.h
index b7026e2..aa13b83 100644
--- a/arch/arm/include/asm/arch-spear/generic.h
+++ b/arch/arm/include/asm/arch-spear/generic.h
@@ -118,10 +118,4 @@  extern int get_socrev(void);
 #define MAC_OFF		0x2
 #define MAC_LEN		0x6
 
-#define PNOR_WIDTH_8			0
-#define	PNOR_WIDTH_16			1
-#define	PNOR_WIDTH_32			2
-#define PNOR_WIDTH_NUM			3
-#define PNOR_WIDTH_SEARCH		0xff
-
 #endif
diff --git a/arch/arm/include/asm/arch-spear/spl_pnor.h b/arch/arm/include/asm/arch-spear/spl_pnor.h
new file mode 100644
index 0000000..f69efc2
--- /dev/null
+++ b/arch/arm/include/asm/arch-spear/spl_pnor.h
@@ -0,0 +1,34 @@ 
+/*
+ * (C) Copyright 2012
+ * Vipin Kumar, ST Micoelectronics, 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
+ */
+
+#ifndef ASM_ARCH_SPEAR_SPL_PNOR_H
+#define ASM_ARCH_SPEAR_SPL_PNOR_H
+
+typedef enum {
+	PNOR_WIDTH_8,
+	PNOR_WIDTH_16,
+	PNOR_WIDTH_32,
+	PNOR_WIDTH_SEARCH
+} pnor_width_t;
+
+#endif
diff --git a/include/configs/spear600-evb.h b/include/configs/spear600-evb.h
index 35761eb..51a349e 100644
--- a/include/configs/spear600-evb.h
+++ b/include/configs/spear600-evb.h
@@ -85,6 +85,7 @@ 
 #define CONFIG_DDR_MT47H32M16
 #define CONFIG_SPL_TEXT_BASE			0xD2800B00
 #define CONFIG_SYS_SNOR_BOOT_BASE		0xF8010000
+#define CONFIG_SYS_PNOR_BOOT_BASE		0x00000000
 #define CONFIG_SYS_NAND_BOOT_BLK		4
 
 #if defined(CONFIG_ENV_IS_IN_FLASH)