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> 1218b415beSYann Gautier #include <common/desc_image_load.h> 13c9d75b3cSYann Gautier #include <drivers/io/io_block.h> 14c9d75b3cSYann Gautier #include <drivers/io/io_driver.h> 151d204ee4SYann Gautier #include <drivers/io/io_fip.h> 16*fa92fef0SPatrick Delaunay #include <drivers/io/io_memmap.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> 2512e21dfdSLionel Debieve #include <drivers/st/stm32_fmc2_nand.h> 2657044228SLionel Debieve #include <drivers/st/stm32_qspi.h> 27c9d75b3cSYann Gautier #include <drivers/st/stm32_sdmmc2.h> 28*fa92fef0SPatrick Delaunay #include <drivers/usb_device.h> 29d5a84eeaSYann Gautier #include <lib/fconf/fconf.h> 30c9d75b3cSYann Gautier #include <lib/mmio.h> 31c9d75b3cSYann Gautier #include <lib/utils.h> 32c9d75b3cSYann Gautier #include <plat/common/platform.h> 331d204ee4SYann Gautier #include <tools_share/firmware_image_package.h> 341d204ee4SYann Gautier 351d204ee4SYann Gautier #include <platform_def.h> 36*fa92fef0SPatrick Delaunay #include <stm32cubeprogrammer.h> 37d5a84eeaSYann Gautier #include <stm32mp_fconf_getter.h> 38*fa92fef0SPatrick Delaunay #include <usb_dfu.h> 39c9d75b3cSYann Gautier 40c9d75b3cSYann Gautier /* IO devices */ 411d204ee4SYann Gautier uintptr_t fip_dev_handle; 421d204ee4SYann Gautier uintptr_t storage_dev_handle; 43c9d75b3cSYann Gautier 441d204ee4SYann Gautier static const io_dev_connector_t *fip_dev_con; 45c9d75b3cSYann Gautier 4646554b64SNicolas Le Bayon #if STM32MP_SDMMC || STM32MP_EMMC 47cddf1bd7SYann Gautier static struct mmc_device_info mmc_info; 48c9d75b3cSYann Gautier 49c9d75b3cSYann Gautier static uint32_t block_buffer[MMC_BLOCK_SIZE] __aligned(MMC_BLOCK_SIZE); 50c9d75b3cSYann Gautier 5118b415beSYann Gautier static io_block_dev_spec_t mmc_block_dev_spec = { 52c9d75b3cSYann Gautier /* It's used as temp buffer in block driver */ 53c9d75b3cSYann Gautier .buffer = { 54c9d75b3cSYann Gautier .offset = (size_t)&block_buffer, 55c9d75b3cSYann Gautier .length = MMC_BLOCK_SIZE, 56c9d75b3cSYann Gautier }, 57c9d75b3cSYann Gautier .ops = { 58c9d75b3cSYann Gautier .read = mmc_read_blocks, 59c9d75b3cSYann Gautier .write = NULL, 60c9d75b3cSYann Gautier }, 61c9d75b3cSYann Gautier .block_size = MMC_BLOCK_SIZE, 62c9d75b3cSYann Gautier }; 63c9d75b3cSYann Gautier 64c9d75b3cSYann Gautier static const io_dev_connector_t *mmc_dev_con; 6546554b64SNicolas Le Bayon #endif /* STM32MP_SDMMC || STM32MP_EMMC */ 66c9d75b3cSYann Gautier 67b1b218fbSLionel Debieve #if STM32MP_SPI_NOR 68b1b218fbSLionel Debieve static io_mtd_dev_spec_t spi_nor_dev_spec = { 69b1b218fbSLionel Debieve .ops = { 70b1b218fbSLionel Debieve .init = spi_nor_init, 71b1b218fbSLionel Debieve .read = spi_nor_read, 72b1b218fbSLionel Debieve }, 73b1b218fbSLionel Debieve }; 74b1b218fbSLionel Debieve #endif 75b1b218fbSLionel Debieve 7612e21dfdSLionel Debieve #if STM32MP_RAW_NAND 7712e21dfdSLionel Debieve static io_mtd_dev_spec_t nand_dev_spec = { 7812e21dfdSLionel Debieve .ops = { 7912e21dfdSLionel Debieve .init = nand_raw_init, 8012e21dfdSLionel Debieve .read = nand_read, 811d204ee4SYann Gautier .seek = nand_seek_bb 8212e21dfdSLionel Debieve }, 8312e21dfdSLionel Debieve }; 8412e21dfdSLionel Debieve 8512e21dfdSLionel Debieve static const io_dev_connector_t *nand_dev_con; 8612e21dfdSLionel Debieve #endif 8712e21dfdSLionel Debieve 8857044228SLionel Debieve #if STM32MP_SPI_NAND 8957044228SLionel Debieve static io_mtd_dev_spec_t spi_nand_dev_spec = { 9057044228SLionel Debieve .ops = { 9157044228SLionel Debieve .init = spi_nand_init, 9257044228SLionel Debieve .read = nand_read, 931d204ee4SYann Gautier .seek = nand_seek_bb 9457044228SLionel Debieve }, 9557044228SLionel Debieve }; 96b1b218fbSLionel Debieve #endif 9757044228SLionel Debieve 98b1b218fbSLionel Debieve #if STM32MP_SPI_NAND || STM32MP_SPI_NOR 9957044228SLionel Debieve static const io_dev_connector_t *spi_dev_con; 10057044228SLionel Debieve #endif 10157044228SLionel Debieve 102*fa92fef0SPatrick Delaunay #if STM32MP_USB_PROGRAMMER 103*fa92fef0SPatrick Delaunay static const io_dev_connector_t *memmap_dev_con; 104*fa92fef0SPatrick Delaunay #endif 105*fa92fef0SPatrick Delaunay 106d5a84eeaSYann Gautier io_block_spec_t image_block_spec = { 1071d204ee4SYann Gautier .offset = 0U, 1081d204ee4SYann Gautier .length = 0U, 109c9d75b3cSYann Gautier }; 110c9d75b3cSYann Gautier 111d5a84eeaSYann Gautier int open_fip(const uintptr_t spec) 112c9d75b3cSYann Gautier { 1131d204ee4SYann Gautier return io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); 114c9d75b3cSYann Gautier } 115c9d75b3cSYann Gautier 116d5a84eeaSYann Gautier int open_storage(const uintptr_t spec) 117c9d75b3cSYann Gautier { 118c9d75b3cSYann Gautier return io_dev_init(storage_dev_handle, 0); 119c9d75b3cSYann Gautier } 120c9d75b3cSYann Gautier 121c9d75b3cSYann Gautier static void print_boot_device(boot_api_context_t *boot_context) 122c9d75b3cSYann Gautier { 123c9d75b3cSYann Gautier switch (boot_context->boot_interface_selected) { 124c9d75b3cSYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 125c9d75b3cSYann Gautier INFO("Using SDMMC\n"); 126c9d75b3cSYann Gautier break; 127c9d75b3cSYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 128c9d75b3cSYann Gautier INFO("Using EMMC\n"); 129c9d75b3cSYann Gautier break; 130b1b218fbSLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: 131b1b218fbSLionel Debieve INFO("Using QSPI NOR\n"); 132b1b218fbSLionel Debieve break; 13312e21dfdSLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: 13412e21dfdSLionel Debieve INFO("Using FMC NAND\n"); 13512e21dfdSLionel Debieve break; 13657044228SLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: 13757044228SLionel Debieve INFO("Using SPI NAND\n"); 13857044228SLionel Debieve break; 139*fa92fef0SPatrick Delaunay case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: 140*fa92fef0SPatrick Delaunay INFO("Using USB\n"); 141*fa92fef0SPatrick Delaunay break; 142c9d75b3cSYann Gautier default: 1431d204ee4SYann Gautier ERROR("Boot interface %u not found\n", 1441d204ee4SYann Gautier boot_context->boot_interface_selected); 145c9d75b3cSYann Gautier panic(); 146c9d75b3cSYann Gautier break; 147c9d75b3cSYann Gautier } 148c9d75b3cSYann Gautier 149c9d75b3cSYann Gautier if (boot_context->boot_interface_instance != 0U) { 150c9d75b3cSYann Gautier INFO(" Instance %d\n", boot_context->boot_interface_instance); 151c9d75b3cSYann Gautier } 152c9d75b3cSYann Gautier } 153c9d75b3cSYann Gautier 15446554b64SNicolas Le Bayon #if STM32MP_SDMMC || STM32MP_EMMC 1550b1aa772SYann Gautier static void boot_mmc(enum mmc_device_type mmc_dev_type, 1560b1aa772SYann Gautier uint16_t boot_interface_instance) 157c9d75b3cSYann Gautier { 158c9d75b3cSYann Gautier int io_result __unused; 159c9d75b3cSYann Gautier struct stm32_sdmmc2_params params; 160c9d75b3cSYann Gautier 16142beea8dSYann Gautier zeromem(¶ms, sizeof(struct stm32_sdmmc2_params)); 162c9d75b3cSYann Gautier 163cddf1bd7SYann Gautier mmc_info.mmc_dev_type = mmc_dev_type; 164c9d75b3cSYann Gautier 1650b1aa772SYann Gautier switch (boot_interface_instance) { 166c9d75b3cSYann Gautier case 1: 1673f9c9784SYann Gautier params.reg_base = STM32MP_SDMMC1_BASE; 168c9d75b3cSYann Gautier break; 169c9d75b3cSYann Gautier case 2: 1703f9c9784SYann Gautier params.reg_base = STM32MP_SDMMC2_BASE; 171c9d75b3cSYann Gautier break; 172c9d75b3cSYann Gautier case 3: 1733f9c9784SYann Gautier params.reg_base = STM32MP_SDMMC3_BASE; 174c9d75b3cSYann Gautier break; 175c9d75b3cSYann Gautier default: 176c9d75b3cSYann Gautier WARN("SDMMC instance not found, using default\n"); 1770b1aa772SYann Gautier if (mmc_dev_type == MMC_IS_SD) { 1780b1aa772SYann Gautier params.reg_base = STM32MP_SDMMC1_BASE; 1790b1aa772SYann Gautier } else { 1800b1aa772SYann Gautier params.reg_base = STM32MP_SDMMC2_BASE; 1810b1aa772SYann Gautier } 182c9d75b3cSYann Gautier break; 183c9d75b3cSYann Gautier } 184c9d75b3cSYann Gautier 185cddf1bd7SYann Gautier params.device_info = &mmc_info; 186c9d75b3cSYann Gautier if (stm32_sdmmc2_mmc_init(¶ms) != 0) { 1870b1aa772SYann Gautier ERROR("SDMMC%u init failed\n", boot_interface_instance); 188c9d75b3cSYann Gautier panic(); 189c9d75b3cSYann Gautier } 190c9d75b3cSYann Gautier 191c9d75b3cSYann Gautier /* Open MMC as a block device to read GPT table */ 192c9d75b3cSYann Gautier io_result = register_io_dev_block(&mmc_dev_con); 193c9d75b3cSYann Gautier if (io_result != 0) { 194c9d75b3cSYann Gautier panic(); 195c9d75b3cSYann Gautier } 196c9d75b3cSYann Gautier 1970b1aa772SYann Gautier io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec, 198c9d75b3cSYann Gautier &storage_dev_handle); 199c9d75b3cSYann Gautier assert(io_result == 0); 2000b1aa772SYann Gautier } 20146554b64SNicolas Le Bayon #endif /* STM32MP_SDMMC || STM32MP_EMMC */ 2020b1aa772SYann Gautier 203b1b218fbSLionel Debieve #if STM32MP_SPI_NOR 204b1b218fbSLionel Debieve static void boot_spi_nor(boot_api_context_t *boot_context) 205b1b218fbSLionel Debieve { 206b1b218fbSLionel Debieve int io_result __unused; 207b1b218fbSLionel Debieve 208b1b218fbSLionel Debieve io_result = stm32_qspi_init(); 209b1b218fbSLionel Debieve assert(io_result == 0); 210b1b218fbSLionel Debieve 211b1b218fbSLionel Debieve io_result = register_io_dev_mtd(&spi_dev_con); 212b1b218fbSLionel Debieve assert(io_result == 0); 213b1b218fbSLionel Debieve 214b1b218fbSLionel Debieve /* Open connections to device */ 215b1b218fbSLionel Debieve io_result = io_dev_open(spi_dev_con, 216b1b218fbSLionel Debieve (uintptr_t)&spi_nor_dev_spec, 217b1b218fbSLionel Debieve &storage_dev_handle); 218b1b218fbSLionel Debieve assert(io_result == 0); 219b1b218fbSLionel Debieve } 220b1b218fbSLionel Debieve #endif /* STM32MP_SPI_NOR */ 221b1b218fbSLionel Debieve 22212e21dfdSLionel Debieve #if STM32MP_RAW_NAND 22312e21dfdSLionel Debieve static void boot_fmc2_nand(boot_api_context_t *boot_context) 22412e21dfdSLionel Debieve { 22512e21dfdSLionel Debieve int io_result __unused; 22612e21dfdSLionel Debieve 22712e21dfdSLionel Debieve io_result = stm32_fmc2_init(); 22812e21dfdSLionel Debieve assert(io_result == 0); 22912e21dfdSLionel Debieve 23012e21dfdSLionel Debieve /* Register the IO device on this platform */ 23112e21dfdSLionel Debieve io_result = register_io_dev_mtd(&nand_dev_con); 23212e21dfdSLionel Debieve assert(io_result == 0); 23312e21dfdSLionel Debieve 23412e21dfdSLionel Debieve /* Open connections to device */ 23512e21dfdSLionel Debieve io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec, 23612e21dfdSLionel Debieve &storage_dev_handle); 23712e21dfdSLionel Debieve assert(io_result == 0); 23812e21dfdSLionel Debieve } 23912e21dfdSLionel Debieve #endif /* STM32MP_RAW_NAND */ 24012e21dfdSLionel Debieve 24157044228SLionel Debieve #if STM32MP_SPI_NAND 24257044228SLionel Debieve static void boot_spi_nand(boot_api_context_t *boot_context) 24357044228SLionel Debieve { 24457044228SLionel Debieve int io_result __unused; 24557044228SLionel Debieve 24657044228SLionel Debieve io_result = stm32_qspi_init(); 24757044228SLionel Debieve assert(io_result == 0); 24857044228SLionel Debieve 24957044228SLionel Debieve io_result = register_io_dev_mtd(&spi_dev_con); 25057044228SLionel Debieve assert(io_result == 0); 25157044228SLionel Debieve 25257044228SLionel Debieve /* Open connections to device */ 25357044228SLionel Debieve io_result = io_dev_open(spi_dev_con, 25457044228SLionel Debieve (uintptr_t)&spi_nand_dev_spec, 25557044228SLionel Debieve &storage_dev_handle); 25657044228SLionel Debieve assert(io_result == 0); 25757044228SLionel Debieve } 25857044228SLionel Debieve #endif /* STM32MP_SPI_NAND */ 25957044228SLionel Debieve 260*fa92fef0SPatrick Delaunay #if STM32MP_USB_PROGRAMMER 261*fa92fef0SPatrick Delaunay static void mmap_io_setup(void) 262*fa92fef0SPatrick Delaunay { 263*fa92fef0SPatrick Delaunay int io_result __unused; 264*fa92fef0SPatrick Delaunay 265*fa92fef0SPatrick Delaunay io_result = register_io_dev_memmap(&memmap_dev_con); 266*fa92fef0SPatrick Delaunay assert(io_result == 0); 267*fa92fef0SPatrick Delaunay 268*fa92fef0SPatrick Delaunay io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 269*fa92fef0SPatrick Delaunay &storage_dev_handle); 270*fa92fef0SPatrick Delaunay assert(io_result == 0); 271*fa92fef0SPatrick Delaunay } 272*fa92fef0SPatrick Delaunay 273*fa92fef0SPatrick Delaunay static void stm32cubeprogrammer_usb(void) 274*fa92fef0SPatrick Delaunay { 275*fa92fef0SPatrick Delaunay int ret __unused; 276*fa92fef0SPatrick Delaunay struct usb_handle *pdev; 277*fa92fef0SPatrick Delaunay 278*fa92fef0SPatrick Delaunay /* Init USB on platform */ 279*fa92fef0SPatrick Delaunay pdev = usb_dfu_plat_init(); 280*fa92fef0SPatrick Delaunay 281*fa92fef0SPatrick Delaunay ret = stm32cubeprog_usb_load(pdev, DWL_BUFFER_BASE, DWL_BUFFER_SIZE); 282*fa92fef0SPatrick Delaunay assert(ret == 0); 283*fa92fef0SPatrick Delaunay } 284*fa92fef0SPatrick Delaunay #endif 285*fa92fef0SPatrick Delaunay 2860b1aa772SYann Gautier void stm32mp_io_setup(void) 2870b1aa772SYann Gautier { 2880b1aa772SYann Gautier int io_result __unused; 2890b1aa772SYann Gautier boot_api_context_t *boot_context = 2900b1aa772SYann Gautier (boot_api_context_t *)stm32mp_get_boot_ctx_address(); 2910b1aa772SYann Gautier 2920b1aa772SYann Gautier print_boot_device(boot_context); 2930b1aa772SYann Gautier 2940b1aa772SYann Gautier if ((boot_context->boot_partition_used_toboot == 1U) || 2950b1aa772SYann Gautier (boot_context->boot_partition_used_toboot == 2U)) { 2961d204ee4SYann Gautier INFO("Boot used partition fsbl%u\n", 2970b1aa772SYann Gautier boot_context->boot_partition_used_toboot); 2980b1aa772SYann Gautier } 2990b1aa772SYann Gautier 3001d204ee4SYann Gautier io_result = register_io_dev_fip(&fip_dev_con); 3010b1aa772SYann Gautier assert(io_result == 0); 3020b1aa772SYann Gautier 3031d204ee4SYann Gautier io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 3041d204ee4SYann Gautier &fip_dev_handle); 3050b1aa772SYann Gautier 3060b1aa772SYann Gautier switch (boot_context->boot_interface_selected) { 30746554b64SNicolas Le Bayon #if STM32MP_SDMMC 3080b1aa772SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 3090b1aa772SYann Gautier dmbsy(); 3100b1aa772SYann Gautier boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance); 3110b1aa772SYann Gautier break; 31246554b64SNicolas Le Bayon #endif 31346554b64SNicolas Le Bayon #if STM32MP_EMMC 3140b1aa772SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 3150b1aa772SYann Gautier dmbsy(); 3160b1aa772SYann Gautier boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance); 317c9d75b3cSYann Gautier break; 31846554b64SNicolas Le Bayon #endif 319b1b218fbSLionel Debieve #if STM32MP_SPI_NOR 320b1b218fbSLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: 321b1b218fbSLionel Debieve dmbsy(); 322b1b218fbSLionel Debieve boot_spi_nor(boot_context); 323b1b218fbSLionel Debieve break; 324b1b218fbSLionel Debieve #endif 32512e21dfdSLionel Debieve #if STM32MP_RAW_NAND 32612e21dfdSLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: 32712e21dfdSLionel Debieve dmbsy(); 32812e21dfdSLionel Debieve boot_fmc2_nand(boot_context); 32912e21dfdSLionel Debieve break; 33012e21dfdSLionel Debieve #endif 33157044228SLionel Debieve #if STM32MP_SPI_NAND 33257044228SLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: 33357044228SLionel Debieve dmbsy(); 33457044228SLionel Debieve boot_spi_nand(boot_context); 33557044228SLionel Debieve break; 33657044228SLionel Debieve #endif 337*fa92fef0SPatrick Delaunay #if STM32MP_USB_PROGRAMMER 338*fa92fef0SPatrick Delaunay case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: 339*fa92fef0SPatrick Delaunay dmbsy(); 340*fa92fef0SPatrick Delaunay mmap_io_setup(); 341*fa92fef0SPatrick Delaunay break; 342*fa92fef0SPatrick Delaunay #endif 343c9d75b3cSYann Gautier 344c9d75b3cSYann Gautier default: 345c9d75b3cSYann Gautier ERROR("Boot interface %d not supported\n", 346c9d75b3cSYann Gautier boot_context->boot_interface_selected); 34771693a66SYann Gautier panic(); 348c9d75b3cSYann Gautier break; 349c9d75b3cSYann Gautier } 350c9d75b3cSYann Gautier } 351c9d75b3cSYann Gautier 3521d204ee4SYann Gautier int bl2_plat_handle_pre_image_load(unsigned int image_id) 3531d204ee4SYann Gautier { 3541d204ee4SYann Gautier static bool gpt_init_done __unused; 3551d204ee4SYann Gautier uint16_t boot_itf = stm32mp_get_boot_itf_selected(); 3561d204ee4SYann Gautier 3571d204ee4SYann Gautier switch (boot_itf) { 3581d204ee4SYann Gautier #if STM32MP_SDMMC || STM32MP_EMMC 3591d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 3601d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 3611d204ee4SYann Gautier if (!gpt_init_done) { 3621d204ee4SYann Gautier const partition_entry_t *entry; 3631d204ee4SYann Gautier 3641d204ee4SYann Gautier partition_init(GPT_IMAGE_ID); 3651d204ee4SYann Gautier entry = get_partition_entry(FIP_IMAGE_NAME); 3661d204ee4SYann Gautier if (entry == NULL) { 3671d204ee4SYann Gautier ERROR("Could NOT find the %s partition!\n", 3681d204ee4SYann Gautier FIP_IMAGE_NAME); 3691d204ee4SYann Gautier return -ENOENT; 3701d204ee4SYann Gautier } 3711d204ee4SYann Gautier 3721d204ee4SYann Gautier image_block_spec.offset = entry->start; 3731d204ee4SYann Gautier image_block_spec.length = entry->length; 3741d204ee4SYann Gautier 3751d204ee4SYann Gautier gpt_init_done = true; 37618b415beSYann Gautier } else { 37718b415beSYann Gautier bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); 37818b415beSYann Gautier 37918b415beSYann Gautier mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base; 38018b415beSYann Gautier mmc_block_dev_spec.buffer.length = bl_mem_params->image_info.image_max_size; 3811d204ee4SYann Gautier } 3821d204ee4SYann Gautier 3831d204ee4SYann Gautier break; 3841d204ee4SYann Gautier #endif 3851d204ee4SYann Gautier 3861d204ee4SYann Gautier #if STM32MP_RAW_NAND || STM32MP_SPI_NAND 3871d204ee4SYann Gautier #if STM32MP_RAW_NAND 3881d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: 3891d204ee4SYann Gautier #endif 3901d204ee4SYann Gautier #if STM32MP_SPI_NAND 3911d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: 3921d204ee4SYann Gautier #endif 3931d204ee4SYann Gautier image_block_spec.offset = STM32MP_NAND_FIP_OFFSET; 3941d204ee4SYann Gautier break; 3951d204ee4SYann Gautier #endif 3961d204ee4SYann Gautier 3971d204ee4SYann Gautier #if STM32MP_SPI_NOR 3981d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: 3991d204ee4SYann Gautier image_block_spec.offset = STM32MP_NOR_FIP_OFFSET; 4001d204ee4SYann Gautier break; 4011d204ee4SYann Gautier #endif 4021d204ee4SYann Gautier 403*fa92fef0SPatrick Delaunay #if STM32MP_USB_PROGRAMMER 404*fa92fef0SPatrick Delaunay case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: 405*fa92fef0SPatrick Delaunay if (image_id == FW_CONFIG_ID) { 406*fa92fef0SPatrick Delaunay stm32cubeprogrammer_usb(); 407*fa92fef0SPatrick Delaunay /* FIP loaded at DWL address */ 408*fa92fef0SPatrick Delaunay image_block_spec.offset = DWL_BUFFER_BASE; 409*fa92fef0SPatrick Delaunay image_block_spec.length = DWL_BUFFER_SIZE; 410*fa92fef0SPatrick Delaunay } 411*fa92fef0SPatrick Delaunay break; 412*fa92fef0SPatrick Delaunay #endif 413*fa92fef0SPatrick Delaunay 4141d204ee4SYann Gautier default: 4151d204ee4SYann Gautier ERROR("FIP Not found\n"); 4161d204ee4SYann Gautier panic(); 4171d204ee4SYann Gautier } 4181d204ee4SYann Gautier 4191d204ee4SYann Gautier return 0; 4201d204ee4SYann Gautier } 4211d204ee4SYann Gautier 422c9d75b3cSYann Gautier /* 423c9d75b3cSYann Gautier * Return an IO device handle and specification which can be used to access 424c9d75b3cSYann Gautier * an image. Use this to enforce platform load policy. 425c9d75b3cSYann Gautier */ 426c9d75b3cSYann Gautier int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 427c9d75b3cSYann Gautier uintptr_t *image_spec) 428c9d75b3cSYann Gautier { 429c9d75b3cSYann Gautier int rc; 430c9d75b3cSYann Gautier const struct plat_io_policy *policy; 431c9d75b3cSYann Gautier 432d5a84eeaSYann Gautier policy = FCONF_GET_PROPERTY(stm32mp, io_policies, image_id); 433c9d75b3cSYann Gautier rc = policy->check(policy->image_spec); 434c9d75b3cSYann Gautier if (rc == 0) { 435c9d75b3cSYann Gautier *image_spec = policy->image_spec; 436c9d75b3cSYann Gautier *dev_handle = *(policy->dev_handle); 437c9d75b3cSYann Gautier } 438c9d75b3cSYann Gautier 439c9d75b3cSYann Gautier return rc; 440c9d75b3cSYann Gautier } 441