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 27 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 28 sizeof(struct image_header)); 29 30 /* read image header to find the image size & load address */ 31 count = mmc->block_dev.block_read(&mmc->block_dev, sector, 1, header); 32 debug("read sector %lx, count=%lu\n", sector, count); 33 if (count == 0) 34 goto end; 35 36 if (image_get_magic(header) != IH_MAGIC) { 37 puts("bad magic\n"); 38 return -1; 39 } 40 41 spl_parse_image_header(header); 42 43 /* convert size to sectors - round up */ 44 image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / 45 mmc->read_bl_len; 46 47 /* Read the header too to avoid extra memcpy */ 48 count = mmc->block_dev.block_read(&mmc->block_dev, sector, 49 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(&mmc->block_dev, 154 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, 155 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, 156 (void *) CONFIG_SYS_SPL_ARGS_ADDR); 157 if (count == 0) { 158 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 159 puts("spl: mmc block read error\n"); 160 #endif 161 return -1; 162 } 163 164 return mmc_load_image_raw_sector(mmc, 165 CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR); 166 } 167 #else 168 int spl_start_uboot(void) 169 { 170 return 1; 171 } 172 static int mmc_load_image_raw_os(struct mmc *mmc) 173 { 174 return -ENOSYS; 175 } 176 #endif 177 178 #ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION 179 int spl_mmc_do_fs_boot(struct mmc *mmc) 180 { 181 int err = -ENOSYS; 182 183 #ifdef CONFIG_SPL_FAT_SUPPORT 184 if (!spl_start_uboot()) { 185 err = spl_load_image_fat_os(&mmc->block_dev, 186 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION); 187 if (!err) 188 return err; 189 } 190 #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME 191 err = spl_load_image_fat(&mmc->block_dev, 192 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, 193 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); 194 if (!err) 195 return err; 196 #endif 197 #endif 198 #ifdef CONFIG_SPL_EXT_SUPPORT 199 if (!spl_start_uboot()) { 200 err = spl_load_image_ext_os(&mmc->block_dev, 201 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION); 202 if (!err) 203 return err; 204 } 205 #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME 206 err = spl_load_image_ext(&mmc->block_dev, 207 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, 208 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); 209 if (!err) 210 return err; 211 #endif 212 #endif 213 214 #if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) 215 err = -ENOENT; 216 #endif 217 218 return err; 219 } 220 #else 221 int spl_mmc_do_fs_boot(struct mmc *mmc) 222 { 223 return -ENOSYS; 224 } 225 #endif 226 227 int spl_mmc_load_image(u32 boot_device) 228 { 229 struct mmc *mmc = NULL; 230 u32 boot_mode; 231 int err = 0; 232 __maybe_unused int part; 233 234 err = spl_mmc_find_device(&mmc, boot_device); 235 if (err) 236 return err; 237 238 err = mmc_init(mmc); 239 if (err) { 240 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 241 printf("spl: mmc init failed with error: %d\n", err); 242 #endif 243 return err; 244 } 245 246 boot_mode = spl_boot_mode(); 247 err = -EINVAL; 248 switch (boot_mode) { 249 case MMCSD_MODE_EMMCBOOT: 250 /* 251 * We need to check what the partition is configured to. 252 * 1 and 2 match up to boot0 / boot1 and 7 is user data 253 * which is the first physical partition (0). 254 */ 255 part = (mmc->part_config >> 3) & PART_ACCESS_MASK; 256 257 if (part == 7) 258 part = 0; 259 260 err = mmc_switch_part(0, part); 261 if (err) { 262 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 263 puts("spl: mmc partition switch failed\n"); 264 #endif 265 return err; 266 } 267 /* Fall through */ 268 case MMCSD_MODE_RAW: 269 debug("spl: mmc boot mode: raw\n"); 270 271 if (!spl_start_uboot()) { 272 err = mmc_load_image_raw_os(mmc); 273 if (!err) 274 return err; 275 } 276 277 err = mmc_load_image_raw_partition(mmc, 278 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION); 279 if (!err) 280 return err; 281 #if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR) 282 err = mmc_load_image_raw_sector(mmc, 283 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 284 if (!err) 285 return err; 286 #endif 287 break; 288 case MMCSD_MODE_FS: 289 debug("spl: mmc boot mode: fs\n"); 290 291 err = spl_mmc_do_fs_boot(mmc); 292 if (!err) 293 return err; 294 295 break; 296 case MMCSD_MODE_UNDEFINED: 297 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 298 default: 299 puts("spl: mmc: wrong boot mode\n"); 300 #endif 301 } 302 303 return err; 304 } 305