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