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> 16fa92fef0SPatrick 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> 28fa92fef0SPatrick 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> 36fa92fef0SPatrick Delaunay #include <stm32cubeprogrammer.h> 37d5a84eeaSYann Gautier #include <stm32mp_fconf_getter.h> 38fa92fef0SPatrick 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*9083fa11SPatrick Delaunay #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER 103fa92fef0SPatrick Delaunay static const io_dev_connector_t *memmap_dev_con; 104fa92fef0SPatrick Delaunay #endif 105fa92fef0SPatrick 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*9083fa11SPatrick Delaunay case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: 140*9083fa11SPatrick Delaunay INFO("Using UART\n"); 141*9083fa11SPatrick Delaunay break; 142fa92fef0SPatrick Delaunay case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: 143fa92fef0SPatrick Delaunay INFO("Using USB\n"); 144fa92fef0SPatrick Delaunay break; 145c9d75b3cSYann Gautier default: 1461d204ee4SYann Gautier ERROR("Boot interface %u not found\n", 1471d204ee4SYann Gautier boot_context->boot_interface_selected); 148c9d75b3cSYann Gautier panic(); 149c9d75b3cSYann Gautier break; 150c9d75b3cSYann Gautier } 151c9d75b3cSYann Gautier 152c9d75b3cSYann Gautier if (boot_context->boot_interface_instance != 0U) { 153c9d75b3cSYann Gautier INFO(" Instance %d\n", boot_context->boot_interface_instance); 154c9d75b3cSYann Gautier } 155c9d75b3cSYann Gautier } 156c9d75b3cSYann Gautier 15746554b64SNicolas Le Bayon #if STM32MP_SDMMC || STM32MP_EMMC 1580b1aa772SYann Gautier static void boot_mmc(enum mmc_device_type mmc_dev_type, 1590b1aa772SYann Gautier uint16_t boot_interface_instance) 160c9d75b3cSYann Gautier { 161c9d75b3cSYann Gautier int io_result __unused; 162c9d75b3cSYann Gautier struct stm32_sdmmc2_params params; 163c9d75b3cSYann Gautier 16442beea8dSYann Gautier zeromem(¶ms, sizeof(struct stm32_sdmmc2_params)); 165c9d75b3cSYann Gautier 166cddf1bd7SYann Gautier mmc_info.mmc_dev_type = mmc_dev_type; 167c9d75b3cSYann Gautier 1680b1aa772SYann Gautier switch (boot_interface_instance) { 169c9d75b3cSYann Gautier case 1: 1703f9c9784SYann Gautier params.reg_base = STM32MP_SDMMC1_BASE; 171c9d75b3cSYann Gautier break; 172c9d75b3cSYann Gautier case 2: 1733f9c9784SYann Gautier params.reg_base = STM32MP_SDMMC2_BASE; 174c9d75b3cSYann Gautier break; 175c9d75b3cSYann Gautier case 3: 1763f9c9784SYann Gautier params.reg_base = STM32MP_SDMMC3_BASE; 177c9d75b3cSYann Gautier break; 178c9d75b3cSYann Gautier default: 179c9d75b3cSYann Gautier WARN("SDMMC instance not found, using default\n"); 1800b1aa772SYann Gautier if (mmc_dev_type == MMC_IS_SD) { 1810b1aa772SYann Gautier params.reg_base = STM32MP_SDMMC1_BASE; 1820b1aa772SYann Gautier } else { 1830b1aa772SYann Gautier params.reg_base = STM32MP_SDMMC2_BASE; 1840b1aa772SYann Gautier } 185c9d75b3cSYann Gautier break; 186c9d75b3cSYann Gautier } 187c9d75b3cSYann Gautier 188cddf1bd7SYann Gautier params.device_info = &mmc_info; 189c9d75b3cSYann Gautier if (stm32_sdmmc2_mmc_init(¶ms) != 0) { 1900b1aa772SYann Gautier ERROR("SDMMC%u init failed\n", boot_interface_instance); 191c9d75b3cSYann Gautier panic(); 192c9d75b3cSYann Gautier } 193c9d75b3cSYann Gautier 194c9d75b3cSYann Gautier /* Open MMC as a block device to read GPT table */ 195c9d75b3cSYann Gautier io_result = register_io_dev_block(&mmc_dev_con); 196c9d75b3cSYann Gautier if (io_result != 0) { 197c9d75b3cSYann Gautier panic(); 198c9d75b3cSYann Gautier } 199c9d75b3cSYann Gautier 2000b1aa772SYann Gautier io_result = io_dev_open(mmc_dev_con, (uintptr_t)&mmc_block_dev_spec, 201c9d75b3cSYann Gautier &storage_dev_handle); 202c9d75b3cSYann Gautier assert(io_result == 0); 2030b1aa772SYann Gautier } 20446554b64SNicolas Le Bayon #endif /* STM32MP_SDMMC || STM32MP_EMMC */ 2050b1aa772SYann Gautier 206b1b218fbSLionel Debieve #if STM32MP_SPI_NOR 207b1b218fbSLionel Debieve static void boot_spi_nor(boot_api_context_t *boot_context) 208b1b218fbSLionel Debieve { 209b1b218fbSLionel Debieve int io_result __unused; 210b1b218fbSLionel Debieve 211b1b218fbSLionel Debieve io_result = stm32_qspi_init(); 212b1b218fbSLionel Debieve assert(io_result == 0); 213b1b218fbSLionel Debieve 214b1b218fbSLionel Debieve io_result = register_io_dev_mtd(&spi_dev_con); 215b1b218fbSLionel Debieve assert(io_result == 0); 216b1b218fbSLionel Debieve 217b1b218fbSLionel Debieve /* Open connections to device */ 218b1b218fbSLionel Debieve io_result = io_dev_open(spi_dev_con, 219b1b218fbSLionel Debieve (uintptr_t)&spi_nor_dev_spec, 220b1b218fbSLionel Debieve &storage_dev_handle); 221b1b218fbSLionel Debieve assert(io_result == 0); 222b1b218fbSLionel Debieve } 223b1b218fbSLionel Debieve #endif /* STM32MP_SPI_NOR */ 224b1b218fbSLionel Debieve 22512e21dfdSLionel Debieve #if STM32MP_RAW_NAND 22612e21dfdSLionel Debieve static void boot_fmc2_nand(boot_api_context_t *boot_context) 22712e21dfdSLionel Debieve { 22812e21dfdSLionel Debieve int io_result __unused; 22912e21dfdSLionel Debieve 23012e21dfdSLionel Debieve io_result = stm32_fmc2_init(); 23112e21dfdSLionel Debieve assert(io_result == 0); 23212e21dfdSLionel Debieve 23312e21dfdSLionel Debieve /* Register the IO device on this platform */ 23412e21dfdSLionel Debieve io_result = register_io_dev_mtd(&nand_dev_con); 23512e21dfdSLionel Debieve assert(io_result == 0); 23612e21dfdSLionel Debieve 23712e21dfdSLionel Debieve /* Open connections to device */ 23812e21dfdSLionel Debieve io_result = io_dev_open(nand_dev_con, (uintptr_t)&nand_dev_spec, 23912e21dfdSLionel Debieve &storage_dev_handle); 24012e21dfdSLionel Debieve assert(io_result == 0); 24112e21dfdSLionel Debieve } 24212e21dfdSLionel Debieve #endif /* STM32MP_RAW_NAND */ 24312e21dfdSLionel Debieve 24457044228SLionel Debieve #if STM32MP_SPI_NAND 24557044228SLionel Debieve static void boot_spi_nand(boot_api_context_t *boot_context) 24657044228SLionel Debieve { 24757044228SLionel Debieve int io_result __unused; 24857044228SLionel Debieve 24957044228SLionel Debieve io_result = stm32_qspi_init(); 25057044228SLionel Debieve assert(io_result == 0); 25157044228SLionel Debieve 25257044228SLionel Debieve io_result = register_io_dev_mtd(&spi_dev_con); 25357044228SLionel Debieve assert(io_result == 0); 25457044228SLionel Debieve 25557044228SLionel Debieve /* Open connections to device */ 25657044228SLionel Debieve io_result = io_dev_open(spi_dev_con, 25757044228SLionel Debieve (uintptr_t)&spi_nand_dev_spec, 25857044228SLionel Debieve &storage_dev_handle); 25957044228SLionel Debieve assert(io_result == 0); 26057044228SLionel Debieve } 26157044228SLionel Debieve #endif /* STM32MP_SPI_NAND */ 26257044228SLionel Debieve 263*9083fa11SPatrick Delaunay #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER 264fa92fef0SPatrick Delaunay static void mmap_io_setup(void) 265fa92fef0SPatrick Delaunay { 266fa92fef0SPatrick Delaunay int io_result __unused; 267fa92fef0SPatrick Delaunay 268fa92fef0SPatrick Delaunay io_result = register_io_dev_memmap(&memmap_dev_con); 269fa92fef0SPatrick Delaunay assert(io_result == 0); 270fa92fef0SPatrick Delaunay 271fa92fef0SPatrick Delaunay io_result = io_dev_open(memmap_dev_con, (uintptr_t)NULL, 272fa92fef0SPatrick Delaunay &storage_dev_handle); 273fa92fef0SPatrick Delaunay assert(io_result == 0); 274fa92fef0SPatrick Delaunay } 275fa92fef0SPatrick Delaunay 276*9083fa11SPatrick Delaunay #if STM32MP_UART_PROGRAMMER 277*9083fa11SPatrick Delaunay static void stm32cubeprogrammer_uart(void) 278*9083fa11SPatrick Delaunay { 279*9083fa11SPatrick Delaunay int ret __unused; 280*9083fa11SPatrick Delaunay boot_api_context_t *boot_context = 281*9083fa11SPatrick Delaunay (boot_api_context_t *)stm32mp_get_boot_ctx_address(); 282*9083fa11SPatrick Delaunay uintptr_t uart_base; 283*9083fa11SPatrick Delaunay 284*9083fa11SPatrick Delaunay uart_base = get_uart_address(boot_context->boot_interface_instance); 285*9083fa11SPatrick Delaunay ret = stm32cubeprog_uart_load(uart_base, DWL_BUFFER_BASE, DWL_BUFFER_SIZE); 286*9083fa11SPatrick Delaunay assert(ret == 0); 287*9083fa11SPatrick Delaunay } 288*9083fa11SPatrick Delaunay #endif 289*9083fa11SPatrick Delaunay 290*9083fa11SPatrick Delaunay #if STM32MP_USB_PROGRAMMER 291fa92fef0SPatrick Delaunay static void stm32cubeprogrammer_usb(void) 292fa92fef0SPatrick Delaunay { 293fa92fef0SPatrick Delaunay int ret __unused; 294fa92fef0SPatrick Delaunay struct usb_handle *pdev; 295fa92fef0SPatrick Delaunay 296fa92fef0SPatrick Delaunay /* Init USB on platform */ 297fa92fef0SPatrick Delaunay pdev = usb_dfu_plat_init(); 298fa92fef0SPatrick Delaunay 299fa92fef0SPatrick Delaunay ret = stm32cubeprog_usb_load(pdev, DWL_BUFFER_BASE, DWL_BUFFER_SIZE); 300fa92fef0SPatrick Delaunay assert(ret == 0); 301fa92fef0SPatrick Delaunay } 302fa92fef0SPatrick Delaunay #endif 303*9083fa11SPatrick Delaunay #endif /* STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER */ 304*9083fa11SPatrick Delaunay 305fa92fef0SPatrick Delaunay 3060b1aa772SYann Gautier void stm32mp_io_setup(void) 3070b1aa772SYann Gautier { 3080b1aa772SYann Gautier int io_result __unused; 3090b1aa772SYann Gautier boot_api_context_t *boot_context = 3100b1aa772SYann Gautier (boot_api_context_t *)stm32mp_get_boot_ctx_address(); 3110b1aa772SYann Gautier 3120b1aa772SYann Gautier print_boot_device(boot_context); 3130b1aa772SYann Gautier 3140b1aa772SYann Gautier if ((boot_context->boot_partition_used_toboot == 1U) || 3150b1aa772SYann Gautier (boot_context->boot_partition_used_toboot == 2U)) { 3161d204ee4SYann Gautier INFO("Boot used partition fsbl%u\n", 3170b1aa772SYann Gautier boot_context->boot_partition_used_toboot); 3180b1aa772SYann Gautier } 3190b1aa772SYann Gautier 3201d204ee4SYann Gautier io_result = register_io_dev_fip(&fip_dev_con); 3210b1aa772SYann Gautier assert(io_result == 0); 3220b1aa772SYann Gautier 3231d204ee4SYann Gautier io_result = io_dev_open(fip_dev_con, (uintptr_t)NULL, 3241d204ee4SYann Gautier &fip_dev_handle); 3250b1aa772SYann Gautier 3260b1aa772SYann Gautier switch (boot_context->boot_interface_selected) { 32746554b64SNicolas Le Bayon #if STM32MP_SDMMC 3280b1aa772SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 3290b1aa772SYann Gautier dmbsy(); 3300b1aa772SYann Gautier boot_mmc(MMC_IS_SD, boot_context->boot_interface_instance); 3310b1aa772SYann Gautier break; 33246554b64SNicolas Le Bayon #endif 33346554b64SNicolas Le Bayon #if STM32MP_EMMC 3340b1aa772SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 3350b1aa772SYann Gautier dmbsy(); 3360b1aa772SYann Gautier boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance); 337c9d75b3cSYann Gautier break; 33846554b64SNicolas Le Bayon #endif 339b1b218fbSLionel Debieve #if STM32MP_SPI_NOR 340b1b218fbSLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: 341b1b218fbSLionel Debieve dmbsy(); 342b1b218fbSLionel Debieve boot_spi_nor(boot_context); 343b1b218fbSLionel Debieve break; 344b1b218fbSLionel Debieve #endif 34512e21dfdSLionel Debieve #if STM32MP_RAW_NAND 34612e21dfdSLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: 34712e21dfdSLionel Debieve dmbsy(); 34812e21dfdSLionel Debieve boot_fmc2_nand(boot_context); 34912e21dfdSLionel Debieve break; 35012e21dfdSLionel Debieve #endif 35157044228SLionel Debieve #if STM32MP_SPI_NAND 35257044228SLionel Debieve case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: 35357044228SLionel Debieve dmbsy(); 35457044228SLionel Debieve boot_spi_nand(boot_context); 35557044228SLionel Debieve break; 35657044228SLionel Debieve #endif 357*9083fa11SPatrick Delaunay #if STM32MP_UART_PROGRAMMER || STM32MP_USB_PROGRAMMER 358*9083fa11SPatrick Delaunay #if STM32MP_UART_PROGRAMMER 359*9083fa11SPatrick Delaunay case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: 360*9083fa11SPatrick Delaunay #endif 361fa92fef0SPatrick Delaunay #if STM32MP_USB_PROGRAMMER 362fa92fef0SPatrick Delaunay case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: 363*9083fa11SPatrick Delaunay #endif 364fa92fef0SPatrick Delaunay dmbsy(); 365fa92fef0SPatrick Delaunay mmap_io_setup(); 366fa92fef0SPatrick Delaunay break; 367fa92fef0SPatrick Delaunay #endif 368c9d75b3cSYann Gautier 369c9d75b3cSYann Gautier default: 370c9d75b3cSYann Gautier ERROR("Boot interface %d not supported\n", 371c9d75b3cSYann Gautier boot_context->boot_interface_selected); 37271693a66SYann Gautier panic(); 373c9d75b3cSYann Gautier break; 374c9d75b3cSYann Gautier } 375c9d75b3cSYann Gautier } 376c9d75b3cSYann Gautier 3771d204ee4SYann Gautier int bl2_plat_handle_pre_image_load(unsigned int image_id) 3781d204ee4SYann Gautier { 3791d204ee4SYann Gautier static bool gpt_init_done __unused; 3801d204ee4SYann Gautier uint16_t boot_itf = stm32mp_get_boot_itf_selected(); 3811d204ee4SYann Gautier 3821d204ee4SYann Gautier switch (boot_itf) { 3831d204ee4SYann Gautier #if STM32MP_SDMMC || STM32MP_EMMC 3841d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_SD: 3851d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: 3861d204ee4SYann Gautier if (!gpt_init_done) { 3871d204ee4SYann Gautier const partition_entry_t *entry; 3881d204ee4SYann Gautier 3891d204ee4SYann Gautier partition_init(GPT_IMAGE_ID); 3901d204ee4SYann Gautier entry = get_partition_entry(FIP_IMAGE_NAME); 3911d204ee4SYann Gautier if (entry == NULL) { 3921d204ee4SYann Gautier ERROR("Could NOT find the %s partition!\n", 3931d204ee4SYann Gautier FIP_IMAGE_NAME); 3941d204ee4SYann Gautier return -ENOENT; 3951d204ee4SYann Gautier } 3961d204ee4SYann Gautier 3971d204ee4SYann Gautier image_block_spec.offset = entry->start; 3981d204ee4SYann Gautier image_block_spec.length = entry->length; 3991d204ee4SYann Gautier 4001d204ee4SYann Gautier gpt_init_done = true; 40118b415beSYann Gautier } else { 40218b415beSYann Gautier bl_mem_params_node_t *bl_mem_params = get_bl_mem_params_node(image_id); 40318b415beSYann Gautier 40418b415beSYann Gautier mmc_block_dev_spec.buffer.offset = bl_mem_params->image_info.image_base; 40518b415beSYann Gautier mmc_block_dev_spec.buffer.length = bl_mem_params->image_info.image_max_size; 4061d204ee4SYann Gautier } 4071d204ee4SYann Gautier 4081d204ee4SYann Gautier break; 4091d204ee4SYann Gautier #endif 4101d204ee4SYann Gautier 4111d204ee4SYann Gautier #if STM32MP_RAW_NAND || STM32MP_SPI_NAND 4121d204ee4SYann Gautier #if STM32MP_RAW_NAND 4131d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: 4141d204ee4SYann Gautier #endif 4151d204ee4SYann Gautier #if STM32MP_SPI_NAND 4161d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI: 4171d204ee4SYann Gautier #endif 4181d204ee4SYann Gautier image_block_spec.offset = STM32MP_NAND_FIP_OFFSET; 4191d204ee4SYann Gautier break; 4201d204ee4SYann Gautier #endif 4211d204ee4SYann Gautier 4221d204ee4SYann Gautier #if STM32MP_SPI_NOR 4231d204ee4SYann Gautier case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: 4241d204ee4SYann Gautier image_block_spec.offset = STM32MP_NOR_FIP_OFFSET; 4251d204ee4SYann Gautier break; 4261d204ee4SYann Gautier #endif 4271d204ee4SYann Gautier 428*9083fa11SPatrick Delaunay #if STM32MP_UART_PROGRAMMER 429*9083fa11SPatrick Delaunay case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_UART: 430*9083fa11SPatrick Delaunay if (image_id == FW_CONFIG_ID) { 431*9083fa11SPatrick Delaunay stm32cubeprogrammer_uart(); 432*9083fa11SPatrick Delaunay /* FIP loaded at DWL address */ 433*9083fa11SPatrick Delaunay image_block_spec.offset = DWL_BUFFER_BASE; 434*9083fa11SPatrick Delaunay image_block_spec.length = DWL_BUFFER_SIZE; 435*9083fa11SPatrick Delaunay } 436*9083fa11SPatrick Delaunay break; 437*9083fa11SPatrick Delaunay #endif 438fa92fef0SPatrick Delaunay #if STM32MP_USB_PROGRAMMER 439fa92fef0SPatrick Delaunay case BOOT_API_CTX_BOOT_INTERFACE_SEL_SERIAL_USB: 440fa92fef0SPatrick Delaunay if (image_id == FW_CONFIG_ID) { 441fa92fef0SPatrick Delaunay stm32cubeprogrammer_usb(); 442fa92fef0SPatrick Delaunay /* FIP loaded at DWL address */ 443fa92fef0SPatrick Delaunay image_block_spec.offset = DWL_BUFFER_BASE; 444fa92fef0SPatrick Delaunay image_block_spec.length = DWL_BUFFER_SIZE; 445fa92fef0SPatrick Delaunay } 446fa92fef0SPatrick Delaunay break; 447fa92fef0SPatrick Delaunay #endif 448fa92fef0SPatrick Delaunay 4491d204ee4SYann Gautier default: 4501d204ee4SYann Gautier ERROR("FIP Not found\n"); 4511d204ee4SYann Gautier panic(); 4521d204ee4SYann Gautier } 4531d204ee4SYann Gautier 4541d204ee4SYann Gautier return 0; 4551d204ee4SYann Gautier } 4561d204ee4SYann Gautier 457c9d75b3cSYann Gautier /* 458c9d75b3cSYann Gautier * Return an IO device handle and specification which can be used to access 459c9d75b3cSYann Gautier * an image. Use this to enforce platform load policy. 460c9d75b3cSYann Gautier */ 461c9d75b3cSYann Gautier int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, 462c9d75b3cSYann Gautier uintptr_t *image_spec) 463c9d75b3cSYann Gautier { 464c9d75b3cSYann Gautier int rc; 465c9d75b3cSYann Gautier const struct plat_io_policy *policy; 466c9d75b3cSYann Gautier 467d5a84eeaSYann Gautier policy = FCONF_GET_PROPERTY(stm32mp, io_policies, image_id); 468c9d75b3cSYann Gautier rc = policy->check(policy->image_spec); 469c9d75b3cSYann Gautier if (rc == 0) { 470c9d75b3cSYann Gautier *image_spec = policy->image_spec; 471c9d75b3cSYann Gautier *dev_handle = *(policy->dev_handle); 472c9d75b3cSYann Gautier } 473c9d75b3cSYann Gautier 474c9d75b3cSYann Gautier return rc; 475c9d75b3cSYann Gautier } 476