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(¶ms, 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(¶ms) != 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