diff --git a/plat/st/common/bl2_io_storage.c b/plat/st/common/bl2_io_storage.c index d0bc605..3ec7d40 100644 --- a/plat/st/common/bl2_io_storage.c +++ b/plat/st/common/bl2_io_storage.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -61,6 +62,15 @@ static const io_dev_connector_t *mmc_dev_con; #endif /* STM32MP_SDMMC || STM32MP_EMMC */ +#if STM32MP_SPI_NOR +static io_mtd_dev_spec_t spi_nor_dev_spec = { + .ops = { + .init = spi_nor_init, + .read = spi_nor_read, + }, +}; +#endif + #if STM32MP_RAW_NAND static io_mtd_dev_spec_t nand_dev_spec = { .ops = { @@ -79,7 +89,9 @@ .read = nand_read, }, }; +#endif +#if STM32MP_SPI_NAND || STM32MP_SPI_NOR static const io_dev_connector_t *spi_dev_con; #endif @@ -236,6 +248,9 @@ case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_EMMC: INFO("Using EMMC\n"); break; + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: + INFO("Using QSPI NOR\n"); + break; case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: INFO("Using FMC NAND\n"); break; @@ -345,6 +360,59 @@ } #endif /* STM32MP_SDMMC || STM32MP_EMMC */ +#if STM32MP_SPI_NOR +static void boot_spi_nor(boot_api_context_t *boot_context) +{ + int io_result __unused; + uint8_t idx; + struct stm32image_part_info *part; + + io_result = stm32_qspi_init(); + assert(io_result == 0); + + io_result = register_io_dev_mtd(&spi_dev_con); + assert(io_result == 0); + + /* Open connections to device */ + io_result = io_dev_open(spi_dev_con, + (uintptr_t)&spi_nor_dev_spec, + &storage_dev_handle); + assert(io_result == 0); + + stm32image_dev_info_spec.device_size = spi_nor_dev_spec.device_size; + + idx = IMG_IDX_BL33; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NOR_BL33_OFFSET; + part->bkp_offset = 0U; + +#ifdef AARCH32_SP_OPTEE + idx = IMG_IDX_OPTEE_HEADER; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NOR_TEEH_OFFSET; + part->bkp_offset = 0U; + + idx = IMG_IDX_OPTEE_PAGED; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NOR_TEED_OFFSET; + part->bkp_offset = 0U; + + idx = IMG_IDX_OPTEE_PAGER; + part = &stm32image_dev_info_spec.part_info[idx]; + part->part_offset = STM32MP_NOR_TEEX_OFFSET; + part->bkp_offset = 0U; +#endif + + io_result = register_io_dev_stm32image(&stm32image_dev_con); + assert(io_result == 0); + + io_result = io_dev_open(stm32image_dev_con, + (uintptr_t)&stm32image_dev_info_spec, + &image_dev_handle); + assert(io_result == 0); +} +#endif /* STM32MP_SPI_NOR */ + #if STM32MP_RAW_NAND static void boot_fmc2_nand(boot_api_context_t *boot_context) { @@ -486,6 +554,12 @@ boot_mmc(MMC_IS_EMMC, boot_context->boot_interface_instance); break; #endif +#if STM32MP_SPI_NOR + case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI: + dmbsy(); + boot_spi_nor(boot_context); + break; +#endif #if STM32MP_RAW_NAND case BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC: dmbsy(); diff --git a/plat/st/stm32mp1/include/boot_api.h b/plat/st/stm32mp1/include/boot_api.h index 1f05d0b..c16639a 100644 --- a/plat/st/stm32mp1/include/boot_api.h +++ b/plat/st/stm32mp1/include/boot_api.h @@ -36,6 +36,9 @@ /* Boot occurred on FMC */ #define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_FMC 0x3U +/* Boot occurred on QSPI NOR */ +#define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NOR_QSPI 0x4U + /* Boot occurred on QSPI NAND */ #define BOOT_API_CTX_BOOT_INTERFACE_SEL_FLASH_NAND_QSPI 0x7U diff --git a/plat/st/stm32mp1/include/stm32mp1_boot_device.h b/plat/st/stm32mp1/include/stm32mp1_boot_device.h index db80f93..a745983 100644 --- a/plat/st/stm32mp1/include/stm32mp1_boot_device.h +++ b/plat/st/stm32mp1/include/stm32mp1_boot_device.h @@ -9,8 +9,10 @@ #include #include +#include int plat_get_raw_nand_data(struct rawnand_device *device); int plat_get_spi_nand_data(struct spinand_device *device); +int plat_get_nor_data(struct nor_device *device); #endif /* STM32MP1_BOOT_DEVICE_H */ diff --git a/plat/st/stm32mp1/platform.mk b/plat/st/stm32mp1/platform.mk index d25f3b3..b86287b 100644 --- a/plat/st/stm32mp1/platform.mk +++ b/plat/st/stm32mp1/platform.mk @@ -29,9 +29,10 @@ STM32MP_SDMMC ?= 0 STM32MP_RAW_NAND ?= 0 STM32MP_SPI_NAND ?= 0 +STM32MP_SPI_NOR ?= 0 ifeq ($(filter 1,${STM32MP_EMMC} ${STM32MP_SDMMC} ${STM32MP_RAW_NAND} \ - ${STM32MP_SPI_NAND}),) + ${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),) $(error "No boot device driver is enabled") endif @@ -39,10 +40,12 @@ $(eval $(call assert_boolean,STM32MP_SDMMC)) $(eval $(call assert_boolean,STM32MP_RAW_NAND)) $(eval $(call assert_boolean,STM32MP_SPI_NAND)) +$(eval $(call assert_boolean,STM32MP_SPI_NOR)) $(eval $(call add_define,STM32MP_EMMC)) $(eval $(call add_define,STM32MP_SDMMC)) $(eval $(call add_define,STM32MP_RAW_NAND)) $(eval $(call add_define,STM32MP_SPI_NAND)) +$(eval $(call add_define,STM32MP_SPI_NOR)) PLAT_INCLUDES := -Iplat/st/common/include/ PLAT_INCLUDES += -Iplat/st/stm32mp1/include/ @@ -116,14 +119,21 @@ BL2_SOURCES += drivers/mtd/nand/spi_nand.c endif -ifeq (${STM32MP_SPI_NAND},1) +ifeq (${STM32MP_SPI_NOR},1) +BL2_SOURCES += drivers/mtd/nor/spi_nor.c +endif + +ifneq ($(filter 1,${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),) BL2_SOURCES += drivers/mtd/spi-mem/spi_mem.c \ drivers/st/spi/stm32_qspi.c endif ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND}),) -BL2_SOURCES += drivers/mtd/nand/core.c \ - plat/st/stm32mp1/stm32mp1_boot_device.c +BL2_SOURCES += drivers/mtd/nand/core.c +endif + +ifneq ($(filter 1,${STM32MP_RAW_NAND} ${STM32MP_SPI_NAND} ${STM32MP_SPI_NOR}),) +BL2_SOURCES += plat/st/stm32mp1/stm32mp1_boot_device.c endif BL2_SOURCES += drivers/st/ddr/stm32mp1_ddr.c \ diff --git a/plat/st/stm32mp1/stm32mp1_boot_device.c b/plat/st/stm32mp1/stm32mp1_boot_device.c index fa352f3..2d8eccf 100644 --- a/plat/st/stm32mp1/stm32mp1_boot_device.c +++ b/plat/st/stm32mp1/stm32mp1_boot_device.c @@ -11,6 +11,7 @@ #include #define SZ_512 0x200U +#define SZ_64M 0x4000000U #if STM32MP_RAW_NAND || STM32MP_SPI_NAND static int get_data_from_otp(struct nand_device *nand_dev, bool is_slc) @@ -149,3 +150,21 @@ } #endif +#if STM32MP_SPI_NOR +int plat_get_nor_data(struct nor_device *device) +{ + device->size = SZ_64M; + + zeromem(&device->read_op, sizeof(struct spi_mem_op)); + device->read_op.cmd.opcode = SPI_NOR_OP_READ_1_1_4; + device->read_op.cmd.buswidth = SPI_MEM_BUSWIDTH_1_LINE; + device->read_op.addr.nbytes = 3U; + device->read_op.addr.buswidth = SPI_MEM_BUSWIDTH_1_LINE; + device->read_op.dummy.nbytes = 1U; + device->read_op.dummy.buswidth = SPI_MEM_BUSWIDTH_1_LINE; + device->read_op.data.buswidth = SPI_MEM_BUSWIDTH_4_LINE; + device->read_op.data.dir = SPI_MEM_DATA_IN; + + return 0; +} +#endif diff --git a/plat/st/stm32mp1/stm32mp1_def.h b/plat/st/stm32mp1/stm32mp1_def.h index a427dcf..11b01ab 100644 --- a/plat/st/stm32mp1/stm32mp1_def.h +++ b/plat/st/stm32mp1/stm32mp1_def.h @@ -151,6 +151,13 @@ /******************************************************************************* * STM32MP1 RAW partition offset for MTD devices ******************************************************************************/ +#define STM32MP_NOR_BL33_OFFSET U(0x00080000) +#ifdef AARCH32_SP_OPTEE +#define STM32MP_NOR_TEEH_OFFSET U(0x00280000) +#define STM32MP_NOR_TEED_OFFSET U(0x002C0000) +#define STM32MP_NOR_TEEX_OFFSET U(0x00300000) +#endif + #define STM32MP_NAND_BL33_OFFSET U(0x00200000) #ifdef AARCH32_SP_OPTEE #define STM32MP_NAND_TEEH_OFFSET U(0x00600000)