1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * (C) Copyright 2010
3*4882a593Smuzhiyun * Texas Instruments, <www.ti.com>
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Aneesh V <aneesh@ti.com>
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * SPDX-License-Identifier: GPL-2.0+
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun #include <common.h>
10*4882a593Smuzhiyun #include <boot_rkimg.h>
11*4882a593Smuzhiyun #include <dm.h>
12*4882a593Smuzhiyun #include <part.h>
13*4882a593Smuzhiyun #include <spl.h>
14*4882a593Smuzhiyun #include <spl_rkfw.h>
15*4882a593Smuzhiyun #include <linux/compiler.h>
16*4882a593Smuzhiyun #include <errno.h>
17*4882a593Smuzhiyun #include <asm/u-boot.h>
18*4882a593Smuzhiyun #include <errno.h>
19*4882a593Smuzhiyun #include <mmc.h>
20*4882a593Smuzhiyun #include <image.h>
21*4882a593Smuzhiyun
22*4882a593Smuzhiyun DECLARE_GLOBAL_DATA_PTR;
23*4882a593Smuzhiyun
mmc_load_legacy(struct spl_image_info * spl_image,struct mmc * mmc,ulong sector,struct image_header * header)24*4882a593Smuzhiyun static int mmc_load_legacy(struct spl_image_info *spl_image, struct mmc *mmc,
25*4882a593Smuzhiyun ulong sector, struct image_header *header)
26*4882a593Smuzhiyun {
27*4882a593Smuzhiyun u32 image_size_sectors;
28*4882a593Smuzhiyun unsigned long count;
29*4882a593Smuzhiyun int ret;
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun ret = spl_parse_image_header(spl_image, header);
32*4882a593Smuzhiyun if (ret)
33*4882a593Smuzhiyun return ret;
34*4882a593Smuzhiyun
35*4882a593Smuzhiyun /* convert size to sectors - round up */
36*4882a593Smuzhiyun image_size_sectors = (spl_image->size + mmc->read_bl_len - 1) /
37*4882a593Smuzhiyun mmc->read_bl_len;
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun /* Read the header too to avoid extra memcpy */
40*4882a593Smuzhiyun count = blk_dread(mmc_get_blk_desc(mmc), sector, image_size_sectors,
41*4882a593Smuzhiyun (void *)(ulong)spl_image->load_addr);
42*4882a593Smuzhiyun debug("read %x sectors to %lx\n", image_size_sectors,
43*4882a593Smuzhiyun spl_image->load_addr);
44*4882a593Smuzhiyun if (count != image_size_sectors)
45*4882a593Smuzhiyun return -EIO;
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun return 0;
48*4882a593Smuzhiyun }
49*4882a593Smuzhiyun
h_spl_load_read(struct spl_load_info * load,ulong sector,ulong count,void * buf)50*4882a593Smuzhiyun static ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
51*4882a593Smuzhiyun ulong count, void *buf)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun return blk_dread(load->dev, sector, count, buf);
54*4882a593Smuzhiyun }
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun static __maybe_unused
mmc_load_image_raw_sector(struct spl_image_info * spl_image,struct mmc * mmc,unsigned long sector)57*4882a593Smuzhiyun int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
58*4882a593Smuzhiyun struct mmc *mmc, unsigned long sector)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun unsigned long count;
61*4882a593Smuzhiyun struct image_header *header;
62*4882a593Smuzhiyun int ret = 0;
63*4882a593Smuzhiyun
64*4882a593Smuzhiyun header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
65*4882a593Smuzhiyun sizeof(struct image_header));
66*4882a593Smuzhiyun
67*4882a593Smuzhiyun /* read image header to find the image size & load address */
68*4882a593Smuzhiyun count = blk_dread(mmc_get_blk_desc(mmc), sector, 1, header);
69*4882a593Smuzhiyun debug("hdr read sector %lx, count=%lu\n", sector, count);
70*4882a593Smuzhiyun if (count == 0) {
71*4882a593Smuzhiyun ret = -EIO;
72*4882a593Smuzhiyun goto end;
73*4882a593Smuzhiyun }
74*4882a593Smuzhiyun
75*4882a593Smuzhiyun #ifdef CONFIG_SPL_FIT_IMAGE_MULTIPLE
76*4882a593Smuzhiyun if ((IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
77*4882a593Smuzhiyun image_get_magic(header) == FDT_MAGIC) ||
78*4882a593Smuzhiyun CONFIG_SPL_FIT_IMAGE_MULTIPLE > 1) {
79*4882a593Smuzhiyun #else
80*4882a593Smuzhiyun if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
81*4882a593Smuzhiyun image_get_magic(header) == FDT_MAGIC) {
82*4882a593Smuzhiyun #endif
83*4882a593Smuzhiyun struct spl_load_info load;
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun debug("Found FIT\n");
86*4882a593Smuzhiyun load.dev = mmc_get_blk_desc(mmc);
87*4882a593Smuzhiyun load.priv = NULL;
88*4882a593Smuzhiyun load.filename = NULL;
89*4882a593Smuzhiyun load.bl_len = mmc->read_bl_len;
90*4882a593Smuzhiyun load.read = h_spl_load_read;
91*4882a593Smuzhiyun ret = spl_load_simple_fit(spl_image, &load, sector, header);
92*4882a593Smuzhiyun } else {
93*4882a593Smuzhiyun ret = mmc_load_legacy(spl_image, mmc, sector, header);
94*4882a593Smuzhiyun }
95*4882a593Smuzhiyun
96*4882a593Smuzhiyun end:
97*4882a593Smuzhiyun if (ret) {
98*4882a593Smuzhiyun #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
99*4882a593Smuzhiyun debug("mmc_load_image_raw_sector error: ret is %d\n", ret);
100*4882a593Smuzhiyun #endif
101*4882a593Smuzhiyun return -1;
102*4882a593Smuzhiyun }
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun return 0;
105*4882a593Smuzhiyun }
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun static int spl_mmc_get_device_index(u32 boot_device)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun switch (boot_device) {
110*4882a593Smuzhiyun case BOOT_DEVICE_MMC1:
111*4882a593Smuzhiyun return 0;
112*4882a593Smuzhiyun case BOOT_DEVICE_MMC2:
113*4882a593Smuzhiyun case BOOT_DEVICE_MMC2_2:
114*4882a593Smuzhiyun return 1;
115*4882a593Smuzhiyun }
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
118*4882a593Smuzhiyun printf("spl: unsupported mmc boot device.\n");
119*4882a593Smuzhiyun #endif
120*4882a593Smuzhiyun
121*4882a593Smuzhiyun return -ENODEV;
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
125*4882a593Smuzhiyun {
126*4882a593Smuzhiyun int err, mmc_dev;
127*4882a593Smuzhiyun
128*4882a593Smuzhiyun mmc_dev = spl_mmc_get_device_index(boot_device);
129*4882a593Smuzhiyun if (mmc_dev < 0)
130*4882a593Smuzhiyun return mmc_dev;
131*4882a593Smuzhiyun
132*4882a593Smuzhiyun err = mmc_initialize(NULL);
133*4882a593Smuzhiyun if (err) {
134*4882a593Smuzhiyun #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
135*4882a593Smuzhiyun printf("spl: could not initialize mmc. error: %d\n", err);
136*4882a593Smuzhiyun #endif
137*4882a593Smuzhiyun return err;
138*4882a593Smuzhiyun }
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun *mmcp = find_mmc_device(mmc_dev);
141*4882a593Smuzhiyun err = *mmcp ? 0 : -ENODEV;
142*4882a593Smuzhiyun if (err) {
143*4882a593Smuzhiyun #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
144*4882a593Smuzhiyun printf("spl: could not find mmc device. error: %d\n", err);
145*4882a593Smuzhiyun #endif
146*4882a593Smuzhiyun return err;
147*4882a593Smuzhiyun }
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun return 0;
150*4882a593Smuzhiyun }
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
153*4882a593Smuzhiyun static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
154*4882a593Smuzhiyun struct mmc *mmc,
155*4882a593Smuzhiyun const char *partition_name,
156*4882a593Smuzhiyun int partition)
157*4882a593Smuzhiyun {
158*4882a593Smuzhiyun disk_partition_t info;
159*4882a593Smuzhiyun int err;
160*4882a593Smuzhiyun
161*4882a593Smuzhiyun #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
162*4882a593Smuzhiyun int type_part;
163*4882a593Smuzhiyun /* Only support MBR so DOS_ENTRY_NUMBERS */
164*4882a593Smuzhiyun for (type_part = 1; type_part <= DOS_ENTRY_NUMBERS; type_part++) {
165*4882a593Smuzhiyun err = part_get_info(mmc_get_blk_desc(mmc), type_part, &info);
166*4882a593Smuzhiyun if (err)
167*4882a593Smuzhiyun continue;
168*4882a593Smuzhiyun if (info.sys_ind ==
169*4882a593Smuzhiyun CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE) {
170*4882a593Smuzhiyun partition = type_part;
171*4882a593Smuzhiyun break;
172*4882a593Smuzhiyun }
173*4882a593Smuzhiyun }
174*4882a593Smuzhiyun #endif
175*4882a593Smuzhiyun if (strcmp(partition_name, ""))
176*4882a593Smuzhiyun err = part_get_info_by_name(mmc_get_blk_desc(mmc),
177*4882a593Smuzhiyun partition_name, &info);
178*4882a593Smuzhiyun else
179*4882a593Smuzhiyun err = part_get_info(mmc_get_blk_desc(mmc), partition, &info);
180*4882a593Smuzhiyun if (err < 0) {
181*4882a593Smuzhiyun #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
182*4882a593Smuzhiyun puts("spl: partition error\n");
183*4882a593Smuzhiyun #endif
184*4882a593Smuzhiyun return -1;
185*4882a593Smuzhiyun }
186*4882a593Smuzhiyun
187*4882a593Smuzhiyun return mmc_load_image_raw_sector(spl_image, mmc, info.start);
188*4882a593Smuzhiyun }
189*4882a593Smuzhiyun #endif
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun #ifdef CONFIG_SPL_OS_BOOT
192*4882a593Smuzhiyun static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
193*4882a593Smuzhiyun struct mmc *mmc)
194*4882a593Smuzhiyun {
195*4882a593Smuzhiyun unsigned long count;
196*4882a593Smuzhiyun int ret;
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun count = blk_dread(mmc_get_blk_desc(mmc),
199*4882a593Smuzhiyun CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
200*4882a593Smuzhiyun CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
201*4882a593Smuzhiyun (void *) CONFIG_SYS_SPL_ARGS_ADDR);
202*4882a593Smuzhiyun if (count != CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS) {
203*4882a593Smuzhiyun #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
204*4882a593Smuzhiyun puts("mmc_load_image_raw_os: mmc block read error\n");
205*4882a593Smuzhiyun #endif
206*4882a593Smuzhiyun return -1;
207*4882a593Smuzhiyun }
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun ret = mmc_load_image_raw_sector(spl_image, mmc,
210*4882a593Smuzhiyun CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
211*4882a593Smuzhiyun if (ret)
212*4882a593Smuzhiyun return ret;
213*4882a593Smuzhiyun
214*4882a593Smuzhiyun if (spl_image->os != IH_OS_LINUX) {
215*4882a593Smuzhiyun puts("Expected Linux image is not found. Trying to start U-boot\n");
216*4882a593Smuzhiyun return -ENOENT;
217*4882a593Smuzhiyun }
218*4882a593Smuzhiyun
219*4882a593Smuzhiyun return 0;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun #else
222*4882a593Smuzhiyun int spl_start_uboot(void)
223*4882a593Smuzhiyun {
224*4882a593Smuzhiyun return 1;
225*4882a593Smuzhiyun }
226*4882a593Smuzhiyun static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
227*4882a593Smuzhiyun struct mmc *mmc)
228*4882a593Smuzhiyun {
229*4882a593Smuzhiyun return -ENOSYS;
230*4882a593Smuzhiyun }
231*4882a593Smuzhiyun #endif
232*4882a593Smuzhiyun
233*4882a593Smuzhiyun #ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION
234*4882a593Smuzhiyun static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc)
235*4882a593Smuzhiyun {
236*4882a593Smuzhiyun int err = -ENOSYS;
237*4882a593Smuzhiyun
238*4882a593Smuzhiyun #ifdef CONFIG_SPL_FAT_SUPPORT
239*4882a593Smuzhiyun if (!spl_start_uboot()) {
240*4882a593Smuzhiyun err = spl_load_image_fat_os(spl_image, mmc_get_blk_desc(mmc),
241*4882a593Smuzhiyun CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
242*4882a593Smuzhiyun if (!err)
243*4882a593Smuzhiyun return err;
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
246*4882a593Smuzhiyun err = spl_load_image_fat(spl_image, mmc_get_blk_desc(mmc),
247*4882a593Smuzhiyun CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
248*4882a593Smuzhiyun CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
249*4882a593Smuzhiyun if (!err)
250*4882a593Smuzhiyun return err;
251*4882a593Smuzhiyun #endif
252*4882a593Smuzhiyun #endif
253*4882a593Smuzhiyun #ifdef CONFIG_SPL_EXT_SUPPORT
254*4882a593Smuzhiyun if (!spl_start_uboot()) {
255*4882a593Smuzhiyun err = spl_load_image_ext_os(spl_image, mmc_get_blk_desc(mmc),
256*4882a593Smuzhiyun CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
257*4882a593Smuzhiyun if (!err)
258*4882a593Smuzhiyun return err;
259*4882a593Smuzhiyun }
260*4882a593Smuzhiyun #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
261*4882a593Smuzhiyun err = spl_load_image_ext(spl_image, mmc_get_blk_desc(mmc),
262*4882a593Smuzhiyun CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
263*4882a593Smuzhiyun CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
264*4882a593Smuzhiyun if (!err)
265*4882a593Smuzhiyun return err;
266*4882a593Smuzhiyun #endif
267*4882a593Smuzhiyun #endif
268*4882a593Smuzhiyun
269*4882a593Smuzhiyun #if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT)
270*4882a593Smuzhiyun err = -ENOENT;
271*4882a593Smuzhiyun #endif
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun return err;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun #else
276*4882a593Smuzhiyun static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image, struct mmc *mmc)
277*4882a593Smuzhiyun {
278*4882a593Smuzhiyun return -ENOSYS;
279*4882a593Smuzhiyun }
280*4882a593Smuzhiyun #endif
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun int spl_mmc_load_image(struct spl_image_info *spl_image,
283*4882a593Smuzhiyun struct spl_boot_device *bootdev)
284*4882a593Smuzhiyun {
285*4882a593Smuzhiyun struct mmc *mmc = NULL;
286*4882a593Smuzhiyun u32 boot_mode;
287*4882a593Smuzhiyun int err = 0;
288*4882a593Smuzhiyun __maybe_unused int part;
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun err = spl_mmc_find_device(&mmc, bootdev->boot_device);
291*4882a593Smuzhiyun if (err)
292*4882a593Smuzhiyun return err;
293*4882a593Smuzhiyun
294*4882a593Smuzhiyun err = mmc_init(mmc);
295*4882a593Smuzhiyun if (err) {
296*4882a593Smuzhiyun #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
297*4882a593Smuzhiyun printf("spl: mmc init failed with error: %d\n", err);
298*4882a593Smuzhiyun #endif
299*4882a593Smuzhiyun return err;
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun
302*4882a593Smuzhiyun #ifdef CONFIG_SPL_LOAD_RKFW
303*4882a593Smuzhiyun struct spl_load_info load;
304*4882a593Smuzhiyun
305*4882a593Smuzhiyun load.dev = mmc_get_blk_desc(mmc);
306*4882a593Smuzhiyun load.priv = NULL;
307*4882a593Smuzhiyun load.filename = NULL;
308*4882a593Smuzhiyun load.bl_len = mmc->read_bl_len;
309*4882a593Smuzhiyun load.read = h_spl_load_read;
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun err = spl_load_rkfw_image(spl_image, &load);
312*4882a593Smuzhiyun if (!err || err != -EAGAIN)
313*4882a593Smuzhiyun return err;
314*4882a593Smuzhiyun #endif
315*4882a593Smuzhiyun boot_mode = spl_boot_mode(bootdev->boot_device);
316*4882a593Smuzhiyun err = -EINVAL;
317*4882a593Smuzhiyun switch (boot_mode) {
318*4882a593Smuzhiyun case MMCSD_MODE_EMMCBOOT:
319*4882a593Smuzhiyun /*
320*4882a593Smuzhiyun * We need to check what the partition is configured to.
321*4882a593Smuzhiyun * 1 and 2 match up to boot0 / boot1 and 7 is user data
322*4882a593Smuzhiyun * which is the first physical partition (0).
323*4882a593Smuzhiyun */
324*4882a593Smuzhiyun part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
325*4882a593Smuzhiyun
326*4882a593Smuzhiyun if (part == 7)
327*4882a593Smuzhiyun part = 0;
328*4882a593Smuzhiyun
329*4882a593Smuzhiyun if (CONFIG_IS_ENABLED(MMC_TINY))
330*4882a593Smuzhiyun err = mmc_switch_part(mmc, part);
331*4882a593Smuzhiyun else
332*4882a593Smuzhiyun err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
333*4882a593Smuzhiyun
334*4882a593Smuzhiyun if (err) {
335*4882a593Smuzhiyun #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
336*4882a593Smuzhiyun puts("spl: mmc partition switch failed\n");
337*4882a593Smuzhiyun #endif
338*4882a593Smuzhiyun return err;
339*4882a593Smuzhiyun }
340*4882a593Smuzhiyun /* Fall through */
341*4882a593Smuzhiyun case MMCSD_MODE_RAW:
342*4882a593Smuzhiyun debug("spl: mmc boot mode: raw\n");
343*4882a593Smuzhiyun
344*4882a593Smuzhiyun if (!spl_start_uboot()) {
345*4882a593Smuzhiyun err = mmc_load_image_raw_os(spl_image, mmc);
346*4882a593Smuzhiyun if (!err)
347*4882a593Smuzhiyun return err;
348*4882a593Smuzhiyun }
349*4882a593Smuzhiyun #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
350*4882a593Smuzhiyun err = mmc_load_image_raw_partition(spl_image, mmc,
351*4882a593Smuzhiyun CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_NAME,
352*4882a593Smuzhiyun CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION);
353*4882a593Smuzhiyun if (!err)
354*4882a593Smuzhiyun return err;
355*4882a593Smuzhiyun #endif
356*4882a593Smuzhiyun #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
357*4882a593Smuzhiyun err = mmc_load_image_raw_sector(spl_image, mmc,
358*4882a593Smuzhiyun CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
359*4882a593Smuzhiyun if (!err)
360*4882a593Smuzhiyun return err;
361*4882a593Smuzhiyun #endif
362*4882a593Smuzhiyun /* If RAW mode fails, try FS mode. */
363*4882a593Smuzhiyun case MMCSD_MODE_FS:
364*4882a593Smuzhiyun debug("spl: mmc boot mode: fs\n");
365*4882a593Smuzhiyun
366*4882a593Smuzhiyun err = spl_mmc_do_fs_boot(spl_image, mmc);
367*4882a593Smuzhiyun if (!err)
368*4882a593Smuzhiyun return err;
369*4882a593Smuzhiyun
370*4882a593Smuzhiyun break;
371*4882a593Smuzhiyun #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
372*4882a593Smuzhiyun default:
373*4882a593Smuzhiyun puts("spl: mmc: wrong boot mode\n");
374*4882a593Smuzhiyun #endif
375*4882a593Smuzhiyun }
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun return err;
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun
380*4882a593Smuzhiyun SPL_LOAD_IMAGE_METHOD("MMC1", 0, BOOT_DEVICE_MMC1, spl_mmc_load_image);
381*4882a593Smuzhiyun SPL_LOAD_IMAGE_METHOD("MMC2", 0, BOOT_DEVICE_MMC2, spl_mmc_load_image);
382*4882a593Smuzhiyun SPL_LOAD_IMAGE_METHOD("MMC2_2", 0, BOOT_DEVICE_MMC2_2, spl_mmc_load_image);
383