xref: /rk3399_ARM-atf/plat/st/common/bl2_io_storage.c (revision 71693a66341e7d9d683ef32981243cb4c4439351)
1c9d75b3cSYann Gautier /*
2cddf1bd7SYann Gautier  * Copyright (c) 2015-2021, ARM Limited and Contributors. All rights reserved.
3c9d75b3cSYann Gautier  *
4c9d75b3cSYann Gautier  * SPDX-License-Identifier: BSD-3-Clause
5c9d75b3cSYann Gautier  */
6c9d75b3cSYann Gautier 
7c9d75b3cSYann Gautier #include <assert.h>
8c9d75b3cSYann Gautier #include <string.h>
9c9d75b3cSYann Gautier 
10c9d75b3cSYann Gautier #include <platform_def.h>
11c9d75b3cSYann Gautier 
12c9d75b3cSYann Gautier #include <arch_helpers.h>
13c9d75b3cSYann Gautier #include <common/debug.h>
14c9d75b3cSYann Gautier #include <drivers/io/io_block.h>
15c9d75b3cSYann Gautier #include <drivers/io/io_driver.h>
16c9d75b3cSYann Gautier #include <drivers/io/io_dummy.h>
1712e21dfdSLionel Debieve #include <drivers/io/io_mtd.h>
18c9d75b3cSYann Gautier #include <drivers/io/io_storage.h>
19c9d75b3cSYann Gautier #include <drivers/mmc.h>
20c9d75b3cSYann Gautier #include <drivers/partition/partition.h>
2112e21dfdSLionel Debieve #include <drivers/raw_nand.h>
2257044228SLionel Debieve #include <drivers/spi_nand.h>
23b1b218fbSLionel Debieve #include <drivers/spi_nor.h>
24c9d75b3cSYann Gautier #include <drivers/st/io_mmc.h>
25c9d75b3cSYann Gautier #include <drivers/st/io_stm32image.h>
2612e21dfdSLionel Debieve #include <drivers/st/stm32_fmc2_nand.h>
2757044228SLionel Debieve #include <drivers/st/stm32_qspi.h>
28c9d75b3cSYann Gautier #include <drivers/st/stm32_sdmmc2.h>
29c9d75b3cSYann Gautier #include <lib/mmio.h>
30c9d75b3cSYann Gautier #include <lib/utils.h>
31c9d75b3cSYann Gautier #include <plat/common/platform.h>
32c9d75b3cSYann Gautier 
33c9d75b3cSYann Gautier /* IO devices */
343f916a41SYann Gautier #ifndef AARCH32_SP_OPTEE
35c9d75b3cSYann Gautier static const io_dev_connector_t *dummy_dev_con;
36c9d75b3cSYann Gautier static uintptr_t dummy_dev_handle;
37c9d75b3cSYann Gautier static uintptr_t dummy_dev_spec;
383f916a41SYann Gautier #endif
39c9d75b3cSYann Gautier 
40c9d75b3cSYann Gautier static uintptr_t image_dev_handle;
4146554b64SNicolas Le Bayon static uintptr_t storage_dev_handle;
42c9d75b3cSYann Gautier 
4346554b64SNicolas Le Bayon #if STM32MP_SDMMC || STM32MP_EMMC
44cddf1bd7SYann Gautier static struct mmc_device_info mmc_info;
45c9d75b3cSYann Gautier static io_block_spec_t gpt_block_spec = {
46c9d75b3cSYann Gautier 	.offset = 0,
47c9d75b3cSYann Gautier 	.length = 34 * MMC_BLOCK_SIZE, /* Size of GPT table */
48c9d75b3cSYann Gautier };
49c9d75b3cSYann Gautier 
50c9d75b3cSYann Gautier static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
51c9d75b3cSYann Gautier 
52c9d75b3cSYann Gautier static const io_block_dev_spec_t mmc_block_dev_spec = {
53c9d75b3cSYann Gautier 	/* It's used as temp buffer in block driver */
54c9d75b3cSYann Gautier 	.buffer = {
55c9d75b3cSYann Gautier 		.offset = (size_t)&block_buffer,
56c9d75b3cSYann Gautier 		.length = MMC_BLOCK_SIZE,
57c9d75b3cSYann Gautier 	},
58c9d75b3cSYann Gautier 	.ops = {
59c9d75b3cSYann Gautier 		.read = mmc_read_blocks,
60c9d75b3cSYann Gautier 		.write = NULL,
61c9d75b3cSYann Gautier 	},
62c9d75b3cSYann Gautier 	.block_size = MMC_BLOCK_SIZE,
63c9d75b3cSYann Gautier };
64c9d75b3cSYann Gautier 
65214c8a8dSVyacheslav Yurkov #if STM32MP_EMMC_BOOT
66214c8a8dSVyacheslav Yurkov static io_block_spec_t emmc_boot_ssbl_block_spec = {
67214c8a8dSVyacheslav Yurkov 	.offset = PLAT_EMMC_BOOT_SSBL_OFFSET,
68214c8a8dSVyacheslav Yurkov 	.length = MMC_BLOCK_SIZE, /* We are interested only in first 4 bytes */
69214c8a8dSVyacheslav Yurkov };
70214c8a8dSVyacheslav Yurkov 
71214c8a8dSVyacheslav Yurkov static const io_block_dev_spec_t mmc_block_dev_boot_part_spec = {
72214c8a8dSVyacheslav Yurkov 	/* It's used as temp buffer in block driver */
73214c8a8dSVyacheslav Yurkov 	.buffer = {
74214c8a8dSVyacheslav Yurkov 		.offset = (size_t)&block_buffer,
75214c8a8dSVyacheslav Yurkov 		.length = MMC_BLOCK_SIZE,
76214c8a8dSVyacheslav Yurkov 	},
77214c8a8dSVyacheslav Yurkov 	.ops = {
78214c8a8dSVyacheslav Yurkov 		.read = mmc_boot_part_read_blocks,
79214c8a8dSVyacheslav Yurkov 		.write = NULL,
80214c8a8dSVyacheslav Yurkov 	},
81214c8a8dSVyacheslav Yurkov 	.block_size = MMC_BLOCK_SIZE,
82214c8a8dSVyacheslav Yurkov };
83214c8a8dSVyacheslav Yurkov #endif
84214c8a8dSVyacheslav Yurkov 
85214c8a8dSVyacheslav Yurkov static struct io_mmc_dev_spec mmc_device_spec = {
86214c8a8dSVyacheslav Yurkov 	.use_boot_part = false,
87214c8a8dSVyacheslav Yurkov };
88214c8a8dSVyacheslav Yurkov 
89c9d75b3cSYann Gautier static const io_dev_connector_t *mmc_dev_con;
9046554b64SNicolas Le Bayon #endif /* STM32MP_SDMMC || STM32MP_EMMC */
91c9d75b3cSYann Gautier 
92b1b218fbSLionel Debieve #if STM32MP_SPI_NOR
93b1b218fbSLionel Debieve static io_mtd_dev_spec_t spi_nor_dev_spec = {
94b1b218fbSLionel Debieve 	.ops = {
95b1b218fbSLionel Debieve 		.init = spi_nor_init,
96b1b218fbSLionel Debieve 		.read = spi_nor_read,
97b1b218fbSLionel Debieve 	},
98b1b218fbSLionel Debieve };
99b1b218fbSLionel Debieve #endif
100b1b218fbSLionel Debieve 
10112e21dfdSLionel Debieve #if STM32MP_RAW_NAND
10212e21dfdSLionel Debieve static io_mtd_dev_spec_t nand_dev_spec = {
10312e21dfdSLionel Debieve 	.ops = {
10412e21dfdSLionel Debieve 		.init = nand_raw_init,
10512e21dfdSLionel Debieve 		.read = nand_read,
10612e21dfdSLionel Debieve 	},
10712e21dfdSLionel Debieve };
10812e21dfdSLionel Debieve 
10912e21dfdSLionel Debieve static const io_dev_connector_t *nand_dev_con;
11012e21dfdSLionel Debieve #endif
11112e21dfdSLionel Debieve 
11257044228SLionel Debieve #if STM32MP_SPI_NAND
11357044228SLionel Debieve static io_mtd_dev_spec_t spi_nand_dev_spec = {
11457044228SLionel Debieve 	.ops = {
11557044228SLionel Debieve 		.init = spi_nand_init,
11657044228SLionel Debieve 		.read = nand_read,
11757044228SLionel Debieve 	},
11857044228SLionel Debieve };
119b1b218fbSLionel Debieve #endif
12057044228SLionel Debieve 
121b1b218fbSLionel Debieve #if STM32MP_SPI_NAND || STM32MP_SPI_NOR
12257044228SLionel Debieve static const io_dev_connector_t *spi_dev_con;
12357044228SLionel Debieve #endif
12457044228SLionel Debieve 
1251989a19cSYann Gautier #ifdef AARCH32_SP_OPTEE
1261989a19cSYann Gautier static const struct stm32image_part_info optee_header_partition_spec = {
1271989a19cSYann Gautier 	.name = OPTEE_HEADER_IMAGE_NAME,
1281989a19cSYann Gautier 	.binary_type = OPTEE_HEADER_BINARY_TYPE,
1291989a19cSYann Gautier };
1301989a19cSYann Gautier 
13106c3b100SYann Gautier static const struct stm32image_part_info optee_core_partition_spec = {
13206c3b100SYann Gautier 	.name = OPTEE_CORE_IMAGE_NAME,
13306c3b100SYann Gautier 	.binary_type = OPTEE_CORE_BINARY_TYPE,
1341989a19cSYann Gautier };
1351989a19cSYann Gautier 
1361989a19cSYann Gautier static const struct stm32image_part_info optee_paged_partition_spec = {
1371989a19cSYann Gautier 	.name = OPTEE_PAGED_IMAGE_NAME,
1381989a19cSYann Gautier 	.binary_type = OPTEE_PAGED_BINARY_TYPE,
1391989a19cSYann Gautier };
1401989a19cSYann Gautier #else
141c9d75b3cSYann Gautier static const io_block_spec_t bl32_block_spec = {
142c9d75b3cSYann Gautier 	.offset = BL32_BASE,
1433f9c9784SYann Gautier 	.length = STM32MP_BL32_SIZE
144c9d75b3cSYann Gautier };
1451989a19cSYann Gautier #endif
146c9d75b3cSYann Gautier 
147c9d75b3cSYann Gautier static const struct stm32image_part_info bl33_partition_spec = {
148c9d75b3cSYann Gautier 	.name = BL33_IMAGE_NAME,
149c9d75b3cSYann Gautier 	.binary_type = BL33_BINARY_TYPE,
150c9d75b3cSYann Gautier };
151c9d75b3cSYann Gautier 
152c9d75b3cSYann Gautier enum {
153c9d75b3cSYann Gautier 	IMG_IDX_BL33,
1541989a19cSYann Gautier #ifdef AARCH32_SP_OPTEE
1551989a19cSYann Gautier 	IMG_IDX_OPTEE_HEADER,
15606c3b100SYann Gautier 	IMG_IDX_OPTEE_CORE,
1571989a19cSYann Gautier 	IMG_IDX_OPTEE_PAGED,
1581989a19cSYann Gautier #endif
159c9d75b3cSYann Gautier 	IMG_IDX_NUM
160c9d75b3cSYann Gautier };
161c9d75b3cSYann Gautier 
16246554b64SNicolas Le Bayon static struct stm32image_device_info stm32image_dev_info_spec __unused = {
163c9d75b3cSYann Gautier 	.lba_size = MMC_BLOCK_SIZE,
164c9d75b3cSYann Gautier 	.part_info[IMG_IDX_BL33] = {
165c9d75b3cSYann Gautier 		.name = BL33_IMAGE_NAME,
166c9d75b3cSYann Gautier 		.binary_type = BL33_BINARY_TYPE,
167c9d75b3cSYann Gautier 	},
1681989a19cSYann Gautier #ifdef AARCH32_SP_OPTEE
1691989a19cSYann Gautier 	.part_info[IMG_IDX_OPTEE_HEADER] = {
1701989a19cSYann Gautier 		.name = OPTEE_HEADER_IMAGE_NAME,
1711989a19cSYann Gautier 		.binary_type = OPTEE_HEADER_BINARY_TYPE,
1721989a19cSYann Gautier 	},
17306c3b100SYann Gautier 	.part_info[IMG_IDX_OPTEE_CORE] = {
17406c3b100SYann Gautier 		.name = OPTEE_CORE_IMAGE_NAME,
17506c3b100SYann Gautier 		.binary_type = OPTEE_CORE_BINARY_TYPE,
1761989a19cSYann Gautier 	},
1771989a19cSYann Gautier 	.part_info[IMG_IDX_OPTEE_PAGED] = {
1781989a19cSYann Gautier 		.name = OPTEE_PAGED_IMAGE_NAME,
1791989a19cSYann Gautier 		.binary_type = OPTEE_PAGED_BINARY_TYPE,
1801989a19cSYann Gautier 	},
1811989a19cSYann Gautier #endif
182c9d75b3cSYann Gautier };
183c9d75b3cSYann Gautier 
184c9d75b3cSYann Gautier static io_block_spec_t stm32image_block_spec = {
185c9d75b3cSYann Gautier 	.offset = 0,
186c9d75b3cSYann Gautier 	.length = 0,
187c9d75b3cSYann Gautier };
188c9d75b3cSYann Gautier 
18946554b64SNicolas Le Bayon static const io_dev_connector_t *stm32image_dev_con __unused;
190c9d75b3cSYann Gautier 
1913f916a41SYann Gautier #ifndef AARCH32_SP_OPTEE
192c9d75b3cSYann Gautier static int open_dummy(const uintptr_t spec);
1933f916a41SYann Gautier #endif
194c9d75b3cSYann Gautier static int open_image(const uintptr_t spec);
195c9d75b3cSYann Gautier static int open_storage(const uintptr_t spec);
196c9d75b3cSYann Gautier 
197c9d75b3cSYann Gautier struct plat_io_policy {
198c9d75b3cSYann Gautier 	uintptr_t *dev_handle;
199c9d75b3cSYann Gautier 	uintptr_t image_spec;
200c9d75b3cSYann Gautier 	int (*check)(const uintptr_t spec);
201c9d75b3cSYann Gautier };
202c9d75b3cSYann Gautier 
203c9d75b3cSYann Gautier static const struct plat_io_policy policies[] = {
2041989a19cSYann Gautier #ifdef AARCH32_SP_OPTEE
2051989a19cSYann Gautier 	[BL32_IMAGE_ID] = {
2061989a19cSYann Gautier 		.dev_handle = &image_dev_handle,
2071989a19cSYann Gautier 		.image_spec = (uintptr_t)&optee_header_partition_spec,
2081989a19cSYann Gautier 		.check = open_image
2091989a19cSYann Gautier 	},
2101989a19cSYann Gautier 	[BL32_EXTRA1_IMAGE_ID] = {
2111989a19cSYann Gautier 		.dev_handle = &image_dev_handle,
21206c3b100SYann Gautier 		.image_spec = (uintptr_t)&optee_core_partition_spec,
2131989a19cSYann Gautier 		.check = open_image
2141989a19cSYann Gautier 	},
2151989a19cSYann Gautier 	[BL32_EXTRA2_IMAGE_ID] = {
2161989a19cSYann Gautier 		.dev_handle = &image_dev_handle,
2171989a19cSYann Gautier 		.image_spec = (uintptr_t)&optee_paged_partition_spec,
2181989a19cSYann Gautier 		.check = open_image
2191989a19cSYann Gautier 	},
2201989a19cSYann Gautier #else
221c9d75b3cSYann Gautier 	[BL32_IMAGE_ID] = {
222c9d75b3cSYann Gautier 		.dev_handle = &dummy_dev_handle,
223c9d75b3cSYann Gautier 		.image_spec = (uintptr_t)&bl32_block_spec,
224c9d75b3cSYann Gautier 		.check = open_dummy
225c9d75b3cSYann Gautier 	},
2261989a19cSYann Gautier #endif
227c9d75b3cSYann Gautier 	[BL33_IMAGE_ID] = {
228c9d75b3cSYann Gautier 		.dev_handle = &image_dev_handle,
229c9d75b3cSYann Gautier 		.image_spec = (uintptr_t)&bl33_partition_spec,
230c9d75b3cSYann Gautier 		.check = open_image
231c9d75b3cSYann Gautier 	},
23246554b64SNicolas Le Bayon #if STM32MP_SDMMC || STM32MP_EMMC
233c9d75b3cSYann Gautier 	[GPT_IMAGE_ID] = {
234c9d75b3cSYann Gautier 		.dev_handle = &storage_dev_handle,
235c9d75b3cSYann Gautier 		.image_spec = (uintptr_t)&gpt_block_spec,
236c9d75b3cSYann Gautier 		.check = open_storage
237c9d75b3cSYann Gautier 	},
23846554b64SNicolas Le Bayon #endif
239c9d75b3cSYann Gautier 	[STM32_IMAGE_ID] = {
240c9d75b3cSYann Gautier 		.dev_handle = &storage_dev_handle,
241c9d75b3cSYann Gautier 		.image_spec = (uintptr_t)&stm32image_block_spec,
242c9d75b3cSYann Gautier 		.check = open_storage
243c9d75b3cSYann Gautier 	}
244c9d75b3cSYann Gautier };
245c9d75b3cSYann Gautier 
2463f916a41SYann Gautier #ifndef AARCH32_SP_OPTEE
247c9d75b3cSYann Gautier static int open_dummy(const uintptr_t spec)
248c9d75b3cSYann Gautier {
249c9d75b3cSYann Gautier 	return io_dev_init(dummy_dev_handle, 0);
250c9d75b3cSYann Gautier }
2513f916a41SYann Gautier #endif
252c9d75b3cSYann Gautier 
253c9d75b3cSYann Gautier static int open_image(const uintptr_t spec)
254c9d75b3cSYann Gautier {
255c9d75b3cSYann Gautier 	return io_dev_init(image_dev_handle, 0);
256c9d75b3cSYann Gautier }
257c9d75b3cSYann Gautier 
258c9d75b3cSYann Gautier static int open_storage(const uintptr_t spec)
259c9d75b3cSYann Gautier {
260c9d75b3cSYann Gautier 	return io_dev_init(storage_dev_handle, 0);
261c9d75b3cSYann Gautier }
262c9d75b3cSYann Gautier 
263214c8a8dSVyacheslav Yurkov #if STM32MP_EMMC_BOOT
264214c8a8dSVyacheslav Yurkov static uint32_t get_boot_part_ssbl_header(void)
265214c8a8dSVyacheslav Yurkov {
266214c8a8dSVyacheslav Yurkov 	uint32_t magic = 0;
267214c8a8dSVyacheslav Yurkov 	int io_result;
268214c8a8dSVyacheslav Yurkov 	size_t bytes_read;
269214c8a8dSVyacheslav Yurkov 
270214c8a8dSVyacheslav Yurkov 	io_result = register_io_dev_block(&mmc_dev_con);
271214c8a8dSVyacheslav Yurkov 	if (io_result != 0) {
272214c8a8dSVyacheslav Yurkov 		panic();
273214c8a8dSVyacheslav Yurkov 	}
274214c8a8dSVyacheslav Yurkov 
275214c8a8dSVyacheslav Yurkov 	io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_boot_part_spec,
276214c8a8dSVyacheslav Yurkov 				&storage_dev_handle);
277214c8a8dSVyacheslav Yurkov 	assert(io_result == 0);
278214c8a8dSVyacheslav Yurkov 
279214c8a8dSVyacheslav Yurkov 	io_result = io_open(storage_dev_handle, (uintptr_t) &emmc_boot_ssbl_block_spec,
280214c8a8dSVyacheslav Yurkov 			    &image_dev_handle);
281214c8a8dSVyacheslav Yurkov 	assert(io_result == 0);
282214c8a8dSVyacheslav Yurkov 
283214c8a8dSVyacheslav Yurkov 	io_result = io_read(image_dev_handle, (uintptr_t) &magic, sizeof(magic),
284214c8a8dSVyacheslav Yurkov 			    &bytes_read);
285214c8a8dSVyacheslav Yurkov 	assert(io_result == 0);
286214c8a8dSVyacheslav Yurkov 	assert(bytes_read == sizeof(magic));
287214c8a8dSVyacheslav Yurkov 
288214c8a8dSVyacheslav Yurkov 	io_result = io_dev_close(storage_dev_handle);
289214c8a8dSVyacheslav Yurkov 	assert(io_result == 0);
290214c8a8dSVyacheslav Yurkov 
291214c8a8dSVyacheslav Yurkov 	return magic;
292214c8a8dSVyacheslav Yurkov }
293214c8a8dSVyacheslav Yurkov #endif
294214c8a8dSVyacheslav Yurkov 
295c9d75b3cSYann Gautier static void print_boot_device(boot_api_context_t *boot_context)
296c9d75b3cSYann Gautier {
297c9d75b3cSYann Gautier 	switch (boot_context->boot_interface_selected) {
298c9d75b3cSYann Gautier 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
299c9d75b3cSYann Gautier 		INFO("Using SDMMC\n");
300c9d75b3cSYann Gautier 		break;
301c9d75b3cSYann Gautier 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
302c9d75b3cSYann Gautier 		INFO("Using EMMC\n");
303c9d75b3cSYann Gautier 		break;
304b1b218fbSLionel Debieve 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
305b1b218fbSLionel Debieve 		INFO("Using QSPI NOR\n");
306b1b218fbSLionel Debieve 		break;
30712e21dfdSLionel Debieve 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
30812e21dfdSLionel Debieve 		INFO("Using FMC NAND\n");
30912e21dfdSLionel Debieve 		break;
31057044228SLionel Debieve 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
31157044228SLionel Debieve 		INFO("Using SPI NAND\n");
31257044228SLionel Debieve 		break;
313c9d75b3cSYann Gautier 	default:
314c9d75b3cSYann Gautier 		ERROR("Boot interface not found\n");
315c9d75b3cSYann Gautier 		panic();
316c9d75b3cSYann Gautier 		break;
317c9d75b3cSYann Gautier 	}
318c9d75b3cSYann Gautier 
319c9d75b3cSYann Gautier 	if (boot_context->boot_interface_instance != 0U) {
320c9d75b3cSYann Gautier 		INFO("  Instance %d\n", boot_context->boot_interface_instance);
321c9d75b3cSYann Gautier 	}
322c9d75b3cSYann Gautier }
323c9d75b3cSYann Gautier 
32446554b64SNicolas Le Bayon #if STM32MP_SDMMC || STM32MP_EMMC
3250b1aa772SYann Gautier static void boot_mmc(enum mmc_device_type mmc_dev_type,
3260b1aa772SYann Gautier 		     uint16_t boot_interface_instance)
327c9d75b3cSYann Gautier {
328c9d75b3cSYann Gautier 	int io_result __unused;
329c9d75b3cSYann Gautier 	uint8_t idx;
330c9d75b3cSYann Gautier 	struct stm32image_part_info *part;
331c9d75b3cSYann Gautier 	struct stm32_sdmmc2_params params;
332214c8a8dSVyacheslav Yurkov 	const partition_entry_t *entry __unused;
333214c8a8dSVyacheslav Yurkov 	uint32_t magic __unused;
334c9d75b3cSYann Gautier 
33542beea8dSYann Gautier 	zeromem(&params, sizeof(struct stm32_sdmmc2_params));
336c9d75b3cSYann Gautier 
337cddf1bd7SYann Gautier 	mmc_info.mmc_dev_type = mmc_dev_type;
338c9d75b3cSYann Gautier 
3390b1aa772SYann Gautier 	switch (boot_interface_instance) {
340c9d75b3cSYann Gautier 	case 1:
3413f9c9784SYann Gautier 		params.reg_base = STM32MP_SDMMC1_BASE;
342c9d75b3cSYann Gautier 		break;
343c9d75b3cSYann Gautier 	case 2:
3443f9c9784SYann Gautier 		params.reg_base = STM32MP_SDMMC2_BASE;
345c9d75b3cSYann Gautier 		break;
346c9d75b3cSYann Gautier 	case 3:
3473f9c9784SYann Gautier 		params.reg_base = STM32MP_SDMMC3_BASE;
348c9d75b3cSYann Gautier 		break;
349c9d75b3cSYann Gautier 	default:
350c9d75b3cSYann Gautier 		WARN("SDMMC instance not found, using default\n");
3510b1aa772SYann Gautier 		if (mmc_dev_type == MMC_IS_SD) {
3520b1aa772SYann Gautier 			params.reg_base = STM32MP_SDMMC1_BASE;
3530b1aa772SYann Gautier 		} else {
3540b1aa772SYann Gautier 			params.reg_base = STM32MP_SDMMC2_BASE;
3550b1aa772SYann Gautier 		}
356c9d75b3cSYann Gautier 		break;
357c9d75b3cSYann Gautier 	}
358c9d75b3cSYann Gautier 
359cddf1bd7SYann Gautier 	params.device_info = &mmc_info;
360c9d75b3cSYann Gautier 	if (stm32_sdmmc2_mmc_init(&params) != 0) {
3610b1aa772SYann Gautier 		ERROR("SDMMC%u init failed\n", boot_interface_instance);
362c9d75b3cSYann Gautier 		panic();
363c9d75b3cSYann Gautier 	}
364c9d75b3cSYann Gautier 
365214c8a8dSVyacheslav Yurkov 	stm32image_dev_info_spec.device_size =
366214c8a8dSVyacheslav Yurkov 		stm32_sdmmc2_mmc_get_device_size();
367214c8a8dSVyacheslav Yurkov 
368214c8a8dSVyacheslav Yurkov #if STM32MP_EMMC_BOOT
369214c8a8dSVyacheslav Yurkov 	magic = get_boot_part_ssbl_header();
370214c8a8dSVyacheslav Yurkov 
371214c8a8dSVyacheslav Yurkov 	if (magic == BOOT_API_IMAGE_HEADER_MAGIC_NB) {
372214c8a8dSVyacheslav Yurkov 		VERBOSE("%s, header found, jump to emmc load\n", __func__);
373214c8a8dSVyacheslav Yurkov 		idx = IMG_IDX_BL33;
374214c8a8dSVyacheslav Yurkov 		part = &stm32image_dev_info_spec.part_info[idx];
375214c8a8dSVyacheslav Yurkov 		part->part_offset = PLAT_EMMC_BOOT_SSBL_OFFSET;
376214c8a8dSVyacheslav Yurkov 		part->bkp_offset = 0U;
377214c8a8dSVyacheslav Yurkov 		mmc_device_spec.use_boot_part = true;
378214c8a8dSVyacheslav Yurkov 
379214c8a8dSVyacheslav Yurkov 		goto emmc_boot;
380214c8a8dSVyacheslav Yurkov 	} else {
381214c8a8dSVyacheslav Yurkov 		WARN("%s: Can't find STM32 header on a boot partition\n", __func__);
382214c8a8dSVyacheslav Yurkov 	}
383214c8a8dSVyacheslav Yurkov #endif
384214c8a8dSVyacheslav Yurkov 
385c9d75b3cSYann Gautier 	/* Open MMC as a block device to read GPT table */
386c9d75b3cSYann Gautier 	io_result = register_io_dev_block(&mmc_dev_con);
387c9d75b3cSYann Gautier 	if (io_result != 0) {
388c9d75b3cSYann Gautier 		panic();
389c9d75b3cSYann Gautier 	}
390c9d75b3cSYann Gautier 
3910b1aa772SYann Gautier 	io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec,
392c9d75b3cSYann Gautier 				&storage_dev_handle);
393c9d75b3cSYann Gautier 	assert(io_result == 0);
394c9d75b3cSYann Gautier 
395c9d75b3cSYann Gautier 	partition_init(GPT_IMAGE_ID);
396c9d75b3cSYann Gautier 
397c9d75b3cSYann Gautier 	io_result = io_dev_close(storage_dev_handle);
398c9d75b3cSYann Gautier 	assert(io_result == 0);
399c9d75b3cSYann Gautier 
400c9d75b3cSYann Gautier 	for (idx = 0U; idx < IMG_IDX_NUM; idx++) {
401c9d75b3cSYann Gautier 		part = &stm32image_dev_info_spec.part_info[idx];
402c9d75b3cSYann Gautier 		entry = get_partition_entry(part->name);
403c9d75b3cSYann Gautier 		if (entry == NULL) {
4040b1aa772SYann Gautier 			ERROR("Partition %s not found\n", part->name);
405c9d75b3cSYann Gautier 			panic();
406c9d75b3cSYann Gautier 		}
407c9d75b3cSYann Gautier 
408c9d75b3cSYann Gautier 		part->part_offset = entry->start;
409c9d75b3cSYann Gautier 		part->bkp_offset = 0U;
410c9d75b3cSYann Gautier 	}
411c9d75b3cSYann Gautier 
412214c8a8dSVyacheslav Yurkov #if STM32MP_EMMC_BOOT
413214c8a8dSVyacheslav Yurkov emmc_boot:
414214c8a8dSVyacheslav Yurkov #endif
415c9d75b3cSYann Gautier 	/*
416c9d75b3cSYann Gautier 	 * Re-open MMC with io_mmc, for better perfs compared to
417c9d75b3cSYann Gautier 	 * io_block.
418c9d75b3cSYann Gautier 	 */
419c9d75b3cSYann Gautier 	io_result = register_io_dev_mmc(&mmc_dev_con);
420c9d75b3cSYann Gautier 	assert(io_result == 0);
421c9d75b3cSYann Gautier 
422214c8a8dSVyacheslav Yurkov 	io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_device_spec,
423214c8a8dSVyacheslav Yurkov 				&storage_dev_handle);
424c9d75b3cSYann Gautier 	assert(io_result == 0);
425c9d75b3cSYann Gautier 
426c9d75b3cSYann Gautier 	io_result = register_io_dev_stm32image(&stm32image_dev_con);
427c9d75b3cSYann Gautier 	assert(io_result == 0);
428c9d75b3cSYann Gautier 
429c9d75b3cSYann Gautier 	io_result = io_dev_open(stm32image_dev_con,
430c9d75b3cSYann Gautier 				(uintptr_t)&stm32image_dev_info_spec,
431c9d75b3cSYann Gautier 				&image_dev_handle);
432c9d75b3cSYann Gautier 	assert(io_result == 0);
4330b1aa772SYann Gautier }
43446554b64SNicolas Le Bayon #endif /* STM32MP_SDMMC || STM32MP_EMMC */
4350b1aa772SYann Gautier 
436b1b218fbSLionel Debieve #if STM32MP_SPI_NOR
437b1b218fbSLionel Debieve static void boot_spi_nor(boot_api_context_t *boot_context)
438b1b218fbSLionel Debieve {
439b1b218fbSLionel Debieve 	int io_result __unused;
440b1b218fbSLionel Debieve 	uint8_t idx;
441b1b218fbSLionel Debieve 	struct stm32image_part_info *part;
442b1b218fbSLionel Debieve 
443b1b218fbSLionel Debieve 	io_result = stm32_qspi_init();
444b1b218fbSLionel Debieve 	assert(io_result == 0);
445b1b218fbSLionel Debieve 
446b1b218fbSLionel Debieve 	io_result = register_io_dev_mtd(&spi_dev_con);
447b1b218fbSLionel Debieve 	assert(io_result == 0);
448b1b218fbSLionel Debieve 
449b1b218fbSLionel Debieve 	/* Open connections to device */
450b1b218fbSLionel Debieve 	io_result = io_dev_open(spi_dev_con,
451b1b218fbSLionel Debieve 				(uintptr_t)&spi_nor_dev_spec,
452b1b218fbSLionel Debieve 				&storage_dev_handle);
453b1b218fbSLionel Debieve 	assert(io_result == 0);
454b1b218fbSLionel Debieve 
455b1b218fbSLionel Debieve 	stm32image_dev_info_spec.device_size = spi_nor_dev_spec.device_size;
456b1b218fbSLionel Debieve 
457b1b218fbSLionel Debieve 	idx = IMG_IDX_BL33;
458b1b218fbSLionel Debieve 	part = &stm32image_dev_info_spec.part_info[idx];
459b1b218fbSLionel Debieve 	part->part_offset = STM32MP_NOR_BL33_OFFSET;
460b1b218fbSLionel Debieve 	part->bkp_offset = 0U;
461b1b218fbSLionel Debieve 
462b1b218fbSLionel Debieve #ifdef AARCH32_SP_OPTEE
463b1b218fbSLionel Debieve 	idx = IMG_IDX_OPTEE_HEADER;
464b1b218fbSLionel Debieve 	part = &stm32image_dev_info_spec.part_info[idx];
465b1b218fbSLionel Debieve 	part->part_offset = STM32MP_NOR_TEEH_OFFSET;
466b1b218fbSLionel Debieve 	part->bkp_offset = 0U;
467b1b218fbSLionel Debieve 
468b1b218fbSLionel Debieve 	idx = IMG_IDX_OPTEE_PAGED;
469b1b218fbSLionel Debieve 	part = &stm32image_dev_info_spec.part_info[idx];
470b1b218fbSLionel Debieve 	part->part_offset = STM32MP_NOR_TEED_OFFSET;
471b1b218fbSLionel Debieve 	part->bkp_offset = 0U;
472b1b218fbSLionel Debieve 
47306c3b100SYann Gautier 	idx = IMG_IDX_OPTEE_CORE;
474b1b218fbSLionel Debieve 	part = &stm32image_dev_info_spec.part_info[idx];
475b1b218fbSLionel Debieve 	part->part_offset = STM32MP_NOR_TEEX_OFFSET;
476b1b218fbSLionel Debieve 	part->bkp_offset = 0U;
477b1b218fbSLionel Debieve #endif
478b1b218fbSLionel Debieve 
479b1b218fbSLionel Debieve 	io_result = register_io_dev_stm32image(&stm32image_dev_con);
480b1b218fbSLionel Debieve 	assert(io_result == 0);
481b1b218fbSLionel Debieve 
482b1b218fbSLionel Debieve 	io_result = io_dev_open(stm32image_dev_con,
483b1b218fbSLionel Debieve 				(uintptr_t)&stm32image_dev_info_spec,
484b1b218fbSLionel Debieve 				&image_dev_handle);
485b1b218fbSLionel Debieve 	assert(io_result == 0);
486b1b218fbSLionel Debieve }
487b1b218fbSLionel Debieve #endif /* STM32MP_SPI_NOR */
488b1b218fbSLionel Debieve 
48912e21dfdSLionel Debieve #if STM32MP_RAW_NAND
49012e21dfdSLionel Debieve static void boot_fmc2_nand(boot_api_context_t *boot_context)
49112e21dfdSLionel Debieve {
49212e21dfdSLionel Debieve 	int io_result __unused;
49312e21dfdSLionel Debieve 	uint8_t idx;
49412e21dfdSLionel Debieve 	struct stm32image_part_info *part;
49512e21dfdSLionel Debieve 
49612e21dfdSLionel Debieve 	io_result = stm32_fmc2_init();
49712e21dfdSLionel Debieve 	assert(io_result == 0);
49812e21dfdSLionel Debieve 
49912e21dfdSLionel Debieve 	/* Register the IO device on this platform */
50012e21dfdSLionel Debieve 	io_result = register_io_dev_mtd(&nand_dev_con);
50112e21dfdSLionel Debieve 	assert(io_result == 0);
50212e21dfdSLionel Debieve 
50312e21dfdSLionel Debieve 	/* Open connections to device */
50412e21dfdSLionel Debieve 	io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
50512e21dfdSLionel Debieve 				&storage_dev_handle);
50612e21dfdSLionel Debieve 	assert(io_result == 0);
50712e21dfdSLionel Debieve 
50812e21dfdSLionel Debieve 	stm32image_dev_info_spec.device_size = nand_dev_spec.device_size;
50912e21dfdSLionel Debieve 
51012e21dfdSLionel Debieve 	idx = IMG_IDX_BL33;
51112e21dfdSLionel Debieve 	part = &stm32image_dev_info_spec.part_info[idx];
51212e21dfdSLionel Debieve 	part->part_offset = STM32MP_NAND_BL33_OFFSET;
51312e21dfdSLionel Debieve 	part->bkp_offset = nand_dev_spec.erase_size;
51412e21dfdSLionel Debieve 
51512e21dfdSLionel Debieve #ifdef AARCH32_SP_OPTEE
51612e21dfdSLionel Debieve 	idx = IMG_IDX_OPTEE_HEADER;
51712e21dfdSLionel Debieve 	part = &stm32image_dev_info_spec.part_info[idx];
51812e21dfdSLionel Debieve 	part->part_offset = STM32MP_NAND_TEEH_OFFSET;
51912e21dfdSLionel Debieve 	part->bkp_offset = nand_dev_spec.erase_size;
52012e21dfdSLionel Debieve 
52112e21dfdSLionel Debieve 	idx = IMG_IDX_OPTEE_PAGED;
52212e21dfdSLionel Debieve 	part = &stm32image_dev_info_spec.part_info[idx];
52312e21dfdSLionel Debieve 	part->part_offset = STM32MP_NAND_TEED_OFFSET;
52412e21dfdSLionel Debieve 	part->bkp_offset = nand_dev_spec.erase_size;
52512e21dfdSLionel Debieve 
52606c3b100SYann Gautier 	idx = IMG_IDX_OPTEE_CORE;
52712e21dfdSLionel Debieve 	part = &stm32image_dev_info_spec.part_info[idx];
52812e21dfdSLionel Debieve 	part->part_offset = STM32MP_NAND_TEEX_OFFSET;
52912e21dfdSLionel Debieve 	part->bkp_offset = nand_dev_spec.erase_size;
53012e21dfdSLionel Debieve #endif
53112e21dfdSLionel Debieve 
53212e21dfdSLionel Debieve 	io_result = register_io_dev_stm32image(&stm32image_dev_con);
53312e21dfdSLionel Debieve 	assert(io_result == 0);
53412e21dfdSLionel Debieve 
53512e21dfdSLionel Debieve 	io_result = io_dev_open(stm32image_dev_con,
53612e21dfdSLionel Debieve 				(uintptr_t)&stm32image_dev_info_spec,
53712e21dfdSLionel Debieve 				&image_dev_handle);
53812e21dfdSLionel Debieve 	assert(io_result == 0);
53912e21dfdSLionel Debieve }
54012e21dfdSLionel Debieve #endif /* STM32MP_RAW_NAND */
54112e21dfdSLionel Debieve 
54257044228SLionel Debieve #if STM32MP_SPI_NAND
54357044228SLionel Debieve static void boot_spi_nand(boot_api_context_t *boot_context)
54457044228SLionel Debieve {
54557044228SLionel Debieve 	int io_result __unused;
54657044228SLionel Debieve 	uint8_t idx;
54757044228SLionel Debieve 	struct stm32image_part_info *part;
54857044228SLionel Debieve 
54957044228SLionel Debieve 	io_result = stm32_qspi_init();
55057044228SLionel Debieve 	assert(io_result == 0);
55157044228SLionel Debieve 
55257044228SLionel Debieve 	io_result = register_io_dev_mtd(&spi_dev_con);
55357044228SLionel Debieve 	assert(io_result == 0);
55457044228SLionel Debieve 
55557044228SLionel Debieve 	/* Open connections to device */
55657044228SLionel Debieve 	io_result = io_dev_open(spi_dev_con,
55757044228SLionel Debieve 				(uintptr_t)&spi_nand_dev_spec,
55857044228SLionel Debieve 				&storage_dev_handle);
55957044228SLionel Debieve 	assert(io_result == 0);
56057044228SLionel Debieve 
56157044228SLionel Debieve 	stm32image_dev_info_spec.device_size =
56257044228SLionel Debieve 		spi_nand_dev_spec.device_size;
56357044228SLionel Debieve 
56457044228SLionel Debieve 	idx = IMG_IDX_BL33;
56557044228SLionel Debieve 	part = &stm32image_dev_info_spec.part_info[idx];
56657044228SLionel Debieve 	part->part_offset = STM32MP_NAND_BL33_OFFSET;
56757044228SLionel Debieve 	part->bkp_offset = spi_nand_dev_spec.erase_size;
56857044228SLionel Debieve 
56957044228SLionel Debieve #ifdef AARCH32_SP_OPTEE
57057044228SLionel Debieve 	idx = IMG_IDX_OPTEE_HEADER;
57157044228SLionel Debieve 	part = &stm32image_dev_info_spec.part_info[idx];
57257044228SLionel Debieve 	part->part_offset = STM32MP_NAND_TEEH_OFFSET;
57357044228SLionel Debieve 	part->bkp_offset = spi_nand_dev_spec.erase_size;
57457044228SLionel Debieve 
57557044228SLionel Debieve 	idx = IMG_IDX_OPTEE_PAGED;
57657044228SLionel Debieve 	part = &stm32image_dev_info_spec.part_info[idx];
57757044228SLionel Debieve 	part->part_offset = STM32MP_NAND_TEED_OFFSET;
57857044228SLionel Debieve 	part->bkp_offset = spi_nand_dev_spec.erase_size;
57957044228SLionel Debieve 
58006c3b100SYann Gautier 	idx = IMG_IDX_OPTEE_CORE;
58157044228SLionel Debieve 	part = &stm32image_dev_info_spec.part_info[idx];
58257044228SLionel Debieve 	part->part_offset = STM32MP_NAND_TEEX_OFFSET;
58357044228SLionel Debieve 	part->bkp_offset = spi_nand_dev_spec.erase_size;
58457044228SLionel Debieve #endif
58557044228SLionel Debieve 
58657044228SLionel Debieve 	io_result = register_io_dev_stm32image(&stm32image_dev_con);
58757044228SLionel Debieve 	assert(io_result == 0);
58857044228SLionel Debieve 
58957044228SLionel Debieve 	io_result = io_dev_open(stm32image_dev_con,
59057044228SLionel Debieve 				(uintptr_t)&stm32image_dev_info_spec,
59157044228SLionel Debieve 				&image_dev_handle);
59257044228SLionel Debieve 	assert(io_result == 0);
59357044228SLionel Debieve }
59457044228SLionel Debieve #endif /* STM32MP_SPI_NAND */
59557044228SLionel Debieve 
5960b1aa772SYann Gautier void stm32mp_io_setup(void)
5970b1aa772SYann Gautier {
5980b1aa772SYann Gautier 	int io_result __unused;
5990b1aa772SYann Gautier 	boot_api_context_t *boot_context =
6000b1aa772SYann Gautier 		(boot_api_context_t *)stm32mp_get_boot_ctx_address();
6010b1aa772SYann Gautier 
6020b1aa772SYann Gautier 	print_boot_device(boot_context);
6030b1aa772SYann Gautier 
6040b1aa772SYann Gautier 	if ((boot_context->boot_partition_used_toboot == 1U) ||
6050b1aa772SYann Gautier 	    (boot_context->boot_partition_used_toboot == 2U)) {
6060b1aa772SYann Gautier 		INFO("Boot used partition fsbl%d\n",
6070b1aa772SYann Gautier 		     boot_context->boot_partition_used_toboot);
6080b1aa772SYann Gautier 	}
6090b1aa772SYann Gautier 
6103f916a41SYann Gautier #ifndef AARCH32_SP_OPTEE
6110b1aa772SYann Gautier 	io_result = register_io_dev_dummy(&dummy_dev_con);
6120b1aa772SYann Gautier 	assert(io_result == 0);
6130b1aa772SYann Gautier 
6140b1aa772SYann Gautier 	io_result = io_dev_open(dummy_dev_con, dummy_dev_spec,
6150b1aa772SYann Gautier 				&dummy_dev_handle);
6160b1aa772SYann Gautier 	assert(io_result == 0);
6173f916a41SYann Gautier #endif
6180b1aa772SYann Gautier 
6190b1aa772SYann Gautier 	switch (boot_context->boot_interface_selected) {
62046554b64SNicolas Le Bayon #if STM32MP_SDMMC
6210b1aa772SYann Gautier 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
6220b1aa772SYann Gautier 		dmbsy();
6230b1aa772SYann Gautier 		boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance);
6240b1aa772SYann Gautier 		break;
62546554b64SNicolas Le Bayon #endif
62646554b64SNicolas Le Bayon #if STM32MP_EMMC
6270b1aa772SYann Gautier 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
6280b1aa772SYann Gautier 		dmbsy();
6290b1aa772SYann Gautier 		boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance);
630c9d75b3cSYann Gautier 		break;
63146554b64SNicolas Le Bayon #endif
632b1b218fbSLionel Debieve #if STM32MP_SPI_NOR
633b1b218fbSLionel Debieve 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
634b1b218fbSLionel Debieve 		dmbsy();
635b1b218fbSLionel Debieve 		boot_spi_nor(boot_context);
636b1b218fbSLionel Debieve 		break;
637b1b218fbSLionel Debieve #endif
63812e21dfdSLionel Debieve #if STM32MP_RAW_NAND
63912e21dfdSLionel Debieve 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
64012e21dfdSLionel Debieve 		dmbsy();
64112e21dfdSLionel Debieve 		boot_fmc2_nand(boot_context);
64212e21dfdSLionel Debieve 		break;
64312e21dfdSLionel Debieve #endif
64457044228SLionel Debieve #if STM32MP_SPI_NAND
64557044228SLionel Debieve 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
64657044228SLionel Debieve 		dmbsy();
64757044228SLionel Debieve 		boot_spi_nand(boot_context);
64857044228SLionel Debieve 		break;
64957044228SLionel Debieve #endif
650c9d75b3cSYann Gautier 
651c9d75b3cSYann Gautier 	default:
652c9d75b3cSYann Gautier 		ERROR("Boot interface %d not supported\n",
653c9d75b3cSYann Gautier 		      boot_context->boot_interface_selected);
654*71693a66SYann Gautier 		panic();
655c9d75b3cSYann Gautier 		break;
656c9d75b3cSYann Gautier 	}
657c9d75b3cSYann Gautier }
658c9d75b3cSYann Gautier 
659c9d75b3cSYann Gautier /*
660c9d75b3cSYann Gautier  * Return an IO device handle and specification which can be used to access
661c9d75b3cSYann Gautier  * an image. Use this to enforce platform load policy.
662c9d75b3cSYann Gautier  */
663c9d75b3cSYann Gautier int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
664c9d75b3cSYann Gautier 			  uintptr_t *image_spec)
665c9d75b3cSYann Gautier {
666c9d75b3cSYann Gautier 	int rc;
667c9d75b3cSYann Gautier 	const struct plat_io_policy *policy;
668c9d75b3cSYann Gautier 
669c9d75b3cSYann Gautier 	assert(image_id < ARRAY_SIZE(policies));
670c9d75b3cSYann Gautier 
671c9d75b3cSYann Gautier 	policy = &policies[image_id];
672c9d75b3cSYann Gautier 	rc = policy->check(policy->image_spec);
673c9d75b3cSYann Gautier 	if (rc == 0) {
674c9d75b3cSYann Gautier 		*image_spec = policy->image_spec;
675c9d75b3cSYann Gautier 		*dev_handle = *(policy->dev_handle);
676c9d75b3cSYann Gautier 	}
677c9d75b3cSYann Gautier 
678c9d75b3cSYann Gautier 	return rc;
679c9d75b3cSYann Gautier }
680