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