diff options
author | Jun Lin <CHLin56@nuvoton.com> | 2021-11-04 10:31:52 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-11-12 20:44:32 +0000 |
commit | 7a544b16076115135a146a343d6d8b5c8cbebadb (patch) | |
tree | c857c07ea04cfb6159f279a678fb707ed1e98ac9 | |
parent | 6faaf44daa8b3d1847df90bcea27d35bd0953da4 (diff) | |
download | chrome-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_priority | 1 | ||||
-rw-r--r-- | zephyr/boards/arm/brya/brya_defconfig | 8 | ||||
-rw-r--r-- | zephyr/boards/arm/herobrine_npcx9/herobrine_npcx9_defconfig | 8 | ||||
-rw-r--r-- | zephyr/boards/arm/npcx9/npcx9_defconfig | 8 | ||||
-rw-r--r-- | zephyr/boards/arm/npcx_evb/npcx7_evb_defconfig | 8 | ||||
-rw-r--r-- | zephyr/boards/arm/npcx_evb/npcx9_evb_defconfig | 8 | ||||
-rw-r--r-- | zephyr/boards/arm/trogdor/trogdor_defconfig | 8 | ||||
-rw-r--r-- | zephyr/boards/arm/volteer/volteer_defconfig | 8 | ||||
-rw-r--r-- | zephyr/drivers/cros_flash/Kconfig | 13 | ||||
-rw-r--r-- | zephyr/drivers/cros_flash/cros_flash_npcx.c | 493 | ||||
-rw-r--r-- | zephyr/dts/bindings/cros_flash/nuvoton,npcx-cros-flash.yaml | 12 | ||||
-rw-r--r-- | zephyr/include/cros/nuvoton/npcx.dtsi | 13 | ||||
-rw-r--r-- | zephyr/include/soc/nuvoton_npcx/reg_def_cros.h | 95 | ||||
-rw-r--r-- | zephyr/shim/src/flash.c | 5 |
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, ®); + 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, ®); + 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, ®); + cros_flash_npcx_get_status_reg(dev, SPI_NOR_CMD_RDSR, ®); /* 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, ®); + cros_flash_npcx_get_status_reg(dev, SPI_NOR_CMD_RDSR2, ®); /* 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); |