driver: flash: npcx: add support for npcx4 series

This CL introduces new Flash Interface Unit (FIU) hardware in npcx4
series. The different operations of npcx9 and npcx4 FIU include:

1. 4-byte mode support for DRA mode move to SPI_DEV reg
2. To access the second flash in DRA mode, we need to configure
   SPI_DEV_SEL field in BURST_CFG additionally.

Signed-off-by: Jun Lin <CHLin56@nuvoton.com>
This commit is contained in:
Jun Lin 2023-06-01 14:10:11 +08:00 committed by Fabio Baltieri
commit df0646ed6e
4 changed files with 68 additions and 14 deletions

View file

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

View file

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

View file

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

View file

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