diff options
Diffstat (limited to 'zephyr/drivers/cros_flash/cros_flash_npcx.c')
-rw-r--r-- | zephyr/drivers/cros_flash/cros_flash_npcx.c | 821 |
1 files changed, 0 insertions, 821 deletions
diff --git a/zephyr/drivers/cros_flash/cros_flash_npcx.c b/zephyr/drivers/cros_flash/cros_flash_npcx.c deleted file mode 100644 index bb1bd12d89..0000000000 --- a/zephyr/drivers/cros_flash/cros_flash_npcx.c +++ /dev/null @@ -1,821 +0,0 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -#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/gpio.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); - -static int all_protected; /* Has all-flash protection been requested? */ -static int addr_prot_start; -static int addr_prot_length; -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; -}; - -/* 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 */ - -/* TODO: It should be defined in the spi_nor.h in the zephyr repository */ -#define SPI_NOR_CMD_FAST_READ 0x0B - -/* 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); - - 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); -} - -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; - - /* Write 3 bytes address to UMA registers */ - inst->UMA_AB2 = addr[2]; - inst->UMA_AB1 = addr[1]; - inst->UMA_AB0 = addr[0]; -} - -static inline void cros_flash_npcx_cs_level(const struct device *dev, int level) -{ - struct fiu_reg *const inst = HAL_INSTANCE(dev); - - /* 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); -} - -static inline void cros_flash_npcx_exec_cmd(const struct device *dev, - uint8_t code, uint8_t cts) -{ - struct fiu_reg *const inst = HAL_INSTANCE(dev); - -#ifdef CONFIG_ASSERT - struct cros_flash_npcx_data *data = DRV_DATA(dev); - - /* Flash mutex must be held while executing UMA commands */ - __ASSERT((k_sem_count_get(&data->lock_sem) == 0), "UMA is not locked"); -#endif - - /* 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)) - ; -} - -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; - } -} - -static inline int cros_flash_npcx_wait_busy_bit_clear(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) - break; - k_usleep(wait_period); - } while (--timeout); /* Wait for busy bit clear */ - - if (timeout) { - return 0; - } else { - return -ETIMEDOUT; - } -} - -/* 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; - - /* Wait for previous operation to complete */ - ret = cros_flash_npcx_wait_ready(dev); - if (ret != 0) - 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); - 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); -} - -static int cros_flash_npcx_program_bytes(const struct device *dev, - uint32_t offset, uint32_t bytes, - const uint8_t *src_data) -{ - int write_size; - int ret = 0; - - 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); - - 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; -} - -static int cros_flash_npcx_write_protection_set(const struct device *dev, - bool enable) -{ - int ret = 0; - - /* Write protection can be cleared only by core domain reset */ - if (!enable) { - 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; -} - -static int cros_flash_npcx_write_protection_is_set(const struct device *dev) -{ - return npcx_pinctrl_flash_write_protect_is_set(); -} - -static int cros_flash_npcx_uma_lock(const struct device *dev, bool enable) -{ - struct fiu_reg *const inst = HAL_INSTANCE(dev); - - if (enable) { - inst->UMA_ECTS |= BIT(NPCX_UMA_ECTS_UMA_LOCK); - } else { - inst->UMA_ECTS &= ~BIT(NPCX_UMA_ECTS_UMA_LOCK); - } - - return 0; -} - -static int flash_get_status1(const struct device *dev) -{ - uint8_t reg; - - if (all_protected) - return saved_sr1; - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - cros_flash_npcx_get_status_reg(dev, CMD_READ_STATUS_REG, ®); - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - return reg; -} - -static int flash_get_status2(const struct device *dev) -{ - uint8_t reg; - - if (all_protected) - return saved_sr1; - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - cros_flash_npcx_get_status_reg(dev, CMD_READ_STATUS_REG2, ®); - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - return reg; -} - -static int flash_write_status_reg(const struct device *dev, uint8_t *data) -{ - return cros_flash_npcx_set_status_reg(dev, data); -} - -static int is_int_flash_protected(const struct device *dev) -{ - return cros_flash_npcx_write_protection_is_set(dev); -} - -static void flash_protect_int_flash(const struct device *dev, int enable) -{ - /* - * Please notice the type of WP_IF bit is R/W1S. Once it's set, - * only rebooting EC can clear it. - */ - if (enable) - cros_flash_npcx_write_protection_set(dev, enable); -} - -static void flash_uma_lock(const struct device *dev, int enable) -{ - if (enable && !all_protected) { - /* - * Store SR1 / SR2 for later use since we're about to lock - * out all access (including read access) to these regs. - */ - saved_sr1 = flash_get_status1(dev); - saved_sr2 = flash_get_status2(dev); - } - - cros_flash_npcx_uma_lock(dev, enable); - all_protected = enable; -} - -static int flash_set_status_for_prot(const struct device *dev, int reg1, - int reg2) -{ - uint8_t regs[2]; - - /* - * Writing SR regs will fail if our UMA lock is enabled. If WP - * is deasserted then remove the lock and allow the write. - */ - if (all_protected) { - if (is_int_flash_protected(dev)) - return EC_ERROR_ACCESS_DENIED; - - if (crec_flash_get_protect() & EC_FLASH_PROTECT_GPIO_ASSERTED) - return EC_ERROR_ACCESS_DENIED; - flash_uma_lock(dev, 0); - } - - /* - * If WP# is active and ec doesn't protect the status registers of - * internal spi-flash, protect it now before setting them. - */ -#ifdef CONFIG_WP_ACTIVE_HIGH - flash_protect_int_flash(dev, gpio_get_level(GPIO_WP)); -#else - flash_protect_int_flash(dev, !gpio_get_level(GPIO_WP_L)); -#endif /*_CONFIG_WP_ACTIVE_HIGH_*/ - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - regs[0] = reg1; - regs[1] = reg2; - flash_write_status_reg(dev, regs); - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - spi_flash_reg_to_protect(reg1, reg2, &addr_prot_start, - &addr_prot_length); - - return EC_SUCCESS; -} - -static int flash_check_prot_reg(const struct device *dev, unsigned int offset, - unsigned int bytes) -{ - unsigned int start; - unsigned int len; - uint8_t sr1, sr2; - int rv = EC_SUCCESS; - - /* - * If WP# is active and ec doesn't protect the status registers of - * internal spi-flash, protect it now. - */ -#ifdef CONFIG_WP_ACTIVE_HIGH - flash_protect_int_flash(dev, gpio_get_level(GPIO_WP)); -#else - flash_protect_int_flash(dev, !gpio_get_level(GPIO_WP_L)); -#endif /* CONFIG_WP_ACTIVE_HIGH */ - - sr1 = flash_get_status1(dev); - sr2 = flash_get_status2(dev); - - /* Invalid value */ - if (offset + bytes > CONFIG_FLASH_SIZE_BYTES) - return EC_ERROR_INVAL; - - /* Compute current protect range */ - rv = spi_flash_reg_to_protect(sr1, sr2, &start, &len); - if (rv) - return rv; - - /* Check if ranges overlap */ - if (MAX(start, offset) < MIN(start + len, offset + bytes)) - return EC_ERROR_ACCESS_DENIED; - - return EC_SUCCESS; -} - -static int flash_write_prot_reg(const struct device *dev, unsigned int offset, - unsigned int bytes, int hw_protect) -{ - int rv; - uint8_t sr1 = flash_get_status1(dev); - uint8_t sr2 = flash_get_status2(dev); - - /* Invalid values */ - if (offset + bytes > CONFIG_FLASH_SIZE_BYTES) - return EC_ERROR_INVAL; - - /* Compute desired protect range */ - rv = spi_flash_protect_to_reg(offset, bytes, &sr1, &sr2); - if (rv) - return rv; - - if (hw_protect) - sr1 |= SPI_FLASH_SR1_SRP0; - - return flash_set_status_for_prot(dev, sr1, sr2); -} - -static int flash_check_prot_range(unsigned int offset, unsigned int bytes) -{ - /* Invalid value */ - if (offset + bytes > CONFIG_FLASH_SIZE_BYTES) - return EC_ERROR_INVAL; - - /* Check if ranges overlap */ - if (MAX(addr_prot_start, offset) < - MIN(addr_prot_start + addr_prot_length, offset + bytes)) - return EC_ERROR_ACCESS_DENIED; - - return EC_SUCCESS; -} - -/* 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. - */ -#ifdef CONFIG_WP_ACTIVE_HIGH - flash_protect_int_flash(dev, gpio_get_level(GPIO_WP)); -#else - flash_protect_int_flash(dev, !gpio_get_level(GPIO_WP_L)); -#endif /*CONFIG_WP_ACTIVE_HIGH */ - - /* Initialize UMA to unlocked */ - flash_uma_lock(dev, 0); - - return 0; -} - -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); - - return ret; -} - -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; - - /* check protection */ - if (all_protected) - return EC_ERROR_ACCESS_DENIED; - - /* check protection */ - 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); - - 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; - - /* check protection */ - if (all_protected) - return EC_ERROR_ACCESS_DENIED; - - /* check protection */ - 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; - } - - /* Erase size must be a non-zero multiple of sectors */ - if ((size == 0) || (size % CONFIG_FLASH_ERASE_SIZE) != 0) { - 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); - - return ret; -} - -static int cros_flash_npcx_get_protect(const struct device *dev, int bank) -{ - uint32_t addr = bank * CONFIG_FLASH_BANK_SIZE; - - return flash_check_prot_reg(dev, addr, CONFIG_FLASH_BANK_SIZE); -} - -static uint32_t cros_flash_npcx_get_protect_flags(const struct device *dev) -{ - uint32_t flags = 0; - - /* Check if WP region is protected in status register */ - if (flash_check_prot_reg(dev, WP_BANK_OFFSET * CONFIG_FLASH_BANK_SIZE, - WP_BANK_COUNT * CONFIG_FLASH_BANK_SIZE)) - flags |= EC_FLASH_PROTECT_RO_AT_BOOT; - - /* - * TODO: If status register protects a range, but SRP0 is not set, - * flags should indicate EC_FLASH_PROTECT_ERROR_INCONSISTENT. - */ - if (flag_prot_inconsistent) - flags |= EC_FLASH_PROTECT_ERROR_INCONSISTENT; - - /* Read all-protected state from our shadow copy */ - if (all_protected) - flags |= EC_FLASH_PROTECT_ALL_NOW; - - return flags; -} - -static int cros_flash_npcx_protect_at_boot(const struct device *dev, - uint32_t new_flags) -{ - int ret; - - if ((new_flags & (EC_FLASH_PROTECT_RO_AT_BOOT | - EC_FLASH_PROTECT_ALL_AT_BOOT)) == 0) { - /* Clear protection bits in status register */ - return flash_set_status_for_prot(dev, 0, 0); - } - - ret = flash_write_prot_reg(dev, CONFIG_WP_STORAGE_OFF, - CONFIG_WP_STORAGE_SIZE, 1); - - /* - * Set UMA_LOCK bit for locking all UMA transaction. - * But we still can read directly from flash mapping address - */ - if (new_flags & EC_FLASH_PROTECT_ALL_AT_BOOT) - flash_uma_lock(dev, 1); - - return ret; -} - -static int cros_flash_npcx_protect_now(const struct device *dev, int all) -{ - if (all) { - /* - * Set UMA_LOCK bit for locking all UMA transaction. - * But we still can read directly from flash mapping address - */ - flash_uma_lock(dev, 1); - } else { - /* TODO: Implement RO "now" protection */ - } - - return EC_SUCCESS; -} - -/* cros ec flash driver registration */ -static const struct cros_flash_driver_api cros_flash_npcx_driver_api = { - .init = cros_flash_npcx_init, - .physical_read = cros_flash_npcx_read, - .physical_write = cros_flash_npcx_write, - .physical_erase = cros_flash_npcx_erase, - .physical_get_protect = cros_flash_npcx_get_protect, - .physical_get_protect_flags = cros_flash_npcx_get_protect_flags, - .physical_protect_at_boot = cros_flash_npcx_protect_at_boot, - .physical_protect_now = cros_flash_npcx_protect_now, -}; - -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); - - int ret; - - /* 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; - } - - return ret; -} - -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_PROP(0, size), - .alts_size = ARRAY_SIZE(cros_flash_alts), - .alts_list = cros_flash_alts, -}; - -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, - &cros_flash_npcx_driver_api); |