u-boot/common/spl/spl_mmc.c
Tom Rini 7dbe63bc95 SPL: Add CONFIG_SUPPORT_EMMC_BOOT support to CONFIG_SPL_FRAMEWORK
We use the switch CONFIG_SUPPORT_EMMC_BOOT today to enable some
additional features of the eMMC boot partitions.  Add support for being
told that we have booted from one of these partitions to the spl
framework and implement this on TI OMAP/related.

Cc: Pantelis Antoniou <panto@antoniou-consulting.com>
Signed-off-by: Tom Rini <trini@ti.com>
Signed-off-by: Pantelis Antoniou <panto@antoniou-consulting.com>
2014-02-07 18:17:48 +02:00

147 lines
3.4 KiB
C

/*
* (C) Copyright 2010
* Texas Instruments, <www.ti.com>
*
* Aneesh V <aneesh@ti.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <spl.h>
#include <asm/u-boot.h>
#include <mmc.h>
#include <version.h>
#include <image.h>
DECLARE_GLOBAL_DATA_PTR;
static int mmc_load_image_raw(struct mmc *mmc, unsigned long sector)
{
unsigned long err;
u32 image_size_sectors;
struct image_header *header;
header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
sizeof(struct image_header));
/* read image header to find the image size & load address */
err = mmc->block_dev.block_read(0, sector, 1, header);
if (err == 0)
goto end;
if (image_get_magic(header) != IH_MAGIC)
return -1;
spl_parse_image_header(header);
/* convert size to sectors - round up */
image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) /
mmc->read_bl_len;
/* Read the header too to avoid extra memcpy */
err = mmc->block_dev.block_read(0, sector, image_size_sectors,
(void *)spl_image.load_addr);
end:
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
if (err == 0)
printf("spl: mmc blk read err - %lu\n", err);
#endif
return (err == 0);
}
#ifdef CONFIG_SPL_OS_BOOT
static int mmc_load_image_raw_os(struct mmc *mmc)
{
if (!mmc->block_dev.block_read(0,
CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
(void *)CONFIG_SYS_SPL_ARGS_ADDR)) {
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
printf("mmc args blk read error\n");
#endif
return -1;
}
return mmc_load_image_raw(mmc, CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
}
#endif
void spl_mmc_load_image(void)
{
struct mmc *mmc;
int err;
u32 boot_mode;
mmc_initialize(gd->bd);
/* We register only one device. So, the dev id is always 0 */
mmc = find_mmc_device(0);
if (!mmc) {
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
puts("spl: mmc device not found!!\n");
#endif
hang();
}
err = mmc_init(mmc);
if (err) {
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
printf("spl: mmc init failed: err - %d\n", err);
#endif
hang();
}
boot_mode = spl_boot_mode();
if (boot_mode == MMCSD_MODE_RAW) {
debug("boot mode - RAW\n");
#ifdef CONFIG_SPL_OS_BOOT
if (spl_start_uboot() || mmc_load_image_raw_os(mmc))
#endif
err = mmc_load_image_raw(mmc,
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
#ifdef CONFIG_SPL_FAT_SUPPORT
} else if (boot_mode == MMCSD_MODE_FAT) {
debug("boot mode - FAT\n");
#ifdef CONFIG_SPL_OS_BOOT
if (spl_start_uboot() || spl_load_image_fat_os(&mmc->block_dev,
CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION))
#endif
err = spl_load_image_fat(&mmc->block_dev,
CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION,
CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME);
#endif
#ifdef CONFIG_SUPPORT_EMMC_BOOT
} else if (boot_mode == MMCSD_MODE_EMMCBOOT) {
/*
* We need to check what the partition is configured to.
* 1 and 2 match up to boot0 / boot1 and 7 is user data
* which is the first physical partition (0).
*/
int part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
if (part == 7)
part = 0;
if (mmc_switch_part(0, part)) {
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
puts("MMC partition switch failed\n");
#endif
hang();
}
#ifdef CONFIG_SPL_OS_BOOT
if (spl_start_uboot() || mmc_load_image_raw_os(mmc))
#endif
err = mmc_load_image_raw(mmc,
CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
#endif
} else {
#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
puts("spl: wrong MMC boot mode\n");
#endif
hang();
}
if (err)
hang();
}