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 <linux/compiler.h> 12 #include <asm/u-boot.h> 13 #include <mmc.h> 14 #include <image.h> 15 16 DECLARE_GLOBAL_DATA_PTR; 17 18 static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector) 19 { 20 unsigned long count; 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 count = mmc->block_dev.block_read(0, sector, 1, header); 29 if (count == 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 count = 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 (count == 0) 48 printf("spl: mmc block read error\n"); 49 #endif 50 51 if (count == 0) 52 return -1; 53 54 return 0; 55 } 56 57 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION 58 static int mmc_load_image_raw_partition(struct mmc *mmc, int partition) 59 { 60 disk_partition_t info; 61 int err; 62 63 err = get_partition_info(&mmc->block_dev, partition, &info); 64 if (err) { 65 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 66 printf("spl: partition error\n"); 67 #endif 68 return -1; 69 } 70 71 return mmc_load_image_raw_sector(mmc, info.start); 72 } 73 #endif 74 75 #ifdef CONFIG_SPL_OS_BOOT 76 static int mmc_load_image_raw_os(struct mmc *mmc) 77 { 78 unsigned long count; 79 80 count = mmc->block_dev.block_read(0, 81 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, 82 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, 83 (void *) CONFIG_SYS_SPL_ARGS_ADDR); 84 if (count == 0) { 85 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 86 printf("spl: mmc block read error\n"); 87 #endif 88 return -1; 89 } 90 91 return mmc_load_image_raw_sector(mmc, 92 CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR); 93 } 94 #endif 95 96 void spl_mmc_load_image(void) 97 { 98 struct mmc *mmc; 99 u32 boot_mode; 100 int err; 101 __maybe_unused int part; 102 103 mmc_initialize(gd->bd); 104 105 /* We register only one device. So, the dev id is always 0 */ 106 mmc = find_mmc_device(0); 107 if (!mmc) { 108 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 109 puts("spl: mmc device not found\n"); 110 #endif 111 hang(); 112 } 113 114 err = mmc_init(mmc); 115 if (err) { 116 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 117 printf("spl: mmc init failed with error: %d\n", err); 118 #endif 119 hang(); 120 } 121 122 boot_mode = spl_boot_mode(); 123 switch (boot_mode) { 124 case MMCSD_MODE_RAW: 125 debug("spl: mmc boot mode: raw\n"); 126 127 #ifdef CONFIG_SPL_OS_BOOT 128 if (!spl_start_uboot()) { 129 err = mmc_load_image_raw_os(mmc); 130 if (!err) 131 return; 132 } 133 #endif 134 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION 135 err = mmc_load_image_raw_partition(mmc, 136 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION); 137 #else 138 err = mmc_load_image_raw_sector(mmc, 139 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 140 #endif 141 if (!err) 142 return; 143 #if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) 144 case MMCSD_MODE_FS: 145 debug("spl: mmc boot mode: fs\n"); 146 147 #ifdef CONFIG_SPL_FAT_SUPPORT 148 #ifdef CONFIG_SPL_OS_BOOT 149 if (!spl_start_uboot()) { 150 err = spl_load_image_fat_os(&mmc->block_dev, 151 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION); 152 if (!err) 153 return; 154 } 155 #endif 156 err = spl_load_image_fat(&mmc->block_dev, 157 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, 158 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); 159 if (!err) 160 return; 161 #endif 162 #ifdef CONFIG_SPL_EXT_SUPPORT 163 #ifdef CONFIG_SPL_OS_BOOT 164 if (!spl_start_uboot()) { 165 err = spl_load_image_ext_os(&mmc->block_dev, 166 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION); 167 if (!err) 168 return; 169 } 170 #endif 171 err = spl_load_image_ext(&mmc->block_dev, 172 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, 173 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); 174 if (!err) 175 return; 176 #endif 177 #endif 178 #ifdef CONFIG_SUPPORT_EMMC_BOOT 179 case MMCSD_MODE_EMMCBOOT: 180 /* 181 * We need to check what the partition is configured to. 182 * 1 and 2 match up to boot0 / boot1 and 7 is user data 183 * which is the first physical partition (0). 184 */ 185 part = (mmc->part_config >> 3) & PART_ACCESS_MASK; 186 187 if (part == 7) 188 part = 0; 189 190 if (mmc_switch_part(0, part)) { 191 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 192 puts("spl: mmc partition switch failed\n"); 193 #endif 194 hang(); 195 } 196 197 #ifdef CONFIG_SPL_OS_BOOT 198 if (!spl_start_uboot()) { 199 err = mmc_load_image_raw_os(mmc); 200 if (!err) 201 return; 202 } 203 #endif 204 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION 205 err = mmc_load_image_raw_partition(mmc, 206 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION); 207 #else 208 err = mmc_load_image_raw_sector(mmc, 209 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 210 #endif 211 if (!err) 212 return; 213 #endif 214 case MMCSD_MODE_UNDEFINED: 215 default: 216 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 217 if (err) 218 puts("spl: mmc: no boot mode left to try\n"); 219 else 220 puts("spl: mmc: wrong boot mode\n"); 221 #endif 222 hang(); 223 } 224 } 225