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