183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2ade8a1a6SYing Zhang /*
3ade8a1a6SYing Zhang * (C) Copyright 2010
4ade8a1a6SYing Zhang * Texas Instruments, <www.ti.com>
5ade8a1a6SYing Zhang *
6ade8a1a6SYing Zhang * Aneesh V <aneesh@ti.com>
7ade8a1a6SYing Zhang */
8ade8a1a6SYing Zhang #include <common.h>
9dc3dedfeSSimon Glass #include <dm.h>
10ade8a1a6SYing Zhang #include <spl.h>
1191199f4aSPaul Kocialkowski #include <linux/compiler.h>
1236afd451SNikita Kiryanov #include <errno.h>
13ade8a1a6SYing Zhang #include <asm/u-boot.h>
144188ba32SNikita Kiryanov #include <errno.h>
15ade8a1a6SYing Zhang #include <mmc.h>
16e4c444b3STom Rini #include <image.h>
17ade8a1a6SYing Zhang
mmc_load_legacy(struct spl_image_info * spl_image,struct mmc * mmc,ulong sector,struct image_header * header)182a2ee2acSSimon Glass static int mmc_load_legacy(struct spl_image_info *spl_image, struct mmc *mmc,
192a2ee2acSSimon Glass ulong sector, struct image_header *header)
20ade8a1a6SYing Zhang {
21ade8a1a6SYing Zhang u32 image_size_sectors;
2296debd1fSSimon Glass unsigned long count;
237e0f2267SMarek Vasut int ret;
24e4c444b3STom Rini
252a2ee2acSSimon Glass ret = spl_parse_image_header(spl_image, header);
267e0f2267SMarek Vasut if (ret)
277e0f2267SMarek Vasut return ret;
287e0f2267SMarek Vasut
29ade8a1a6SYing Zhang /* convert size to sectors - round up */
302a2ee2acSSimon Glass image_size_sectors = (spl_image->size + mmc->read_bl_len - 1) /
31ade8a1a6SYing Zhang mmc->read_bl_len;
32ade8a1a6SYing Zhang
33ade8a1a6SYing Zhang /* Read the header too to avoid extra memcpy */
34ef5609c3SSimon Glass count = blk_dread(mmc_get_blk_desc(mmc), sector, image_size_sectors,
352a2ee2acSSimon Glass (void *)(ulong)spl_image->load_addr);
3611e1479bSAndre Przywara debug("read %x sectors to %lx\n", image_size_sectors,
372a2ee2acSSimon Glass spl_image->load_addr);
3896debd1fSSimon Glass if (count != image_size_sectors)
3996debd1fSSimon Glass return -EIO;
4096debd1fSSimon Glass
4196debd1fSSimon Glass return 0;
4296debd1fSSimon Glass }
4396debd1fSSimon Glass
h_spl_load_read(struct spl_load_info * load,ulong sector,ulong count,void * buf)4496debd1fSSimon Glass static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
4596debd1fSSimon Glass ulong count, void *buf)
4696debd1fSSimon Glass {
4796debd1fSSimon Glass struct mmc *mmc = load->dev;
4896debd1fSSimon Glass
49ef5609c3SSimon Glass return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf);
5096debd1fSSimon Glass }
5196debd1fSSimon Glass
52b016b585SSeung-Woo Kim static __maybe_unused
mmc_load_image_raw_sector(struct spl_image_info * spl_image,struct mmc * mmc,unsigned long sector)53b016b585SSeung-Woo Kim int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
542a2ee2acSSimon Glass struct mmc *mmc, unsigned long sector)
5596debd1fSSimon Glass {
5696debd1fSSimon Glass unsigned long count;
5796debd1fSSimon Glass struct image_header *header;
5804ce5427SMarek Vasut struct blk_desc *bd = mmc_get_blk_desc(mmc);
5996debd1fSSimon Glass int ret = 0;
6096debd1fSSimon Glass
6104ce5427SMarek Vasut header = spl_get_load_buffer(-sizeof(*header), bd->blksz);
6296debd1fSSimon Glass
6396debd1fSSimon Glass /* read image header to find the image size & load address */
6404ce5427SMarek Vasut count = blk_dread(bd, sector, 1, header);
6596debd1fSSimon Glass debug("hdr read sector %lx, count=%lu\n", sector, count);
6696debd1fSSimon Glass if (count == 0) {
6796debd1fSSimon Glass ret = -EIO;
6896debd1fSSimon Glass goto end;
6996debd1fSSimon Glass }
7096debd1fSSimon Glass
714976f482SMasahiro Yamada if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
724976f482SMasahiro Yamada image_get_magic(header) == FDT_MAGIC) {
7396debd1fSSimon Glass struct spl_load_info load;
7496debd1fSSimon Glass
7596debd1fSSimon Glass debug("Found FIT\n");
7696debd1fSSimon Glass load.dev = mmc;
7796debd1fSSimon Glass load.priv = NULL;
78eafd5410SLokesh Vutla load.filename = NULL;
7996debd1fSSimon Glass load.bl_len = mmc->read_bl_len;
8096debd1fSSimon Glass load.read = h_spl_load_read;
81f4d7d859SSimon Glass ret = spl_load_simple_fit(spl_image, &load, sector, header);
824976f482SMasahiro Yamada } else {
832a2ee2acSSimon Glass ret = mmc_load_legacy(spl_image, mmc, sector, header);
8496debd1fSSimon Glass }
85ade8a1a6SYing Zhang
86ade8a1a6SYing Zhang end:
8796debd1fSSimon Glass if (ret) {
888112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
895bbf4099SFabio Estevam puts("mmc_load_image_raw_sector: mmc block read error\n");
908112f5faSPaul Burton #endif
913bc37b6dSPaul Kocialkowski return -1;
921ec26469SPaul Kocialkowski }
933bc37b6dSPaul Kocialkowski
943bc37b6dSPaul Kocialkowski return 0;
95ade8a1a6SYing Zhang }
96ade8a1a6SYing Zhang
spl_mmc_get_device_index(u32 boot_device)97207d8b35SMasahiro Yamada static int spl_mmc_get_device_index(u32 boot_device)
98a1e56cf6SNikita Kiryanov {
99a1e56cf6SNikita Kiryanov switch (boot_device) {
100a1e56cf6SNikita Kiryanov case BOOT_DEVICE_MMC1:
101a1e56cf6SNikita Kiryanov return 0;
102a1e56cf6SNikita Kiryanov case BOOT_DEVICE_MMC2:
103a1e56cf6SNikita Kiryanov case BOOT_DEVICE_MMC2_2:
104a1e56cf6SNikita Kiryanov return 1;
105a1e56cf6SNikita Kiryanov }
106a1e56cf6SNikita Kiryanov
107a1e56cf6SNikita Kiryanov #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
108a1e56cf6SNikita Kiryanov printf("spl: unsupported mmc boot device.\n");
109a1e56cf6SNikita Kiryanov #endif
110a1e56cf6SNikita Kiryanov
111a1e56cf6SNikita Kiryanov return -ENODEV;
112a1e56cf6SNikita Kiryanov }
113a1e56cf6SNikita Kiryanov
spl_mmc_find_device(struct mmc ** mmcp,u32 boot_device)11499c7a51aSSimon Glass static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
1154188ba32SNikita Kiryanov {
116c4d660d4SSimon Glass #if CONFIG_IS_ENABLED(DM_MMC)
1174188ba32SNikita Kiryanov struct udevice *dev;
118b4857aa9SSimon Glass #endif
119a1e56cf6SNikita Kiryanov int err, mmc_dev;
120a1e56cf6SNikita Kiryanov
121a1e56cf6SNikita Kiryanov mmc_dev = spl_mmc_get_device_index(boot_device);
122a1e56cf6SNikita Kiryanov if (mmc_dev < 0)
123a1e56cf6SNikita Kiryanov return mmc_dev;
1244188ba32SNikita Kiryanov
1254188ba32SNikita Kiryanov err = mmc_initialize(NULL);
1264188ba32SNikita Kiryanov if (err) {
1274188ba32SNikita Kiryanov #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
1284188ba32SNikita Kiryanov printf("spl: could not initialize mmc. error: %d\n", err);
1294188ba32SNikita Kiryanov #endif
1304188ba32SNikita Kiryanov return err;
1314188ba32SNikita Kiryanov }
1324188ba32SNikita Kiryanov
133c4d660d4SSimon Glass #if CONFIG_IS_ENABLED(DM_MMC)
134a1e56cf6SNikita Kiryanov err = uclass_get_device(UCLASS_MMC, mmc_dev, &dev);
135b4857aa9SSimon Glass if (!err)
136b4857aa9SSimon Glass *mmcp = mmc_get_mmc_dev(dev);
137b4857aa9SSimon Glass #else
138b4857aa9SSimon Glass *mmcp = find_mmc_device(mmc_dev);
139b4857aa9SSimon Glass err = *mmcp ? 0 : -ENODEV;
140b4857aa9SSimon Glass #endif
1414188ba32SNikita Kiryanov if (err) {
1424188ba32SNikita Kiryanov #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
143aa608b6cSAlex Kiernan printf("spl: could not find mmc device %d. error: %d\n",
144aa608b6cSAlex Kiernan mmc_dev, err);
1454188ba32SNikita Kiryanov #endif
1464188ba32SNikita Kiryanov return err;
1474188ba32SNikita Kiryanov }
1484188ba32SNikita Kiryanov
1494188ba32SNikita Kiryanov return 0;
1504188ba32SNikita Kiryanov }
1514188ba32SNikita Kiryanov
152949123e3SDalon Westergreen #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
mmc_load_image_raw_partition(struct spl_image_info * spl_image,struct mmc * mmc,int partition,unsigned long sector)1532a2ee2acSSimon Glass static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
154*65f2e689SAndreas Dannenberg struct mmc *mmc, int partition,
155*65f2e689SAndreas Dannenberg unsigned long sector)
156b97300b6SPaul Kocialkowski {
157b97300b6SPaul Kocialkowski disk_partition_t info;
1583bc37b6dSPaul Kocialkowski int err;
159b97300b6SPaul Kocialkowski
160f0fb4fa7SDalon Westergreen #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
161f0fb4fa7SDalon Westergreen int type_part;
162f0fb4fa7SDalon Westergreen /* Only support MBR so DOS_ENTRY_NUMBERS */
163f0fb4fa7SDalon Westergreen for (type_part = 1; type_part <= DOS_ENTRY_NUMBERS; type_part++) {
164f0fb4fa7SDalon Westergreen err = part_get_info(mmc_get_blk_desc(mmc), type_part, &info);
165f0fb4fa7SDalon Westergreen if (err)
166f0fb4fa7SDalon Westergreen continue;
167f0fb4fa7SDalon Westergreen if (info.sys_ind ==
168f0fb4fa7SDalon Westergreen CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE) {
169f0fb4fa7SDalon Westergreen partition = type_part;
170f0fb4fa7SDalon Westergreen break;
171f0fb4fa7SDalon Westergreen }
172f0fb4fa7SDalon Westergreen }
173f0fb4fa7SDalon Westergreen #endif
174f0fb4fa7SDalon Westergreen
1751e2b3ef8SSimon Glass err = part_get_info(mmc_get_blk_desc(mmc), partition, &info);
1763bc37b6dSPaul Kocialkowski if (err) {
177b97300b6SPaul Kocialkowski #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
1781ec26469SPaul Kocialkowski puts("spl: partition error\n");
179b97300b6SPaul Kocialkowski #endif
180b97300b6SPaul Kocialkowski return -1;
181b97300b6SPaul Kocialkowski }
182b97300b6SPaul Kocialkowski
18338fed8abSSemen Protsenko #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
184*65f2e689SAndreas Dannenberg return mmc_load_image_raw_sector(spl_image, mmc, info.start + sector);
1854bfcc54cSStefan Roese #else
1862a2ee2acSSimon Glass return mmc_load_image_raw_sector(spl_image, mmc, info.start);
1874bfcc54cSStefan Roese #endif
188b97300b6SPaul Kocialkowski }
189b97300b6SPaul Kocialkowski #endif
190b97300b6SPaul Kocialkowski
1912b75b0adSPeter Korsgaard #ifdef CONFIG_SPL_OS_BOOT
mmc_load_image_raw_os(struct spl_image_info * spl_image,struct mmc * mmc)1922a2ee2acSSimon Glass static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
1932a2ee2acSSimon Glass struct mmc *mmc)
1942b75b0adSPeter Korsgaard {
195811906aeSLokesh Vutla int ret;
19691199f4aSPaul Kocialkowski
1977267fbf7SYork Sun #if defined(CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR)
1987267fbf7SYork Sun unsigned long count;
1997267fbf7SYork Sun
20087bce4e5SSimon Glass count = blk_dread(mmc_get_blk_desc(mmc),
2012b75b0adSPeter Korsgaard CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
2022b75b0adSPeter Korsgaard CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
20391199f4aSPaul Kocialkowski (void *) CONFIG_SYS_SPL_ARGS_ADDR);
2049585dd3fSTom Rini if (count != CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS) {
2058112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
2065bbf4099SFabio Estevam puts("mmc_load_image_raw_os: mmc block read error\n");
2078112f5faSPaul Burton #endif
2082b75b0adSPeter Korsgaard return -1;
2092b75b0adSPeter Korsgaard }
2107267fbf7SYork Sun #endif /* CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR */
2112b75b0adSPeter Korsgaard
2122a2ee2acSSimon Glass ret = mmc_load_image_raw_sector(spl_image, mmc,
213b97300b6SPaul Kocialkowski CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
214811906aeSLokesh Vutla if (ret)
215811906aeSLokesh Vutla return ret;
216811906aeSLokesh Vutla
2172a2ee2acSSimon Glass if (spl_image->os != IH_OS_LINUX) {
218811906aeSLokesh Vutla puts("Expected Linux image is not found. Trying to start U-boot\n");
219811906aeSLokesh Vutla return -ENOENT;
220811906aeSLokesh Vutla }
221811906aeSLokesh Vutla
222811906aeSLokesh Vutla return 0;
2232b75b0adSPeter Korsgaard }
224339245b7SNikita Kiryanov #else
spl_start_uboot(void)225339245b7SNikita Kiryanov int spl_start_uboot(void)
226339245b7SNikita Kiryanov {
227339245b7SNikita Kiryanov return 1;
228339245b7SNikita Kiryanov }
mmc_load_image_raw_os(struct spl_image_info * spl_image,struct mmc * mmc)2292a2ee2acSSimon Glass static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
2302a2ee2acSSimon Glass struct mmc *mmc)
231339245b7SNikita Kiryanov {
232339245b7SNikita Kiryanov return -ENOSYS;
233339245b7SNikita Kiryanov }
2342b75b0adSPeter Korsgaard #endif
2352b75b0adSPeter Korsgaard
236f52b7293SNikita Kiryanov #ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION
spl_mmc_do_fs_boot(struct spl_image_info * spl_image,struct mmc * mmc,const char * filename)237*65f2e689SAndreas Dannenberg static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc,
238*65f2e689SAndreas Dannenberg const char *filename)
239f52b7293SNikita Kiryanov {
240f52b7293SNikita Kiryanov int err = -ENOSYS;
241f52b7293SNikita Kiryanov
2420c3a9ed4STien Fong Chee #ifdef CONFIG_SPL_FS_FAT
243f52b7293SNikita Kiryanov if (!spl_start_uboot()) {
244710e9ca5SSimon Glass err = spl_load_image_fat_os(spl_image, mmc_get_blk_desc(mmc),
245f52b7293SNikita Kiryanov CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
246f52b7293SNikita Kiryanov if (!err)
247f52b7293SNikita Kiryanov return err;
248f52b7293SNikita Kiryanov }
249f52b7293SNikita Kiryanov #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
250710e9ca5SSimon Glass err = spl_load_image_fat(spl_image, mmc_get_blk_desc(mmc),
251f52b7293SNikita Kiryanov CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
252*65f2e689SAndreas Dannenberg filename);
253f52b7293SNikita Kiryanov if (!err)
254f52b7293SNikita Kiryanov return err;
255f52b7293SNikita Kiryanov #endif
256f52b7293SNikita Kiryanov #endif
257f4b40924STien Fong Chee #ifdef CONFIG_SPL_FS_EXT4
258f52b7293SNikita Kiryanov if (!spl_start_uboot()) {
2591a92541dSMichal Simek err = spl_load_image_ext_os(spl_image, mmc_get_blk_desc(mmc),
260f52b7293SNikita Kiryanov CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
261f52b7293SNikita Kiryanov if (!err)
262f52b7293SNikita Kiryanov return err;
263f52b7293SNikita Kiryanov }
264f52b7293SNikita Kiryanov #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
2651a92541dSMichal Simek err = spl_load_image_ext(spl_image, mmc_get_blk_desc(mmc),
266f52b7293SNikita Kiryanov CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
267*65f2e689SAndreas Dannenberg filename);
268f52b7293SNikita Kiryanov if (!err)
269f52b7293SNikita Kiryanov return err;
270f52b7293SNikita Kiryanov #endif
271f52b7293SNikita Kiryanov #endif
272f52b7293SNikita Kiryanov
273f4b40924STien Fong Chee #if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
274f52b7293SNikita Kiryanov err = -ENOENT;
275f52b7293SNikita Kiryanov #endif
276f52b7293SNikita Kiryanov
277f52b7293SNikita Kiryanov return err;
278f52b7293SNikita Kiryanov }
279f52b7293SNikita Kiryanov #else
spl_mmc_do_fs_boot(struct spl_image_info * spl_image,struct mmc * mmc,const char * filename)280*65f2e689SAndreas Dannenberg static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc,
281*65f2e689SAndreas Dannenberg const char *filename)
282f52b7293SNikita Kiryanov {
283f52b7293SNikita Kiryanov return -ENOSYS;
284f52b7293SNikita Kiryanov }
285f52b7293SNikita Kiryanov #endif
286f52b7293SNikita Kiryanov
spl_boot_mode(const u32 boot_device)287d695d662SLukasz Majewski u32 __weak spl_boot_mode(const u32 boot_device)
288d695d662SLukasz Majewski {
289f4b40924STien Fong Chee #if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
290d695d662SLukasz Majewski return MMCSD_MODE_FS;
291d695d662SLukasz Majewski #elif defined(CONFIG_SUPPORT_EMMC_BOOT)
292d695d662SLukasz Majewski return MMCSD_MODE_EMMCBOOT;
293d695d662SLukasz Majewski #else
294d695d662SLukasz Majewski return MMCSD_MODE_RAW;
295d695d662SLukasz Majewski #endif
296d695d662SLukasz Majewski }
297d695d662SLukasz Majewski
29835a66960SPatrick Delaunay #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
29935a66960SPatrick Delaunay __weak
spl_boot_partition(const u32 boot_device)30035a66960SPatrick Delaunay int spl_boot_partition(const u32 boot_device)
30135a66960SPatrick Delaunay {
30235a66960SPatrick Delaunay return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION;
30335a66960SPatrick Delaunay }
30435a66960SPatrick Delaunay #endif
30535a66960SPatrick Delaunay
spl_mmc_load(struct spl_image_info * spl_image,struct spl_boot_device * bootdev,const char * filename,int raw_part,unsigned long raw_sect)306*65f2e689SAndreas Dannenberg int spl_mmc_load(struct spl_image_info *spl_image,
307*65f2e689SAndreas Dannenberg struct spl_boot_device *bootdev,
308*65f2e689SAndreas Dannenberg const char *filename,
309*65f2e689SAndreas Dannenberg int raw_part,
310*65f2e689SAndreas Dannenberg unsigned long raw_sect)
311ade8a1a6SYing Zhang {
312*65f2e689SAndreas Dannenberg static struct mmc *mmc;
313ade8a1a6SYing Zhang u32 boot_mode;
314dc3dedfeSSimon Glass int err = 0;
31591199f4aSPaul Kocialkowski __maybe_unused int part;
316ade8a1a6SYing Zhang
317*65f2e689SAndreas Dannenberg /* Perform peripheral init only once */
318*65f2e689SAndreas Dannenberg if (!mmc) {
319ecdfd69aSSimon Glass err = spl_mmc_find_device(&mmc, bootdev->boot_device);
32036afd451SNikita Kiryanov if (err)
32136afd451SNikita Kiryanov return err;
322ade8a1a6SYing Zhang
323ade8a1a6SYing Zhang err = mmc_init(mmc);
324ade8a1a6SYing Zhang if (err) {
325*65f2e689SAndreas Dannenberg mmc = NULL;
3268112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
32791199f4aSPaul Kocialkowski printf("spl: mmc init failed with error: %d\n", err);
3288112f5faSPaul Burton #endif
32936afd451SNikita Kiryanov return err;
330ade8a1a6SYing Zhang }
331*65f2e689SAndreas Dannenberg }
33279adb7a2SPeter Korsgaard
333ecdfd69aSSimon Glass boot_mode = spl_boot_mode(bootdev->boot_device);
33436afd451SNikita Kiryanov err = -EINVAL;
33591199f4aSPaul Kocialkowski switch (boot_mode) {
33683cdf6faSNikita Kiryanov case MMCSD_MODE_EMMCBOOT:
33783cdf6faSNikita Kiryanov /*
33883cdf6faSNikita Kiryanov * We need to check what the partition is configured to.
33983cdf6faSNikita Kiryanov * 1 and 2 match up to boot0 / boot1 and 7 is user data
34083cdf6faSNikita Kiryanov * which is the first physical partition (0).
34183cdf6faSNikita Kiryanov */
34283cdf6faSNikita Kiryanov part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
34383cdf6faSNikita Kiryanov
34483cdf6faSNikita Kiryanov if (part == 7)
34583cdf6faSNikita Kiryanov part = 0;
34683cdf6faSNikita Kiryanov
347b5b838f1SMarek Vasut if (CONFIG_IS_ENABLED(MMC_TINY))
348b5b838f1SMarek Vasut err = mmc_switch_part(mmc, part);
349b5b838f1SMarek Vasut else
35069f45cd5SSimon Glass err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
351b5b838f1SMarek Vasut
35236afd451SNikita Kiryanov if (err) {
35383cdf6faSNikita Kiryanov #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
35483cdf6faSNikita Kiryanov puts("spl: mmc partition switch failed\n");
35583cdf6faSNikita Kiryanov #endif
35636afd451SNikita Kiryanov return err;
35783cdf6faSNikita Kiryanov }
35883cdf6faSNikita Kiryanov /* Fall through */
35991199f4aSPaul Kocialkowski case MMCSD_MODE_RAW:
36091199f4aSPaul Kocialkowski debug("spl: mmc boot mode: raw\n");
36191199f4aSPaul Kocialkowski
36291199f4aSPaul Kocialkowski if (!spl_start_uboot()) {
3632a2ee2acSSimon Glass err = mmc_load_image_raw_os(spl_image, mmc);
36491199f4aSPaul Kocialkowski if (!err)
36536afd451SNikita Kiryanov return err;
36691199f4aSPaul Kocialkowski }
367949123e3SDalon Westergreen #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
368*65f2e689SAndreas Dannenberg err = mmc_load_image_raw_partition(spl_image, mmc, raw_part,
369*65f2e689SAndreas Dannenberg raw_sect);
37091199f4aSPaul Kocialkowski if (!err)
37136afd451SNikita Kiryanov return err;
372949123e3SDalon Westergreen #endif
37338fed8abSSemen Protsenko #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
374*65f2e689SAndreas Dannenberg err = mmc_load_image_raw_sector(spl_image, mmc, raw_sect);
3753ae8f4c8SPaul Kocialkowski if (!err)
37636afd451SNikita Kiryanov return err;
3773ae8f4c8SPaul Kocialkowski #endif
37886a0df73SGuillaume GARDET /* If RAW mode fails, try FS mode. */
37991199f4aSPaul Kocialkowski case MMCSD_MODE_FS:
38091199f4aSPaul Kocialkowski debug("spl: mmc boot mode: fs\n");
38191199f4aSPaul Kocialkowski
382*65f2e689SAndreas Dannenberg err = spl_mmc_do_fs_boot(spl_image, mmc, filename);
38391199f4aSPaul Kocialkowski if (!err)
38436afd451SNikita Kiryanov return err;
385f52b7293SNikita Kiryanov
386fd61d399SNikita Kiryanov break;
3878112f5faSPaul Burton #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
388fd61d399SNikita Kiryanov default:
38991199f4aSPaul Kocialkowski puts("spl: mmc: wrong boot mode\n");
3908112f5faSPaul Burton #endif
391ade8a1a6SYing Zhang }
392fd61d399SNikita Kiryanov
39336afd451SNikita Kiryanov return err;
394ade8a1a6SYing Zhang }
3950fed9c7eSSimon Glass
spl_mmc_load_image(struct spl_image_info * spl_image,struct spl_boot_device * bootdev)396*65f2e689SAndreas Dannenberg int spl_mmc_load_image(struct spl_image_info *spl_image,
397*65f2e689SAndreas Dannenberg struct spl_boot_device *bootdev)
398*65f2e689SAndreas Dannenberg {
399*65f2e689SAndreas Dannenberg return spl_mmc_load(spl_image, bootdev,
400*65f2e689SAndreas Dannenberg #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
401*65f2e689SAndreas Dannenberg CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
402*65f2e689SAndreas Dannenberg #else
403*65f2e689SAndreas Dannenberg NULL,
404*65f2e689SAndreas Dannenberg #endif
405*65f2e689SAndreas Dannenberg #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
406*65f2e689SAndreas Dannenberg spl_boot_partition(bootdev->boot_device),
407*65f2e689SAndreas Dannenberg #else
408*65f2e689SAndreas Dannenberg 0,
409*65f2e689SAndreas Dannenberg #endif
410*65f2e689SAndreas Dannenberg #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
411*65f2e689SAndreas Dannenberg CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
412*65f2e689SAndreas Dannenberg #else
413*65f2e689SAndreas Dannenberg 0);
414*65f2e689SAndreas Dannenberg #endif
415*65f2e689SAndreas Dannenberg }
416*65f2e689SAndreas Dannenberg
417ebc4ef61SSimon Glass SPL_LOAD_IMAGE_METHOD("MMC1", 0, BOOT_DEVICE_MMC1, spl_mmc_load_image);
418ebc4ef61SSimon Glass SPL_LOAD_IMAGE_METHOD("MMC2", 0, BOOT_DEVICE_MMC2, spl_mmc_load_image);
419ebc4ef61SSimon Glass SPL_LOAD_IMAGE_METHOD("MMC2_2", 0, BOOT_DEVICE_MMC2_2, spl_mmc_load_image);
420