summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJun Lin <CHLin56@nuvoton.com>2021-11-04 10:31:52 +0800
committerCommit Bot <commit-bot@chromium.org>2021-11-12 20:44:32 +0000
commit7a544b16076115135a146a343d6d8b5c8cbebadb (patch)
treec857c07ea04cfb6159f279a678fb707ed1e98ac9
parent6faaf44daa8b3d1847df90bcea27d35bd0953da4 (diff)
downloadchrome-ec-7a544b16076115135a146a343d6d8b5c8cbebadb.tar.gz
zephyr: flash: npcx: move the flash operations to upstream
In PR:39644, the SPI (FIU/UMA) driver is added to the Zephyr upstream. The flash access now can be via the flash APIs in spi_nor driver, including flash write/read/erase/read_jedec_id. Note that because there is no API in the flash driver to read/write the status register, it is implemented here via the spi_transceive API. BRANCH=none BUG=b:202295086 TEST=pass "zmake testall" TEST=enable flash console command on volteer and npcx9_evb, test the following flash related commands: flashread/flashwrite/flasherase/flashwp/flashchip/flashinfo. Signed-off-by: Jun Lin <CHLin56@nuvoton.com> Cq-Depend: chromium:3261416 Change-Id: I012ea359695a22cbb54d39124b4b78ff95cca36d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3261447 Tested-by: CH Lin <chlin56@nuvoton.com> Commit-Queue: Keith Short <keithshort@chromium.org> Reviewed-by: Keith Short <keithshort@chromium.org>
-rw-r--r--zephyr/Kconfig.init_priority1
-rw-r--r--zephyr/boards/arm/brya/brya_defconfig8
-rw-r--r--zephyr/boards/arm/herobrine_npcx9/herobrine_npcx9_defconfig8
-rw-r--r--zephyr/boards/arm/npcx9/npcx9_defconfig8
-rw-r--r--zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig8
-rw-r--r--zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig8
-rw-r--r--zephyr/boards/arm/trogdor/trogdor_defconfig8
-rw-r--r--zephyr/boards/arm/volteer/volteer_defconfig8
-rw-r--r--zephyr/drivers/cros_flash/Kconfig13
-rw-r--r--zephyr/drivers/cros_flash/cros_flash_npcx.c493
-rw-r--r--zephyr/dts/bindings/cros_flash/nuvoton,npcx-cros-flash.yaml12
-rw-r--r--zephyr/include/cros/nuvoton/npcx.dtsi13
-rw-r--r--zephyr/include/soc/nuvoton_npcx/reg_def_cros.h95
-rw-r--r--zephyr/shim/src/flash.c5
14 files changed, 216 insertions, 472 deletions
diff --git a/zephyr/Kconfig.init_priority b/zephyr/Kconfig.init_priority
index af858a5296..5370072c2c 100644
--- a/zephyr/Kconfig.init_priority
+++ b/zephyr/Kconfig.init_priority
@@ -4,6 +4,7 @@
config PLATFORM_EC_FLASH_INIT_PRIORITY
int "Init priority of the flash module"
+ default 90 if SOC_FAMILY_NPCX
default 52
help
The initialization priority of the flash module. This should always be
diff --git a/zephyr/boards/arm/brya/brya_defconfig b/zephyr/boards/arm/brya/brya_defconfig
index e8c412a592..09c80a57a8 100644
--- a/zephyr/boards/arm/brya/brya_defconfig
+++ b/zephyr/boards/arm/brya/brya_defconfig
@@ -39,3 +39,11 @@ CONFIG_WATCHDOG=y
# BBRAM
CONFIG_BBRAM=y
CONFIG_BBRAM_NPCX=y
+
+# SPI
+CONFIG_SPI=y
+
+# Flash
+CONFIG_FLASH=y
+CONFIG_SPI_NOR=y
+CONFIG_FLASH_JESD216_API=y
diff --git a/zephyr/boards/arm/herobrine_npcx9/herobrine_npcx9_defconfig b/zephyr/boards/arm/herobrine_npcx9/herobrine_npcx9_defconfig
index 907ae9ed34..609a8312f1 100644
--- a/zephyr/boards/arm/herobrine_npcx9/herobrine_npcx9_defconfig
+++ b/zephyr/boards/arm/herobrine_npcx9/herobrine_npcx9_defconfig
@@ -38,3 +38,11 @@ CONFIG_SOC_POWER_MANAGEMENT_TRACE=y
# BBRAM
CONFIG_BBRAM=y
CONFIG_BBRAM_NPCX=y
+
+# SPI
+CONFIG_SPI=y
+
+# Flash
+CONFIG_FLASH=y
+CONFIG_SPI_NOR=y
+CONFIG_FLASH_JESD216_API=y
diff --git a/zephyr/boards/arm/npcx9/npcx9_defconfig b/zephyr/boards/arm/npcx9/npcx9_defconfig
index d20fd87f3a..f8cfd551af 100644
--- a/zephyr/boards/arm/npcx9/npcx9_defconfig
+++ b/zephyr/boards/arm/npcx9/npcx9_defconfig
@@ -31,3 +31,11 @@ CONFIG_WATCHDOG=y
CONFIG_BBRAM=y
CONFIG_BBRAM_NPCX=y
+
+# SPI
+CONFIG_SPI=y
+
+# Flash
+CONFIG_FLASH=y
+CONFIG_SPI_NOR=y
+CONFIG_FLASH_JESD216_API=y
diff --git a/zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig b/zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig
index b2fc879cbc..b2da6c4631 100644
--- a/zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig
+++ b/zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig
@@ -53,3 +53,11 @@ CONFIG_SOC_POWER_MANAGEMENT_TRACE=y
# BBRAM
CONFIG_BBRAM=y
CONFIG_BBRAM_NPCX=y
+
+# SPI
+CONFIG_SPI=y
+
+# Flash
+CONFIG_FLASH=y
+CONFIG_SPI_NOR=y
+CONFIG_FLASH_JESD216_API=y
diff --git a/zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig b/zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig
index 9a946584ef..6d0f10d1ed 100644
--- a/zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig
+++ b/zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig
@@ -52,3 +52,11 @@ CONFIG_SOC_POWER_MANAGEMENT_TRACE=y
# BBRAM
CONFIG_BBRAM=y
CONFIG_BBRAM_NPCX=y
+
+# SPI
+CONFIG_SPI=y
+
+# Flash
+CONFIG_FLASH=y
+CONFIG_SPI_NOR=y
+CONFIG_FLASH_JESD216_API=y
diff --git a/zephyr/boards/arm/trogdor/trogdor_defconfig b/zephyr/boards/arm/trogdor/trogdor_defconfig
index 2a61f3dd5c..e5ca49969f 100644
--- a/zephyr/boards/arm/trogdor/trogdor_defconfig
+++ b/zephyr/boards/arm/trogdor/trogdor_defconfig
@@ -38,3 +38,11 @@ CONFIG_SOC_POWER_MANAGEMENT_TRACE=y
# BBRAM
CONFIG_BBRAM=y
CONFIG_BBRAM_NPCX=y
+
+# SPI
+CONFIG_SPI=y
+
+# Flash
+CONFIG_FLASH=y
+CONFIG_SPI_NOR=y
+CONFIG_FLASH_JESD216_API=y
diff --git a/zephyr/boards/arm/volteer/volteer_defconfig b/zephyr/boards/arm/volteer/volteer_defconfig
index a3f184dff8..16eee231a3 100644
--- a/zephyr/boards/arm/volteer/volteer_defconfig
+++ b/zephyr/boards/arm/volteer/volteer_defconfig
@@ -43,3 +43,11 @@ CONFIG_SOC_POWER_MANAGEMENT_TRACE=y
# BBRAM
CONFIG_BBRAM=y
CONFIG_BBRAM_NPCX=y
+
+# SPI
+CONFIG_SPI=y
+
+# Flash
+CONFIG_FLASH=y
+CONFIG_SPI_NOR=y
+CONFIG_FLASH_JESD216_API=y
diff --git a/zephyr/drivers/cros_flash/Kconfig b/zephyr/drivers/cros_flash/Kconfig
index 1d100a6068..05de5c5e5b 100644
--- a/zephyr/drivers/cros_flash/Kconfig
+++ b/zephyr/drivers/cros_flash/Kconfig
@@ -12,6 +12,19 @@ menuconfig CROS_FLASH_NPCX
continue to use most of the existing flash memory processing code in
ECOS.
+if CROS_FLASH_NPCX
+
+config CROS_FLASH_NPCX_INIT_PRIORITY
+ int "Nuvoton NPCX flash driver priority for the Zephyr shim"
+ default 85
+ help
+ This sets the priority of the NPCX flash driver for zephyr shim.
+ This driver depends on the SPI controller and SPI NOR flash drivers.
+ Its priority must be lower than CONFIG_SPI_INIT_PRIORITY and
+ CONFIG_SPI_NOR_INIT_PRIORITY.
+
+endif # CROS_FLASH_NPCX
+
config CROS_FLASH_IT8XXX2
bool "ITE IT81202 flash driver for the Zephyr shim"
depends on SOC_FAMILY_RISCV_ITE
diff --git a/zephyr/drivers/cros_flash/cros_flash_npcx.c b/zephyr/drivers/cros_flash/cros_flash_npcx.c
index abeabcbf3d..902117d4c1 100644
--- a/zephyr/drivers/cros_flash/cros_flash_npcx.c
+++ b/zephyr/drivers/cros_flash/cros_flash_npcx.c
@@ -5,21 +5,17 @@
#define DT_DRV_COMPAT nuvoton_npcx_cros_flash
-#include <dt-bindings/clock/npcx_clock.h>
#include <drivers/cros_flash.h>
-#include <drivers/clock_control.h>
+#include <drivers/flash.h>
#include <drivers/gpio.h>
+#include <drivers/spi.h>
#include <kernel.h>
#include <logging/log.h>
#include <soc.h>
-#include <soc/nuvoton_npcx/reg_def_cros.h>
-#include <sys/__assert.h>
-#include "ec_tasks.h"
+
#include "flash.h"
#include "gpio.h"
-#include "soc_miwu.h"
#include "spi_flash_reg.h"
-#include "task.h"
#include "../drivers/flash/spi_nor.h"
LOG_MODULE_REGISTER(cros_flash, LOG_LEVEL_ERR);
@@ -31,130 +27,90 @@ static uint8_t flag_prot_inconsistent;
static uint8_t saved_sr1;
static uint8_t saved_sr2;
-#define CMD_READ_STATUS_REG 0x05
-#define CMD_READ_STATUS_REG2 0x35
-
-/* Device config */
-struct cros_flash_npcx_config {
- /* flash interface unit base address */
- uintptr_t base;
- /* clock configuration */
- struct npcx_clk_cfg clk_cfg;
- /* Flash size (Unit:bytes) */
- int size;
- /* pinmux configuration */
- const uint8_t alts_size;
- const struct npcx_alt *alts_list;
-};
-
/* Device data */
struct cros_flash_npcx_data {
- /* flag of flash write protection */
- bool write_protectied;
- /* mutex of flash interface controller */
- struct k_sem lock_sem;
+ const struct device *flash_dev;
+ const struct device *spi_ctrl_dev;
};
-/* TODO: Should we replace them with Kconfig variables */
-#define CONFIG_FLASH_WRITE_SIZE 0x1 /* minimum write size */
-#define CONFIG_FLASH_WRITE_IDEAL_SIZE 256 /* one page size for write */
+static struct spi_config spi_cfg;
-/* TODO: It should be defined in the spi_nor.h in the zephyr repository */
-#define SPI_NOR_CMD_FAST_READ 0x0B
+#define FLASH_DEV DT_NODELABEL(int_flash)
+#define SPI_CONTROLLER_DEV DT_NODELABEL(spi_fiu0)
-/* Driver convenience defines */
-#define DRV_CONFIG(dev) ((const struct cros_flash_npcx_config *)(dev)->config)
#define DRV_DATA(dev) ((struct cros_flash_npcx_data *)(dev)->data)
-#define HAL_INSTANCE(dev) (struct fiu_reg *)(DRV_CONFIG(dev)->base)
-/* cros ec flash local inline functions */
-static inline void cros_flash_npcx_mutex_lock(const struct device *dev)
-{
- struct cros_flash_npcx_data *data = DRV_DATA(dev);
+#define SPI_NOR_CMD_RDSR2 0x35
- k_sem_take(&data->lock_sem, K_FOREVER);
-}
-
-static inline void cros_flash_npcx_mutex_unlock(const struct device *dev)
-{
- struct cros_flash_npcx_data *data = DRV_DATA(dev);
-
- k_sem_give(&data->lock_sem);
-}
+/* cros ec flash local functions */
+static int cros_flash_npcx_get_status_reg(const struct device *dev,
+ uint8_t cmd_code, uint8_t *data)
+{
+ uint8_t opcode;
+ struct cros_flash_npcx_data *dev_data = DRV_DATA(dev);
+
+ struct spi_buf spi_buf[2] = {
+ [0] = {
+ .buf = &opcode,
+ .len = 1,
+ },
+ [1] = {
+ .buf = data,
+ .len = 1,
+ }
+ };
-static inline void cros_flash_npcx_set_address(const struct device *dev,
- uint32_t qspi_addr)
-{
- struct fiu_reg *const inst = HAL_INSTANCE(dev);
- uint8_t *addr = (uint8_t *)&qspi_addr;
+ const struct spi_buf_set tx_set = {
+ .buffers = spi_buf,
+ .count = 2,
+ };
- /* Write 3 bytes address to UMA registers */
- inst->UMA_AB2 = addr[2];
- inst->UMA_AB1 = addr[1];
- inst->UMA_AB0 = addr[0];
-}
+ const struct spi_buf_set rx_set = {
+ .buffers = spi_buf,
+ .count = 2,
+ };
-static inline void cros_flash_npcx_cs_level(const struct device *dev, int level)
-{
- struct fiu_reg *const inst = HAL_INSTANCE(dev);
+ if (data == 0)
+ return -EINVAL;
- /* Set chip select to high/low level */
- if (level == 0)
- inst->UMA_ECTS &= ~BIT(NPCX_UMA_ECTS_SW_CS1);
- else
- inst->UMA_ECTS |= BIT(NPCX_UMA_ECTS_SW_CS1);
+ opcode = cmd_code;
+ return spi_transceive(dev_data->spi_ctrl_dev, &spi_cfg, &tx_set,
+ &rx_set);
}
-static inline void cros_flash_npcx_exec_cmd(const struct device *dev,
- uint8_t code, uint8_t cts)
+static int cros_flash_npcx_wait_ready(const struct device *dev)
{
- struct fiu_reg *const inst = HAL_INSTANCE(dev);
-
-#ifdef CONFIG_ASSERT
- struct cros_flash_npcx_data *data = DRV_DATA(dev);
+ int wait_period = 10; /* 10 us period t0 check status register */
+ int timeout = (10 * USEC_PER_SEC) / wait_period; /* 10 seconds */
- /* Flash mutex must be held while executing UMA commands */
- __ASSERT((k_sem_count_get(&data->lock_sem) == 0), "UMA is not locked");
-#endif
+ do {
+ uint8_t reg;
- /* set UMA_CODE */
- inst->UMA_CODE = code;
- /* execute UMA flash transaction */
- inst->UMA_CTS = cts;
- while (IS_BIT_SET(inst->UMA_CTS, NPCX_UMA_CTS_EXEC_DONE))
- ;
-}
+ cros_flash_npcx_get_status_reg(dev, SPI_NOR_CMD_RDSR, &reg);
+ if ((reg & SPI_NOR_WIP_BIT) == 0)
+ break;
+ k_usleep(wait_period);
+ } while (--timeout); /* Wait for busy bit clear */
-static inline void cros_flash_npcx_burst_read(const struct device *dev,
- char *dst_data, int dst_size)
-{
- struct fiu_reg *const inst = HAL_INSTANCE(dev);
-
- /* Burst read transaction */
- for (int idx = 0; idx < dst_size; idx++) {
- /* 1101 0101 - EXEC, RD, NO CMD, NO ADDR, 4 bytes */
- inst->UMA_CTS = UMA_CODE_RD_BYTE(1);
- /* wait for UMA to complete */
- while (IS_BIT_SET(inst->UMA_CTS, NPCX_UMA_CTS_EXEC_DONE))
- ;
- /* Get read transaction results*/
- dst_data[idx] = inst->UMA_DB0;
+ if (timeout) {
+ return 0;
+ } else {
+ return -ETIMEDOUT;
}
}
-static inline int cros_flash_npcx_wait_busy_bit_clear(const struct device *dev)
+/* Check the BUSY bit is cleared and WE bit is set */
+static int cros_flash_npcx_wait_ready_and_we(const struct device *dev)
{
- struct fiu_reg *const inst = HAL_INSTANCE(dev);
int wait_period = 10; /* 10 us period t0 check status register */
int timeout = (10 * USEC_PER_SEC) / wait_period; /* 10 seconds */
do {
- /* Read status register */
- inst->UMA_CTS = UMA_CODE_RD_BYTE(1);
- while (IS_BIT_SET(inst->UMA_CTS, NPCX_UMA_CTS_EXEC_DONE))
- ;
- /* Status bit is clear */
- if ((inst->UMA_DB0 & SPI_NOR_WIP_BIT) == 0)
+ uint8_t reg;
+
+ cros_flash_npcx_get_status_reg(dev, SPI_NOR_CMD_RDSR, &reg);
+ if ((reg & SPI_NOR_WIP_BIT) == 0 &&
+ (reg & SPI_NOR_WEL_BIT) != 0)
break;
k_usleep(wait_period);
} while (--timeout); /* Wait for busy bit clear */
@@ -166,28 +122,21 @@ static inline int cros_flash_npcx_wait_busy_bit_clear(const struct device *dev)
}
}
-/* cros ec flash local functions */
-static int cros_flash_npcx_wait_ready(const struct device *dev)
-{
- int ret = 0;
-
- /* Drive CS to low */
- cros_flash_npcx_cs_level(dev, 0);
-
- /* Command for Read status register of flash */
- cros_flash_npcx_exec_cmd(dev, SPI_NOR_CMD_RDSR, UMA_CODE_CMD_ONLY);
- /* Wait busy bit is clear */
- ret = cros_flash_npcx_wait_busy_bit_clear(dev);
- /* Drive CS to low */
- cros_flash_npcx_cs_level(dev, 1);
-
- return ret;
-}
-
static int cros_flash_npcx_set_write_enable(const struct device *dev)
{
- struct fiu_reg *const inst = HAL_INSTANCE(dev);
int ret;
+ uint8_t opcode = SPI_NOR_CMD_WREN;
+ struct cros_flash_npcx_data *data = DRV_DATA(dev);
+
+ struct spi_buf spi_buf = {
+ .buf = &opcode,
+ .len = 1,
+ };
+
+ const struct spi_buf_set tx_set = {
+ .buffers = &spi_buf,
+ .count = 1,
+ };
/* Wait for previous operation to complete */
ret = cros_flash_npcx_wait_ready(dev);
@@ -195,117 +144,49 @@ static int cros_flash_npcx_set_write_enable(const struct device *dev)
return ret;
/* Write enable command */
- cros_flash_npcx_exec_cmd(dev, SPI_NOR_CMD_WREN, UMA_CODE_CMD_ONLY);
-
- /* Wait for flash is not busy */
- ret = cros_flash_npcx_wait_ready(dev);
+ ret = spi_transceive(data->spi_ctrl_dev, &spi_cfg, &tx_set, NULL);
if (ret != 0)
return ret;
- if ((inst->UMA_DB0 & SPI_NOR_WEL_BIT) != 0)
- return 0;
- else
- return -EINVAL;
-}
-
-static void cros_flash_npcx_burst_write(const struct device *dev,
- unsigned int dest_addr,
- unsigned int bytes,
- const char *src_data)
-{
- /* Chip Select down */
- cros_flash_npcx_cs_level(dev, 0);
-
- /* Set write address */
- cros_flash_npcx_set_address(dev, dest_addr);
- /* Start programming */
- cros_flash_npcx_exec_cmd(dev, SPI_NOR_CMD_PP, UMA_CODE_CMD_WR_ADR);
- for (int i = 0; i < bytes; i++) {
- cros_flash_npcx_exec_cmd(dev, *src_data, UMA_CODE_CMD_WR_ONLY);
- src_data++;
- }
-
- /* Chip Select up */
- cros_flash_npcx_cs_level(dev, 1);
+ /* Wait for flash is not busy */
+ return cros_flash_npcx_wait_ready_and_we(dev);
}
-static int cros_flash_npcx_program_bytes(const struct device *dev,
- uint32_t offset, uint32_t bytes,
- const uint8_t *src_data)
+static int cros_flash_npcx_set_status_reg(const struct device *dev, char *data)
{
- int write_size;
+ uint8_t opcode = SPI_NOR_CMD_WRSR;
int ret = 0;
+ struct cros_flash_npcx_data *dev_data = DRV_DATA(dev);
+
+ struct spi_buf spi_buf[2] = {
+ [0] = {
+ .buf = &opcode,
+ .len = 1,
+ },
+ [1] = {
+ .buf = data,
+ .len = 2,
+ }
+ };
- while (bytes > 0) {
- /* Write length can not go beyond the end of the flash page */
- write_size = MIN(bytes,
- CONFIG_FLASH_WRITE_IDEAL_SIZE -
- (offset &
- (CONFIG_FLASH_WRITE_IDEAL_SIZE - 1)));
-
- /* Enable write */
- ret = cros_flash_npcx_set_write_enable(dev);
- if (ret != 0)
- return ret;
-
- /* Executr UMA burst write transaction */
- cros_flash_npcx_burst_write(dev, offset, write_size, src_data);
-
- /* Wait write completed */
- ret = cros_flash_npcx_wait_ready(dev);
- if (ret != 0)
- return ret;
-
- src_data += write_size;
- offset += write_size;
- bytes -= write_size;
- }
-
- return ret;
-}
-
-static int cros_flash_npcx_get_status_reg(const struct device *dev,
- char cmd_code, char *data)
-{
- int ret = 0;
- struct fiu_reg *const inst = HAL_INSTANCE(dev);
+ const struct spi_buf_set tx_set = {
+ .buffers = spi_buf,
+ .count = 2,
+ };
if (data == 0) {
return -EINVAL;
}
- /* Lock flash interface device during reading status register */
- cros_flash_npcx_mutex_lock(dev);
-
- cros_flash_npcx_exec_cmd(dev, cmd_code, UMA_CODE_CMD_RD_BYTE(1));
- *data = inst->UMA_DB0;
- /* Unlock flash interface device */
- cros_flash_npcx_mutex_unlock(dev);
-
- return ret;
-}
-
-static int cros_flash_npcx_set_status_reg(const struct device *dev, char *data)
-{
- int ret = 0;
- struct fiu_reg *const inst = HAL_INSTANCE(dev);
-
- /* Lock flash interface device */
- cros_flash_npcx_mutex_lock(dev);
/* Enable write */
ret = cros_flash_npcx_set_write_enable(dev);
if (ret != 0)
return ret;
- inst->UMA_DB0 = data[0];
- inst->UMA_DB1 = data[1];
- /* Write status register 1/2 */
- cros_flash_npcx_exec_cmd(dev, SPI_NOR_CMD_WRSR,
- UMA_CODE_CMD_WR_BYTE(2));
- /* Unlock flash interface device */
- cros_flash_npcx_mutex_unlock(dev);
-
- return ret;
+ ret = spi_transceive(dev_data->spi_ctrl_dev, &spi_cfg, &tx_set, NULL);
+ if (ret != 0)
+ return ret;
+ return cros_flash_npcx_wait_ready(dev);
}
static int cros_flash_npcx_write_protection_set(const struct device *dev,
@@ -318,11 +199,7 @@ static int cros_flash_npcx_write_protection_set(const struct device *dev,
LOG_ERR("WP can be disabled only via core domain reset ");
return -ENOTSUP;
}
- /* Lock flash interface device */
- cros_flash_npcx_mutex_lock(dev);
ret = npcx_pinctrl_flash_write_protect_set();
- /* Unlock flash interface device */
- cros_flash_npcx_mutex_unlock(dev);
return ret;
}
@@ -334,15 +211,15 @@ static int cros_flash_npcx_write_protection_is_set(const struct device *dev)
static int cros_flash_npcx_uma_lock(const struct device *dev, bool enable)
{
- struct fiu_reg *const inst = HAL_INSTANCE(dev);
+ struct cros_flash_npcx_data *data = DRV_DATA(dev);
if (enable) {
- inst->UMA_ECTS |= BIT(NPCX_UMA_ECTS_UMA_LOCK);
+ spi_cfg.operation |= SPI_LOCK_ON;
} else {
- inst->UMA_ECTS &= ~BIT(NPCX_UMA_ECTS_UMA_LOCK);
+ spi_cfg.operation &= ~SPI_LOCK_ON;
}
- return 0;
+ return spi_transceive(data->spi_ctrl_dev, &spi_cfg, NULL, NULL);
}
static int flash_get_status1(const struct device *dev)
@@ -355,7 +232,7 @@ static int flash_get_status1(const struct device *dev)
/* Lock physical flash operations */
crec_flash_lock_mapped_storage(1);
- cros_flash_npcx_get_status_reg(dev, CMD_READ_STATUS_REG, &reg);
+ cros_flash_npcx_get_status_reg(dev, SPI_NOR_CMD_RDSR, &reg);
/* Unlock physical flash operations */
crec_flash_lock_mapped_storage(0);
@@ -373,7 +250,7 @@ static int flash_get_status2(const struct device *dev)
/* Lock physical flash operations */
crec_flash_lock_mapped_storage(1);
- cros_flash_npcx_get_status_reg(dev, CMD_READ_STATUS_REG2, &reg);
+ cros_flash_npcx_get_status_reg(dev, SPI_NOR_CMD_RDSR2, &reg);
/* Unlock physical flash operations */
crec_flash_lock_mapped_storage(0);
@@ -536,15 +413,6 @@ static int flash_check_prot_range(unsigned int offset, unsigned int bytes)
/* cros ec flash api functions */
static int cros_flash_npcx_init(const struct device *dev)
{
- const struct cros_flash_npcx_config *const config = DRV_CONFIG(dev);
- struct cros_flash_npcx_data *data = DRV_DATA(dev);
-
- /* initialize mutux for flash interface controller */
- k_sem_init(&data->lock_sem, 1, 1);
-
- /* Configure pin-mux for FIU device */
- npcx_pinctrl_mux_configure(config->alts_list, config->alts_size, 1);
-
/*
* Protect status registers of internal spi-flash if WP# is active
* during ec initialization.
@@ -561,39 +429,20 @@ static int cros_flash_npcx_init(const struct device *dev)
return 0;
}
+/* TODO(b/205175314): Migrate cros-flash driver to Zephyr flash driver) */
static int cros_flash_npcx_read(const struct device *dev, int offset, int size,
char *dst_data)
{
- int ret = 0;
-
- /* Unlock flash interface device during reading flash */
- cros_flash_npcx_mutex_lock(dev);
-
- /* Chip Select down */
- cros_flash_npcx_cs_level(dev, 0);
-
- /* Set read address */
- cros_flash_npcx_set_address(dev, offset);
- /* Start with fast read command (skip one dummy byte) */
- cros_flash_npcx_exec_cmd(dev, SPI_NOR_CMD_FAST_READ,
- UMA_CODE_CMD_ADR_WR_BYTE(1));
- /* Execute burst read */
- cros_flash_npcx_burst_read(dev, dst_data, size);
-
- /* Chip Select up */
- cros_flash_npcx_cs_level(dev, 1);
-
- /* Unlock flash interface device */
- cros_flash_npcx_mutex_unlock(dev);
+ struct cros_flash_npcx_data *data = DRV_DATA(dev);
- return ret;
+ return flash_read(data->flash_dev, offset, dst_data, size);
}
static int cros_flash_npcx_write(const struct device *dev, int offset, int size,
const char *src_data)
{
- struct cros_flash_npcx_data *const data = DRV_DATA(dev);
int ret = 0;
+ struct cros_flash_npcx_data *data = DRV_DATA(dev);
/* check protection */
if (all_protected)
@@ -603,47 +452,20 @@ static int cros_flash_npcx_write(const struct device *dev, int offset, int size,
if (flash_check_prot_range(offset, size))
return EC_ERROR_ACCESS_DENIED;
- /* Is write protection enabled? */
- if (data->write_protectied) {
- return -EACCES;
- }
-
/* Invalid data pointer? */
if (src_data == 0) {
return -EINVAL;
}
- /* Unlock flash interface device during writing flash */
- cros_flash_npcx_mutex_lock(dev);
-
- while (size > 0) {
- /* First write multiples of 256, then (size % 256) last */
- int write_len =
- ((size % CONFIG_FLASH_WRITE_IDEAL_SIZE) == size) ?
- size :
- CONFIG_FLASH_WRITE_IDEAL_SIZE;
-
- ret = cros_flash_npcx_program_bytes(dev, offset, write_len,
- src_data);
- if (ret != 0)
- break;
-
- src_data += write_len;
- offset += write_len;
- size -= write_len;
- }
-
- /* Unlock flash interface device */
- cros_flash_npcx_mutex_unlock(dev);
+ ret = flash_write(data->flash_dev, offset, src_data, size);
return ret;
}
static int cros_flash_npcx_erase(const struct device *dev, int offset, int size)
{
- const struct cros_flash_npcx_config *const config = DRV_CONFIG(dev);
- struct cros_flash_npcx_data *const data = DRV_DATA(dev);
int ret = 0;
+ struct cros_flash_npcx_data *data = DRV_DATA(dev);
/* check protection */
if (all_protected)
@@ -653,18 +475,6 @@ static int cros_flash_npcx_erase(const struct device *dev, int offset, int size)
if (flash_check_prot_range(offset, size))
return EC_ERROR_ACCESS_DENIED;
- /* Is write protection enabled? */
- if (data->write_protectied) {
- return -EACCES;
- }
- /* affected region should be within device */
- if (offset < 0 || (offset + size) > config->size) {
- LOG_ERR("Flash erase address or size exceeds expected values. "
- "Addr: 0x%lx size %zu",
- (long)offset, size);
- return -EINVAL;
- }
-
/* address must be aligned to erase size */
if ((offset % CONFIG_FLASH_ERASE_SIZE) != 0) {
return -EINVAL;
@@ -675,32 +485,7 @@ static int cros_flash_npcx_erase(const struct device *dev, int offset, int size)
return -EINVAL;
}
- /* Unlock flash interface device during erasing flash */
- cros_flash_npcx_mutex_lock(dev);
-
- /* Alignment has been checked in upper layer */
- for (; size > 0; size -= CONFIG_FLASH_ERASE_SIZE,
- offset += CONFIG_FLASH_ERASE_SIZE) {
-
- /* Enable write */
- ret = cros_flash_npcx_set_write_enable(dev);
- if (ret != 0)
- break;
-
- /* Set erase address */
- cros_flash_npcx_set_address(dev, offset);
- /* Start erasing */
- cros_flash_npcx_exec_cmd(dev, SPI_NOR_CMD_BE, UMA_CODE_CMD_ADR);
-
- /* Wait erase completed */
- ret = cros_flash_npcx_wait_ready(dev);
- if (ret != 0) {
- break;
- }
- }
-
- /* Unlock flash interface device */
- cros_flash_npcx_mutex_unlock(dev);
+ ret = flash_erase(data->flash_dev, offset, size);
return ret;
}
@@ -778,23 +563,23 @@ static int cros_flash_npcx_get_jedec_id(const struct device *dev,
uint8_t *manufacturer,
uint16_t *device)
{
- struct fiu_reg *const inst = HAL_INSTANCE(dev);
+ int ret;
+ uint8_t jedec_id[3];
+ struct cros_flash_npcx_data *data = DRV_DATA(dev);
/* Lock physical flash operations */
crec_flash_lock_mapped_storage(1);
- /* Read manufacturer and device ID */
- cros_flash_npcx_exec_cmd(dev,
- SPI_NOR_CMD_RDID,
- UMA_CODE_CMD_RD_BYTE(3));
-
- *manufacturer = inst->UMA_DB0;
- *device = (inst->UMA_DB1 << 8) | inst->UMA_DB2;
+ ret = flash_read_jedec_id(data->flash_dev, jedec_id);
+ if (ret == 0) {
+ *manufacturer = jedec_id[0];
+ *device = (jedec_id[1] << 8) | jedec_id[2];
+ }
/* Unlock physical flash operations */
crec_flash_lock_mapped_storage(0);
- return EC_SUCCESS;
+ return ret;
}
static int cros_flash_npcx_get_status(const struct device *dev,
@@ -822,34 +607,28 @@ static const struct cros_flash_driver_api cros_flash_npcx_driver_api = {
static int flash_npcx_init(const struct device *dev)
{
- const struct cros_flash_npcx_config *const config = DRV_CONFIG(dev);
- const struct device *clk_dev = DEVICE_DT_GET(NPCX_CLK_CTRL_NODE);
+ struct cros_flash_npcx_data *data = DRV_DATA(dev);
- int ret;
+ data->flash_dev = DEVICE_DT_GET(FLASH_DEV);
+ if (!device_is_ready(data->flash_dev)) {
+ LOG_ERR("%s device not ready", data->flash_dev->name);
+ return -ENODEV;
+ }
- /* Turn on device clock first and get source clock freq. */
- ret = clock_control_on(clk_dev,
- (clock_control_subsys_t *)&config->clk_cfg);
- if (ret < 0) {
- LOG_ERR("Turn on FIU clock fail %d", ret);
- return ret;
+ data->spi_ctrl_dev = DEVICE_DT_GET(SPI_CONTROLLER_DEV);
+ if (!device_is_ready(data->spi_ctrl_dev)) {
+ LOG_ERR("%s device not ready", data->spi_ctrl_dev->name);
+ return -ENODEV;
}
- return ret;
+ return EC_SUCCESS;
}
-static const struct npcx_alt cros_flash_alts[] = NPCX_DT_ALT_ITEMS_LIST(0);
-static const struct cros_flash_npcx_config cros_flash_cfg = {
- .base = DT_INST_REG_ADDR(0),
- .clk_cfg = NPCX_DT_CLK_CFG_ITEM(0),
- .size = DT_INST_REG_SIZE(0),
- .alts_size = ARRAY_SIZE(cros_flash_alts),
- .alts_list = cros_flash_alts,
-};
-
+#if CONFIG_CROS_FLASH_NPCX_INIT_PRIORITY <= CONFIG_SPI_NOR_INIT_PRIORITY
+#error "CONFIG_CROS_FLASH_NPCX_INIT_PRIORITY must be greater than" \
+ "CONFIG_SPI_NOR_INIT_PRIORITY."
+#endif
static struct cros_flash_npcx_data cros_flash_data;
-
-DEVICE_DT_INST_DEFINE(0, flash_npcx_init, NULL, &cros_flash_data,
- &cros_flash_cfg, PRE_KERNEL_1,
- CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
+DEVICE_DT_INST_DEFINE(0, flash_npcx_init, NULL, &cros_flash_data, NULL,
+ POST_KERNEL, CONFIG_CROS_FLASH_NPCX_INIT_PRIORITY,
&cros_flash_npcx_driver_api);
diff --git a/zephyr/dts/bindings/cros_flash/nuvoton,npcx-cros-flash.yaml b/zephyr/dts/bindings/cros_flash/nuvoton,npcx-cros-flash.yaml
index 139a6c6a9b..f67bf1fe5c 100644
--- a/zephyr/dts/bindings/cros_flash/nuvoton,npcx-cros-flash.yaml
+++ b/zephyr/dts/bindings/cros_flash/nuvoton,npcx-cros-flash.yaml
@@ -6,15 +6,3 @@ description: Nuvoton, NPCX-cros-flash node
compatible: "nuvoton,npcx-cros-flash"
include: cros-flash-controller.yaml
-
-properties:
- reg:
- required: true
-
- clocks:
- required: true
-
- pinctrl-0:
- type: phandles
- required: true
- description: configurations of pinmux controllers
diff --git a/zephyr/include/cros/nuvoton/npcx.dtsi b/zephyr/include/cros/nuvoton/npcx.dtsi
index 1f8d0c6546..8767ee7c5b 100644
--- a/zephyr/include/cros/nuvoton/npcx.dtsi
+++ b/zephyr/include/cros/nuvoton/npcx.dtsi
@@ -60,6 +60,11 @@
};
};
+ fiu0: cros-flash{
+ compatible = "nuvoton,npcx-cros-flash";
+ label = "INTERNAL_FLASH";
+ };
+
soc {
cros_kb_raw: cros-kb-raw@400a3000 {
@@ -109,14 +114,6 @@
label = "MTC";
};
- fiu0: cros-flash@40020000 {
- compatible = "nuvoton,npcx-cros-flash";
- reg = <0x40020000 0x80000>;
- clocks = <&pcc NPCX_CLOCK_BUS_APB3 NPCX_PWDWN_CTL1 2>;
- label = "FLASH_INTERFACE_UNIT0";
- pinctrl-0 = <>;
- };
-
shi: shi@4000f000 {
compatible = "nuvoton,npcx-cros-shi";
reg = <0x4000f000 0x120>;
diff --git a/zephyr/include/soc/nuvoton_npcx/reg_def_cros.h b/zephyr/include/soc/nuvoton_npcx/reg_def_cros.h
index 8702502a13..c4d176851d 100644
--- a/zephyr/include/soc/nuvoton_npcx/reg_def_cros.h
+++ b/zephyr/include/soc/nuvoton_npcx/reg_def_cros.h
@@ -57,101 +57,6 @@ struct kbs_reg {
#define KBS_CFG_INDX_CDIV 4 /* Keyboard Scan Clock Divisor */
/*
- * Flash Interface Unit (FIU) device registers
- */
-struct fiu_reg {
- /* 0x001: Burst Configuration */
- volatile uint8_t BURST_CFG;
- /* 0x002: FIU Response Configuration */
- volatile uint8_t RESP_CFG;
- volatile uint8_t reserved1[18];
- /* 0x014: SPI Flash Configuration */
- volatile uint8_t SPI_FL_CFG;
- volatile uint8_t reserved2;
- /* 0x016: UMA Code Byte */
- volatile uint8_t UMA_CODE;
- /* 0x017: UMA Address Byte 0 */
- volatile uint8_t UMA_AB0;
- /* 0x018: UMA Address Byte 1 */
- volatile uint8_t UMA_AB1;
- /* 0x019: UMA Address Byte 2 */
- volatile uint8_t UMA_AB2;
- /* 0x01A: UMA Data Byte 0 */
- volatile uint8_t UMA_DB0;
- /* 0x01B: UMA Data Byte 1 */
- volatile uint8_t UMA_DB1;
- /* 0x01C: UMA Data Byte 2 */
- volatile uint8_t UMA_DB2;
- /* 0x01D: UMA Data Byte 3 */
- volatile uint8_t UMA_DB3;
- /* 0x01E: UMA Control and Status */
- volatile uint8_t UMA_CTS;
- /* 0x01F: UMA Extended Control and Status */
- volatile uint8_t UMA_ECTS;
- /* 0x020: UMA Data Bytes 0-3 */
- volatile uint32_t UMA_DB0_3;
- volatile uint8_t reserved3[2];
- /* 0x026: CRC Control Register */
- volatile uint8_t CRCCON;
- /* 0x027: CRC Entry Register */
- volatile uint8_t CRCENT;
- /* 0x028: CRC Initialization and Result Register */
- volatile uint32_t CRCRSLT;
- volatile uint8_t reserved4[4];
- /* 0x030: FIU Read Command */
- volatile uint8_t FIU_RD_CMD;
- volatile uint8_t reserved5;
- /* 0x032: FIU Dummy Cycles */
- volatile uint8_t FIU_DMM_CYC;
- /* 0x033: FIU Extended Configuration */
- volatile uint8_t FIU_EXT_CFG;
-};
-
-/* FIU register fields */
-#define NPCX_RESP_CFG_IAD_EN 0
-#define NPCX_RESP_CFG_DEV_SIZE_EX 2
-#define NPCX_UMA_CTS_A_SIZE 3
-#define NPCX_UMA_CTS_C_SIZE 4
-#define NPCX_UMA_CTS_RD_WR 5
-#define NPCX_UMA_CTS_DEV_NUM 6
-#define NPCX_UMA_CTS_EXEC_DONE 7
-#define NPCX_UMA_ECTS_SW_CS0 0
-#define NPCX_UMA_ECTS_SW_CS1 1
-#define NPCX_UMA_ECTS_SEC_CS 2
-#define NPCX_UMA_ECTS_UMA_LOCK 3
-
-/* UMA fields selections */
-#define UMA_FLD_ADDR BIT(NPCX_UMA_CTS_A_SIZE) /* 3-bytes ADR field */
-#define UMA_FLD_NO_CMD BIT(NPCX_UMA_CTS_C_SIZE) /* No 1-Byte CMD field */
-#define UMA_FLD_WRITE BIT(NPCX_UMA_CTS_RD_WR) /* Write transaction */
-#define UMA_FLD_SHD_SL BIT(NPCX_UMA_CTS_DEV_NUM) /* Shared flash selected */
-#define UMA_FLD_EXEC BIT(NPCX_UMA_CTS_EXEC_DONE)
-
-#define UMA_FIELD_DATA_1 0x01
-#define UMA_FIELD_DATA_2 0x02
-#define UMA_FIELD_DATA_3 0x03
-#define UMA_FIELD_DATA_4 0x04
-
-/* UMA code for transaction */
-#define UMA_CODE_CMD_ONLY (UMA_FLD_EXEC | UMA_FLD_SHD_SL)
-#define UMA_CODE_CMD_ADR (UMA_FLD_EXEC | UMA_FLD_ADDR | \
- UMA_FLD_SHD_SL)
-#define UMA_CODE_CMD_RD_BYTE(n) (UMA_FLD_EXEC | UMA_FIELD_DATA_##n | \
- UMA_FLD_SHD_SL)
-#define UMA_CODE_RD_BYTE(n) (UMA_FLD_EXEC | UMA_FLD_NO_CMD | \
- UMA_FIELD_DATA_##n | UMA_FLD_SHD_SL)
-#define UMA_CODE_CMD_WR_ONLY (UMA_FLD_EXEC | UMA_FLD_WRITE | \
- UMA_FLD_SHD_SL)
-#define UMA_CODE_CMD_WR_BYTE(n) (UMA_FLD_EXEC | UMA_FLD_WRITE | \
- UMA_FIELD_DATA_##n | UMA_FLD_SHD_SL)
-#define UMA_CODE_CMD_WR_ADR (UMA_FLD_EXEC | UMA_FLD_WRITE | UMA_FLD_ADDR | \
- UMA_FLD_SHD_SL)
-
-#define UMA_CODE_CMD_ADR_WR_BYTE(n) (UMA_FLD_EXEC | UMA_FLD_WRITE | \
- UMA_FLD_ADDR | UMA_FIELD_DATA_##n | \
- UMA_FLD_SHD_SL)
-
-/*
* Monotonic Counter (MTC) device registers
*/
struct mtc_reg {
diff --git a/zephyr/shim/src/flash.c b/zephyr/shim/src/flash.c
index d5a94ff28b..15e32269d2 100644
--- a/zephyr/shim/src/flash.c
+++ b/zephyr/shim/src/flash.c
@@ -184,4 +184,9 @@ SHELL_CMD_REGISTER(flashchip, NULL, "Information about flash chip",
CONFIG_PLATFORM_EC_GPIO_INIT_PRIORITY
#error "Flash must be initialized after GPIOs"
#endif
+#if CONFIG_PLATFORM_EC_FLASH_INIT_PRIORITY <= \
+ CONFIG_CROS_FLASH_NPCX_INIT_PRIORITY
+#error "CONFIG_PLATFORM_EC_FLASH_INIT_PRIORITY must be greater than" \
+ "CONFIG_CROS_FLASH_NPCX_INIT_PRIORITY."
+#endif
SYS_INIT(flash_dev_init, POST_KERNEL, CONFIG_PLATFORM_EC_FLASH_INIT_PRIORITY);