1ade8a1a6SYing Zhang /* 2ade8a1a6SYing Zhang * (C) Copyright 2010 3ade8a1a6SYing Zhang * Texas Instruments, <www.ti.com> 4ade8a1a6SYing Zhang * 5ade8a1a6SYing Zhang * Aneesh V <aneesh@ti.com> 6ade8a1a6SYing Zhang * 71a459660SWolfgang Denk * SPDX-License-Identifier: GPL-2.0+ 8ade8a1a6SYing Zhang */ 9ade8a1a6SYing Zhang #include <common.h> 10ade8a1a6SYing Zhang #include <spl.h> 11ade8a1a6SYing Zhang #include <asm/u-boot.h> 12ade8a1a6SYing Zhang #include <mmc.h> 13ade8a1a6SYing Zhang #include <version.h> 14e4c444b3STom Rini #include <image.h> 15ade8a1a6SYing Zhang 16ade8a1a6SYing Zhang DECLARE_GLOBAL_DATA_PTR; 17ade8a1a6SYing Zhang 18721931f8SPeter Korsgaard static int mmc_load_image_raw(struct mmc *mmc, unsigned long sector) 19ade8a1a6SYing Zhang { 20ade8a1a6SYing Zhang unsigned long err; 21ade8a1a6SYing Zhang u32 image_size_sectors; 22ade8a1a6SYing Zhang struct image_header *header; 23ade8a1a6SYing Zhang 24ade8a1a6SYing Zhang header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 25ade8a1a6SYing Zhang sizeof(struct image_header)); 26ade8a1a6SYing Zhang 27ade8a1a6SYing Zhang /* read image header to find the image size & load address */ 28721931f8SPeter Korsgaard err = mmc->block_dev.block_read(0, sector, 1, header); 29ade8a1a6SYing Zhang if (err == 0) 30ade8a1a6SYing Zhang goto end; 31ade8a1a6SYing Zhang 32e4c444b3STom Rini if (image_get_magic(header) != IH_MAGIC) 33e4c444b3STom Rini return -1; 34e4c444b3STom Rini 35ade8a1a6SYing Zhang spl_parse_image_header(header); 36ade8a1a6SYing Zhang 37ade8a1a6SYing Zhang /* convert size to sectors - round up */ 38ade8a1a6SYing Zhang image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / 39ade8a1a6SYing Zhang mmc->read_bl_len; 40ade8a1a6SYing Zhang 41ade8a1a6SYing Zhang /* Read the header too to avoid extra memcpy */ 42721931f8SPeter Korsgaard err = mmc->block_dev.block_read(0, sector, image_size_sectors, 43721931f8SPeter Korsgaard (void *)spl_image.load_addr); 44ade8a1a6SYing Zhang 45ade8a1a6SYing Zhang end: 468112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 4779adb7a2SPeter Korsgaard if (err == 0) 48ade8a1a6SYing Zhang printf("spl: mmc blk read err - %lu\n", err); 498112f5faSPaul Burton #endif 5079adb7a2SPeter Korsgaard 5179adb7a2SPeter Korsgaard return (err == 0); 52ade8a1a6SYing Zhang } 53ade8a1a6SYing Zhang 542b75b0adSPeter Korsgaard #ifdef CONFIG_SPL_OS_BOOT 552b75b0adSPeter Korsgaard static int mmc_load_image_raw_os(struct mmc *mmc) 562b75b0adSPeter Korsgaard { 572b75b0adSPeter Korsgaard if (!mmc->block_dev.block_read(0, 582b75b0adSPeter Korsgaard CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, 592b75b0adSPeter Korsgaard CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, 602b75b0adSPeter Korsgaard (void *)CONFIG_SYS_SPL_ARGS_ADDR)) { 618112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 622b75b0adSPeter Korsgaard printf("mmc args blk read error\n"); 638112f5faSPaul Burton #endif 642b75b0adSPeter Korsgaard return -1; 652b75b0adSPeter Korsgaard } 662b75b0adSPeter Korsgaard 672b75b0adSPeter Korsgaard return mmc_load_image_raw(mmc, CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR); 682b75b0adSPeter Korsgaard } 692b75b0adSPeter Korsgaard #endif 702b75b0adSPeter Korsgaard 71ade8a1a6SYing Zhang void spl_mmc_load_image(void) 72ade8a1a6SYing Zhang { 73ade8a1a6SYing Zhang struct mmc *mmc; 74ade8a1a6SYing Zhang int err; 75ade8a1a6SYing Zhang u32 boot_mode; 76ade8a1a6SYing Zhang 77ade8a1a6SYing Zhang mmc_initialize(gd->bd); 78ade8a1a6SYing Zhang /* We register only one device. So, the dev id is always 0 */ 79ade8a1a6SYing Zhang mmc = find_mmc_device(0); 80ade8a1a6SYing Zhang if (!mmc) { 818112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 82ade8a1a6SYing Zhang puts("spl: mmc device not found!!\n"); 838112f5faSPaul Burton #endif 84ade8a1a6SYing Zhang hang(); 85ade8a1a6SYing Zhang } 86ade8a1a6SYing Zhang 87ade8a1a6SYing Zhang err = mmc_init(mmc); 88ade8a1a6SYing Zhang if (err) { 898112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 90ade8a1a6SYing Zhang printf("spl: mmc init failed: err - %d\n", err); 918112f5faSPaul Burton #endif 92ade8a1a6SYing Zhang hang(); 93ade8a1a6SYing Zhang } 9479adb7a2SPeter Korsgaard 95ade8a1a6SYing Zhang boot_mode = spl_boot_mode(); 96ade8a1a6SYing Zhang if (boot_mode == MMCSD_MODE_RAW) { 97ade8a1a6SYing Zhang debug("boot mode - RAW\n"); 982b75b0adSPeter Korsgaard #ifdef CONFIG_SPL_OS_BOOT 992b75b0adSPeter Korsgaard if (spl_start_uboot() || mmc_load_image_raw_os(mmc)) 1002b75b0adSPeter Korsgaard #endif 101721931f8SPeter Korsgaard err = mmc_load_image_raw(mmc, 102721931f8SPeter Korsgaard CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 103ade8a1a6SYing Zhang #ifdef CONFIG_SPL_FAT_SUPPORT 104*205b4f33SGuillaume GARDET } else if (boot_mode == MMCSD_MODE_FS) { 105ade8a1a6SYing Zhang debug("boot mode - FAT\n"); 1067ad2cc79SPeter Korsgaard #ifdef CONFIG_SPL_OS_BOOT 107773b5940SDan Murphy if (spl_start_uboot() || spl_load_image_fat_os(&mmc->block_dev, 108*205b4f33SGuillaume GARDET CONFIG_SYS_MMC_SD_FS_BOOT_PARTITION)) 1097ad2cc79SPeter Korsgaard #endif 110773b5940SDan Murphy err = spl_load_image_fat(&mmc->block_dev, 111*205b4f33SGuillaume GARDET CONFIG_SYS_MMC_SD_FS_BOOT_PARTITION, 112*205b4f33SGuillaume GARDET CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); 113ade8a1a6SYing Zhang #endif 1147dbe63bcSTom Rini #ifdef CONFIG_SUPPORT_EMMC_BOOT 1157dbe63bcSTom Rini } else if (boot_mode == MMCSD_MODE_EMMCBOOT) { 1167dbe63bcSTom Rini /* 1177dbe63bcSTom Rini * We need to check what the partition is configured to. 1187dbe63bcSTom Rini * 1 and 2 match up to boot0 / boot1 and 7 is user data 1197dbe63bcSTom Rini * which is the first physical partition (0). 1207dbe63bcSTom Rini */ 1217dbe63bcSTom Rini int part = (mmc->part_config >> 3) & PART_ACCESS_MASK; 1227dbe63bcSTom Rini 1237dbe63bcSTom Rini if (part == 7) 1247dbe63bcSTom Rini part = 0; 1257dbe63bcSTom Rini 1267dbe63bcSTom Rini if (mmc_switch_part(0, part)) { 1277dbe63bcSTom Rini #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 1287dbe63bcSTom Rini puts("MMC partition switch failed\n"); 1297dbe63bcSTom Rini #endif 1307dbe63bcSTom Rini hang(); 1317dbe63bcSTom Rini } 1327dbe63bcSTom Rini #ifdef CONFIG_SPL_OS_BOOT 1337dbe63bcSTom Rini if (spl_start_uboot() || mmc_load_image_raw_os(mmc)) 1347dbe63bcSTom Rini #endif 1357dbe63bcSTom Rini err = mmc_load_image_raw(mmc, 1367dbe63bcSTom Rini CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 1377dbe63bcSTom Rini #endif 138ade8a1a6SYing Zhang } else { 1398112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 140ade8a1a6SYing Zhang puts("spl: wrong MMC boot mode\n"); 1418112f5faSPaul Burton #endif 142ade8a1a6SYing Zhang hang(); 143ade8a1a6SYing Zhang } 14479adb7a2SPeter Korsgaard 14579adb7a2SPeter Korsgaard if (err) 14679adb7a2SPeter Korsgaard hang(); 147ade8a1a6SYing Zhang } 148