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