]> git.ipfire.org Git - thirdparty/u-boot.git/blame - common/spl/spl_mmc.c
global: Use proper project name U-Boot
[thirdparty/u-boot.git] / common / spl / spl_mmc.c
CommitLineData
83d290c5 1// SPDX-License-Identifier: GPL-2.0+
9ea5c6ef
SS
2/*
3 * (C) Copyright 2010
4 * Texas Instruments, <www.ti.com>
5 *
6 * Aneesh V <aneesh@ti.com>
9ea5c6ef
SS
7 */
8#include <common.h>
dc3dedfe 9#include <dm.h>
f7ae49fc 10#include <log.h>
e6f6f9e6 11#include <part.h>
47f7bcae 12#include <spl.h>
91199f4a 13#include <linux/compiler.h>
36afd451 14#include <errno.h>
9ea5c6ef 15#include <asm/u-boot.h>
4188ba32 16#include <errno.h>
9ea5c6ef 17#include <mmc.h>
e4c444b3 18#include <image.h>
9ea5c6ef 19
2e0429bc
T
20static int mmc_load_legacy(struct spl_image_info *spl_image,
21 struct spl_boot_device *bootdev,
22 struct mmc *mmc,
f3543e69 23 ulong sector, struct legacy_img_hdr *header)
96debd1f 24{
5fce2875 25 u32 image_offset_sectors;
96debd1f
SG
26 u32 image_size_sectors;
27 unsigned long count;
5fce2875 28 u32 image_offset;
7e0f2267
MV
29 int ret;
30
2e0429bc 31 ret = spl_parse_image_header(spl_image, bootdev, header);
7e0f2267
MV
32 if (ret)
33 return ret;
96debd1f 34
5fce2875
T
35 /* convert offset to sectors - round down */
36 image_offset_sectors = spl_image->offset / mmc->read_bl_len;
37 /* calculate remaining offset */
38 image_offset = spl_image->offset % mmc->read_bl_len;
39
96debd1f 40 /* convert size to sectors - round up */
2a2ee2ac 41 image_size_sectors = (spl_image->size + mmc->read_bl_len - 1) /
96debd1f
SG
42 mmc->read_bl_len;
43
44 /* Read the header too to avoid extra memcpy */
5fce2875
T
45 count = blk_dread(mmc_get_blk_desc(mmc),
46 sector + image_offset_sectors,
47 image_size_sectors,
2a2ee2ac 48 (void *)(ulong)spl_image->load_addr);
11e1479b 49 debug("read %x sectors to %lx\n", image_size_sectors,
2a2ee2ac 50 spl_image->load_addr);
96debd1f
SG
51 if (count != image_size_sectors)
52 return -EIO;
53
5fce2875
T
54 if (image_offset)
55 memmove((void *)(ulong)spl_image->load_addr,
56 (void *)(ulong)spl_image->load_addr + image_offset,
57 spl_image->size);
58
96debd1f
SG
59 return 0;
60}
61
96debd1f
SG
62static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
63 ulong count, void *buf)
64{
65 struct mmc *mmc = load->dev;
66
ef5609c3 67 return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf);
96debd1f 68}
96debd1f 69
e42afd84
BS
70static __maybe_unused unsigned long spl_mmc_raw_uboot_offset(int part)
71{
72#if IS_ENABLED(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR)
73 if (part == 0)
74 return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET;
75#endif
76
77 return 0;
78}
79
b016b585
SWK
80static __maybe_unused
81int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
2e0429bc 82 struct spl_boot_device *bootdev,
b016b585 83 struct mmc *mmc, unsigned long sector)
9ea5c6ef 84{
3bc37b6d 85 unsigned long count;
f3543e69 86 struct legacy_img_hdr *header;
04ce5427 87 struct blk_desc *bd = mmc_get_blk_desc(mmc);
96debd1f 88 int ret = 0;
9ea5c6ef 89
04ce5427 90 header = spl_get_load_buffer(-sizeof(*header), bd->blksz);
9ea5c6ef
SS
91
92 /* read image header to find the image size & load address */
04ce5427 93 count = blk_dread(bd, sector, 1, header);
96debd1f
SG
94 debug("hdr read sector %lx, count=%lu\n", sector, count);
95 if (count == 0) {
96 ret = -EIO;
9ea5c6ef 97 goto end;
96debd1f 98 }
9ea5c6ef 99
4976f482
MY
100 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
101 image_get_magic(header) == FDT_MAGIC) {
96debd1f
SG
102 struct spl_load_info load;
103
104 debug("Found FIT\n");
105 load.dev = mmc;
106 load.priv = NULL;
eafd5410 107 load.filename = NULL;
96debd1f
SG
108 load.bl_len = mmc->read_bl_len;
109 load.read = h_spl_load_read;
f4d7d859 110 ret = spl_load_simple_fit(spl_image, &load, sector, header);
dd7d0911
PF
111 } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
112 struct spl_load_info load;
113
114 load.dev = mmc;
115 load.priv = NULL;
116 load.filename = NULL;
117 load.bl_len = mmc->read_bl_len;
118 load.read = h_spl_load_read;
119
120 ret = spl_load_imx_container(spl_image, &load, sector);
4976f482 121 } else {
2e0429bc 122 ret = mmc_load_legacy(spl_image, bootdev, mmc, sector, header);
fdfa39d3 123 }
e4c444b3 124
9ea5c6ef 125end:
96debd1f 126 if (ret) {
8112f5fa 127#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
5bbf4099 128 puts("mmc_load_image_raw_sector: mmc block read error\n");
8112f5fa 129#endif
3bc37b6d 130 return -1;
1ec26469 131 }
3bc37b6d
PK
132
133 return 0;
9ea5c6ef
SS
134}
135
207d8b35 136static int spl_mmc_get_device_index(u32 boot_device)
a1e56cf6
NK
137{
138 switch (boot_device) {
139 case BOOT_DEVICE_MMC1:
140 return 0;
141 case BOOT_DEVICE_MMC2:
142 case BOOT_DEVICE_MMC2_2:
143 return 1;
144 }
145
146#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
147 printf("spl: unsupported mmc boot device.\n");
148#endif
149
150 return -ENODEV;
151}
152
99c7a51a 153static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
4188ba32 154{
a1e56cf6
NK
155 int err, mmc_dev;
156
157 mmc_dev = spl_mmc_get_device_index(boot_device);
158 if (mmc_dev < 0)
159 return mmc_dev;
4188ba32 160
80f02019
LV
161#if CONFIG_IS_ENABLED(DM_MMC)
162 err = mmc_init_device(mmc_dev);
163#else
4188ba32 164 err = mmc_initialize(NULL);
80f02019 165#endif /* DM_MMC */
4188ba32
NK
166 if (err) {
167#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
168 printf("spl: could not initialize mmc. error: %d\n", err);
169#endif
170 return err;
171 }
b4857aa9
SG
172 *mmcp = find_mmc_device(mmc_dev);
173 err = *mmcp ? 0 : -ENODEV;
4188ba32
NK
174 if (err) {
175#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
aa608b6c
AK
176 printf("spl: could not find mmc device %d. error: %d\n",
177 mmc_dev, err);
4188ba32
NK
178#endif
179 return err;
180 }
181
4188ba32
NK
182 return 0;
183}
4188ba32 184
949123e3 185#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
2a2ee2ac 186static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
2e0429bc 187 struct spl_boot_device *bootdev,
e1eb6ada
AD
188 struct mmc *mmc, int partition,
189 unsigned long sector)
b97300b6 190{
0528979f 191 struct disk_partition info;
3bc37b6d 192 int err;
b97300b6 193
f0fb4fa7
DW
194#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
195 int type_part;
196 /* Only support MBR so DOS_ENTRY_NUMBERS */
197 for (type_part = 1; type_part <= DOS_ENTRY_NUMBERS; type_part++) {
198 err = part_get_info(mmc_get_blk_desc(mmc), type_part, &info);
199 if (err)
200 continue;
0a50b3c9 201 if (info.sys_ind ==
f0fb4fa7
DW
202 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE) {
203 partition = type_part;
204 break;
205 }
206 }
207#endif
208
1e2b3ef8 209 err = part_get_info(mmc_get_blk_desc(mmc), partition, &info);
3bc37b6d 210 if (err) {
b97300b6 211#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
1ec26469 212 puts("spl: partition error\n");
b97300b6
PK
213#endif
214 return -1;
215 }
216
38fed8ab 217#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
2e0429bc 218 return mmc_load_image_raw_sector(spl_image, bootdev, mmc, info.start + sector);
4bfcc54c 219#else
2e0429bc 220 return mmc_load_image_raw_sector(spl_image, bootdev, mmc, info.start);
4bfcc54c 221#endif
b97300b6
PK
222}
223#endif
224
22eb1526 225#if CONFIG_IS_ENABLED(FALCON_BOOT_MMCSD)
2a2ee2ac 226static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
2e0429bc 227 struct spl_boot_device *bootdev,
2a2ee2ac 228 struct mmc *mmc)
2b75b0ad 229{
811906ae 230 int ret;
91199f4a 231
103d1aec 232#if CONFIG_VAL(SYS_MMCSD_RAW_MODE_ARGS_SECTOR)
7267fbf7
YS
233 unsigned long count;
234
87bce4e5 235 count = blk_dread(mmc_get_blk_desc(mmc),
3bc37b6d
PK
236 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
237 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
238 (void *) CONFIG_SYS_SPL_ARGS_ADDR);
9585dd3f 239 if (count != CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS) {
8112f5fa 240#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
5bbf4099 241 puts("mmc_load_image_raw_os: mmc block read error\n");
8112f5fa 242#endif
2b75b0ad
PK
243 return -1;
244 }
7267fbf7 245#endif /* CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR */
2b75b0ad 246
2e0429bc 247 ret = mmc_load_image_raw_sector(spl_image, bootdev, mmc,
91199f4a 248 CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
811906ae
LV
249 if (ret)
250 return ret;
251
5f6e5c37 252 if (spl_image->os != IH_OS_LINUX && spl_image->os != IH_OS_TEE) {
1be82afa 253 puts("Expected image is not found. Trying to start U-Boot\n");
811906ae
LV
254 return -ENOENT;
255 }
256
257 return 0;
2b75b0ad 258}
339245b7 259#else
2a2ee2ac 260static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
2e0429bc 261 struct spl_boot_device *bootdev,
2a2ee2ac 262 struct mmc *mmc)
339245b7
NK
263{
264 return -ENOSYS;
265}
2b75b0ad
PK
266#endif
267
22eb1526
AG
268#ifndef CONFIG_SPL_OS_BOOT
269int spl_start_uboot(void)
270{
271 return 1;
272}
273#endif
274
718d1c74 275#ifdef CONFIG_SYS_MMCSD_FS_BOOT
2e0429bc
T
276static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image,
277 struct spl_boot_device *bootdev,
278 struct mmc *mmc,
e1eb6ada 279 const char *filename)
f52b7293
NK
280{
281 int err = -ENOSYS;
282
5fa973eb
JC
283 __maybe_unused int partition = CONFIG_SYS_MMCSD_FS_BOOT_PARTITION;
284
285#if CONFIG_SYS_MMCSD_FS_BOOT_PARTITION == -1
286 {
287 struct disk_partition info;
288 debug("Checking for the first MBR bootable partition\n");
289 for (int type_part = 1; type_part <= DOS_ENTRY_NUMBERS; type_part++) {
290 err = part_get_info(mmc_get_blk_desc(mmc), type_part, &info);
291 if (err)
292 continue;
293 debug("Partition %d is of type %d and bootable=%d\n", type_part, info.sys_ind, info.bootable);
294 if (info.bootable != 0) {
295 debug("Partition %d is bootable, using it\n", type_part);
296 partition = type_part;
297 break;
298 }
299 }
300 printf("Using first bootable partition: %d\n", partition);
301 if (partition == CONFIG_SYS_MMCSD_FS_BOOT_PARTITION) {
302 return -ENOSYS;
303 }
304 }
305#endif
306
0c3a9ed4 307#ifdef CONFIG_SPL_FS_FAT
f52b7293 308 if (!spl_start_uboot()) {
2e0429bc 309 err = spl_load_image_fat_os(spl_image, bootdev, mmc_get_blk_desc(mmc),
5fa973eb 310 partition);
f52b7293
NK
311 if (!err)
312 return err;
313 }
314#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
2e0429bc 315 err = spl_load_image_fat(spl_image, bootdev, mmc_get_blk_desc(mmc),
5fa973eb 316 partition,
e1eb6ada 317 filename);
f52b7293
NK
318 if (!err)
319 return err;
320#endif
321#endif
f4b40924 322#ifdef CONFIG_SPL_FS_EXT4
f52b7293 323 if (!spl_start_uboot()) {
2e0429bc 324 err = spl_load_image_ext_os(spl_image, bootdev, mmc_get_blk_desc(mmc),
5fa973eb 325 partition);
f52b7293
NK
326 if (!err)
327 return err;
328 }
329#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
2e0429bc 330 err = spl_load_image_ext(spl_image, bootdev, mmc_get_blk_desc(mmc),
5fa973eb 331 partition,
e1eb6ada 332 filename);
f52b7293
NK
333 if (!err)
334 return err;
335#endif
336#endif
337
f4b40924 338#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
f52b7293
NK
339 err = -ENOENT;
340#endif
341
342 return err;
343}
f52b7293
NK
344#endif
345
59073573 346u32 __weak spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
d695d662 347{
f4b40924 348#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
d695d662
LM
349 return MMCSD_MODE_FS;
350#elif defined(CONFIG_SUPPORT_EMMC_BOOT)
351 return MMCSD_MODE_EMMCBOOT;
352#else
353 return MMCSD_MODE_RAW;
354#endif
355}
356
35a66960 357#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
c51b7518 358int __weak spl_mmc_boot_partition(const u32 boot_device)
35a66960
PD
359{
360 return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION;
361}
362#endif
363
cf008255
FA
364unsigned long __weak spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
365 unsigned long raw_sect)
30ecc9c3 366{
cf008255 367 return raw_sect;
30ecc9c3
PF
368}
369
9b191591
MV
370int default_spl_mmc_emmc_boot_partition(struct mmc *mmc)
371{
372 int part;
373#ifdef CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION
374 part = CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION;
375#else
376 /*
377 * We need to check what the partition is configured to.
378 * 1 and 2 match up to boot0 / boot1 and 7 is user data
379 * which is the first physical partition (0).
380 */
8b882066 381 part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
9b191591
MV
382 if (part == 7)
383 part = 0;
384#endif
385 return part;
386}
387
388int __weak spl_mmc_emmc_boot_partition(struct mmc *mmc)
389{
390 return default_spl_mmc_emmc_boot_partition(mmc);
391}
392
bf28d9a6
HS
393static int spl_mmc_get_mmc_devnum(struct mmc *mmc)
394{
395 struct blk_desc *block_dev;
396#if !CONFIG_IS_ENABLED(BLK)
397 block_dev = &mmc->block_dev;
398#else
399 block_dev = dev_get_uclass_plat(mmc->dev);
400#endif
401 return block_dev->devnum;
402}
403
e1eb6ada
AD
404int spl_mmc_load(struct spl_image_info *spl_image,
405 struct spl_boot_device *bootdev,
406 const char *filename,
407 int raw_part,
408 unsigned long raw_sect)
9ea5c6ef 409{
e1eb6ada 410 static struct mmc *mmc;
9ea5c6ef 411 u32 boot_mode;
dc3dedfe 412 int err = 0;
e42afd84 413 __maybe_unused int part = 0;
bf28d9a6 414 int mmc_dev;
9ea5c6ef 415
bf28d9a6
HS
416 /* Perform peripheral init only once for an mmc device */
417 mmc_dev = spl_mmc_get_device_index(bootdev->boot_device);
418 if (!mmc || spl_mmc_get_mmc_devnum(mmc) != mmc_dev) {
e1eb6ada
AD
419 err = spl_mmc_find_device(&mmc, bootdev->boot_device);
420 if (err)
421 return err;
9ea5c6ef 422
e1eb6ada
AD
423 err = mmc_init(mmc);
424 if (err) {
425 mmc = NULL;
8112f5fa 426#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
e1eb6ada 427 printf("spl: mmc init failed with error: %d\n", err);
8112f5fa 428#endif
e1eb6ada
AD
429 return err;
430 }
9ea5c6ef 431 }
79adb7a2 432
59073573 433 boot_mode = spl_mmc_boot_mode(mmc, bootdev->boot_device);
36afd451 434 err = -EINVAL;
91199f4a 435 switch (boot_mode) {
83cdf6fa 436 case MMCSD_MODE_EMMCBOOT:
9b191591 437 part = spl_mmc_emmc_boot_partition(mmc);
9243990b
MR
438
439 if (CONFIG_IS_ENABLED(MMC_TINY))
440 err = mmc_switch_part(mmc, part);
441 else
442 err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
443
444 if (err) {
83cdf6fa 445#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
9243990b 446 puts("spl: mmc partition switch failed\n");
83cdf6fa 447#endif
9243990b
MR
448 return err;
449 }
450 /* Fall through */
91199f4a
PK
451 case MMCSD_MODE_RAW:
452 debug("spl: mmc boot mode: raw\n");
453
91199f4a 454 if (!spl_start_uboot()) {
2e0429bc 455 err = mmc_load_image_raw_os(spl_image, bootdev, mmc);
91199f4a 456 if (!err)
36afd451 457 return err;
91199f4a 458 }
a335f805 459
cf008255 460 raw_sect = spl_mmc_get_uboot_raw_sector(mmc, raw_sect);
a335f805 461
949123e3 462#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
2e0429bc
T
463 err = mmc_load_image_raw_partition(spl_image, bootdev,
464 mmc, raw_part,
e1eb6ada 465 raw_sect);
3ae8f4c8 466 if (!err)
36afd451 467 return err;
949123e3 468#endif
38fed8ab 469#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
2e0429bc 470 err = mmc_load_image_raw_sector(spl_image, bootdev, mmc,
e42afd84 471 raw_sect + spl_mmc_raw_uboot_offset(part));
91199f4a 472 if (!err)
36afd451 473 return err;
3ae8f4c8 474#endif
86a0df73 475 /* If RAW mode fails, try FS mode. */
718d1c74 476#ifdef CONFIG_SYS_MMCSD_FS_BOOT
91199f4a
PK
477 case MMCSD_MODE_FS:
478 debug("spl: mmc boot mode: fs\n");
479
2e0429bc 480 err = spl_mmc_do_fs_boot(spl_image, bootdev, mmc, filename);
91199f4a 481 if (!err)
36afd451 482 return err;
f52b7293 483
fd61d399 484 break;
718d1c74 485#endif
8112f5fa 486#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
fd61d399
NK
487 default:
488 puts("spl: mmc: wrong boot mode\n");
8112f5fa 489#endif
91199f4a 490 }
fd61d399 491
36afd451 492 return err;
9ea5c6ef 493}
0fed9c7e 494
e1eb6ada
AD
495int spl_mmc_load_image(struct spl_image_info *spl_image,
496 struct spl_boot_device *bootdev)
497{
498 return spl_mmc_load(spl_image, bootdev,
499#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
500 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
501#else
502 NULL,
503#endif
504#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
c51b7518 505 spl_mmc_boot_partition(bootdev->boot_device),
e1eb6ada
AD
506#else
507 0,
508#endif
509#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
510 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
511#else
512 0);
513#endif
514}
515
ebc4ef61
SG
516SPL_LOAD_IMAGE_METHOD("MMC1", 0, BOOT_DEVICE_MMC1, spl_mmc_load_image);
517SPL_LOAD_IMAGE_METHOD("MMC2", 0, BOOT_DEVICE_MMC2, spl_mmc_load_image);
518SPL_LOAD_IMAGE_METHOD("MMC2_2", 0, BOOT_DEVICE_MMC2_2, spl_mmc_load_image);