@@ -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
@@ -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_ */
@@ -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 */
@@ -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 $@
@@ -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;
Signed-off-by: Aneesh V <aneesh@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(-)