xref: /rk3399_ARM-atf/plat/st/common/bl2_io_storage.c (revision 1d204ee4ab12893fceb12097bd4f0a074be253b2)
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 <arch_helpers.h>
11c9d75b3cSYann Gautier #include <common/debug.h>
12c9d75b3cSYann Gautier #include <drivers/io/io_block.h>
13c9d75b3cSYann Gautier #include <drivers/io/io_driver.h>
14*1d204ee4SYann Gautier #include <drivers/io/io_fip.h>
1512e21dfdSLionel Debieve #include <drivers/io/io_mtd.h>
16c9d75b3cSYann Gautier #include <drivers/io/io_storage.h>
17c9d75b3cSYann Gautier #include <drivers/mmc.h>
18c9d75b3cSYann Gautier #include <drivers/partition/partition.h>
1912e21dfdSLionel Debieve #include <drivers/raw_nand.h>
2057044228SLionel Debieve #include <drivers/spi_nand.h>
21b1b218fbSLionel Debieve #include <drivers/spi_nor.h>
22c9d75b3cSYann Gautier #include <drivers/st/io_mmc.h>
2312e21dfdSLionel Debieve #include <drivers/st/stm32_fmc2_nand.h>
2457044228SLionel Debieve #include <drivers/st/stm32_qspi.h>
25c9d75b3cSYann Gautier #include <drivers/st/stm32_sdmmc2.h>
26c9d75b3cSYann Gautier #include <lib/mmio.h>
27c9d75b3cSYann Gautier #include <lib/utils.h>
28c9d75b3cSYann Gautier #include <plat/common/platform.h>
29*1d204ee4SYann Gautier #include <tools_share/firmware_image_package.h>
30*1d204ee4SYann Gautier 
31*1d204ee4SYann Gautier #include <platform_def.h>
32c9d75b3cSYann Gautier 
33c9d75b3cSYann Gautier /* IO devices */
34*1d204ee4SYann Gautier uintptr_t fip_dev_handle;
35*1d204ee4SYann Gautier uintptr_t storage_dev_handle;
36c9d75b3cSYann Gautier 
37*1d204ee4SYann Gautier static const io_dev_connector_t *fip_dev_con;
38c9d75b3cSYann Gautier 
3946554b64SNicolas Le Bayon #if STM32MP_SDMMC || STM32MP_EMMC
40cddf1bd7SYann Gautier static struct mmc_device_info mmc_info;
41c9d75b3cSYann Gautier static io_block_spec_t gpt_block_spec = {
42*1d204ee4SYann Gautier 	.offset = 0U,
43*1d204ee4SYann Gautier 	.length = 34U * MMC_BLOCK_SIZE, /* Size of GPT table */
44c9d75b3cSYann Gautier };
45c9d75b3cSYann Gautier 
46c9d75b3cSYann Gautier static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE);
47c9d75b3cSYann Gautier 
48c9d75b3cSYann Gautier static const io_block_dev_spec_t mmc_block_dev_spec = {
49c9d75b3cSYann Gautier 	/* It's used as temp buffer in block driver */
50c9d75b3cSYann Gautier 	.buffer = {
51c9d75b3cSYann Gautier 		.offset = (size_t)&block_buffer,
52c9d75b3cSYann Gautier 		.length = MMC_BLOCK_SIZE,
53c9d75b3cSYann Gautier 	},
54c9d75b3cSYann Gautier 	.ops = {
55c9d75b3cSYann Gautier 		.read = mmc_read_blocks,
56c9d75b3cSYann Gautier 		.write = NULL,
57c9d75b3cSYann Gautier 	},
58c9d75b3cSYann Gautier 	.block_size = MMC_BLOCK_SIZE,
59c9d75b3cSYann Gautier };
60c9d75b3cSYann Gautier 
61c9d75b3cSYann Gautier static const io_dev_connector_t *mmc_dev_con;
6246554b64SNicolas Le Bayon #endif /* STM32MP_SDMMC || STM32MP_EMMC */
63c9d75b3cSYann Gautier 
64b1b218fbSLionel Debieve #if STM32MP_SPI_NOR
65b1b218fbSLionel Debieve static io_mtd_dev_spec_t spi_nor_dev_spec = {
66b1b218fbSLionel Debieve 	.ops = {
67b1b218fbSLionel Debieve 		.init = spi_nor_init,
68b1b218fbSLionel Debieve 		.read = spi_nor_read,
69b1b218fbSLionel Debieve 	},
70b1b218fbSLionel Debieve };
71b1b218fbSLionel Debieve #endif
72b1b218fbSLionel Debieve 
7312e21dfdSLionel Debieve #if STM32MP_RAW_NAND
7412e21dfdSLionel Debieve static io_mtd_dev_spec_t nand_dev_spec = {
7512e21dfdSLionel Debieve 	.ops = {
7612e21dfdSLionel Debieve 		.init = nand_raw_init,
7712e21dfdSLionel Debieve 		.read = nand_read,
78*1d204ee4SYann Gautier 		.seek = nand_seek_bb
7912e21dfdSLionel Debieve 	},
8012e21dfdSLionel Debieve };
8112e21dfdSLionel Debieve 
8212e21dfdSLionel Debieve static const io_dev_connector_t *nand_dev_con;
8312e21dfdSLionel Debieve #endif
8412e21dfdSLionel Debieve 
8557044228SLionel Debieve #if STM32MP_SPI_NAND
8657044228SLionel Debieve static io_mtd_dev_spec_t spi_nand_dev_spec = {
8757044228SLionel Debieve 	.ops = {
8857044228SLionel Debieve 		.init = spi_nand_init,
8957044228SLionel Debieve 		.read = nand_read,
90*1d204ee4SYann Gautier 		.seek = nand_seek_bb
9157044228SLionel Debieve 	},
9257044228SLionel Debieve };
93b1b218fbSLionel Debieve #endif
9457044228SLionel Debieve 
95b1b218fbSLionel Debieve #if STM32MP_SPI_NAND || STM32MP_SPI_NOR
9657044228SLionel Debieve static const io_dev_connector_t *spi_dev_con;
9757044228SLionel Debieve #endif
9857044228SLionel Debieve 
99*1d204ee4SYann Gautier static const io_uuid_spec_t bl33_partition_spec = {
100*1d204ee4SYann Gautier 	.uuid = UUID_NON_TRUSTED_FIRMWARE_BL33
101*1d204ee4SYann Gautier };
102*1d204ee4SYann Gautier 
103*1d204ee4SYann Gautier static const io_uuid_spec_t tos_fw_config_uuid_spec = {
104*1d204ee4SYann Gautier 	.uuid = UUID_TOS_FW_CONFIG,
105*1d204ee4SYann Gautier };
106*1d204ee4SYann Gautier 
107*1d204ee4SYann Gautier static const io_uuid_spec_t hw_config_uuid_spec = {
108*1d204ee4SYann Gautier 	.uuid = UUID_HW_CONFIG,
109*1d204ee4SYann Gautier };
110*1d204ee4SYann Gautier 
1111989a19cSYann Gautier #ifdef AARCH32_SP_OPTEE
112*1d204ee4SYann Gautier static const io_uuid_spec_t optee_header_partition_spec = {
113*1d204ee4SYann Gautier 	.uuid = UUID_SECURE_PAYLOAD_BL32
1141989a19cSYann Gautier };
1151989a19cSYann Gautier 
116*1d204ee4SYann Gautier static const io_uuid_spec_t optee_core_partition_spec = {
117*1d204ee4SYann Gautier 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA1
1181989a19cSYann Gautier };
1191989a19cSYann Gautier 
120*1d204ee4SYann Gautier static const io_uuid_spec_t optee_paged_partition_spec = {
121*1d204ee4SYann Gautier 	.uuid = UUID_SECURE_PAYLOAD_BL32_EXTRA2
1221989a19cSYann Gautier };
1231989a19cSYann Gautier #else
124*1d204ee4SYann Gautier static const io_uuid_spec_t bl32_partition_spec = {
125*1d204ee4SYann Gautier 	.uuid = UUID_SECURE_PAYLOAD_BL32
126c9d75b3cSYann Gautier };
1271989a19cSYann Gautier #endif
128c9d75b3cSYann Gautier 
129*1d204ee4SYann Gautier static io_block_spec_t image_block_spec = {
130*1d204ee4SYann Gautier 	.offset = 0U,
131*1d204ee4SYann Gautier 	.length = 0U,
132c9d75b3cSYann Gautier };
133c9d75b3cSYann Gautier 
134*1d204ee4SYann Gautier static int open_fip(const uintptr_t spec);
135c9d75b3cSYann Gautier static int open_storage(const uintptr_t spec);
136c9d75b3cSYann Gautier 
137c9d75b3cSYann Gautier struct plat_io_policy {
138c9d75b3cSYann Gautier 	uintptr_t *dev_handle;
139c9d75b3cSYann Gautier 	uintptr_t image_spec;
140c9d75b3cSYann Gautier 	int (*check)(const uintptr_t spec);
141c9d75b3cSYann Gautier };
142c9d75b3cSYann Gautier 
143c9d75b3cSYann Gautier static const struct plat_io_policy policies[] = {
144*1d204ee4SYann Gautier 	[FIP_IMAGE_ID] = {
145*1d204ee4SYann Gautier 		.dev_handle = &storage_dev_handle,
146*1d204ee4SYann Gautier 		.image_spec = (uintptr_t)&image_block_spec,
147*1d204ee4SYann Gautier 		.check = open_storage
148*1d204ee4SYann Gautier 	},
1491989a19cSYann Gautier #ifdef AARCH32_SP_OPTEE
1501989a19cSYann Gautier 	[BL32_IMAGE_ID] = {
151*1d204ee4SYann Gautier 		.dev_handle = &fip_dev_handle,
1521989a19cSYann Gautier 		.image_spec = (uintptr_t)&optee_header_partition_spec,
153*1d204ee4SYann Gautier 		.check = open_fip
1541989a19cSYann Gautier 	},
1551989a19cSYann Gautier 	[BL32_EXTRA1_IMAGE_ID] = {
156*1d204ee4SYann Gautier 		.dev_handle = &fip_dev_handle,
15706c3b100SYann Gautier 		.image_spec = (uintptr_t)&optee_core_partition_spec,
158*1d204ee4SYann Gautier 		.check = open_fip
1591989a19cSYann Gautier 	},
1601989a19cSYann Gautier 	[BL32_EXTRA2_IMAGE_ID] = {
161*1d204ee4SYann Gautier 		.dev_handle = &fip_dev_handle,
1621989a19cSYann Gautier 		.image_spec = (uintptr_t)&optee_paged_partition_spec,
163*1d204ee4SYann Gautier 		.check = open_fip
1641989a19cSYann Gautier 	},
1651989a19cSYann Gautier #else
166c9d75b3cSYann Gautier 	[BL32_IMAGE_ID] = {
167*1d204ee4SYann Gautier 		.dev_handle = &fip_dev_handle,
168*1d204ee4SYann Gautier 		.image_spec = (uintptr_t)&bl32_partition_spec,
169*1d204ee4SYann Gautier 		.check = open_fip
170c9d75b3cSYann Gautier 	},
1711989a19cSYann Gautier #endif
172c9d75b3cSYann Gautier 	[BL33_IMAGE_ID] = {
173*1d204ee4SYann Gautier 		.dev_handle = &fip_dev_handle,
174c9d75b3cSYann Gautier 		.image_spec = (uintptr_t)&bl33_partition_spec,
175*1d204ee4SYann Gautier 		.check = open_fip
176*1d204ee4SYann Gautier 	},
177*1d204ee4SYann Gautier 	[TOS_FW_CONFIG_ID] = {
178*1d204ee4SYann Gautier 		.dev_handle = &fip_dev_handle,
179*1d204ee4SYann Gautier 		.image_spec = (uintptr_t)&tos_fw_config_uuid_spec,
180*1d204ee4SYann Gautier 		.check = open_fip
181*1d204ee4SYann Gautier 	},
182*1d204ee4SYann Gautier 	[HW_CONFIG_ID] = {
183*1d204ee4SYann Gautier 		.dev_handle = &fip_dev_handle,
184*1d204ee4SYann Gautier 		.image_spec = (uintptr_t)&hw_config_uuid_spec,
185*1d204ee4SYann Gautier 		.check = open_fip
186c9d75b3cSYann Gautier 	},
18746554b64SNicolas Le Bayon #if STM32MP_SDMMC || STM32MP_EMMC
188c9d75b3cSYann Gautier 	[GPT_IMAGE_ID] = {
189c9d75b3cSYann Gautier 		.dev_handle = &storage_dev_handle,
190c9d75b3cSYann Gautier 		.image_spec = (uintptr_t)&gpt_block_spec,
191c9d75b3cSYann Gautier 		.check = open_storage
192c9d75b3cSYann Gautier 	},
19346554b64SNicolas Le Bayon #endif
194c9d75b3cSYann Gautier };
195c9d75b3cSYann Gautier 
196*1d204ee4SYann Gautier static int open_fip(const uintptr_t spec)
197c9d75b3cSYann Gautier {
198*1d204ee4SYann Gautier 	return io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID);
199c9d75b3cSYann Gautier }
200c9d75b3cSYann Gautier 
201c9d75b3cSYann Gautier static int open_storage(const uintptr_t spec)
202c9d75b3cSYann Gautier {
203c9d75b3cSYann Gautier 	return io_dev_init(storage_dev_handle, 0);
204c9d75b3cSYann Gautier }
205c9d75b3cSYann Gautier 
206c9d75b3cSYann Gautier static void print_boot_device(boot_api_context_t *boot_context)
207c9d75b3cSYann Gautier {
208c9d75b3cSYann Gautier 	switch (boot_context->boot_interface_selected) {
209c9d75b3cSYann Gautier 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
210c9d75b3cSYann Gautier 		INFO("Using SDMMC\n");
211c9d75b3cSYann Gautier 		break;
212c9d75b3cSYann Gautier 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
213c9d75b3cSYann Gautier 		INFO("Using EMMC\n");
214c9d75b3cSYann Gautier 		break;
215b1b218fbSLionel Debieve 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
216b1b218fbSLionel Debieve 		INFO("Using QSPI NOR\n");
217b1b218fbSLionel Debieve 		break;
21812e21dfdSLionel Debieve 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
21912e21dfdSLionel Debieve 		INFO("Using FMC NAND\n");
22012e21dfdSLionel Debieve 		break;
22157044228SLionel Debieve 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
22257044228SLionel Debieve 		INFO("Using SPI NAND\n");
22357044228SLionel Debieve 		break;
224c9d75b3cSYann Gautier 	default:
225*1d204ee4SYann Gautier 		ERROR("Boot interface %u not found\n",
226*1d204ee4SYann Gautier 		      boot_context->boot_interface_selected);
227c9d75b3cSYann Gautier 		panic();
228c9d75b3cSYann Gautier 		break;
229c9d75b3cSYann Gautier 	}
230c9d75b3cSYann Gautier 
231c9d75b3cSYann Gautier 	if (boot_context->boot_interface_instance != 0U) {
232c9d75b3cSYann Gautier 		INFO("  Instance %d\n", boot_context->boot_interface_instance);
233c9d75b3cSYann Gautier 	}
234c9d75b3cSYann Gautier }
235c9d75b3cSYann Gautier 
23646554b64SNicolas Le Bayon #if STM32MP_SDMMC || STM32MP_EMMC
2370b1aa772SYann Gautier static void boot_mmc(enum mmc_device_type mmc_dev_type,
2380b1aa772SYann Gautier 		     uint16_t boot_interface_instance)
239c9d75b3cSYann Gautier {
240c9d75b3cSYann Gautier 	int io_result __unused;
241c9d75b3cSYann Gautier 	struct stm32_sdmmc2_params params;
242c9d75b3cSYann Gautier 
24342beea8dSYann Gautier 	zeromem(&params, sizeof(struct stm32_sdmmc2_params));
244c9d75b3cSYann Gautier 
245cddf1bd7SYann Gautier 	mmc_info.mmc_dev_type = mmc_dev_type;
246c9d75b3cSYann Gautier 
2470b1aa772SYann Gautier 	switch (boot_interface_instance) {
248c9d75b3cSYann Gautier 	case 1:
2493f9c9784SYann Gautier 		params.reg_base = STM32MP_SDMMC1_BASE;
250c9d75b3cSYann Gautier 		break;
251c9d75b3cSYann Gautier 	case 2:
2523f9c9784SYann Gautier 		params.reg_base = STM32MP_SDMMC2_BASE;
253c9d75b3cSYann Gautier 		break;
254c9d75b3cSYann Gautier 	case 3:
2553f9c9784SYann Gautier 		params.reg_base = STM32MP_SDMMC3_BASE;
256c9d75b3cSYann Gautier 		break;
257c9d75b3cSYann Gautier 	default:
258c9d75b3cSYann Gautier 		WARN("SDMMC instance not found, using default\n");
2590b1aa772SYann Gautier 		if (mmc_dev_type == MMC_IS_SD) {
2600b1aa772SYann Gautier 			params.reg_base = STM32MP_SDMMC1_BASE;
2610b1aa772SYann Gautier 		} else {
2620b1aa772SYann Gautier 			params.reg_base = STM32MP_SDMMC2_BASE;
2630b1aa772SYann Gautier 		}
264c9d75b3cSYann Gautier 		break;
265c9d75b3cSYann Gautier 	}
266c9d75b3cSYann Gautier 
267cddf1bd7SYann Gautier 	params.device_info = &mmc_info;
268c9d75b3cSYann Gautier 	if (stm32_sdmmc2_mmc_init(&params) != 0) {
2690b1aa772SYann Gautier 		ERROR("SDMMC%u init failed\n", boot_interface_instance);
270c9d75b3cSYann Gautier 		panic();
271c9d75b3cSYann Gautier 	}
272c9d75b3cSYann Gautier 
273c9d75b3cSYann Gautier 	/* Open MMC as a block device to read GPT table */
274c9d75b3cSYann Gautier 	io_result = register_io_dev_block(&mmc_dev_con);
275c9d75b3cSYann Gautier 	if (io_result != 0) {
276c9d75b3cSYann Gautier 		panic();
277c9d75b3cSYann Gautier 	}
278c9d75b3cSYann Gautier 
2790b1aa772SYann Gautier 	io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec,
280c9d75b3cSYann Gautier 				&storage_dev_handle);
281c9d75b3cSYann Gautier 	assert(io_result == 0);
2820b1aa772SYann Gautier }
28346554b64SNicolas Le Bayon #endif /* STM32MP_SDMMC || STM32MP_EMMC */
2840b1aa772SYann Gautier 
285b1b218fbSLionel Debieve #if STM32MP_SPI_NOR
286b1b218fbSLionel Debieve static void boot_spi_nor(boot_api_context_t *boot_context)
287b1b218fbSLionel Debieve {
288b1b218fbSLionel Debieve 	int io_result __unused;
289b1b218fbSLionel Debieve 
290b1b218fbSLionel Debieve 	io_result = stm32_qspi_init();
291b1b218fbSLionel Debieve 	assert(io_result == 0);
292b1b218fbSLionel Debieve 
293b1b218fbSLionel Debieve 	io_result = register_io_dev_mtd(&spi_dev_con);
294b1b218fbSLionel Debieve 	assert(io_result == 0);
295b1b218fbSLionel Debieve 
296b1b218fbSLionel Debieve 	/* Open connections to device */
297b1b218fbSLionel Debieve 	io_result = io_dev_open(spi_dev_con,
298b1b218fbSLionel Debieve 				(uintptr_t)&spi_nor_dev_spec,
299b1b218fbSLionel Debieve 				&storage_dev_handle);
300b1b218fbSLionel Debieve 	assert(io_result == 0);
301b1b218fbSLionel Debieve }
302b1b218fbSLionel Debieve #endif /* STM32MP_SPI_NOR */
303b1b218fbSLionel Debieve 
30412e21dfdSLionel Debieve #if STM32MP_RAW_NAND
30512e21dfdSLionel Debieve static void boot_fmc2_nand(boot_api_context_t *boot_context)
30612e21dfdSLionel Debieve {
30712e21dfdSLionel Debieve 	int io_result __unused;
30812e21dfdSLionel Debieve 
30912e21dfdSLionel Debieve 	io_result = stm32_fmc2_init();
31012e21dfdSLionel Debieve 	assert(io_result == 0);
31112e21dfdSLionel Debieve 
31212e21dfdSLionel Debieve 	/* Register the IO device on this platform */
31312e21dfdSLionel Debieve 	io_result = register_io_dev_mtd(&nand_dev_con);
31412e21dfdSLionel Debieve 	assert(io_result == 0);
31512e21dfdSLionel Debieve 
31612e21dfdSLionel Debieve 	/* Open connections to device */
31712e21dfdSLionel Debieve 	io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec,
31812e21dfdSLionel Debieve 				&storage_dev_handle);
31912e21dfdSLionel Debieve 	assert(io_result == 0);
32012e21dfdSLionel Debieve }
32112e21dfdSLionel Debieve #endif /* STM32MP_RAW_NAND */
32212e21dfdSLionel Debieve 
32357044228SLionel Debieve #if STM32MP_SPI_NAND
32457044228SLionel Debieve static void boot_spi_nand(boot_api_context_t *boot_context)
32557044228SLionel Debieve {
32657044228SLionel Debieve 	int io_result __unused;
32757044228SLionel Debieve 
32857044228SLionel Debieve 	io_result = stm32_qspi_init();
32957044228SLionel Debieve 	assert(io_result == 0);
33057044228SLionel Debieve 
33157044228SLionel Debieve 	io_result = register_io_dev_mtd(&spi_dev_con);
33257044228SLionel Debieve 	assert(io_result == 0);
33357044228SLionel Debieve 
33457044228SLionel Debieve 	/* Open connections to device */
33557044228SLionel Debieve 	io_result = io_dev_open(spi_dev_con,
33657044228SLionel Debieve 				(uintptr_t)&spi_nand_dev_spec,
33757044228SLionel Debieve 				&storage_dev_handle);
33857044228SLionel Debieve 	assert(io_result == 0);
33957044228SLionel Debieve }
34057044228SLionel Debieve #endif /* STM32MP_SPI_NAND */
34157044228SLionel Debieve 
3420b1aa772SYann Gautier void stm32mp_io_setup(void)
3430b1aa772SYann Gautier {
3440b1aa772SYann Gautier 	int io_result __unused;
3450b1aa772SYann Gautier 	boot_api_context_t *boot_context =
3460b1aa772SYann Gautier 		(boot_api_context_t *)stm32mp_get_boot_ctx_address();
3470b1aa772SYann Gautier 
3480b1aa772SYann Gautier 	print_boot_device(boot_context);
3490b1aa772SYann Gautier 
3500b1aa772SYann Gautier 	if ((boot_context->boot_partition_used_toboot == 1U) ||
3510b1aa772SYann Gautier 	    (boot_context->boot_partition_used_toboot == 2U)) {
352*1d204ee4SYann Gautier 		INFO("Boot used partition fsbl%u\n",
3530b1aa772SYann Gautier 		     boot_context->boot_partition_used_toboot);
3540b1aa772SYann Gautier 	}
3550b1aa772SYann Gautier 
356*1d204ee4SYann Gautier 	io_result = register_io_dev_fip(&fip_dev_con);
3570b1aa772SYann Gautier 	assert(io_result == 0);
3580b1aa772SYann Gautier 
359*1d204ee4SYann Gautier 	io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL,
360*1d204ee4SYann Gautier 				&fip_dev_handle);
3610b1aa772SYann Gautier 
3620b1aa772SYann Gautier 	switch (boot_context->boot_interface_selected) {
36346554b64SNicolas Le Bayon #if STM32MP_SDMMC
3640b1aa772SYann Gautier 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
3650b1aa772SYann Gautier 		dmbsy();
3660b1aa772SYann Gautier 		boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance);
3670b1aa772SYann Gautier 		break;
36846554b64SNicolas Le Bayon #endif
36946554b64SNicolas Le Bayon #if STM32MP_EMMC
3700b1aa772SYann Gautier 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
3710b1aa772SYann Gautier 		dmbsy();
3720b1aa772SYann Gautier 		boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance);
373c9d75b3cSYann Gautier 		break;
37446554b64SNicolas Le Bayon #endif
375b1b218fbSLionel Debieve #if STM32MP_SPI_NOR
376b1b218fbSLionel Debieve 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
377b1b218fbSLionel Debieve 		dmbsy();
378b1b218fbSLionel Debieve 		boot_spi_nor(boot_context);
379b1b218fbSLionel Debieve 		break;
380b1b218fbSLionel Debieve #endif
38112e21dfdSLionel Debieve #if STM32MP_RAW_NAND
38212e21dfdSLionel Debieve 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
38312e21dfdSLionel Debieve 		dmbsy();
38412e21dfdSLionel Debieve 		boot_fmc2_nand(boot_context);
38512e21dfdSLionel Debieve 		break;
38612e21dfdSLionel Debieve #endif
38757044228SLionel Debieve #if STM32MP_SPI_NAND
38857044228SLionel Debieve 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
38957044228SLionel Debieve 		dmbsy();
39057044228SLionel Debieve 		boot_spi_nand(boot_context);
39157044228SLionel Debieve 		break;
39257044228SLionel Debieve #endif
393c9d75b3cSYann Gautier 
394c9d75b3cSYann Gautier 	default:
395c9d75b3cSYann Gautier 		ERROR("Boot interface %d not supported\n",
396c9d75b3cSYann Gautier 		      boot_context->boot_interface_selected);
39771693a66SYann Gautier 		panic();
398c9d75b3cSYann Gautier 		break;
399c9d75b3cSYann Gautier 	}
400c9d75b3cSYann Gautier }
401c9d75b3cSYann Gautier 
402*1d204ee4SYann Gautier int bl2_plat_handle_pre_image_load(unsigned int image_id)
403*1d204ee4SYann Gautier {
404*1d204ee4SYann Gautier 	static bool gpt_init_done __unused;
405*1d204ee4SYann Gautier 	uint16_t boot_itf = stm32mp_get_boot_itf_selected();
406*1d204ee4SYann Gautier 
407*1d204ee4SYann Gautier 	switch (boot_itf) {
408*1d204ee4SYann Gautier #if STM32MP_SDMMC || STM32MP_EMMC
409*1d204ee4SYann Gautier 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD:
410*1d204ee4SYann Gautier 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC:
411*1d204ee4SYann Gautier 		if (!gpt_init_done) {
412*1d204ee4SYann Gautier 			const partition_entry_t *entry;
413*1d204ee4SYann Gautier 
414*1d204ee4SYann Gautier 			partition_init(GPT_IMAGE_ID);
415*1d204ee4SYann Gautier 			entry = get_partition_entry(FIP_IMAGE_NAME);
416*1d204ee4SYann Gautier 			if (entry == NULL) {
417*1d204ee4SYann Gautier 				ERROR("Could NOT find the %s partition!\n",
418*1d204ee4SYann Gautier 				      FIP_IMAGE_NAME);
419*1d204ee4SYann Gautier 				return -ENOENT;
420*1d204ee4SYann Gautier 			}
421*1d204ee4SYann Gautier 
422*1d204ee4SYann Gautier 			image_block_spec.offset = entry->start;
423*1d204ee4SYann Gautier 			image_block_spec.length = entry->length;
424*1d204ee4SYann Gautier 
425*1d204ee4SYann Gautier 			gpt_init_done = true;
426*1d204ee4SYann Gautier 		}
427*1d204ee4SYann Gautier 
428*1d204ee4SYann Gautier 		break;
429*1d204ee4SYann Gautier #endif
430*1d204ee4SYann Gautier 
431*1d204ee4SYann Gautier #if STM32MP_RAW_NAND || STM32MP_SPI_NAND
432*1d204ee4SYann Gautier #if STM32MP_RAW_NAND
433*1d204ee4SYann Gautier 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC:
434*1d204ee4SYann Gautier #endif
435*1d204ee4SYann Gautier #if STM32MP_SPI_NAND
436*1d204ee4SYann Gautier 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI:
437*1d204ee4SYann Gautier #endif
438*1d204ee4SYann Gautier 		image_block_spec.offset = STM32MP_NAND_FIP_OFFSET;
439*1d204ee4SYann Gautier 		break;
440*1d204ee4SYann Gautier #endif
441*1d204ee4SYann Gautier 
442*1d204ee4SYann Gautier #if STM32MP_SPI_NOR
443*1d204ee4SYann Gautier 	case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI:
444*1d204ee4SYann Gautier 		image_block_spec.offset = STM32MP_NOR_FIP_OFFSET;
445*1d204ee4SYann Gautier 		break;
446*1d204ee4SYann Gautier #endif
447*1d204ee4SYann Gautier 
448*1d204ee4SYann Gautier 	default:
449*1d204ee4SYann Gautier 		ERROR("FIP Not found\n");
450*1d204ee4SYann Gautier 		panic();
451*1d204ee4SYann Gautier 	}
452*1d204ee4SYann Gautier 
453*1d204ee4SYann Gautier 	return 0;
454*1d204ee4SYann Gautier }
455*1d204ee4SYann Gautier 
456c9d75b3cSYann Gautier /*
457c9d75b3cSYann Gautier  * Return an IO device handle and specification which can be used to access
458c9d75b3cSYann Gautier  * an image. Use this to enforce platform load policy.
459c9d75b3cSYann Gautier  */
460c9d75b3cSYann Gautier int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle,
461c9d75b3cSYann Gautier 			  uintptr_t *image_spec)
462c9d75b3cSYann Gautier {
463c9d75b3cSYann Gautier 	int rc;
464c9d75b3cSYann Gautier 	const struct plat_io_policy *policy;
465c9d75b3cSYann Gautier 
466c9d75b3cSYann Gautier 	assert(image_id < ARRAY_SIZE(policies));
467c9d75b3cSYann Gautier 
468c9d75b3cSYann Gautier 	policy = &policies[image_id];
469c9d75b3cSYann Gautier 	rc = policy->check(policy->image_spec);
470c9d75b3cSYann Gautier 	if (rc == 0) {
471c9d75b3cSYann Gautier 		*image_spec = policy->image_spec;
472c9d75b3cSYann Gautier 		*dev_handle = *(policy->dev_handle);
473c9d75b3cSYann Gautier 	}
474c9d75b3cSYann Gautier 
475c9d75b3cSYann Gautier 	return rc;
476c9d75b3cSYann Gautier }
477