]> Git Repo - J-u-boot.git/blame - common/spl/spl_mmc.c
Merge https://gitlab.denx.de/u-boot/custodians/u-boot-fsl-qoriq
[J-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 <[email protected]>
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
2a2ee2ac
SG
20static int mmc_load_legacy(struct spl_image_info *spl_image, struct mmc *mmc,
21 ulong sector, struct image_header *header)
96debd1f
SG
22{
23 u32 image_size_sectors;
24 unsigned long count;
7e0f2267
MV
25 int ret;
26
2a2ee2ac 27 ret = spl_parse_image_header(spl_image, header);
7e0f2267
MV
28 if (ret)
29 return ret;
96debd1f 30
96debd1f 31 /* convert size to sectors - round up */
2a2ee2ac 32 image_size_sectors = (spl_image->size + mmc->read_bl_len - 1) /
96debd1f
SG
33 mmc->read_bl_len;
34
35 /* Read the header too to avoid extra memcpy */
ef5609c3 36 count = blk_dread(mmc_get_blk_desc(mmc), sector, image_size_sectors,
2a2ee2ac 37 (void *)(ulong)spl_image->load_addr);
11e1479b 38 debug("read %x sectors to %lx\n", image_size_sectors,
2a2ee2ac 39 spl_image->load_addr);
96debd1f
SG
40 if (count != image_size_sectors)
41 return -EIO;
42
43 return 0;
44}
45
96debd1f
SG
46static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
47 ulong count, void *buf)
48{
49 struct mmc *mmc = load->dev;
50
ef5609c3 51 return blk_dread(mmc_get_blk_desc(mmc), sector, count, buf);
96debd1f 52}
96debd1f 53
e42afd84
BS
54static __maybe_unused unsigned long spl_mmc_raw_uboot_offset(int part)
55{
56#if IS_ENABLED(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR)
57 if (part == 0)
58 return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET;
59#endif
60
61 return 0;
62}
63
b016b585
SWK
64static __maybe_unused
65int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
66 struct mmc *mmc, unsigned long sector)
9ea5c6ef 67{
3bc37b6d 68 unsigned long count;
2e222105 69 struct image_header *header;
04ce5427 70 struct blk_desc *bd = mmc_get_blk_desc(mmc);
96debd1f 71 int ret = 0;
9ea5c6ef 72
04ce5427 73 header = spl_get_load_buffer(-sizeof(*header), bd->blksz);
9ea5c6ef
SS
74
75 /* read image header to find the image size & load address */
04ce5427 76 count = blk_dread(bd, sector, 1, header);
96debd1f
SG
77 debug("hdr read sector %lx, count=%lu\n", sector, count);
78 if (count == 0) {
79 ret = -EIO;
9ea5c6ef 80 goto end;
96debd1f 81 }
9ea5c6ef 82
4976f482
MY
83 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
84 image_get_magic(header) == FDT_MAGIC) {
96debd1f
SG
85 struct spl_load_info load;
86
87 debug("Found FIT\n");
88 load.dev = mmc;
89 load.priv = NULL;
eafd5410 90 load.filename = NULL;
96debd1f
SG
91 load.bl_len = mmc->read_bl_len;
92 load.read = h_spl_load_read;
f4d7d859 93 ret = spl_load_simple_fit(spl_image, &load, sector, header);
dd7d0911
PF
94 } else if (IS_ENABLED(CONFIG_SPL_LOAD_IMX_CONTAINER)) {
95 struct spl_load_info load;
96
97 load.dev = mmc;
98 load.priv = NULL;
99 load.filename = NULL;
100 load.bl_len = mmc->read_bl_len;
101 load.read = h_spl_load_read;
102
103 ret = spl_load_imx_container(spl_image, &load, sector);
4976f482 104 } else {
2a2ee2ac 105 ret = mmc_load_legacy(spl_image, mmc, sector, header);
fdfa39d3 106 }
e4c444b3 107
9ea5c6ef 108end:
96debd1f 109 if (ret) {
8112f5fa 110#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
5bbf4099 111 puts("mmc_load_image_raw_sector: mmc block read error\n");
8112f5fa 112#endif
3bc37b6d 113 return -1;
1ec26469 114 }
3bc37b6d
PK
115
116 return 0;
9ea5c6ef
SS
117}
118
207d8b35 119static int spl_mmc_get_device_index(u32 boot_device)
a1e56cf6
NK
120{
121 switch (boot_device) {
122 case BOOT_DEVICE_MMC1:
123 return 0;
124 case BOOT_DEVICE_MMC2:
125 case BOOT_DEVICE_MMC2_2:
126 return 1;
127 }
128
129#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
130 printf("spl: unsupported mmc boot device.\n");
131#endif
132
133 return -ENODEV;
134}
135
99c7a51a 136static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
4188ba32 137{
a1e56cf6
NK
138 int err, mmc_dev;
139
140 mmc_dev = spl_mmc_get_device_index(boot_device);
141 if (mmc_dev < 0)
142 return mmc_dev;
4188ba32 143
80f02019
LV
144#if CONFIG_IS_ENABLED(DM_MMC)
145 err = mmc_init_device(mmc_dev);
146#else
4188ba32 147 err = mmc_initialize(NULL);
80f02019 148#endif /* DM_MMC */
4188ba32
NK
149 if (err) {
150#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
151 printf("spl: could not initialize mmc. error: %d\n", err);
152#endif
153 return err;
154 }
b4857aa9
SG
155 *mmcp = find_mmc_device(mmc_dev);
156 err = *mmcp ? 0 : -ENODEV;
4188ba32
NK
157 if (err) {
158#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
aa608b6c
AK
159 printf("spl: could not find mmc device %d. error: %d\n",
160 mmc_dev, err);
4188ba32
NK
161#endif
162 return err;
163 }
164
4188ba32
NK
165 return 0;
166}
4188ba32 167
949123e3 168#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
2a2ee2ac 169static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
e1eb6ada
AD
170 struct mmc *mmc, int partition,
171 unsigned long sector)
b97300b6 172{
0528979f 173 struct disk_partition info;
3bc37b6d 174 int err;
b97300b6 175
f0fb4fa7
DW
176#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
177 int type_part;
178 /* Only support MBR so DOS_ENTRY_NUMBERS */
179 for (type_part = 1; type_part <= DOS_ENTRY_NUMBERS; type_part++) {
180 err = part_get_info(mmc_get_blk_desc(mmc), type_part, &info);
181 if (err)
182 continue;
183 if (info.sys_ind ==
184 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE) {
185 partition = type_part;
186 break;
187 }
188 }
189#endif
190
1e2b3ef8 191 err = part_get_info(mmc_get_blk_desc(mmc), partition, &info);
3bc37b6d 192 if (err) {
b97300b6 193#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
1ec26469 194 puts("spl: partition error\n");
b97300b6
PK
195#endif
196 return -1;
197 }
198
38fed8ab 199#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
e1eb6ada 200 return mmc_load_image_raw_sector(spl_image, mmc, info.start + sector);
4bfcc54c 201#else
2a2ee2ac 202 return mmc_load_image_raw_sector(spl_image, mmc, info.start);
4bfcc54c 203#endif
b97300b6
PK
204}
205#endif
206
2b75b0ad 207#ifdef CONFIG_SPL_OS_BOOT
2a2ee2ac
SG
208static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
209 struct mmc *mmc)
2b75b0ad 210{
811906ae 211 int ret;
91199f4a 212
7267fbf7
YS
213#if defined(CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR)
214 unsigned long count;
215
87bce4e5 216 count = blk_dread(mmc_get_blk_desc(mmc),
3bc37b6d
PK
217 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
218 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
219 (void *) CONFIG_SYS_SPL_ARGS_ADDR);
9585dd3f 220 if (count != CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS) {
8112f5fa 221#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
5bbf4099 222 puts("mmc_load_image_raw_os: mmc block read error\n");
8112f5fa 223#endif
2b75b0ad
PK
224 return -1;
225 }
7267fbf7 226#endif /* CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR */
2b75b0ad 227
2a2ee2ac 228 ret = mmc_load_image_raw_sector(spl_image, mmc,
91199f4a 229 CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
811906ae
LV
230 if (ret)
231 return ret;
232
2a2ee2ac 233 if (spl_image->os != IH_OS_LINUX) {
811906ae
LV
234 puts("Expected Linux image is not found. Trying to start U-boot\n");
235 return -ENOENT;
236 }
237
238 return 0;
2b75b0ad 239}
339245b7
NK
240#else
241int spl_start_uboot(void)
242{
243 return 1;
244}
2a2ee2ac
SG
245static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
246 struct mmc *mmc)
339245b7
NK
247{
248 return -ENOSYS;
249}
2b75b0ad
PK
250#endif
251
f52b7293 252#ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION
e1eb6ada
AD
253static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc,
254 const char *filename)
f52b7293
NK
255{
256 int err = -ENOSYS;
257
0c3a9ed4 258#ifdef CONFIG_SPL_FS_FAT
f52b7293 259 if (!spl_start_uboot()) {
710e9ca5 260 err = spl_load_image_fat_os(spl_image, mmc_get_blk_desc(mmc),
f52b7293
NK
261 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
262 if (!err)
263 return err;
264 }
265#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
710e9ca5 266 err = spl_load_image_fat(spl_image, mmc_get_blk_desc(mmc),
f52b7293 267 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
e1eb6ada 268 filename);
f52b7293
NK
269 if (!err)
270 return err;
271#endif
272#endif
f4b40924 273#ifdef CONFIG_SPL_FS_EXT4
f52b7293 274 if (!spl_start_uboot()) {
1a92541d 275 err = spl_load_image_ext_os(spl_image, mmc_get_blk_desc(mmc),
f52b7293
NK
276 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
277 if (!err)
278 return err;
279 }
280#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
1a92541d 281 err = spl_load_image_ext(spl_image, mmc_get_blk_desc(mmc),
f52b7293 282 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
e1eb6ada 283 filename);
f52b7293
NK
284 if (!err)
285 return err;
286#endif
287#endif
288
f4b40924 289#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
f52b7293
NK
290 err = -ENOENT;
291#endif
292
293 return err;
294}
295#else
e1eb6ada
AD
296static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc,
297 const char *filename)
f52b7293
NK
298{
299 return -ENOSYS;
300}
301#endif
302
e9759065 303u32 __weak spl_mmc_boot_mode(const u32 boot_device)
d695d662 304{
f4b40924 305#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
d695d662
LM
306 return MMCSD_MODE_FS;
307#elif defined(CONFIG_SUPPORT_EMMC_BOOT)
308 return MMCSD_MODE_EMMCBOOT;
309#else
310 return MMCSD_MODE_RAW;
311#endif
312}
313
35a66960 314#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
c51b7518 315int __weak spl_mmc_boot_partition(const u32 boot_device)
35a66960
PD
316{
317 return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION;
318}
319#endif
320
cf008255
FA
321unsigned long __weak spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
322 unsigned long raw_sect)
30ecc9c3 323{
cf008255 324 return raw_sect;
30ecc9c3
PF
325}
326
e1eb6ada
AD
327int spl_mmc_load(struct spl_image_info *spl_image,
328 struct spl_boot_device *bootdev,
329 const char *filename,
330 int raw_part,
331 unsigned long raw_sect)
9ea5c6ef 332{
e1eb6ada 333 static struct mmc *mmc;
9ea5c6ef 334 u32 boot_mode;
dc3dedfe 335 int err = 0;
e42afd84 336 __maybe_unused int part = 0;
9ea5c6ef 337
e1eb6ada
AD
338 /* Perform peripheral init only once */
339 if (!mmc) {
340 err = spl_mmc_find_device(&mmc, bootdev->boot_device);
341 if (err)
342 return err;
9ea5c6ef 343
e1eb6ada
AD
344 err = mmc_init(mmc);
345 if (err) {
346 mmc = NULL;
8112f5fa 347#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
e1eb6ada 348 printf("spl: mmc init failed with error: %d\n", err);
8112f5fa 349#endif
e1eb6ada
AD
350 return err;
351 }
9ea5c6ef 352 }
79adb7a2 353
e9759065 354 boot_mode = spl_mmc_boot_mode(bootdev->boot_device);
36afd451 355 err = -EINVAL;
91199f4a 356 switch (boot_mode) {
83cdf6fa 357 case MMCSD_MODE_EMMCBOOT:
17241ea0
MR
358#ifdef CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION
359 part = CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION;
360#else
9243990b
MR
361 /*
362 * We need to check what the partition is configured to.
363 * 1 and 2 match up to boot0 / boot1 and 7 is user data
364 * which is the first physical partition (0).
365 */
366 part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
367
368 if (part == 7)
369 part = 0;
17241ea0 370#endif
9243990b
MR
371
372 if (CONFIG_IS_ENABLED(MMC_TINY))
373 err = mmc_switch_part(mmc, part);
374 else
375 err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
376
377 if (err) {
83cdf6fa 378#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
9243990b 379 puts("spl: mmc partition switch failed\n");
83cdf6fa 380#endif
9243990b
MR
381 return err;
382 }
383 /* Fall through */
91199f4a
PK
384 case MMCSD_MODE_RAW:
385 debug("spl: mmc boot mode: raw\n");
386
91199f4a 387 if (!spl_start_uboot()) {
2a2ee2ac 388 err = mmc_load_image_raw_os(spl_image, mmc);
91199f4a 389 if (!err)
36afd451 390 return err;
91199f4a 391 }
a335f805 392
cf008255 393 raw_sect = spl_mmc_get_uboot_raw_sector(mmc, raw_sect);
a335f805 394
949123e3 395#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
e1eb6ada
AD
396 err = mmc_load_image_raw_partition(spl_image, mmc, raw_part,
397 raw_sect);
3ae8f4c8 398 if (!err)
36afd451 399 return err;
949123e3 400#endif
38fed8ab 401#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
e42afd84
BS
402 err = mmc_load_image_raw_sector(spl_image, mmc,
403 raw_sect + spl_mmc_raw_uboot_offset(part));
91199f4a 404 if (!err)
36afd451 405 return err;
3ae8f4c8 406#endif
86a0df73 407 /* If RAW mode fails, try FS mode. */
91199f4a
PK
408 case MMCSD_MODE_FS:
409 debug("spl: mmc boot mode: fs\n");
410
e1eb6ada 411 err = spl_mmc_do_fs_boot(spl_image, mmc, filename);
91199f4a 412 if (!err)
36afd451 413 return err;
f52b7293 414
fd61d399 415 break;
8112f5fa 416#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
fd61d399
NK
417 default:
418 puts("spl: mmc: wrong boot mode\n");
8112f5fa 419#endif
91199f4a 420 }
fd61d399 421
36afd451 422 return err;
9ea5c6ef 423}
0fed9c7e 424
e1eb6ada
AD
425int spl_mmc_load_image(struct spl_image_info *spl_image,
426 struct spl_boot_device *bootdev)
427{
428 return spl_mmc_load(spl_image, bootdev,
429#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
430 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
431#else
432 NULL,
433#endif
434#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
c51b7518 435 spl_mmc_boot_partition(bootdev->boot_device),
e1eb6ada
AD
436#else
437 0,
438#endif
439#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
440 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
441#else
442 0);
443#endif
444}
445
ebc4ef61
SG
446SPL_LOAD_IMAGE_METHOD("MMC1", 0, BOOT_DEVICE_MMC1, spl_mmc_load_image);
447SPL_LOAD_IMAGE_METHOD("MMC2", 0, BOOT_DEVICE_MMC2, spl_mmc_load_image);
448SPL_LOAD_IMAGE_METHOD("MMC2_2", 0, BOOT_DEVICE_MMC2_2, spl_mmc_load_image);
This page took 0.466929 seconds and 4 git commands to generate.