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