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 <asm/u-boot.h> 12 #include <mmc.h> 13 #include <version.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 blk read err - %lu\n", err); 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 if (!mmc->block_dev.block_read(0, 74 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, 75 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, 76 (void *)CONFIG_SYS_SPL_ARGS_ADDR)) { 77 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 78 printf("mmc args blk read error\n"); 79 #endif 80 return -1; 81 } 82 83 return mmc_load_image_raw_sector(mmc, 84 CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR); 85 } 86 #endif 87 88 void spl_mmc_load_image(void) 89 { 90 struct mmc *mmc; 91 int err; 92 u32 boot_mode; 93 94 mmc_initialize(gd->bd); 95 /* We register only one device. So, the dev id is always 0 */ 96 mmc = find_mmc_device(0); 97 if (!mmc) { 98 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 99 puts("spl: mmc device not found!!\n"); 100 #endif 101 hang(); 102 } 103 104 err = mmc_init(mmc); 105 if (err) { 106 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 107 printf("spl: mmc init failed: err - %d\n", err); 108 #endif 109 hang(); 110 } 111 112 boot_mode = spl_boot_mode(); 113 if (boot_mode == MMCSD_MODE_RAW) { 114 debug("boot mode - RAW\n"); 115 #ifdef CONFIG_SPL_OS_BOOT 116 if (spl_start_uboot() || mmc_load_image_raw_os(mmc)) 117 #endif 118 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION 119 err = mmc_load_image_raw_partition(mmc, 120 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION); 121 #else 122 err = mmc_load_image_raw_sector(mmc, 123 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 124 #endif 125 #if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) 126 } 127 if (err || boot_mode == MMCSD_MODE_FS) { 128 debug("boot mode - FS\n"); 129 #ifdef CONFIG_SPL_FAT_SUPPORT 130 #ifdef CONFIG_SPL_OS_BOOT 131 if (spl_start_uboot() || spl_load_image_fat_os(&mmc->block_dev, 132 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION)) 133 #endif 134 err = spl_load_image_fat(&mmc->block_dev, 135 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, 136 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); 137 if(err) 138 #endif /* CONFIG_SPL_FAT_SUPPORT */ 139 { 140 #ifdef CONFIG_SPL_EXT_SUPPORT 141 #ifdef CONFIG_SPL_OS_BOOT 142 if (spl_start_uboot() || spl_load_image_ext_os(&mmc->block_dev, 143 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION)) 144 #endif 145 err = spl_load_image_ext(&mmc->block_dev, 146 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, 147 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); 148 #endif /* CONFIG_SPL_EXT_SUPPORT */ 149 } 150 #endif /* defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) */ 151 #ifdef CONFIG_SUPPORT_EMMC_BOOT 152 } else if (boot_mode == MMCSD_MODE_EMMCBOOT) { 153 /* 154 * We need to check what the partition is configured to. 155 * 1 and 2 match up to boot0 / boot1 and 7 is user data 156 * which is the first physical partition (0). 157 */ 158 int part = (mmc->part_config >> 3) & PART_ACCESS_MASK; 159 160 if (part == 7) 161 part = 0; 162 163 if (mmc_switch_part(0, part)) { 164 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 165 puts("MMC partition switch failed\n"); 166 #endif 167 hang(); 168 } 169 #ifdef CONFIG_SPL_OS_BOOT 170 if (spl_start_uboot() || mmc_load_image_raw_os(mmc)) 171 #endif 172 err = mmc_load_image_raw_sector(mmc, 173 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 174 #endif 175 } 176 177 switch(boot_mode){ 178 case MMCSD_MODE_RAW: 179 #if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) 180 case MMCSD_MODE_FS: 181 #endif 182 #ifdef CONFIG_SUPPORT_EMMC_BOOT 183 case MMCSD_MODE_EMMCBOOT: 184 #endif 185 /* Boot mode is ok. Nothing to do. */ 186 break; 187 case MMCSD_MODE_UNDEFINED: 188 default: 189 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 190 puts("spl: wrong MMC boot mode\n"); 191 #endif 192 hang(); 193 } 194 195 if (err) 196 hang(); 197 } 198