stm32mp1: Add support for SPI-NOR boot device

STM32MP1 platform is able to boot from SPI-NOR devices.
These modifications add this support using the new
SPI-NOR framework.

Change-Id: I75ff9eba4661f9fb87ce24ced2bacbf8558ebe44
Signed-off-by: Lionel Debieve <lionel.debieve@st.com>
This commit is contained in:
Lionel Debieve 2019-09-25 09:11:31 +02:00
parent 5704422814
commit b1b218fb1b
6 changed files with 119 additions and 4 deletions

View File

@ -20,6 +20,7 @@
#include <drivers/partition/partition.h>
#include <drivers/raw_nand.h>
#include <drivers/spi_nand.h>
#include <drivers/spi_nor.h>
#include <drivers/st/io_mmc.h>
#include <drivers/st/io_stm32image.h>
#include <drivers/st/stm32_fmc2_nand.h>
@ -61,6 +62,15 @@ static const io_block_dev_spec_t mmc_block_dev_spec = {
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 @@ static io_mtd_dev_spec_t spi_nand_dev_spec = {
.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 @@ static void print_boot_device(boot_api_context_t *boot_context)
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 @@ static void boot_mmc(enum mmc_device_type mmc_dev_type,
}
#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 @@ void stm32mp_io_setup(void)
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();

View File

@ -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

View File

@ -9,8 +9,10 @@
#include <drivers/raw_nand.h>
#include <drivers/spi_nand.h>
#include <drivers/spi_nor.h>
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 */

View File

@ -29,9 +29,10 @@ STM32MP_EMMC ?= 0
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_EMMC))
$(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 @@ ifeq (${STM32MP_SPI_NAND},1)
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 \

View File

@ -11,6 +11,7 @@
#include <plat/common/platform.h>
#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 @@ int plat_get_spi_nand_data(struct spinand_device *device)
}
#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

View File

@ -151,6 +151,13 @@ enum ddr_type {
/*******************************************************************************
* 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)