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