xref: /rk3399_rockchip-uboot/common/spl/spl_mmc.c (revision ef5609c33fc6a8323613a296f08c8efa3161d77f)
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 mmc *mmc, ulong sector,
22 			   struct image_header *header)
23 {
24 	u32 image_size_sectors;
25 	unsigned long count;
26 	int ret;
27 
28 	ret = spl_parse_image_header(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 %x\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 int mmc_load_image_raw_sector(struct mmc *mmc, unsigned long sector)
56 {
57 	unsigned long count;
58 	struct image_header *header;
59 	int ret = 0;
60 
61 	header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
62 					 sizeof(struct image_header));
63 
64 	/* read image header to find the image size & load address */
65 	count = blk_dread(mmc_get_blk_desc(mmc), sector, 1, header);
66 	debug("hdr read sector %lx, count=%lu\n", sector, count);
67 	if (count == 0) {
68 		ret = -EIO;
69 		goto end;
70 	}
71 
72 	if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
73 	    image_get_magic(header) == FDT_MAGIC) {
74 		struct spl_load_info load;
75 
76 		debug("Found FIT\n");
77 		load.dev = mmc;
78 		load.priv = NULL;
79 		load.bl_len = mmc->read_bl_len;
80 		load.read = h_spl_load_read;
81 		ret = spl_load_simple_fit(&load, sector, header);
82 	} else {
83 		ret = mmc_load_legacy(mmc, sector, header);
84 	}
85 
86 end:
87 	if (ret) {
88 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
89 		puts("mmc_load_image_raw_sector: mmc block read error\n");
90 #endif
91 		return -1;
92 	}
93 
94 	return 0;
95 }
96 
97 int spl_mmc_get_device_index(u32 boot_device)
98 {
99 	switch (boot_device) {
100 	case BOOT_DEVICE_MMC1:
101 		return 0;
102 	case BOOT_DEVICE_MMC2:
103 	case BOOT_DEVICE_MMC2_2:
104 		return 1;
105 	}
106 
107 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
108 	printf("spl: unsupported mmc boot device.\n");
109 #endif
110 
111 	return -ENODEV;
112 }
113 
114 static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
115 {
116 #ifdef CONFIG_DM_MMC
117 	struct udevice *dev;
118 #endif
119 	int err, mmc_dev;
120 
121 	mmc_dev = spl_mmc_get_device_index(boot_device);
122 	if (mmc_dev < 0)
123 		return mmc_dev;
124 
125 	err = mmc_initialize(NULL);
126 	if (err) {
127 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
128 		printf("spl: could not initialize mmc. error: %d\n", err);
129 #endif
130 		return err;
131 	}
132 
133 #ifdef CONFIG_DM_MMC
134 	err = uclass_get_device(UCLASS_MMC, mmc_dev, &dev);
135 	if (!err)
136 		*mmcp = mmc_get_mmc_dev(dev);
137 #else
138 	*mmcp = find_mmc_device(mmc_dev);
139 	err = *mmcp ? 0 : -ENODEV;
140 #endif
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_PARTITION
152 static int mmc_load_image_raw_partition(struct mmc *mmc, int partition)
153 {
154 	disk_partition_t info;
155 	int err;
156 
157 	err = part_get_info(&mmc->block_dev, partition, &info);
158 	if (err) {
159 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
160 		puts("spl: partition error\n");
161 #endif
162 		return -1;
163 	}
164 
165 #ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
166 	return mmc_load_image_raw_sector(mmc, info.start +
167 					 CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
168 #else
169 	return mmc_load_image_raw_sector(mmc, info.start);
170 #endif
171 }
172 #else
173 #define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION -1
174 static int mmc_load_image_raw_partition(struct mmc *mmc, int partition)
175 {
176 	return -ENOSYS;
177 }
178 #endif
179 
180 #ifdef CONFIG_SPL_OS_BOOT
181 static int mmc_load_image_raw_os(struct mmc *mmc)
182 {
183 	unsigned long count;
184 	int ret;
185 
186 	count = mmc->block_dev.block_read(&mmc->block_dev,
187 		CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
188 		CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
189 		(void *) CONFIG_SYS_SPL_ARGS_ADDR);
190 	if (count == 0) {
191 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
192 		puts("mmc_load_image_raw_os: mmc block read error\n");
193 #endif
194 		return -1;
195 	}
196 
197 	ret = mmc_load_image_raw_sector(mmc,
198 		CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
199 	if (ret)
200 		return ret;
201 
202 	if (spl_image.os != IH_OS_LINUX) {
203 		puts("Expected Linux image is not found. Trying to start U-boot\n");
204 		return -ENOENT;
205 	}
206 
207 	return 0;
208 }
209 #else
210 int spl_start_uboot(void)
211 {
212 	return 1;
213 }
214 static int mmc_load_image_raw_os(struct mmc *mmc)
215 {
216 	return -ENOSYS;
217 }
218 #endif
219 
220 #ifdef CONFIG_SYS_MMCSD_FS_BOOT_PARTITION
221 int spl_mmc_do_fs_boot(struct mmc *mmc)
222 {
223 	int err = -ENOSYS;
224 
225 #ifdef CONFIG_SPL_FAT_SUPPORT
226 	if (!spl_start_uboot()) {
227 		err = spl_load_image_fat_os(&mmc->block_dev,
228 			CONFIG_SYS_MMCSD_FS_BOOT_PARTITION);
229 		if (!err)
230 			return err;
231 	}
232 #ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
233 	err = spl_load_image_fat(&mmc->block_dev,
234 				 CONFIG_SYS_MMCSD_FS_BOOT_PARTITION,
235 				 CONFIG_SPL_FS_LOAD_PAYLOAD_NAME);
236 	if (!err)
237 		return err;
238 #endif
239 #endif
240 #ifdef CONFIG_SPL_EXT_SUPPORT
241 	if (!spl_start_uboot()) {
242 		err = spl_load_image_ext_os(&mmc->block_dev,
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_ext(&mmc->block_dev,
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 
256 #if defined(CONFIG_SPL_FAT_SUPPORT) || defined(CONFIG_SPL_EXT_SUPPORT)
257 	err = -ENOENT;
258 #endif
259 
260 	return err;
261 }
262 #else
263 int spl_mmc_do_fs_boot(struct mmc *mmc)
264 {
265 	return -ENOSYS;
266 }
267 #endif
268 
269 int spl_mmc_load_image(u32 boot_device)
270 {
271 	struct mmc *mmc = NULL;
272 	u32 boot_mode;
273 	int err = 0;
274 	__maybe_unused int part;
275 
276 	err = spl_mmc_find_device(&mmc, boot_device);
277 	if (err)
278 		return err;
279 
280 	err = mmc_init(mmc);
281 	if (err) {
282 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
283 		printf("spl: mmc init failed with error: %d\n", err);
284 #endif
285 		return err;
286 	}
287 
288 	boot_mode = spl_boot_mode();
289 	err = -EINVAL;
290 	switch (boot_mode) {
291 	case MMCSD_MODE_EMMCBOOT:
292 			/*
293 			 * We need to check what the partition is configured to.
294 			 * 1 and 2 match up to boot0 / boot1 and 7 is user data
295 			 * which is the first physical partition (0).
296 			 */
297 			part = (mmc->part_config >> 3) & PART_ACCESS_MASK;
298 
299 			if (part == 7)
300 				part = 0;
301 
302 			err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
303 			if (err) {
304 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
305 				puts("spl: mmc partition switch failed\n");
306 #endif
307 				return err;
308 			}
309 			/* Fall through */
310 	case MMCSD_MODE_RAW:
311 		debug("spl: mmc boot mode: raw\n");
312 
313 		if (!spl_start_uboot()) {
314 			err = mmc_load_image_raw_os(mmc);
315 			if (!err)
316 				return err;
317 		}
318 
319 		err = mmc_load_image_raw_partition(mmc,
320 			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION);
321 		if (!err)
322 			return err;
323 #if defined(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR)
324 		err = mmc_load_image_raw_sector(mmc,
325 			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
326 		if (!err)
327 			return err;
328 #endif
329 		/* If RAW mode fails, try FS mode. */
330 	case MMCSD_MODE_FS:
331 		debug("spl: mmc boot mode: fs\n");
332 
333 		err = spl_mmc_do_fs_boot(mmc);
334 		if (!err)
335 			return err;
336 
337 		break;
338 	case MMCSD_MODE_UNDEFINED:
339 #ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
340 	default:
341 		puts("spl: mmc: wrong boot mode\n");
342 #endif
343 	}
344 
345 	return err;
346 }
347