drivers: flash: npcx: add setting of low flash device

This commit adds functions to select the low flash device and set the
size of the low flash device.

Signed-off-by: Tom Chang <CHChang19@nuvoton.com>
This commit is contained in:
Tom Chang 2024-09-27 17:43:30 +08:00 committed by Benjamin Cabé
commit 5c62097bda
5 changed files with 77 additions and 0 deletions

View file

@ -65,4 +65,12 @@ config FLASH_NPCX_FIU_SUPP_DRA_2_DEV
Selected if NPCX series supports two external SPI devices in Direct
Read Access (DRA) on QSPI bus.
DT_NPCX_FIU_LOW_DEV_SWAP := $(dt_nodelabel_bool_prop,qspi_fiu1,flash-dev-inv)
config FLASH_NPCX_FIU_SUPP_LOW_DEV_SWAP
bool "Inverse the access of the two external flashes"
default y if SOC_SERIES_NPCX4 && FLASH_NPCX_FIU_SUPP_DRA_2_DEV && \
"$(DT_NPCX_FIU_LOW_DEV_SWAP)"
help
Select if it needs to swap the access of the two external flashes.
endif #FLASH_NPCX_FIU_QSPI

View file

@ -587,9 +587,23 @@ static int flash_npcx_nor_init(const struct device *dev)
}
}
if (config->qspi_cfg.is_logical_low_dev && IS_ENABLED(CONFIG_FLASH_NPCX_FIU_DRA_V2)) {
qspi_npcx_fiu_set_spi_size(config->qspi_bus, &config->qspi_cfg);
}
return 0;
}
#define NPCX_FLASH_IS_LOGICAL_LOW_DEV(n) \
(DT_PROP(DT_PARENT(DT_DRV_INST(n)), en_direct_access_2dev) && \
(DT_PROP(DT_PARENT(DT_DRV_INST(n)), flash_dev_inv) == \
((DT_INST_PROP(n, qspi_flags) & NPCX_QSPI_SEC_FLASH_SL) == \
NPCX_QSPI_SEC_FLASH_SL)))
#define NPCX_FLASH_SPI_ALLOCATE_SIZE(n) \
COND_CODE_1(DT_INST_NODE_HAS_PROP(n, spi_dev_size), \
(DT_INST_STRING_TOKEN(n, spi_dev_size)), (0xFF))
#define NPCX_FLASH_NOR_INIT(n) \
BUILD_ASSERT(DT_INST_QUAD_EN_PROP_OR(n) == JESD216_DW15_QER_NONE || \
DT_INST_STRING_TOKEN(n, rd_mode) == NPCX_RD_MODE_FAST_DUAL, \
@ -606,6 +620,8 @@ static const struct flash_npcx_nor_config flash_npcx_nor_config_##n = { \
.enter_4ba = DT_INST_PROP_OR(n, enter_4byte_addr, 0), \
.qer_type = DT_INST_QUAD_EN_PROP_OR(n), \
.rd_mode = DT_INST_STRING_TOKEN(n, rd_mode), \
.is_logical_low_dev = NPCX_FLASH_IS_LOGICAL_LOW_DEV(n), \
.spi_dev_sz = NPCX_FLASH_SPI_ALLOCATE_SIZE(n), \
}, \
IF_ENABLED(CONFIG_FLASH_PAGE_LAYOUT, ( \
.layout = { \

View file

@ -30,6 +30,7 @@ struct npcx_qspi_fiu_config {
struct npcx_clk_cfg clk_cfg;
/* Enable 2 external SPI devices for direct read on QSPI bus */
bool en_direct_access_2dev;
bool base_flash_inv;
};
/* Device data */
@ -244,6 +245,25 @@ void qspi_npcx_fiu_mutex_unlock(const struct device *dev)
k_sem_give(&data->lock_sem);
}
#if defined(CONFIG_FLASH_NPCX_FIU_DRA_V2)
void qspi_npcx_fiu_set_spi_size(const struct device *dev, const struct npcx_qspi_cfg *cfg)
{
struct fiu_reg *const inst = HAL_INSTANCE(dev);
uint8_t flags = cfg->flags;
if (cfg->spi_dev_sz <= NPCX_SPI_DEV_SIZE_128M) {
if ((flags & NPCX_QSPI_SEC_FLASH_SL) == 0) {
SET_FIELD(inst->BURST_CFG, NPCX_BURST_CFG_SPI_DEV_SEL, NPCX_SPI_F_CS0);
} else {
SET_FIELD(inst->BURST_CFG, NPCX_BURST_CFG_SPI_DEV_SEL, NPCX_SPI_F_CS1);
}
inst->SPI_DEV_SIZE = BIT(cfg->spi_dev_sz);
} else {
LOG_ERR("Invalid setting of low device size");
}
}
#endif
static int qspi_npcx_fiu_init(const struct device *dev)
{
const struct npcx_qspi_fiu_config *const config = dev->config;
@ -273,6 +293,11 @@ static int qspi_npcx_fiu_init(const struct device *dev)
struct fiu_reg *const inst = HAL_INSTANCE(dev);
inst->FIU_EXT_CFG |= BIT(NPCX_FIU_EXT_CFG_SPI1_2DEV);
#if defined(CONFIG_FLASH_NPCX_FIU_SUPP_LOW_DEV_SWAP)
if (config->base_flash_inv) {
inst->FIU_EXT_CFG |= BIT(NPCX_FIU_EXT_CFG_LOW_DEV_NUM);
}
#endif
#endif
}
@ -284,6 +309,7 @@ static const struct npcx_qspi_fiu_config npcx_qspi_fiu_config_##n = { \
.base = DT_INST_REG_ADDR(n), \
.clk_cfg = NPCX_DT_CLK_CFG_ITEM(n), \
.en_direct_access_2dev = DT_INST_PROP(n, en_direct_access_2dev), \
.base_flash_inv = DT_INST_PROP(n, flash_dev_inv), \
}; \
static struct npcx_qspi_fiu_data npcx_qspi_fiu_data_##n; \
DEVICE_DT_INST_DEFINE(n, qspi_npcx_fiu_init, NULL, \

View file

@ -25,6 +25,20 @@ extern "C" {
#define NPCX_DEV_NUM_ADDR_3BYTE 3
#define NPCX_DEV_NUM_ADDR_4BYTE 4
#define NPCX_SPI_F_CS0 0
#define NPCX_SPI_F_CS1 1
enum NPCX_SPI_DEV_SIZE {
NPCX_SPI_DEV_SIZE_1M,
NPCX_SPI_DEV_SIZE_2M,
NPCX_SPI_DEV_SIZE_4M,
NPCX_SPI_DEV_SIZE_8M,
NPCX_SPI_DEV_SIZE_16M,
NPCX_SPI_DEV_SIZE_32M,
NPCX_SPI_DEV_SIZE_64M,
NPCX_SPI_DEV_SIZE_128M,
};
/* UMA operation configuration for a SPI device */
struct npcx_uma_cfg {
uint8_t opcode;
@ -48,6 +62,8 @@ struct npcx_qspi_cfg {
uint8_t enter_4ba;
/* SPI read access type of Direct Read Access mode */
uint8_t rd_mode;
bool is_logical_low_dev;
uint8_t spi_dev_sz;
/* Configurations for the Quad-SPI peripherals */
int flags;
};
@ -81,6 +97,16 @@ void qspi_npcx_fiu_mutex_lock_configure(const struct device *dev,
*/
void qspi_npcx_fiu_mutex_unlock(const struct device *dev);
#if defined(CONFIG_FLASH_NPCX_FIU_DRA_V2)
/**
* @brief Set the size of the address space allocated for SPI device.
*
* @param dev Pointer to the device structure for qspi bus controller instance.
* @param cfg Pointer to the configuration for the device on qspi bus.
*/
void qspi_npcx_fiu_set_spi_size(const struct device *dev, const struct npcx_qspi_cfg *cfg);
#endif
#ifdef __cplusplus
}
#endif

View file

@ -38,6 +38,7 @@
/* NPCX4 FIU register fields */
#define NPCX_FIU_EXT_CFG_SPI1_2DEV 6
#define NPCX_FIU_EXT_CFG_LOW_DEV_NUM 7
/* NPCX4 supported group mask of DEVALT_LK */
#define NPCX_DEVALT_LK_GROUP_MASK \