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