1 /* 2 * (C) Copyright 2010 3 * Texas Instruments, <www.ti.com> 4 * 5 * Aneesh V <aneesh@ti.com> 6 * 7 * SPDX-License-Identifier: GPL-2.0+ 8 */ 9 #include <common.h> 10 #include <spl.h> 11 #include <asm/u-boot.h> 12 #include <mmc.h> 13 #include <version.h> 14 #include <image.h> 15 16 DECLARE_GLOBAL_DATA_PTR; 17 18 static int mmc_load_image_raw(struct mmc *mmc, unsigned long sector) 19 { 20 unsigned long err; 21 u32 image_size_sectors; 22 struct image_header *header; 23 24 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 25 sizeof(struct image_header)); 26 27 /* read image header to find the image size & load address */ 28 err = mmc->block_dev.block_read(0, sector, 1, header); 29 if (err == 0) 30 goto end; 31 32 if (image_get_magic(header) != IH_MAGIC) 33 return -1; 34 35 spl_parse_image_header(header); 36 37 /* convert size to sectors - round up */ 38 image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / 39 mmc->read_bl_len; 40 41 /* Read the header too to avoid extra memcpy */ 42 err = mmc->block_dev.block_read(0, sector, image_size_sectors, 43 (void *)spl_image.load_addr); 44 45 end: 46 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 47 if (err == 0) 48 printf("spl: mmc blk read err - %lu\n", err); 49 #endif 50 51 return (err == 0); 52 } 53 54 #ifdef CONFIG_SPL_OS_BOOT 55 static int mmc_load_image_raw_os(struct mmc *mmc) 56 { 57 if (!mmc->block_dev.block_read(0, 58 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, 59 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, 60 (void *)CONFIG_SYS_SPL_ARGS_ADDR)) { 61 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 62 printf("mmc args blk read error\n"); 63 #endif 64 return -1; 65 } 66 67 return mmc_load_image_raw(mmc, CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR); 68 } 69 #endif 70 71 void spl_mmc_load_image(void) 72 { 73 struct mmc *mmc; 74 int err; 75 u32 boot_mode; 76 77 mmc_initialize(gd->bd); 78 /* We register only one device. So, the dev id is always 0 */ 79 mmc = find_mmc_device(0); 80 if (!mmc) { 81 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 82 puts("spl: mmc device not found!!\n"); 83 #endif 84 hang(); 85 } 86 87 err = mmc_init(mmc); 88 if (err) { 89 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 90 printf("spl: mmc init failed: err - %d\n", err); 91 #endif 92 hang(); 93 } 94 95 boot_mode = spl_boot_mode(); 96 if (boot_mode == MMCSD_MODE_RAW) { 97 debug("boot mode - RAW\n"); 98 #ifdef CONFIG_SPL_OS_BOOT 99 if (spl_start_uboot() || mmc_load_image_raw_os(mmc)) 100 #endif 101 err = mmc_load_image_raw(mmc, 102 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 103 #if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) 104 } else if (boot_mode == MMCSD_MODE_FS) { 105 debug("boot mode - FS\n"); 106 #ifdef CONFIG_SPL_FAT_SUPPORT 107 #ifdef CONFIG_SPL_OS_BOOT 108 if (spl_start_uboot() || spl_load_image_fat_os(&mmc->block_dev, 109 CONFIG_SYS_MMC_SD_FS_BOOT_PARTITION)) 110 #endif 111 err = spl_load_image_fat(&mmc->block_dev, 112 CONFIG_SYS_MMC_SD_FS_BOOT_PARTITION, 113 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); 114 if(err) 115 #endif /* CONFIG_SPL_FAT_SUPPORT */ 116 { 117 #ifdef CONFIG_SPL_EXT_SUPPORT 118 #ifdef CONFIG_SPL_OS_BOOT 119 if (spl_start_uboot() || spl_load_image_ext_os(&mmc->block_dev, 120 CONFIG_SYS_MMC_SD_FS_BOOT_PARTITION)) 121 #endif 122 err = spl_load_image_ext(&mmc->block_dev, 123 CONFIG_SYS_MMC_SD_FS_BOOT_PARTITION, 124 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); 125 #endif /* CONFIG_SPL_EXT_SUPPORT */ 126 } 127 #endif /* defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) */ 128 #ifdef CONFIG_SUPPORT_EMMC_BOOT 129 } else if (boot_mode == MMCSD_MODE_EMMCBOOT) { 130 /* 131 * We need to check what the partition is configured to. 132 * 1 and 2 match up to boot0 / boot1 and 7 is user data 133 * which is the first physical partition (0). 134 */ 135 int part = (mmc->part_config >> 3) & PART_ACCESS_MASK; 136 137 if (part == 7) 138 part = 0; 139 140 if (mmc_switch_part(0, part)) { 141 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 142 puts("MMC partition switch failed\n"); 143 #endif 144 hang(); 145 } 146 #ifdef CONFIG_SPL_OS_BOOT 147 if (spl_start_uboot() || mmc_load_image_raw_os(mmc)) 148 #endif 149 err = mmc_load_image_raw(mmc, 150 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 151 #endif 152 } else { 153 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 154 puts("spl: wrong MMC boot mode\n"); 155 #endif 156 hang(); 157 } 158 159 if (err) 160 hang(); 161 } 162