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 <image.h> 14 15 DECLARE_GLOBAL_DATA_PTR; 16 17 static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector) 18 { 19 unsigned long err; 20 u32 image_size_sectors; 21 struct image_header *header; 22 23 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 24 sizeof(struct image_header)); 25 26 /* read image header to find the image size & load address */ 27 err = mmc->block_dev.block_read(0, sector, 1, header); 28 if (err == 0) 29 goto end; 30 31 if (image_get_magic(header) != IH_MAGIC) 32 return -1; 33 34 spl_parse_image_header(header); 35 36 /* convert size to sectors - round up */ 37 image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / 38 mmc->read_bl_len; 39 40 /* Read the header too to avoid extra memcpy */ 41 err = mmc->block_dev.block_read(0, sector, image_size_sectors, 42 (void *)spl_image.load_addr); 43 44 end: 45 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 46 if (err == 0) 47 printf("spl: mmc blk read err - %lu\n", err); 48 #endif 49 50 return (err == 0); 51 } 52 53 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION 54 static int mmc_load_image_raw_partition(struct mmc *mmc, int partition) 55 { 56 disk_partition_t info; 57 58 if (get_partition_info(&mmc->block_dev, partition, &info)) { 59 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 60 printf("spl: partition error\n"); 61 #endif 62 return -1; 63 } 64 65 return mmc_load_image_raw_sector(mmc, info.start); 66 } 67 #endif 68 69 #ifdef CONFIG_SPL_OS_BOOT 70 static int mmc_load_image_raw_os(struct mmc *mmc) 71 { 72 if (!mmc->block_dev.block_read(0, 73 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, 74 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, 75 (void *)CONFIG_SYS_SPL_ARGS_ADDR)) { 76 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 77 printf("mmc args blk read error\n"); 78 #endif 79 return -1; 80 } 81 82 return mmc_load_image_raw_sector(mmc, 83 CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR); 84 } 85 #endif 86 87 void spl_mmc_load_image(void) 88 { 89 struct mmc *mmc; 90 int err; 91 u32 boot_mode; 92 93 mmc_initialize(gd->bd); 94 /* We register only one device. So, the dev id is always 0 */ 95 mmc = find_mmc_device(0); 96 if (!mmc) { 97 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 98 puts("spl: mmc device not found!!\n"); 99 #endif 100 hang(); 101 } 102 103 err = mmc_init(mmc); 104 if (err) { 105 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 106 printf("spl: mmc init failed: err - %d\n", err); 107 #endif 108 hang(); 109 } 110 111 boot_mode = spl_boot_mode(); 112 if (boot_mode == MMCSD_MODE_RAW) { 113 debug("boot mode - RAW\n"); 114 #ifdef CONFIG_SPL_OS_BOOT 115 if (spl_start_uboot() || mmc_load_image_raw_os(mmc)) 116 #endif 117 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION 118 err = mmc_load_image_raw_partition(mmc, 119 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION); 120 #else 121 err = mmc_load_image_raw_sector(mmc, 122 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 123 #endif 124 #if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) 125 } 126 if (err || boot_mode == MMCSD_MODE_FS) { 127 debug("boot mode - FS\n"); 128 #ifdef CONFIG_SPL_FAT_SUPPORT 129 #ifdef CONFIG_SPL_OS_BOOT 130 if (spl_start_uboot() || spl_load_image_fat_os(&mmc->block_dev, 131 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION)) 132 #endif 133 err = spl_load_image_fat(&mmc->block_dev, 134 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, 135 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); 136 if(err) 137 #endif /* CONFIG_SPL_FAT_SUPPORT */ 138 { 139 #ifdef CONFIG_SPL_EXT_SUPPORT 140 #ifdef CONFIG_SPL_OS_BOOT 141 if (spl_start_uboot() || spl_load_image_ext_os(&mmc->block_dev, 142 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION)) 143 #endif 144 err = spl_load_image_ext(&mmc->block_dev, 145 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION, 146 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME); 147 #endif /* CONFIG_SPL_EXT_SUPPORT */ 148 } 149 #endif /* defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) */ 150 #ifdef CONFIG_SUPPORT_EMMC_BOOT 151 } else if (boot_mode == MMCSD_MODE_EMMCBOOT) { 152 /* 153 * We need to check what the partition is configured to. 154 * 1 and 2 match up to boot0 / boot1 and 7 is user data 155 * which is the first physical partition (0). 156 */ 157 int part = (mmc->part_config >> 3) & PART_ACCESS_MASK; 158 159 if (part == 7) 160 part = 0; 161 162 if (mmc_switch_part(0, part)) { 163 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 164 puts("MMC partition switch failed\n"); 165 #endif 166 hang(); 167 } 168 #ifdef CONFIG_SPL_OS_BOOT 169 if (spl_start_uboot() || mmc_load_image_raw_os(mmc)) 170 #endif 171 err = mmc_load_image_raw_sector(mmc, 172 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 173 #endif 174 } 175 176 switch(boot_mode){ 177 case MMCSD_MODE_RAW: 178 #if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT) 179 case MMCSD_MODE_FS: 180 #endif 181 #ifdef CONFIG_SUPPORT_EMMC_BOOT 182 case MMCSD_MODE_EMMCBOOT: 183 #endif 184 /* Boot mode is ok. Nothing to do. */ 185 break; 186 case MMCSD_MODE_UNDEFINED: 187 default: 188 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT 189 puts("spl: wrong MMC boot mode\n"); 190 #endif 191 hang(); 192 } 193 194 if (err) 195 hang(); 196 } 197