1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * (C) Copyright 2010
4 * Texas Instruments, <www.ti.com>
5 *
6 * Aneesh V <aneesh@ti.com>
7 */
8#include <common.h>
9#include <dm.h>
10#include <log.h>
11#include <part.h>
12#include <spl.h>
13#include <spl_load.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#include <imx_container.h>
21
22static ulong h_spl_load_read(struct spl_load_info *load, ulong off,
23			     ulong size, void *buf)
24{
25	struct blk_desc *bd = load->priv;
26	lbaint_t sector = off >> bd->log2blksz;
27	lbaint_t count = size >> bd->log2blksz;
28
29	return blk_dread(bd, sector, count, buf) << bd->log2blksz;
30}
31
32static __maybe_unused unsigned long spl_mmc_raw_uboot_offset(int part)
33{
34#if IS_ENABLED(CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR)
35	if (part == 0)
36		return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_DATA_PART_OFFSET;
37#endif
38
39	return 0;
40}
41
42static __maybe_unused
43int mmc_load_image_raw_sector(struct spl_image_info *spl_image,
44			      struct spl_boot_device *bootdev,
45			      struct mmc *mmc, unsigned long sector)
46{
47	int ret;
48	struct blk_desc *bd = mmc_get_blk_desc(mmc);
49	struct spl_load_info load;
50
51	load.priv = bd;
52	spl_set_bl_len(&load, bd->blksz);
53	load.read = h_spl_load_read;
54	ret = spl_load(spl_image, bootdev, &load, 0, sector << bd->log2blksz);
55	if (ret) {
56#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
57		puts("mmc_load_image_raw_sector: mmc block read error\n");
58#endif
59		return -1;
60	}
61
62	return 0;
63}
64
65static int spl_mmc_get_device_index(u32 boot_device)
66{
67	switch (boot_device) {
68	case BOOT_DEVICE_MMC1:
69		return 0;
70	case BOOT_DEVICE_MMC2:
71	case BOOT_DEVICE_MMC2_2:
72		return 1;
73	}
74
75#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
76	printf("spl: unsupported mmc boot device.\n");
77#endif
78
79	return -ENODEV;
80}
81
82static int spl_mmc_find_device(struct mmc **mmcp, u32 boot_device)
83{
84	int err, mmc_dev;
85
86	mmc_dev = spl_mmc_get_device_index(boot_device);
87	if (mmc_dev < 0)
88		return mmc_dev;
89
90#if CONFIG_IS_ENABLED(DM_MMC)
91	err = mmc_init_device(mmc_dev);
92#else
93	err = mmc_initialize(NULL);
94#endif /* DM_MMC */
95	if (err) {
96#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
97		printf("spl: could not initialize mmc. error: %d\n", err);
98#endif
99		return err;
100	}
101	*mmcp = find_mmc_device(mmc_dev);
102	err = *mmcp ? 0 : -ENODEV;
103	if (err) {
104#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
105		printf("spl: could not find mmc device %d. error: %d\n",
106		       mmc_dev, err);
107#endif
108		return err;
109	}
110
111	return 0;
112}
113
114#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
115static int mmc_load_image_raw_partition(struct spl_image_info *spl_image,
116					struct spl_boot_device *bootdev,
117					struct mmc *mmc, int partition,
118					unsigned long sector)
119{
120	struct disk_partition info;
121	int err;
122
123#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION_TYPE
124	int type_part;
125	/* Only support MBR so DOS_ENTRY_NUMBERS */
126	for (type_part = 1; type_part <= DOS_ENTRY_NUMBERS; type_part++) {
127		err = part_get_info(mmc_get_blk_desc(mmc), type_part, &info);
128		if (err)
129			continue;
130		if (info.sys_ind ==
131			CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_TYPE) {
132			partition = type_part;
133			break;
134		}
135	}
136#endif
137
138	err = part_get_info(mmc_get_blk_desc(mmc), partition, &info);
139	if (err) {
140#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
141		puts("spl: partition error\n");
142#endif
143		return -1;
144	}
145
146#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
147	return mmc_load_image_raw_sector(spl_image, bootdev, mmc, info.start + sector);
148#else
149	return mmc_load_image_raw_sector(spl_image, bootdev, mmc, info.start);
150#endif
151}
152#endif
153
154#if CONFIG_IS_ENABLED(FALCON_BOOT_MMCSD)
155static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
156				 struct spl_boot_device *bootdev,
157				 struct mmc *mmc)
158{
159	int ret;
160
161#if defined(CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR)
162	unsigned long count;
163
164	count = blk_dread(mmc_get_blk_desc(mmc),
165		CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR,
166		CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS,
167		(void *)CONFIG_SPL_PAYLOAD_ARGS_ADDR);
168	if (count != CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTORS) {
169#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
170		puts("mmc_load_image_raw_os: mmc block read error\n");
171#endif
172		return -1;
173	}
174#endif	/* CONFIG_SYS_MMCSD_RAW_MODE_ARGS_SECTOR */
175
176	ret = mmc_load_image_raw_sector(spl_image, bootdev, mmc,
177		CONFIG_SYS_MMCSD_RAW_MODE_KERNEL_SECTOR);
178	if (ret)
179		return ret;
180
181	if (spl_image->os != IH_OS_LINUX && spl_image->os != IH_OS_TEE) {
182		puts("Expected image is not found. Trying to start U-Boot\n");
183		return -ENOENT;
184	}
185
186	return 0;
187}
188#else
189static int mmc_load_image_raw_os(struct spl_image_info *spl_image,
190				 struct spl_boot_device *bootdev,
191				 struct mmc *mmc)
192{
193	return -ENOSYS;
194}
195#endif
196
197#ifndef CONFIG_SPL_OS_BOOT
198int spl_start_uboot(void)
199{
200	return 1;
201}
202#endif
203
204#ifdef CONFIG_SYS_MMCSD_FS_BOOT
205static int spl_mmc_do_fs_boot(struct spl_image_info *spl_image,
206			      struct spl_boot_device *bootdev,
207			      struct mmc *mmc,
208			      const char *filename)
209{
210	int err = -ENOSYS;
211
212	__maybe_unused int partition = CONFIG_SYS_MMCSD_FS_BOOT_PARTITION;
213
214#if CONFIG_SYS_MMCSD_FS_BOOT_PARTITION == -1
215	{
216		struct disk_partition info;
217		debug("Checking for the first MBR bootable partition\n");
218		for (int type_part = 1; type_part <= DOS_ENTRY_NUMBERS; type_part++) {
219			err = part_get_info(mmc_get_blk_desc(mmc), type_part, &info);
220			if (err)
221				continue;
222			debug("Partition %d is of type %d and bootable=%d\n", type_part, info.sys_ind, info.bootable);
223			if (info.bootable != 0) {
224				debug("Partition %d is bootable, using it\n", type_part);
225				partition = type_part;
226				break;
227			}
228		}
229		printf("Using first bootable partition: %d\n", partition);
230		if (partition == CONFIG_SYS_MMCSD_FS_BOOT_PARTITION) {
231			return -ENOSYS;
232		}
233	}
234#endif
235
236#ifdef CONFIG_SPL_FS_FAT
237	if (!spl_start_uboot()) {
238		err = spl_load_image_fat_os(spl_image, bootdev, mmc_get_blk_desc(mmc),
239			partition);
240		if (!err)
241			return err;
242	}
243#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
244	err = spl_load_image_fat(spl_image, bootdev, mmc_get_blk_desc(mmc),
245				 partition,
246				 filename);
247	if (!err)
248		return err;
249#endif
250#endif
251#ifdef CONFIG_SPL_FS_EXT4
252	if (!spl_start_uboot()) {
253		err = spl_load_image_ext_os(spl_image, bootdev, mmc_get_blk_desc(mmc),
254			partition);
255		if (!err)
256			return err;
257	}
258#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
259	err = spl_load_image_ext(spl_image, bootdev, mmc_get_blk_desc(mmc),
260				 partition,
261				 filename);
262	if (!err)
263		return err;
264#endif
265#endif
266
267#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
268	err = -ENOENT;
269#endif
270
271	return err;
272}
273#endif
274
275u32 __weak spl_mmc_boot_mode(struct mmc *mmc, const u32 boot_device)
276{
277#if defined(CONFIG_SPL_FS_FAT) || defined(CONFIG_SPL_FS_EXT4)
278	return MMCSD_MODE_FS;
279#elif defined(CONFIG_SUPPORT_EMMC_BOOT)
280	return MMCSD_MODE_EMMCBOOT;
281#else
282	return MMCSD_MODE_RAW;
283#endif
284}
285
286#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
287int __weak spl_mmc_boot_partition(const u32 boot_device)
288{
289	return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION;
290}
291#endif
292
293unsigned long __weak arch_spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
294						       unsigned long raw_sect)
295{
296	return raw_sect;
297}
298
299unsigned long __weak board_spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
300						  unsigned long raw_sect)
301{
302	return arch_spl_mmc_get_uboot_raw_sector(mmc, raw_sect);
303}
304
305unsigned long __weak spl_mmc_get_uboot_raw_sector(struct mmc *mmc,
306						  unsigned long raw_sect)
307{
308	return board_spl_mmc_get_uboot_raw_sector(mmc, raw_sect);
309}
310
311int default_spl_mmc_emmc_boot_partition(struct mmc *mmc)
312{
313	int part;
314#ifdef CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION
315	part = CONFIG_SYS_MMCSD_RAW_MODE_EMMC_BOOT_PARTITION;
316#else
317	/*
318	 * We need to check what the partition is configured to.
319	 * 1 and 2 match up to boot0 / boot1 and 7 is user data
320	 * which is the first physical partition (0).
321	 */
322	part = EXT_CSD_EXTRACT_BOOT_PART(mmc->part_config);
323	if (part == 7)
324		part = 0;
325#endif
326	return part;
327}
328
329int __weak spl_mmc_emmc_boot_partition(struct mmc *mmc)
330{
331	return default_spl_mmc_emmc_boot_partition(mmc);
332}
333
334static int spl_mmc_get_mmc_devnum(struct mmc *mmc)
335{
336	struct blk_desc *block_dev;
337#if !CONFIG_IS_ENABLED(BLK)
338	block_dev = &mmc->block_dev;
339#else
340	block_dev = mmc_get_blk_desc(mmc);
341#endif
342	return block_dev->devnum;
343}
344
345static struct mmc *mmc;
346
347void spl_mmc_clear_cache(void)
348{
349	mmc = NULL;
350}
351
352int spl_mmc_load(struct spl_image_info *spl_image,
353		 struct spl_boot_device *bootdev,
354		 const char *filename,
355		 int raw_part,
356		 unsigned long raw_sect)
357{
358	u32 boot_mode;
359	int err = 0;
360	__maybe_unused int part = 0;
361	int mmc_dev;
362
363	/* Perform peripheral init only once for an mmc device */
364	mmc_dev = spl_mmc_get_device_index(bootdev->boot_device);
365	if (!mmc || spl_mmc_get_mmc_devnum(mmc) != mmc_dev) {
366		err = spl_mmc_find_device(&mmc, bootdev->boot_device);
367		if (err)
368			return err;
369
370		err = mmc_init(mmc);
371		if (err) {
372			mmc = NULL;
373#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
374			printf("spl: mmc init failed with error: %d\n", err);
375#endif
376			return err;
377		}
378	}
379
380	boot_mode = spl_mmc_boot_mode(mmc, bootdev->boot_device);
381	err = -EINVAL;
382	switch (boot_mode) {
383	case MMCSD_MODE_EMMCBOOT:
384		part = spl_mmc_emmc_boot_partition(mmc);
385
386		if (CONFIG_IS_ENABLED(MMC_TINY))
387			err = mmc_switch_part(mmc, part);
388		else
389			err = blk_dselect_hwpart(mmc_get_blk_desc(mmc), part);
390
391		if (err) {
392#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
393			puts("spl: mmc partition switch failed\n");
394#endif
395			return err;
396		}
397		/* Fall through */
398	case MMCSD_MODE_RAW:
399		debug("spl: mmc boot mode: raw\n");
400
401		if (!spl_start_uboot()) {
402			err = mmc_load_image_raw_os(spl_image, bootdev, mmc);
403			if (!err)
404				return err;
405		}
406
407		raw_sect = spl_mmc_get_uboot_raw_sector(mmc, raw_sect);
408
409#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_PARTITION
410		err = mmc_load_image_raw_partition(spl_image, bootdev,
411						   mmc, raw_part,
412						   raw_sect);
413		if (!err)
414			return err;
415#endif
416#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR
417		err = mmc_load_image_raw_sector(spl_image, bootdev, mmc,
418				raw_sect + spl_mmc_raw_uboot_offset(part));
419		if (!err)
420			return err;
421#endif
422		/* If RAW mode fails, try FS mode. */
423#ifdef CONFIG_SYS_MMCSD_FS_BOOT
424	case MMCSD_MODE_FS:
425		debug("spl: mmc boot mode: fs\n");
426
427		err = spl_mmc_do_fs_boot(spl_image, bootdev, mmc, filename);
428		if (!err)
429			return err;
430
431		break;
432#endif
433#ifdef CONFIG_SPL_LIBCOMMON_SUPPORT
434	default:
435		puts("spl: mmc: wrong boot mode\n");
436#endif
437	}
438
439	return err;
440}
441
442int spl_mmc_load_image(struct spl_image_info *spl_image,
443		       struct spl_boot_device *bootdev)
444{
445	return spl_mmc_load(spl_image, bootdev,
446#ifdef CONFIG_SPL_FS_LOAD_PAYLOAD_NAME
447			    CONFIG_SPL_FS_LOAD_PAYLOAD_NAME,
448#else
449			    NULL,
450#endif
451#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION
452			    spl_mmc_boot_partition(bootdev->boot_device),
453#else
454			    0,
455#endif
456#ifdef CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR
457			    CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR);
458#else
459			    0);
460#endif
461}
462
463SPL_LOAD_IMAGE_METHOD("MMC1", 0, BOOT_DEVICE_MMC1, spl_mmc_load_image);
464SPL_LOAD_IMAGE_METHOD("MMC2", 0, BOOT_DEVICE_MMC2, spl_mmc_load_image);
465SPL_LOAD_IMAGE_METHOD("MMC2_2", 0, BOOT_DEVICE_MMC2_2, spl_mmc_load_image);
466