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 <asm/utils.h> 13 #include <mmc.h> 14 #include <fat.h> 15 #include <version.h> 16 17 DECLARE_GLOBAL_DATA_PTR; 18 19 static int mmc_load_image_raw(struct mmc *mmc, unsigned long sector) 20 { 21 unsigned long err; 22 u32 image_size_sectors; 23 struct image_header *header; 24 25 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 26 sizeof(struct image_header)); 27 28 /* read image header to find the image size & load address */ 29 err = mmc->block_dev.block_read(0, sector, 1, header); 30 if (err == 0) 31 goto end; 32 33 spl_parse_image_header(header); 34 35 /* convert size to sectors - round up */ 36 image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) / 37 mmc->read_bl_len; 38 39 /* Read the header too to avoid extra memcpy */ 40 err = mmc->block_dev.block_read(0, sector, image_size_sectors, 41 (void *)spl_image.load_addr); 42 43 end: 44 if (err == 0) 45 printf("spl: mmc blk read err - %lu\n", err); 46 47 return (err == 0); 48 } 49 50 #ifdef CONFIG_SPL_OS_BOOT 51 static int mmc_load_image_raw_os(struct mmc *mmc) 52 { 53 if (!mmc->block_dev.block_read(0, 54 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR, 55 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS, 56 (void *)CONFIG_SYS_SPL_ARGS_ADDR)) { 57 printf("mmc args blk read error\n"); 58 return -1; 59 } 60 61 return mmc_load_image_raw(mmc, CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR); 62 } 63 #endif 64 65 #ifdef CONFIG_SPL_FAT_SUPPORT 66 static int mmc_load_image_fat(struct mmc *mmc, const char *filename) 67 { 68 int err; 69 struct image_header *header; 70 71 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 72 sizeof(struct image_header)); 73 74 err = file_fat_read(filename, header, sizeof(struct image_header)); 75 if (err <= 0) 76 goto end; 77 78 spl_parse_image_header(header); 79 80 err = file_fat_read(filename, (u8 *)spl_image.load_addr, 0); 81 82 end: 83 if (err <= 0) 84 printf("spl: error reading image %s, err - %d\n", 85 filename, err); 86 87 return (err <= 0); 88 } 89 90 #ifdef CONFIG_SPL_OS_BOOT 91 static int mmc_load_image_fat_os(struct mmc *mmc) 92 { 93 int err; 94 95 err = file_fat_read(CONFIG_SPL_FAT_LOAD_ARGS_NAME, 96 (void *)CONFIG_SYS_SPL_ARGS_ADDR, 0); 97 if (err <= 0) { 98 printf("spl: error reading image %s, err - %d\n", 99 CONFIG_SPL_FAT_LOAD_ARGS_NAME, err); 100 return -1; 101 } 102 103 return mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_KERNEL_NAME); 104 } 105 #endif 106 107 #endif 108 109 void spl_mmc_load_image(void) 110 { 111 struct mmc *mmc; 112 int err; 113 u32 boot_mode; 114 115 mmc_initialize(gd->bd); 116 /* We register only one device. So, the dev id is always 0 */ 117 mmc = find_mmc_device(0); 118 if (!mmc) { 119 puts("spl: mmc device not found!!\n"); 120 hang(); 121 } 122 123 err = mmc_init(mmc); 124 if (err) { 125 printf("spl: mmc init failed: err - %d\n", err); 126 hang(); 127 } 128 129 boot_mode = spl_boot_mode(); 130 if (boot_mode == MMCSD_MODE_RAW) { 131 debug("boot mode - RAW\n"); 132 #ifdef CONFIG_SPL_OS_BOOT 133 if (spl_start_uboot() || mmc_load_image_raw_os(mmc)) 134 #endif 135 err = mmc_load_image_raw(mmc, 136 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR); 137 #ifdef CONFIG_SPL_FAT_SUPPORT 138 } else if (boot_mode == MMCSD_MODE_FAT) { 139 debug("boot mode - FAT\n"); 140 141 err = fat_register_device(&mmc->block_dev, 142 CONFIG_SYS_MMC_SD_FAT_BOOT_PARTITION); 143 if (err) { 144 printf("spl: fat register err - %d\n", err); 145 hang(); 146 } 147 148 #ifdef CONFIG_SPL_OS_BOOT 149 if (spl_start_uboot() || mmc_load_image_fat_os(mmc)) 150 #endif 151 err = mmc_load_image_fat(mmc, CONFIG_SPL_FAT_LOAD_PAYLOAD_NAME); 152 #endif 153 } else { 154 puts("spl: wrong MMC boot mode\n"); 155 hang(); 156 } 157 158 if (err) 159 hang(); 160 } 161