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 Selected if NPCX series supports two external SPI devices in Direct
Read Access (DRA) on QSPI bus. 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 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; 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) \ #define NPCX_FLASH_NOR_INIT(n) \
BUILD_ASSERT(DT_INST_QUAD_EN_PROP_OR(n) == JESD216_DW15_QER_NONE || \ 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, \ 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), \ .enter_4ba = DT_INST_PROP_OR(n, enter_4byte_addr, 0), \
.qer_type = DT_INST_QUAD_EN_PROP_OR(n), \ .qer_type = DT_INST_QUAD_EN_PROP_OR(n), \
.rd_mode = DT_INST_STRING_TOKEN(n, rd_mode), \ .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, ( \ IF_ENABLED(CONFIG_FLASH_PAGE_LAYOUT, ( \
.layout = { \ .layout = { \

View file

@ -30,6 +30,7 @@ struct npcx_qspi_fiu_config {
struct npcx_clk_cfg clk_cfg; struct npcx_clk_cfg clk_cfg;
/* Enable 2 external SPI devices for direct read on QSPI bus */ /* Enable 2 external SPI devices for direct read on QSPI bus */
bool en_direct_access_2dev; bool en_direct_access_2dev;
bool base_flash_inv;
}; };
/* Device data */ /* Device data */
@ -244,6 +245,25 @@ void qspi_npcx_fiu_mutex_unlock(const struct device *dev)
k_sem_give(&data->lock_sem); 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) static int qspi_npcx_fiu_init(const struct device *dev)
{ {
const struct npcx_qspi_fiu_config *const config = dev->config; 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); struct fiu_reg *const inst = HAL_INSTANCE(dev);
inst->FIU_EXT_CFG |= BIT(NPCX_FIU_EXT_CFG_SPI1_2DEV); 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 #endif
} }
@ -284,6 +309,7 @@ static const struct npcx_qspi_fiu_config npcx_qspi_fiu_config_##n = { \
.base = DT_INST_REG_ADDR(n), \ .base = DT_INST_REG_ADDR(n), \
.clk_cfg = NPCX_DT_CLK_CFG_ITEM(n), \ .clk_cfg = NPCX_DT_CLK_CFG_ITEM(n), \
.en_direct_access_2dev = DT_INST_PROP(n, en_direct_access_2dev), \ .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; \ static struct npcx_qspi_fiu_data npcx_qspi_fiu_data_##n; \
DEVICE_DT_INST_DEFINE(n, qspi_npcx_fiu_init, NULL, \ 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_3BYTE 3
#define NPCX_DEV_NUM_ADDR_4BYTE 4 #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 */ /* UMA operation configuration for a SPI device */
struct npcx_uma_cfg { struct npcx_uma_cfg {
uint8_t opcode; uint8_t opcode;
@ -48,6 +62,8 @@ struct npcx_qspi_cfg {
uint8_t enter_4ba; uint8_t enter_4ba;
/* SPI read access type of Direct Read Access mode */ /* SPI read access type of Direct Read Access mode */
uint8_t rd_mode; uint8_t rd_mode;
bool is_logical_low_dev;
uint8_t spi_dev_sz;
/* Configurations for the Quad-SPI peripherals */ /* Configurations for the Quad-SPI peripherals */
int flags; 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); 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 #ifdef __cplusplus
} }
#endif #endif

View file

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