
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
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)