diff --git a/drivers/espi/espi_taf_npcx.c b/drivers/espi/espi_taf_npcx.c index 04062f4363c..855f2b382c7 100644 --- a/drivers/espi/espi_taf_npcx.c +++ b/drivers/espi/espi_taf_npcx.c @@ -18,7 +18,15 @@ LOG_MODULE_REGISTER(espi_taf, CONFIG_ESPI_LOG_LEVEL); -static const struct device *const spi_dev = DEVICE_DT_GET(DT_ALIAS(taf_flash)); +#define NPCX_TAF_PRIME_FLASH_NODE DT_ALIAS(taf_flash) +#define NPCX_TAF_SEC_FLASH_NODE DT_ALIAS(taf_flash1) + +#define NPCX_TAF_ALLOC_SIZE(node) (MB(1) << DT_ENUM_IDX(node, spi_dev_size)) + +static const struct device *const spi_dev = DEVICE_DT_GET(NPCX_TAF_PRIME_FLASH_NODE); +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) +static const struct device *const spi_dev1 = DEVICE_DT_GET(NPCX_TAF_SEC_FLASH_NODE); +#endif enum ESPI_TAF_ERASE_LEN { NPCX_ESPI_TAF_ERASE_LEN_4KB, @@ -52,6 +60,11 @@ struct espi_taf_npcx_data { uint32_t src[16]; uint8_t read_buf[MAX_TX_PAYLOAD_SIZE]; struct k_work work; +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) + const struct device *low_dev_ptr; + const struct device *high_dev_ptr; + uint32_t low_dev_size; +#endif }; static struct espi_taf_npcx_data npcx_espi_taf_data; @@ -236,6 +249,11 @@ static bool espi_taf_npcx_channel_ready(const struct device *dev) if (!device_is_ready(spi_dev)) { return false; } +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) + if (!device_is_ready(spi_dev1)) { + return false; + } +#endif return true; } @@ -362,7 +380,34 @@ static int espi_taf_npcx_flash_read(const struct device *dev, struct espi_saf_pa } do { +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) + if ((addr + len) <= npcx_espi_taf_data.low_dev_size) { + rc = flash_read(npcx_espi_taf_data.low_dev_ptr, addr, + npcx_espi_taf_data.read_buf, len); + } else if (addr >= npcx_espi_taf_data.low_dev_size) { + rc = flash_read(npcx_espi_taf_data.high_dev_ptr, + (addr - npcx_espi_taf_data.low_dev_size), + npcx_espi_taf_data.read_buf, len); + } else { + rc = flash_read(npcx_espi_taf_data.low_dev_ptr, addr, + npcx_espi_taf_data.read_buf, + (npcx_espi_taf_data.low_dev_size.low_dev_size - addr)); + + if (rc) { + LOG_ERR("flash read fail 0x%x", rc); + return -EIO; + } + + uint32_t index = low_dev_size - addr; + + rc = flash_read( + npcx_espi_taf_data.high_dev_ptr, 0x0, + &npcx_espi_taf_data.read_buf[index], + (addr + len - npcx_espi_taf_data.low_dev_size.low_dev_size)); + } +#else rc = flash_read(spi_dev, addr, npcx_espi_taf_data.read_buf, len); +#endif if (rc) { LOG_ERR("flash read fail 0x%x", rc); return -EIO; @@ -394,6 +439,8 @@ static int espi_taf_npcx_flash_write(const struct device *dev, struct espi_saf_p { struct espi_taf_npcx_pckt *taf_data_ptr = (struct espi_taf_npcx_pckt *)pckt->buf; uint8_t *data_ptr = (uint8_t *)(taf_data_ptr->data); + uint32_t addr = pckt->flash_addr; + uint32_t len = pckt->len; int rc; if (espi_taf_check_write_protect(dev, pckt->flash_addr, @@ -402,7 +449,19 @@ static int espi_taf_npcx_flash_write(const struct device *dev, struct espi_saf_p return -EINVAL; } - rc = flash_write(spi_dev, pckt->flash_addr, data_ptr, pckt->len); +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) + if ((addr + len) <= npcx_espi_taf_data.low_dev_size) { + rc = flash_write(npcx_espi_taf_data.low_dev_ptr, addr, data_ptr, len); + } else if (addr >= npcx_espi_taf_data.low_dev_size) { + rc = flash_write(npcx_espi_taf_data.high_dev_ptr, + (addr - npcx_espi_taf_data.low_dev_size), data_ptr, len); + } else { + LOG_ERR("Write across two flashes"); + return -EINVAL; + } +#else + rc = flash_write(spi_dev, addr, data_ptr, len); +#endif if (rc) { LOG_ERR("flash write fail 0x%x", rc); return -EIO; @@ -438,7 +497,19 @@ static int espi_taf_npcx_flash_erase(const struct device *dev, struct espi_saf_p return -EINVAL; } +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) + if ((addr + len) <= npcx_espi_taf_data.low_dev_size) { + rc = flash_erase(npcx_espi_taf_data.low_dev_ptr, addr, len); + } else if (addr >= npcx_espi_taf_data.low_dev_size) { + rc = flash_erase(npcx_espi_taf_data.high_dev_ptr, + (addr - npcx_espi_taf_data.low_dev_size), len); + } else { + LOG_ERR("Erase across two flashes"); + return -EINVAL; + } +#else rc = flash_erase(spi_dev, addr, len); +#endif if (rc) { LOG_ERR("flash erase fail"); return -EIO; @@ -620,6 +691,18 @@ static int espi_taf_npcx_init(const struct device *dev) config->max_rd_sz); inst->FLASHBASE = config->mapped_addr; +#if DT_NODE_HAS_STATUS_OKAY(NPCX_TAF_SEC_FLASH_NODE) + if (IS_ENABLED(CONFIG_FLASH_NPCX_FIU_SUPP_LOW_DEV_SWAP)) { + npcx_espi_taf_data.low_dev_ptr = spi_dev1; + npcx_espi_taf_data.high_dev_ptr = spi_dev; + npcx_espi_taf_data.low_dev_size = NPCX_TAF_ALLOC_SIZE(NPCX_TAF_SEC_FLASH_NODE); + } else { + npcx_espi_taf_data.low_dev_ptr = spi_dev; + npcx_espi_taf_data.high_dev_ptr = spi_dev1; + npcx_espi_taf_data.low_dev_size = NPCX_TAF_ALLOC_SIZE(NPCX_TAF_PRIME_FLASH_NODE); + } +#endif + #ifdef CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT uint8_t count_num = 0;