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