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