diff --git a/drivers/flash/flash_npcx_fiu_qspi.c b/drivers/flash/flash_npcx_fiu_qspi.c index 8b53be28c86..e8c557b8e25 100644 --- a/drivers/flash/flash_npcx_fiu_qspi.c +++ b/drivers/flash/flash_npcx_fiu_qspi.c @@ -96,11 +96,43 @@ static inline void qspi_npcx_config_uma_mode(const struct device *dev, } } +static inline void qspi_npcx_config_dra_4byte_mode(const struct device *dev, + const struct npcx_qspi_cfg *qspi_cfg) +{ +#if !defined(CONFIG_SOC_SERIES_NPCX7) /* NPCX7 doesn't support this feature */ + struct fiu_reg *const inst = HAL_INSTANCE(dev); + +#if defined(CONFIG_SOC_SERIES_NPCX9) + if (qspi_cfg->enter_4ba != 0) { + if ((qspi_cfg->flags & NPCX_QSPI_SEC_FLASH_SL) != 0) { + inst->SPI1_DEV |= BIT(NPCX_SPI1_DEV_FOUR_BADDR_CS11); + } else { + inst->SPI1_DEV |= BIT(NPCX_SPI1_DEV_FOUR_BADDR_CS10); + } + } else { + inst->SPI1_DEV &= ~(BIT(NPCX_SPI1_DEV_FOUR_BADDR_CS11) | + BIT(NPCX_SPI1_DEV_FOUR_BADDR_CS10)); + } +#elif defined(CONFIG_SOC_SERIES_NPCX4) + if (qspi_cfg->enter_4ba != 0) { + SET_FIELD(inst->SPI_DEV, NPCX_SPI_DEV_NADDRB, NPCX_DEV_NUM_ADDR_4BYTE); + } +#endif +#endif /* CONFIG_SOC_SERIES_NPCX7 */ +} + static inline void qspi_npcx_config_dra_mode(const struct device *dev, const struct npcx_qspi_cfg *qspi_cfg) { struct fiu_reg *const inst = HAL_INSTANCE(dev); + /* Select SPI device number for DRA mode in npcx4 series */ + if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX4)) { + int spi_dev_num = (qspi_cfg->flags & NPCX_QSPI_SEC_FLASH_SL) != 0 ? 1 : 0; + + SET_FIELD(inst->BURST_CFG, NPCX_BURST_CFG_SPI_DEV_SEL, spi_dev_num); + } + /* Enable quad mode of Direct Read Mode if needed */ if (qspi_cfg->qer_type != JESD216_DW15_QER_NONE) { inst->RESP_CFG |= BIT(NPCX_RESP_CFG_QUAD_EN); @@ -112,18 +144,7 @@ static inline void qspi_npcx_config_dra_mode(const struct device *dev, SET_FIELD(inst->SPI_FL_CFG, NPCX_SPI_FL_CFG_RD_MODE, qspi_cfg->rd_mode); /* Enable/Disable 4 byte address mode for Direct Read Access (DRA) */ -#if !defined(CONFIG_SOC_SERIES_NPCX7) /* NPCX7 doesn't support this feature */ - if (qspi_cfg->enter_4ba != 0) { - if ((qspi_cfg->flags & NPCX_QSPI_SEC_FLASH_SL) != 0) { - inst->SPI1_DEV |= BIT(NPCX_SPI1_DEV_FOUR_BADDR_CS11); - } else { - inst->SPI1_DEV |= BIT(NPCX_SPI1_DEV_FOUR_BADDR_CS10); - } - } else { - inst->SPI1_DEV &= ~(BIT(NPCX_SPI1_DEV_FOUR_BADDR_CS11) | - BIT(NPCX_SPI1_DEV_FOUR_BADDR_CS10)); - } -#endif /* CONFIG_SOC_SERIES_NPCX7 */ + qspi_npcx_config_dra_4byte_mode(dev, qspi_cfg); } static inline void qspi_npcx_fiu_set_operation(const struct device *dev, uint32_t operation) @@ -249,11 +270,16 @@ static int qspi_npcx_fiu_init(const struct device *dev) /* Enable direct access for 2 external SPI devices */ if (config->en_direct_access_2dev) { - if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX9)) { + if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX9) || IS_ENABLED(CONFIG_SOC_SERIES_NPCX4)) { inst->FIU_EXT_CFG |= BIT(NPCX_FIU_EXT_CFG_SPI1_2DEV); } } + /* Make sure there is no address field (UMA_ADDR_SIZE is zero) in UMA mode */ + if (IS_ENABLED(CONFIG_SOC_SERIES_NPCX4)) { + SET_FIELD(inst->UMA_ECTS, NPCX_UMA_ECTS_UMA_ADDR_SIZE, 0); + } + return 0; } diff --git a/drivers/flash/flash_npcx_fiu_qspi.h b/drivers/flash/flash_npcx_fiu_qspi.h index 092c4371e65..1136684d453 100644 --- a/drivers/flash/flash_npcx_fiu_qspi.h +++ b/drivers/flash/flash_npcx_fiu_qspi.h @@ -19,6 +19,12 @@ extern "C" { #define NPCX_UMA_ACCESS_READ BIT(1) #define NPCX_UMA_ACCESS_ADDR BIT(2) +/* Valid value of Dn_NADDRB that sets the number of address bytes in a transaction */ +#define NPCX_DEV_NUM_ADDR_1BYTE 1 +#define NPCX_DEV_NUM_ADDR_2BYTE 2 +#define NPCX_DEV_NUM_ADDR_3BYTE 3 +#define NPCX_DEV_NUM_ADDR_4BYTE 4 + /* UMA operation configuration for a SPI device */ struct npcx_uma_cfg { uint8_t opcode; diff --git a/soc/arm/nuvoton_npcx/common/reg/reg_def.h b/soc/arm/nuvoton_npcx/common/reg/reg_def.h index 098550c5cca..afcb0597f1e 100644 --- a/soc/arm/nuvoton_npcx/common/reg/reg_def.h +++ b/soc/arm/nuvoton_npcx/common/reg/reg_def.h @@ -1533,10 +1533,24 @@ struct fiu_reg { volatile uint8_t SPI1_DEV; /* 0x03E-0x3F */ volatile uint8_t reserved9[2]; +#elif defined(CONFIG_SOC_SERIES_NPCX4) + /* 0x034: UMA address byte 0-3 */ + volatile uint32_t UMA_AB0_3; + /* 0x038-0x3B */ + volatile uint8_t reserved8[4]; + /* 0x03C: SPI Device */ + volatile uint8_t SPI_DEV; + /* 0x03D */ + volatile uint8_t reserved9; + /* 0x03E */ + volatile uint8_t SPI_DEV_SIZE; + /* 0x03F */ + volatile uint8_t reserved10; #endif }; /* FIU register fields */ +#define NPCX_BURST_CFG_SPI_DEV_SEL FIELD(4, 2) #define NPCX_RESP_CFG_IAD_EN 0 #define NPCX_RESP_CFG_DEV_SIZE_EX 2 #define NPCX_RESP_CFG_QUAD_EN 3 @@ -1550,12 +1564,20 @@ struct fiu_reg { #define NPCX_UMA_ECTS_SW_CS1 1 #define NPCX_UMA_ECTS_SEC_CS 2 #define NPCX_UMA_ECTS_UMA_LOCK 3 +#define NPCX_UMA_ECTS_UMA_ADDR_SIZE FIELD(4, 3) #define NPCX_SPI1_DEV_FOUR_BADDR_CS10 6 #define NPCX_SPI1_DEV_FOUR_BADDR_CS11 7 #define NPCX_SPI1_DEV_SPI1_LO_DEV_SIZE FIELD(0, 4) +#if defined(CONFIG_SOC_SERIES_NPCX9) #define NPCX_FIU_EXT_CFG_SPI1_2DEV 7 +#else +#define NPCX_FIU_EXT_CFG_SPI1_2DEV 6 +#endif #define NPCX_FIU_EXT_CFG_SET_DMM_EN 2 #define NPCX_FIU_EXT_CFG_SET_CMD_EN 1 +#define NPCX_SPI_DEV_NADDRB FIELD(5, 3) + +#define NPCX_MSR_IE_CFG_UMA_BLOCK 3 /* UMA fields selections */ #define UMA_FLD_ADDR BIT(NPCX_UMA_CTS_A_SIZE) /* 3-bytes ADR field */ diff --git a/soc/arm/nuvoton_npcx/common/registers.c b/soc/arm/nuvoton_npcx/common/registers.c index 453fffbe24a..0405bee3567 100644 --- a/soc/arm/nuvoton_npcx/common/registers.c +++ b/soc/arm/nuvoton_npcx/common/registers.c @@ -162,7 +162,7 @@ NPCX_REG_OFFSET_CHECK(ps2_reg, PSISIG, 0x008); NPCX_REG_OFFSET_CHECK(ps2_reg, PSIEN, 0x00a); /* FIU register structure check */ -#if defined(CONFIG_SOC_SERIES_NPCX9) +#if defined(CONFIG_SOC_SERIES_NPCX9) || defined(CONFIG_SOC_SERIES_NPCX4) NPCX_REG_SIZE_CHECK(fiu_reg, 0x040); #else NPCX_REG_SIZE_CHECK(fiu_reg, 0x034);