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 <dm.h> 11 #include <spl.h> 12 #include <linux/compiler.h> 13 #include <errno.h> 14 #include <asm/u-boot.h> 15 #include <errno.h> 16 #include <mmc.h> 17 #include <image.h> 18 19 DECLARE_GLOBAL_DATA_PTR; 20 21 static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector) 22 { 23 unsigned long count; 24 u32 image_size_sectors; 25 struct image_header *header; 26 int dev_num = mmc->block_dev.dev; 27 28 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 29 sizeof(struct image_header)); 30 31 /* read image header to find the image size & load address */ 32 count = mmc->block_dev.block_read(dev_num, sector, 1, header); 33 debug("read sector %lx, count=%lu\n", sector, count); 34 if (count == 0) 35 goto end; 36 37 if (image_get_magic(header) != IH_MAGIC) { 38 puts("bad magic\n"); 39 return -1; 40 } 41 42 spl_parse_image_header(header); 43 44 /* convert size to sectors - round up */ 45 image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / 46 mmc->read_bl_len; 47 48 /* Read the header too to avoid extra memcpy */ 49 count = mmc->block_dev.block_read(dev_num, sector, image_size_sectors, 50 (void *)(ulong)spl_image.load_addr); 51 debug("read %x sectors to %x\n", image_size_sectors, 52 spl_image.load_addr); 53 54 end: 55 if (count == 0) { 56 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 57 puts("spl: mmc block read error\n"); 58 #endif 59 return -1; 60 } 61 62 return 0; 63 } 64 65 int spl_mmc_get_device_index(u32 boot_device) 66 { 67 switch (boot_device) { 68 case BOOT_DEVICE_MMC1: 69 return 0; 70 case BOOT_DEVICE_MMC2: 71 case BOOT_DEVICE_MMC2_2: 72 return 1; 73 } 74 75 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 76 printf("spl: unsupported mmc boot device.\n"); 77 #endif 78 79 return -ENODEV; 80 } 81 82 static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device) 83 { 84 #ifdef CONFIG_DM_MMC 85 struct udevice *dev; 86 #endif 87 int err, mmc_dev; 88 89 mmc_dev = spl_mmc_get_device_index(boot_device); 90 if (mmc_dev < 0) 91 return mmc_dev; 92 93 err = mmc_initialize(NULL); 94 if (err) { 95 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 96 printf("spl: could not initialize mmc. error: %d\n", err); 97 #endif 98 return err; 99 } 100 101 #ifdef CONFIG_DM_MMC 102 err = uclass_get_device(UCLASS_MMC, mmc_dev, &dev); 103 if (!err) 104 *mmcp = mmc_get_mmc_dev(dev); 105 #else 106 *mmcp = find_mmc_device(mmc_dev); 107 err = *mmcp ? 0 : -ENODEV; 108 #endif 109 if (err) { 110 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 111 printf("spl: could not find mmc device. error: %d\n", err); 112 #endif 113 return err; 114 } 115 116 return 0; 117 } 118 119 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION 120 static int mmc_load_image_raw_partition(struct mmc *mmc, int partition) 121 { 122 disk_partition_t info; 123 int err; 124 125 err = get_partition_info(&mmc->block_dev, partition, &info); 126 if (err) { 127 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 128 puts("spl: partition error\n"); 129 #endif 130 return -1; 131 } 132 133 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR 134 return mmc_load_image_raw_sector(mmc, info.start + 135 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 136 #else 137 return mmc_load_image_raw_sector(mmc, info.start); 138 #endif 139 } 140 #else 141 #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION -1 142 static int mmc_load_image_raw_partition(struct mmc *mmc, int partition) 143 { 144 return -ENOSYS; 145 } 146 #endif 147 148 #ifdef CONFIG_SPL_OS_BOOT 149 static int mmc_load_image_raw_os(struct mmc *mmc) 150 { 151 unsigned long count; 152 153 count = mmc->block_dev.block_read( 154 mmc->block_dev.dev, 155 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, 156 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, 157 (void *) CONFIG_SYS_SPL_ARGS_ADDR); 158 if (count == 0) { 159 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 160 puts("spl: mmc block read error\n"); 161 #endif 162 return -1; 163 } 164 165 return mmc_load_image_raw_sector(mmc, 166 CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR); 167 } 168 #else 169 int spl_start_uboot(void) 170 { 171 return 1; 172 } 173 static int mmc_load_image_raw_os(struct mmc *mmc) 174 { 175 return -ENOSYS; 176 } 177 #endif 178 179 #ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 180 int spl_mmc_do_fs_boot(struct mmc *mmc) 181 { 182 int err = -ENOSYS; 183 184 #ifdef CONFIG_SPL_FAT_SUPPORT 185 if (!spl_start_uboot()) { 186 err = spl_load_image_fat_os(&mmc->block_dev, 187 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION); 188 if (!err) 189 return err; 190 } 191 #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME 192 err = spl_load_image_fat(&mmc->block_dev, 193 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, 194 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); 195 if (!err) 196 return err; 197 #endif 198 #endif 199 #ifdef CONFIG_SPL_EXT_SUPPORT 200 if (!spl_start_uboot()) { 201 err = spl_load_image_ext_os(&mmc->block_dev, 202 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION); 203 if (!err) 204 return err; 205 } 206 #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME 207 err = spl_load_image_ext(&mmc->block_dev, 208 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, 209 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); 210 if (!err) 211 return err; 212 #endif 213 #endif 214 215 #if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) 216 err = -ENOENT; 217 #endif 218 219 return err; 220 } 221 #else 222 int spl_mmc_do_fs_boot(struct mmc *mmc) 223 { 224 return -ENOSYS; 225 } 226 #endif 227 228 int spl_mmc_load_image(u32 boot_device) 229 { 230 struct mmc *mmc = NULL; 231 u32 boot_mode; 232 int err = 0; 233 __maybe_unused int part; 234 235 err = spl_mmc_find_device(&mmc, boot_device); 236 if (err) 237 return err; 238 239 err = mmc_init(mmc); 240 if (err) { 241 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 242 printf("spl: mmc init failed with error: %d\n", err); 243 #endif 244 return err; 245 } 246 247 boot_mode = spl_boot_mode(); 248 err = -EINVAL; 249 switch (boot_mode) { 250 case MMCSD_MODE_EMMCBOOT: 251 /* 252 * We need to check what the partition is configured to. 253 * 1 and 2 match up to boot0 / boot1 and 7 is user data 254 * which is the first physical partition (0). 255 */ 256 part = (mmc->part_config >> 3) & PART_ACCESS_MASK; 257 258 if (part == 7) 259 part = 0; 260 261 err = mmc_switch_part(0, part); 262 if (err) { 263 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 264 puts("spl: mmc partition switch failed\n"); 265 #endif 266 return err; 267 } 268 /* Fall through */ 269 case MMCSD_MODE_RAW: 270 debug("spl: mmc boot mode: raw\n"); 271 272 if (!spl_start_uboot()) { 273 err = mmc_load_image_raw_os(mmc); 274 if (!err) 275 return err; 276 } 277 278 err = mmc_load_image_raw_partition(mmc, 279 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION); 280 if (!err) 281 return err; 282 #if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR) 283 err = mmc_load_image_raw_sector(mmc, 284 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 285 if (!err) 286 return err; 287 #endif 288 break; 289 case MMCSD_MODE_FS: 290 debug("spl: mmc boot mode: fs\n"); 291 292 err = spl_mmc_do_fs_boot(mmc); 293 if (!err) 294 return err; 295 296 break; 297 case MMCSD_MODE_UNDEFINED: 298 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 299 default: 300 puts("spl: mmc: wrong boot mode\n"); 301 #endif 302 } 303 304 return err; 305 } 306