diff mbox

[U-Boot,v2,19/22] omap: add MMC support to SPL

Message ID 1305472900-4004-20-git-send-email-aneesh@ti.com
State Changes Requested
Headers show

Commit Message

Aneesh V May 15, 2011, 3:21 p.m. UTC
Signed-off-by: Aneesh V <aneesh@ti.com>
---
V2:
* Changes for make file changes
---
 arch/arm/cpu/armv7/start.S         |    1 +
 arch/arm/include/asm/omap_common.h |    4 +
 include/configs/omap4_sdp4430.h    |    7 ++-
 spl/board/ti/omap4.mk              |   35 +++++++++++
 spl/board/ti/spl-omap.c            |  112 +++++++++++++++++++++++++++++++++++-
 5 files changed, 156 insertions(+), 3 deletions(-)
diff mbox

Patch

diff --git a/arch/arm/cpu/armv7/start.S b/arch/arm/cpu/armv7/start.S
index f676d7d..351276a 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 10fc9c8..efd3b3c 100644
--- a/arch/arm/include/asm/omap_common.h
+++ b/arch/arm/include/asm/omap_common.h
@@ -55,4 +55,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 13e7623..0b67345 100644
--- a/include/configs/omap4_sdp4430.h
+++ b/include/configs/omap4_sdp4430.h
@@ -261,7 +261,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/omap4.mk b/spl/board/ti/omap4.mk
index a0e2142..ecf605e 100644
--- a/spl/board/ti/omap4.mk
+++ b/spl/board/ti/omap4.mk
@@ -72,6 +72,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 855572f..2174c55 100644
--- a/spl/board/ti/spl-omap.c
+++ b/spl/board/ti/spl-omap.c
@@ -28,25 +28,135 @@ 
 #include <common.h>
 #include <asm/u-boot.h>
 #include <asm/arch/sys_proto.h>
+#include <mmc.h>
 #include <timestamp_autogenerated.h>
 #include <version_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, u_boot_size_sectors, err;
+	u32 *magic_loc = (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 (*magic_loc++ == 0xDEADBEEF) {
+		/* Signature found - get the size saved in the next word */
+		u_boot_size = *magic_loc;
+	} else {
+		/* Signature not found - however continue to load U-Boot */
+		debug("U-Boot signature not found!\n");
+		/* Let's assume U-Boot will not be more than 200 KB */
+		u_boot_size = 200 * 1024;
+	}
+
+	/*
+	 * 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 the remaining sectors */
+	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 */
+	debug("Jumping to U-Boot\n");
+	u_boot_entry();
+}
+
 void preloader_console_init(void)
 {
 	const char *u_boot_rev = U_BOOT_VERSION;