Signed-off-by: Aneesh V <ane...@ti.com> --- arch/arm/cpu/armv7/start.S | 1 + arch/arm/include/asm/omap_common.h | 4 + include/configs/omap4_sdp4430.h | 7 ++- spl/board/ti/sdp4430/Makefile | 35 +++++++++++ spl/board/ti/spl-omap.c | 112 +++++++++++++++++++++++++++++++++++- 5 files changed, 156 insertions(+), 3 deletions(-)
diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S index 1cbd128..927476c 100644 --- a/arch/arm/cpu/armv7/start.S +++ b/arch/arm/cpu/armv7/start.S @@ -64,6 +64,7 @@ _pad: .word 0x12345678 /* now 16*4=64 */ .global _end_vect _end_vect: +/* This label should be at the same location for SPL and U-Boot */ .global _u_boot_size _u_boot_size: .word 0xDEADBEEF diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 9f2616c..c2efa7c 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -99,4 +99,8 @@ u32 omap_boot_device(void); u32 omap_boot_mode(void); void preloader_console_init(void); +/* symbols from start.S */ +extern u32 _u_boot_size; +extern u32 _start; + #endif /* _OMAP_COMMON_H_ */ diff --git a/include/configs/omap4_sdp4430.h b/include/configs/omap4_sdp4430.h index a4332b7..0ed474d 100644 --- a/include/configs/omap4_sdp4430.h +++ b/include/configs/omap4_sdp4430.h @@ -257,7 +257,10 @@ #define CONFIG_SYS_SPL_MAX_SIZE 0x7800 /* 30 K */ #define CONFIG_SYS_SPL_STACK LOW_LEVEL_SRAM_STACK -#define CONFIG_SYS_SPL_BSS_START_ADDR 0x80000000 -#define CONFIG_SYS_SPL_BSS_MAX_SIZE 0x80000 /* 512 KB */ +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 0x300 /* address 0x60000 */ +#define CONFIG_SYS_U_BOOT_MAX_SIZE_SECTORS 0x200 /* 256 KB */ + +#define CONFIG_SYS_SPL_BSS_START_ADDR 0x80000000 +#define CONFIG_SYS_SPL_BSS_MAX_SIZE 0x80000 /* 512 KB */ #endif /* __CONFIG_H */ diff --git a/spl/board/ti/sdp4430/Makefile b/spl/board/ti/sdp4430/Makefile index d89dea0..18c5b8e 100644 --- a/spl/board/ti/sdp4430/Makefile +++ b/spl/board/ti/sdp4430/Makefile @@ -68,6 +68,41 @@ $(obj)ctype.c: COBJS += serial.o ns16550.o string.o vsprintf.o console.o stdio.o COBJS += ctype.o eabi_compat.o div64.o + +# mmc +$(obj)mmc.c: + @rm -f $@ + @ln -s $(TOPDIR)/drivers/mmc/mmc.c $@ + +$(obj)omap_hsmmc.c: + @rm -f $@ + @ln -s $(TOPDIR)/drivers/mmc/omap_hsmmc.c $@ + +$(obj)omap24xx_i2c.c: $(obj)omap24xx_i2c.h + @rm -f $@ + @ln -s $(TOPDIR)/drivers/i2c/omap24xx_i2c.c $@ + +$(obj)omap24xx_i2c.h: + @rm -f $@ + @ln -s $(TOPDIR)/drivers/i2c/omap24xx_i2c.h $@ + +$(obj)time.c: + @rm -f $@ + @ln -s $(TOPDIR)/lib/time.c $@ + +$(obj)part.c: + @rm -f $@ + @ln -s $(TOPDIR)/disk/part.c $@ + +$(obj)part_dos.c: $(obj)part_dos.h + @rm -f $@ + @ln -s $(TOPDIR)/disk/part_dos.c $@ + +$(obj)part_dos.h: + @rm -f $@ + @ln -s $(TOPDIR)/disk/part_dos.h $@ + +COBJS += omap_hsmmc.o omap24xx_i2c.o mmc.o time.o part.o part_dos.o # armv7 $(obj)start.S: @rm -f $@ diff --git a/spl/board/ti/spl-omap.c b/spl/board/ti/spl-omap.c index 57ddb7d..b64eac9 100644 --- a/spl/board/ti/spl-omap.c +++ b/spl/board/ti/spl-omap.c @@ -28,24 +28,134 @@ #include <common.h> #include <asm/u-boot.h> #include <asm/arch/sys_proto.h> +#include <mmc.h> #include <timestamp_autogenerated.h> +#include <asm/omap_common.h> +#include <asm/arch/mmc_host_def.h> +#include <i2c.h> /* Define global data structure pointer to it*/ gd_t gdata __attribute__ ((section(".data"))); bd_t bdata __attribute__ ((section(".data"))); gd_t *gd = &gdata; +typedef void (*u_boot_entry_t)(void)__attribute__ ((noreturn)); + void board_init_f(ulong dummy) { relocate_code(CONFIG_SYS_SPL_STACK, &gdata, CONFIG_SYS_SPL_TEXT_BASE); } -void board_init_r(gd_t *id, ulong dummy) +inline void hang(void) { + puts("### ERROR ### Please RESET the board ###\n"); for (;;) ; } +#ifdef CONFIG_GENERIC_MMC +int board_mmc_init(bd_t *bis) +{ + omap_mmc_init(0); + omap_mmc_init(1); + return 0; +} +#endif + +static void mmc_load_uboot_raw(struct mmc *mmc, u32 mmc_dev) +{ + u32 u_boot_size_sectors, err; + u32 *u_boot_size = (u32 *)(CONFIG_SYS_TEXT_BASE + + (u32) &_u_boot_size - (u32) &_start); + + /* read one sector first to find u-boot size */ + err = mmc->block_dev.block_read(mmc_dev, + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR, 1, + (void *)CONFIG_SYS_TEXT_BASE); + if (err <= 0) + goto end; + + if (*u_boot_size != 0xDEADBEEF) { + err = 0xDEADBEEF; + goto end; + } + + /* move to the next word that has size */ + u_boot_size++; + + /* + * convert size to sectors - round down is fine because we have + * already read 1 sector + */ + u_boot_size_sectors = *u_boot_size/MMCSD_SECTOR_SIZE; + debug("spl: u-boot raw sectors - %d\n", u_boot_size_sectors + 1); + /* read one sector first to find u-boot size */ + err = mmc->block_dev.block_read(mmc_dev, + CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR + 1, + u_boot_size_sectors, + (void *)(CONFIG_SYS_TEXT_BASE + MMCSD_SECTOR_SIZE)); +end: + if (err <= 0) { + printf("spl: mmc blk read err - %d\n", err); + hang(); + } +} + +static void mmc_load_uboot(u32 mmc_dev) +{ + struct mmc *mmc; + int err; + u32 boot_mode; + + mmc_initialize(gd->bd); + mmc = find_mmc_device(mmc_dev); + if (!mmc) { + puts("spl: mmc device not found!!\n"); + hang(); + } + + err = mmc_init(mmc); + if (err) { + printf("spl: mmc init failed: mmc_dev - %d err - %d\n", + mmc_dev, err); + hang(); + } + + boot_mode = omap_boot_mode(); + if (boot_mode == MMCSD_MODE_RAW) + mmc_load_uboot_raw(mmc, mmc_dev); + else { + puts("spl: wrong MMC boot mode\n"); + hang(); + } +} + +void board_init_r(gd_t *id, ulong dummy) +{ + u32 boot_device; + u_boot_entry_t u_boot_entry = (u_boot_entry_t) CONFIG_SYS_TEXT_BASE; + + timer_init(); + i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE); + boot_device = omap_boot_device(); + switch (boot_device) { + case BOOT_DEVICE_MMC1: + case BOOT_DEVICE_MMC2: + mmc_load_uboot(boot_device - BOOT_DEVICE_MMC1); + break; + default: + printf("SPL: Un-supported Boot Device - %d!!!\n", boot_device); + hang(); + break; + } + + /* + * Jump to u-boot with magic number as input to indicate that it + * was loaded by SPL + */ + u_boot_entry(); +} + void preloader_console_init(void) { gd->bd = &bdata; -- 1.7.0.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot