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