]> git.ipfire.org Git - people/ms/u-boot.git/blame - common/spl/spl_mmc.c
spl: change return values of spl_*_load_image()
[people/ms/u-boot.git] / common / spl / spl_mmc.c
CommitLineData
9ea5c6ef
SS
1/*
2 * (C) Copyright 2010
3 * Texas Instruments, <www.ti.com>
4 *
5 * Aneesh V <aneesh@ti.com>
6 *
1a459660 7 * SPDX-License-Identifier: GPL-2.0+
9ea5c6ef
SS
8 */
9#include <common.h>
dc3dedfe 10#include <dm.h>
47f7bcae 11#include <spl.h>
91199f4a 12#include <linux/compiler.h>
36afd451 13#include <errno.h>
9ea5c6ef 14#include <asm/u-boot.h>
4188ba32 15#include <errno.h>
9ea5c6ef 16#include <mmc.h>
e4c444b3 17#include <image.h>
9ea5c6ef
SS
18
19DECLARE_GLOBAL_DATA_PTR;
20
b97300b6 21static int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector)
9ea5c6ef 22{
3bc37b6d 23 unsigned long count;
2e222105
PK
24 u32 image_size_sectors;
25 struct image_header *header;
9ea5c6ef
SS
26
27 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
91199f4a 28 sizeof(struct image_header));
9ea5c6ef
SS
29
30 /* read image header to find the image size & load address */
3bc37b6d 31 count = mmc->block_dev.block_read(0, sector, 1, header);
fdfa39d3 32 debug("read sector %lx, count=%lu\n", sector, count);
3bc37b6d 33 if (count == 0)
9ea5c6ef
SS
34 goto end;
35
fdfa39d3
SG
36 if (image_get_magic(header) != IH_MAGIC) {
37 puts("bad magic\n");
e4c444b3 38 return -1;
fdfa39d3 39 }
e4c444b3 40
9ea5c6ef
SS
41 spl_parse_image_header(header);
42
43 /* convert size to sectors - round up */
f0881250 44 image_size_sectors = (spl_image.size + mmc->read_bl_len - 1) /
91199f4a 45 mmc->read_bl_len;
9ea5c6ef
SS
46
47 /* Read the header too to avoid extra memcpy */
3bc37b6d 48 count = mmc->block_dev.block_read(0, sector, image_size_sectors,
7ef4c45c 49 (void *)(ulong)spl_image.load_addr);
fdfa39d3
SG
50 debug("read %x sectors to %x\n", image_size_sectors,
51 spl_image.load_addr);
9ea5c6ef
SS
52
53end:
1ec26469 54 if (count == 0) {
8112f5fa 55#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
1ec26469 56 puts("spl: mmc block read error\n");
8112f5fa 57#endif
3bc37b6d 58 return -1;
1ec26469 59 }
3bc37b6d
PK
60
61 return 0;
9ea5c6ef
SS
62}
63
4188ba32
NK
64#ifdef CONFIG_DM_MMC
65static int spl_mmc_find_device(struct mmc **mmc)
66{
67 struct udevice *dev;
68 int err;
69
70 err = mmc_initialize(NULL);
71 if (err) {
72#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
73 printf("spl: could not initialize mmc. error: %d\n", err);
74#endif
75 return err;
76 }
77
78 err = uclass_get_device(UCLASS_MMC, 0, &dev);
79 if (err) {
80#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
81 printf("spl: could not find mmc device. error: %d\n", err);
82#endif
83 return err;
84 }
85
86 *mmc = NULL;
87 *mmc = mmc_get_mmc_dev(dev);
88 return *mmc != NULL ? 0 : -ENODEV;
89}
90#else
91static int spl_mmc_find_device(struct mmc **mmc)
92{
93 int err;
94
95 err = mmc_initialize(gd->bd);
96 if (err) {
97#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
98 printf("spl: could not initialize mmc. error: %d\n", err);
99#endif
100 return err;
101 }
102
103 /* We register only one device. So, the dev id is always 0 */
104 *mmc = find_mmc_device(0);
105 if (!*mmc) {
106#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
107 puts("spl: mmc device not found\n");
108#endif
109 return -ENODEV;
110 }
111
112 return 0;
113}
114#endif
115
b97300b6
PK
116#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
117static int mmc_load_image_raw_partition(struct mmc *mmc, int partition)
118{
119 disk_partition_t info;
3bc37b6d 120 int err;
b97300b6 121
3bc37b6d
PK
122 err = get_partition_info(&mmc->block_dev, partition, &info);
123 if (err) {
b97300b6 124#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
1ec26469 125 puts("spl: partition error\n");
b97300b6
PK
126#endif
127 return -1;
128 }
129
4bfcc54c
SR
130#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
131 return mmc_load_image_raw_sector(mmc, info.start +
132 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
133#else
b97300b6 134 return mmc_load_image_raw_sector(mmc, info.start);
4bfcc54c 135#endif
b97300b6 136}
d074ebb9
NK
137#else
138#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION -1
139static int mmc_load_image_raw_partition(struct mmc *mmc, int partition)
140{
141 return -ENOSYS;
142}
b97300b6
PK
143#endif
144
2b75b0ad
PK
145#ifdef CONFIG_SPL_OS_BOOT
146static int mmc_load_image_raw_os(struct mmc *mmc)
147{
3bc37b6d 148 unsigned long count;
91199f4a 149
3bc37b6d
PK
150 count = mmc->block_dev.block_read(0,
151 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
152 CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
153 (void *) CONFIG_SYS_SPL_ARGS_ADDR);
154 if (count == 0) {
8112f5fa 155#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
1ec26469 156 puts("spl: mmc block read error\n");
8112f5fa 157#endif
2b75b0ad
PK
158 return -1;
159 }
160
b97300b6 161 return mmc_load_image_raw_sector(mmc,
91199f4a 162 CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
2b75b0ad 163}
339245b7
NK
164#else
165int spl_start_uboot(void)
166{
167 return 1;
168}
169static int mmc_load_image_raw_os(struct mmc *mmc)
170{
171 return -ENOSYS;
172}
2b75b0ad
PK
173#endif
174
f52b7293
NK
175#ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION
176int spl_mmc_do_fs_boot(struct mmc *mmc)
177{
178 int err = -ENOSYS;
179
180#ifdef CONFIG_SPL_FAT_SUPPORT
181 if (!spl_start_uboot()) {
182 err = spl_load_image_fat_os(&mmc->block_dev,
183 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
184 if (!err)
185 return err;
186 }
187#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
188 err = spl_load_image_fat(&mmc->block_dev,
189 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
190 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
191 if (!err)
192 return err;
193#endif
194#endif
195#ifdef CONFIG_SPL_EXT_SUPPORT
196 if (!spl_start_uboot()) {
197 err = spl_load_image_ext_os(&mmc->block_dev,
198 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
199 if (!err)
200 return err;
201 }
202#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
203 err = spl_load_image_ext(&mmc->block_dev,
204 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
205 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
206 if (!err)
207 return err;
208#endif
209#endif
210
211#if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT)
212 err = -ENOENT;
213#endif
214
215 return err;
216}
217#else
218int spl_mmc_do_fs_boot(struct mmc *mmc)
219{
220 return -ENOSYS;
221}
222#endif
223
36afd451 224int spl_mmc_load_image(void)
9ea5c6ef
SS
225{
226 struct mmc *mmc;
9ea5c6ef 227 u32 boot_mode;
dc3dedfe 228 int err = 0;
91199f4a 229 __maybe_unused int part;
9ea5c6ef 230
36afd451
NK
231 err = spl_mmc_find_device(&mmc);
232 if (err)
233 return err;
9ea5c6ef 234
4188ba32 235 err = mmc_init(mmc);
9ea5c6ef 236 if (err) {
8112f5fa 237#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
91199f4a 238 printf("spl: mmc init failed with error: %d\n", err);
8112f5fa 239#endif
36afd451 240 return err;
9ea5c6ef 241 }
79adb7a2 242
37189a19 243 boot_mode = spl_boot_mode();
36afd451 244 err = -EINVAL;
91199f4a 245 switch (boot_mode) {
83cdf6fa
NK
246 case MMCSD_MODE_EMMCBOOT:
247 /*
248 * We need to check what the partition is configured to.
249 * 1 and 2 match up to boot0 / boot1 and 7 is user data
250 * which is the first physical partition (0).
251 */
252 part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
253
254 if (part == 7)
255 part = 0;
256
36afd451
NK
257 err = mmc_switch_part(0, part);
258 if (err) {
83cdf6fa
NK
259#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
260 puts("spl: mmc partition switch failed\n");
261#endif
36afd451 262 return err;
83cdf6fa
NK
263 }
264 /* Fall through */
91199f4a
PK
265 case MMCSD_MODE_RAW:
266 debug("spl: mmc boot mode: raw\n");
267
91199f4a
PK
268 if (!spl_start_uboot()) {
269 err = mmc_load_image_raw_os(mmc);
270 if (!err)
36afd451 271 return err;
91199f4a 272 }
d074ebb9 273
b97300b6
PK
274 err = mmc_load_image_raw_partition(mmc,
275 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION);
3ae8f4c8 276 if (!err)
36afd451 277 return err;
d074ebb9 278#if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR)
b97300b6 279 err = mmc_load_image_raw_sector(mmc,
773b5940 280 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
91199f4a 281 if (!err)
36afd451 282 return err;
3ae8f4c8 283#endif
fd61d399 284 break;
91199f4a
PK
285 case MMCSD_MODE_FS:
286 debug("spl: mmc boot mode: fs\n");
287
f52b7293 288 err = spl_mmc_do_fs_boot(mmc);
91199f4a 289 if (!err)
36afd451 290 return err;
f52b7293 291
fd61d399 292 break;
91199f4a 293 case MMCSD_MODE_UNDEFINED:
8112f5fa 294#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
fd61d399
NK
295 default:
296 puts("spl: mmc: wrong boot mode\n");
8112f5fa 297#endif
91199f4a 298 }
fd61d399 299
36afd451 300 return err;
9ea5c6ef 301}