diff --git a/drivers/espi/CMakeLists.txt b/drivers/espi/CMakeLists.txt index 77455ebda01..5379d00ea21 100644 --- a/drivers/espi/CMakeLists.txt +++ b/drivers/espi/CMakeLists.txt @@ -7,6 +7,7 @@ zephyr_library() zephyr_library_sources_ifdef(CONFIG_ESPI_XEC espi_mchp_xec.c) zephyr_library_sources_ifdef(CONFIG_ESPI_NPCX espi_npcx.c) zephyr_library_sources_ifdef(CONFIG_ESPI_NPCX host_subs_npcx.c) +zephyr_library_sources_ifdef(CONFIG_ESPI_TAF_NPCX espi_taf_npcx.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE espi_handlers.c) zephyr_library_sources_ifdef(CONFIG_ESPI_EMUL espi_emul.c) zephyr_library_sources_ifdef(CONFIG_ESPI_SAF_XEC espi_saf_mchp_xec.c) diff --git a/drivers/espi/Kconfig.npcx b/drivers/espi/Kconfig.npcx index 69a7087fce7..3f1d511caa1 100644 --- a/drivers/espi/Kconfig.npcx +++ b/drivers/espi/Kconfig.npcx @@ -58,6 +58,36 @@ config ESPI_NPCX_PERIPHERAL_DEBUG_PORT_80_RING_BUF_SIZE The size of the ring buffer in byte used by the Port80 ISR to store Postcodes from Host. +config ESPI_TAF_NPCX + bool "Nuvoton NPCX embedded controller (EC) ESPI TAF driver" + depends on SOC_SERIES_NPCX4 + help + This option enables the Intel Enhanced Serial Peripheral Interface + Target Attached Flash (eSPI TAF) for NPCX4 family of processors. + +choice ESPI_TAF_ACCESS_MODE_CHOICE + prompt "eSPI TAF Read Access Mode" + default ESPI_TAF_AUTO_MODE + +config ESPI_TAF_AUTO_MODE + bool "eSPI TAF Automatic Mode" + help + This is the setting to use auto mode for eSPI TAF read. + +config ESPI_TAF_MANUAL_MODE + bool "eSPI TAF Manual Mode" + help + This is the setting to use manual mode for eSPI TAF read. + +endchoice + +config ESPI_TAF_PR_NUM + int "Sets of protection region settings" + default 16 + help + This size is display how many group of slave attached flash protection + region. + # The default value 'y' for the existing options if ESPI_NPCX is selected. if ESPI_NPCX diff --git a/drivers/espi/espi_npcx.c b/drivers/espi/espi_npcx.c index d6177dee388..6a8a83a13c3 100644 --- a/drivers/espi/espi_npcx.c +++ b/drivers/espi/espi_npcx.c @@ -7,6 +7,7 @@ #define DT_DRV_COMPAT nuvoton_npcx_espi #include +#include #include #include #include @@ -74,8 +75,8 @@ struct espi_npcx_data { ((hdr & 0xf0000) >> 8)) /* Flash channel maximum payload size */ -#define NPCX_ESPI_FLASH_MAX_RX_PAYLOAD 64 -#define NPCX_ESPI_FLASH_MAX_TX_PAYLOAD 16 +#define NPCX_ESPI_FLASH_MAX_RX_PAYLOAD DT_INST_PROP(0, rx_plsize) +#define NPCX_ESPI_FLASH_MAX_TX_PAYLOAD DT_INST_PROP(0, tx_plsize) /* eSPI cycle type field for OOB and FLASH channels */ #define ESPI_FLASH_READ_CYCLE_TYPE 0x00 @@ -275,6 +276,19 @@ static void espi_bus_cfg_update_isr(const struct device *dev) NPCX_ESPI_HOST_CH_EN(NPCX_ESPI_CH_VW))) { espi_vw_send_bootload_done(dev); } + +#if (defined(CONFIG_ESPI_FLASH_CHANNEL) && defined(CONFIG_ESPI_SAF)) + /* If CONFIG_ESPI_SAF is set, set to auto or manual mode accroding + * to configuration. + */ + if (IS_BIT_SET(inst->ESPICFG, NPCX_ESPICFG_FLCHANMODE)) { +#if defined(CONFIG_ESPI_TAF_AUTO_MODE) + inst->FLASHCTL |= BIT(NPCX_FLASHCTL_SAF_AUTO_READ); +#else + inst->FLASHCTL &= ~BIT(NPCX_FLASHCTL_SAF_AUTO_READ); +#endif + } +#endif } #if defined(CONFIG_ESPI_OOB_CHANNEL) @@ -288,12 +302,82 @@ static void espi_bus_oob_rx_isr(const struct device *dev) #endif #if defined(CONFIG_ESPI_FLASH_CHANNEL) +#if defined(CONFIG_ESPI_SAF) +static struct espi_taf_pckt taf_pckt; + +static uint32_t espi_taf_parse(const struct device *dev) +{ + struct espi_reg *const inst = HAL_INSTANCE(dev); + struct npcx_taf_head taf_head; + uint32_t taf_addr; + uint8_t i, roundsize; + + /* Get type, length and tag from RX buffer */ + memcpy(&taf_head, (void *)&inst->FLASHRXBUF[0], sizeof(taf_head)); + taf_pckt.type = taf_head.type; + taf_pckt.len = (((uint16_t)taf_head.tag_hlen & 0xF) << 8) | taf_head.llen; + taf_pckt.tag = taf_head.tag_hlen >> 4; + + if ((taf_pckt.len == 0) && ((taf_pckt.type & 0xF) == NPCX_ESPI_TAF_REQ_READ)) { + taf_pckt.len = KB(4); + } + + /* Get address from RX buffer */ + taf_addr = inst->FLASHRXBUF[1]; + taf_pckt.addr = sys_cpu_to_be32(taf_addr); + + /* Get written data if eSPI TAF write */ + if ((taf_pckt.type & 0xF) == NPCX_ESPI_TAF_REQ_WRITE) { + roundsize = DIV_ROUND_UP(taf_pckt.len, sizeof(uint32_t)); + for (i = 0; i < roundsize; i++) { + taf_pckt.src[i] = inst->FLASHRXBUF[2 + i]; + } + } + + return (uint32_t)&taf_pckt; +} +#endif /* CONFIG_ESPI_SAF */ + static void espi_bus_flash_rx_isr(const struct device *dev) { + struct espi_reg *const inst = HAL_INSTANCE(dev); struct espi_npcx_data *const data = dev->data; - LOG_DBG("%s", __func__); - k_sem_give(&data->flash_rx_lock); + /* Controller Attached Flash Access */ + if ((inst->ESPICFG & BIT(NPCX_ESPICFG_FLCHANMODE)) == 0) { + k_sem_give(&data->flash_rx_lock); + } else { /* Target Attached Flash Access */ +#if defined(CONFIG_ESPI_SAF) + struct espi_event evt = { + .evt_type = ESPI_BUS_SAF_NOTIFICATION, + .evt_details = ESPI_CHANNEL_FLASH, + .evt_data = espi_taf_parse(dev), + }; + espi_send_callbacks(&data->callbacks, dev, evt); +#else + LOG_WRN("ESPI TAF not supported"); +#endif + } +} + +static void espi_bus_completion_sent_isr(const struct device *dev) +{ + struct espi_reg *const inst = HAL_INSTANCE(dev); + + /* check that ESPISTS.FLNACS is clear. */ + if (IS_BIT_SET(inst->ESPISTS, NPCX_ESPISTS_FLNACS)) { + LOG_ERR("ESPISTS_FLNACS not clear\r\n"); + } + + /* flash operation is done, Make sure the TAFS transmit buffer is empty */ + if (IS_BIT_SET(inst->FLASHCTL, NPCX_FLASHCTL_FLASH_TX_AVAIL)) { + LOG_ERR("FLASH_TX_AVAIL not clear\r\n"); + } + + /* In auto mode, release FLASH_NP_FREE here to get next SAF request.*/ + if (IS_BIT_SET(inst->FLASHCTL, NPCX_FLASHCTL_SAF_AUTO_READ)) { + inst->FLASHCTL |= BIT(NPCX_FLASHCTL_FLASH_NP_FREE); + } } #endif @@ -307,6 +391,7 @@ const struct espi_bus_isr espi_bus_isr_tbl[] = { #endif #if defined(CONFIG_ESPI_FLASH_CHANNEL) NPCX_ESPI_BUS_INT_ITEM(FLASHRX, espi_bus_flash_rx_isr), + NPCX_ESPI_BUS_INT_ITEM(FLNACS, espi_bus_completion_sent_isr), #endif }; diff --git a/drivers/espi/espi_taf_npcx.c b/drivers/espi/espi_taf_npcx.c new file mode 100644 index 00000000000..722b26730e8 --- /dev/null +++ b/drivers/espi/espi_taf_npcx.c @@ -0,0 +1,466 @@ +/* + * Copyright (c) 2023 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT nuvoton_npcx_espi_taf + +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(espi_taf, CONFIG_ESPI_LOG_LEVEL); + +static const struct device *const spi_dev = DEVICE_DT_GET(DT_ALIAS(taf_flash)); + +struct espi_taf_npcx_config { + uintptr_t base; + uintptr_t mapped_addr; + uintptr_t rx_plsz; + enum NPCX_ESPI_TAF_ERASE_BLOCK_SIZE erase_sz; + enum NPCX_ESPI_TAF_MAX_READ_REQ max_rd_sz; +}; + +struct espi_taf_npcx_data { + sys_slist_t callbacks; +}; + +#define HAL_INSTANCE(dev) \ + ((struct espi_reg *)((const struct espi_taf_npcx_config *) \ + (dev)->config)->base) + +#define FLBASE_ADDR ( \ + GET_FIELD(inst->FLASHBASE, NPCX_FLASHBASE_FLBASE_ADDR) \ + << GET_FIELD_POS(NPCX_FLASHBASE_FLBASE_ADDR)) + +#define PRTR_BADDR(i) ( \ + GET_FIELD(inst->FLASH_PRTR_BADDR[i], NPCX_FLASH_PRTR_BADDR) \ + << GET_FIELD_POS(NPCX_FLASH_PRTR_BADDR)) + +#define PRTR_HADDR(i) ( \ + GET_FIELD(inst->FLASH_PRTR_HADDR[i], NPCX_FLASH_PRTR_HADDR) \ + << GET_FIELD_POS(NPCX_FLASH_PRTR_HADDR)) | 0xFFF; + +/* Check access region of read request is protected or not */ +static bool espi_taf_check_read_protect(const struct device *dev, uint32_t addr, uint32_t len, + uint8_t tag) +{ + struct espi_reg *const inst = HAL_INSTANCE(dev); + uint32_t flash_addr = addr; + uint8_t i; + uint16_t override_rd; + uint32_t base, high; + bool rdpr; + + flash_addr += FLBASE_ADDR; + + for (i = 0; i < CONFIG_ESPI_TAF_PR_NUM; i++) { + base = PRTR_BADDR(i); + high = PRTR_HADDR(i); + + rdpr = IS_BIT_SET(inst->FLASH_PRTR_BADDR[i], NPCX_FRGN_RPR); + override_rd = GET_FIELD(inst->FLASH_RGN_TAG_OVR[i], NPCX_FLASH_TAG_OVR_RPR); + + if (rdpr && !IS_BIT_SET(override_rd, tag) && + (base <= flash_addr + len - 1 && flash_addr <= high)) { + return true; + } + } + + return false; +} + +/* Check access region of write request is protected or not */ +static bool espi_taf_check_write_protect(const struct device *dev, uint32_t addr, + uint32_t len, uint8_t tag) +{ + struct espi_reg *const inst = HAL_INSTANCE(dev); + uint32_t flash_addr = addr; + uint8_t i; + uint16_t override_wr; + uint32_t base, high; + bool wrpr; + + flash_addr += FLBASE_ADDR; + + for (i = 0; i < CONFIG_ESPI_TAF_PR_NUM; i++) { + base = PRTR_BADDR(i); + high = PRTR_HADDR(i); + + wrpr = IS_BIT_SET(inst->FLASH_PRTR_BADDR[i], NPCX_FRGN_WPR); + override_wr = GET_FIELD(inst->FLASH_RGN_TAG_OVR[i], NPCX_FLASH_TAG_OVR_WPR); + + if (wrpr && !IS_BIT_SET(override_wr, tag) && + (base <= flash_addr + len - 1 && flash_addr <= high)) { + return true; + } + } + + return false; +} + +static int espi_taf_npcx_configure(const struct device *dev, const struct espi_saf_cfg *cfg) +{ + struct espi_reg *const inst = HAL_INSTANCE(dev); + +#if defined(CONFIG_ESPI_TAF_AUTO_MODE) + inst->FLASHCTL |= BIT(NPCX_FLASHCTL_SAF_AUTO_READ); +#else + inst->FLASHCTL &= ~BIT(NPCX_FLASHCTL_SAF_AUTO_READ); +#endif + return 0; +} + +static int espi_taf_npcx_set_pr(const struct device *dev, const struct espi_saf_protection *pr) +{ + struct espi_reg *const inst = HAL_INSTANCE(dev); + const struct espi_saf_pr *preg = pr->pregions; + size_t n = pr->nregions; + uint8_t regnum; + uint16_t bitmask, offset; + uint32_t rw_pr, override_rw; + + if ((dev == NULL) || (pr == NULL)) { + return -EINVAL; + } + + if (pr->nregions >= CONFIG_ESPI_TAF_PR_NUM) { + return -EINVAL; + } + + while (n--) { + regnum = preg->pr_num; + + if (regnum >= CONFIG_ESPI_TAF_PR_NUM) { + return -EINVAL; + } + + rw_pr = preg->master_bm_we << NPCX_FRGN_WPR; + rw_pr = rw_pr | (preg->master_bm_rd << NPCX_FRGN_RPR); + + if (preg->flags) { + bitmask = BIT_MASK(GET_FIELD_SZ(NPCX_FLASH_PRTR_BADDR)); + offset = GET_FIELD_POS(NPCX_FLASH_PRTR_BADDR); + inst->FLASH_PRTR_BADDR[regnum] = ((preg->start & bitmask) << offset) + | rw_pr; + bitmask = BIT_MASK(GET_FIELD_SZ(NPCX_FLASH_PRTR_HADDR)); + offset = GET_FIELD_POS(NPCX_FLASH_PRTR_HADDR); + inst->FLASH_PRTR_HADDR[regnum] = (preg->end & bitmask) << offset; + } + + override_rw = (preg->override_r << 16) | preg->override_w; + inst->FLASH_RGN_TAG_OVR[regnum] = override_rw; + preg++; + } + + return 0; +} + +static int espi_taf_npcx_activate(const struct device *dev) +{ + struct espi_reg *const inst = HAL_INSTANCE(dev); + + inst->FLASHCTL &= ~BIT(NPCX_FLASHCTL_AUTO_RD_DIS_CTL); + inst->FLASHCTL &= ~BIT(NPCX_FLASHCTL_BLK_FLASH_NP_FREE); + + return 0; +} + +static bool espi_taf_npcx_channel_ready(const struct device *dev) +{ + struct espi_reg *const inst = HAL_INSTANCE(dev); + + if (!IS_BIT_SET(inst->ESPICFG, NPCX_ESPICFG_FLCHANMODE)) { + return false; + } + return true; +} + +/* This routine set FLASH_C_AVAIL for standard request */ +static void taf_set_flash_c_avail(const struct device *dev) +{ + struct espi_reg *const inst = HAL_INSTANCE(dev); + uint32_t tmp = inst->FLASHCTL; + + /* + * Clear FLASHCTL_FLASH_NP_FREE to avoid host puts a flash + * standard request command at here. + */ + tmp &= NPCX_FLASHCTL_ACCESS_MASK; + + /* Set FLASHCTL_FLASH_TX_AVAIL */ + tmp |= BIT(NPCX_FLASHCTL_FLASH_TX_AVAIL); + inst->FLASHCTL = tmp; +} + +/* This routine release FLASH_NP_FREE for standard request */ +static void taf_release_flash_np_free(const struct device *dev) +{ + struct espi_reg *const inst = HAL_INSTANCE(dev); + uint32_t tmp = inst->FLASHCTL; + + /* + * Clear FLASHCTL_FLASH_TX_AVAIL to avoid host puts a + * GET_FLASH_C command at here. + */ + tmp &= NPCX_FLASHCTL_ACCESS_MASK; + + /* Release FLASH_NP_FREE */ + tmp |= BIT(NPCX_FLASHCTL_FLASH_NP_FREE); + inst->FLASHCTL = tmp; +} + +static int taf_npcx_completion_handler(const struct device *dev, uint32_t *buffer) +{ + uint16_t size = DIV_ROUND_UP((uint8_t)(buffer[0]) + 1, sizeof(uint32_t)); + struct espi_reg *const inst = HAL_INSTANCE(dev); + struct npcx_taf_head *head = (struct npcx_taf_head *)buffer; + uint8_t i; + + /* Check the Flash Access TX Queue is empty by polling + * FLASH_TX_AVAIL. + */ + if (WAIT_FOR(IS_BIT_SET(inst->FLASHCTL, NPCX_FLASHCTL_FLASH_TX_AVAIL), + NPCX_FLASH_CHK_TIMEOUT, NULL)) { + LOG_ERR("Check TX Queue Is Empty Timeout"); + return -EBUSY; + } + + /* Check ESPISTS.FLNACS is clear (no slave completion is detected) */ + if (WAIT_FOR(IS_BIT_SET(inst->ESPISTS, NPCX_ESPISTS_FLNACS), + NPCX_FLASH_CHK_TIMEOUT, NULL)) { + LOG_ERR("Check Slave Completion Timeout"); + return -EBUSY; + } + + /* Write packet to FLASHTXBUF */ + for (i = 0; i < size; i++) { + inst->FLASHTXBUF[i] = buffer[i]; + } + + /* Set the FLASHCTL.FLASH_TX_AVAIL bit to 1 to enqueue the packet */ + taf_set_flash_c_avail(dev); + + /* Release FLASH_NP_FREE here to ready get next TAF request */ + if ((head->type != CYC_SCS_CMP_WITH_DATA_FIRST) && + (head->type != CYC_SCS_CMP_WITH_DATA_MIDDLE)) { + taf_release_flash_np_free(dev); + } + + return 0; +} + +static int espi_taf_npcx_flash_read(const struct device *dev, struct espi_saf_packet *pckt) +{ + struct espi_reg *const inst = HAL_INSTANCE(dev); + struct espi_taf_npcx_config *config = ((struct espi_taf_npcx_config *)(dev)->config); + 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; + uint8_t cycle_type = CYC_SCS_CMP_WITH_DATA_ONLY; + uint32_t total_len = pckt->len; + uint32_t len = total_len; + uint32_t addr = pckt->flash_addr; + uint8_t flash_req_size = GET_FIELD(inst->FLASHCFG, NPCX_FLASHCFG_FLASHREQSIZE); + uint8_t target_max_size = GET_FIELD(inst->FLASHCFG, NPCX_FLASHCFG_FLREQSUP); + uint16_t max_read_req = 32 << flash_req_size; + struct npcx_taf_head taf_head; + int rc; + + if (flash_req_size > target_max_size) { + LOG_DBG("Exceeded the maximum supported length"); + if (target_max_size == 0) { + target_max_size = 1; + } + max_read_req = 32 << target_max_size; + } + + if (total_len > max_read_req) { + LOG_ERR("Exceeded the limitation of read length"); + return -EINVAL; + } + + if (espi_taf_check_read_protect(dev, addr, len, taf_data_ptr->tag)) { + LOG_ERR("Access protect region"); + return -EINVAL; + } + + if (total_len <= config->rx_plsz) { + cycle_type = CYC_SCS_CMP_WITH_DATA_ONLY; + len = total_len; + } else { + cycle_type = CYC_SCS_CMP_WITH_DATA_FIRST; + len = config->rx_plsz; + } + + do { + data_ptr = (uint8_t *)taf_data_ptr->data; + + taf_head.pkt_len = len + NPCX_TAF_CMP_HEADER_LEN; + taf_head.type = cycle_type; + taf_head.tag_hlen = (taf_data_ptr->tag << 4) | ((len & 0xF00) >> 8); + taf_head.llen = len & 0xFF; + memcpy(data_ptr, &taf_head, sizeof(taf_head)); + + rc = flash_read(spi_dev, addr, data_ptr + 4, len); + if (rc) { + LOG_ERR("flash read fail 0x%x", rc); + return -EIO; + } + + rc = taf_npcx_completion_handler(dev, (uint32_t *)taf_data_ptr->data); + if (rc) { + LOG_ERR("espi taf completion handler fail"); + return rc; + } + + total_len -= len; + addr += len; + + if (total_len <= config->rx_plsz) { + cycle_type = CYC_SCS_CMP_WITH_DATA_LAST; + len = total_len; + } else { + cycle_type = CYC_SCS_CMP_WITH_DATA_MIDDLE; + } + } while (total_len); + + return 0; +} + +static int espi_taf_npcx_flash_write(const struct device *dev, struct espi_saf_packet *pckt) +{ + 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); + struct npcx_taf_head taf_head; + int rc; + + if (espi_taf_check_write_protect(dev, pckt->flash_addr, + pckt->len, taf_data_ptr->tag)) { + LOG_ERR("Access protection region"); + return -EINVAL; + } + + rc = flash_write(spi_dev, pckt->flash_addr, data_ptr, pckt->len); + if (rc) { + LOG_ERR("flash write fail 0x%x", rc); + return -EIO; + } + + taf_head.pkt_len = NPCX_TAF_CMP_HEADER_LEN; + taf_head.type = CYC_SCS_CMP_WITHOUT_DATA; + taf_head.tag_hlen = (taf_data_ptr->tag << 4); + taf_head.llen = 0x0; + memcpy(data_ptr, &taf_head, sizeof(taf_head)); + + rc = taf_npcx_completion_handler(dev, (uint32_t *)taf_data_ptr->data); + if (rc) { + LOG_ERR("espi taf completion handler fail"); + return rc; + } + + return 0; +} + +static int espi_taf_npcx_flash_erase(const struct device *dev, struct espi_saf_packet *pckt) +{ + 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; + struct npcx_taf_head taf_head; + int rc; + + if (espi_taf_check_write_protect(dev, addr, len, taf_data_ptr->tag)) { + LOG_ERR("Access protection region"); + return -EINVAL; + } + + rc = flash_erase(spi_dev, addr, len); + if (rc) { + LOG_ERR("flash erase fail"); + return -EIO; + } + + taf_head.pkt_len = NPCX_TAF_CMP_HEADER_LEN; + taf_head.type = CYC_SCS_CMP_WITHOUT_DATA; + taf_head.tag_hlen = (taf_data_ptr->tag << 4); + taf_head.llen = 0x0; + memcpy(data_ptr, &taf_head, sizeof(taf_head)); + + rc = taf_npcx_completion_handler(dev, (uint32_t *)taf_data_ptr->data); + if (rc) { + LOG_ERR("espi taf completion handler fail"); + return rc; + } + + return 0; +} + +static int espi_taf_npcx_flash_unsuccess(const struct device *dev, struct espi_saf_packet *pckt) +{ + 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; + struct npcx_taf_head taf_head; + int rc; + + taf_head.pkt_len = NPCX_TAF_CMP_HEADER_LEN; + taf_head.type = CYC_UNSCS_CMP_WITHOUT_DATA_ONLY; + taf_head.tag_hlen = (taf_data_ptr->tag << 4); + taf_head.llen = 0x0; + memcpy(data_ptr, &taf_head, sizeof(taf_head)); + + rc = taf_npcx_completion_handler(dev, (uint32_t *)taf_data_ptr->data); + if (rc) { + LOG_ERR("espi taf completion handler fail"); + return rc; + } + + return 0; +} + +static int espi_taf_npcx_init(const struct device *dev) +{ + struct espi_reg *const inst = HAL_INSTANCE(dev); + struct espi_taf_npcx_config *config = ((struct espi_taf_npcx_config *)(dev)->config); + + SET_FIELD(inst->FLASHCFG, NPCX_FLASHCFG_FLCAPA, + NPCX_FLASH_SHARING_CAP_SUPP_TAF_AND_CAF); + SET_FIELD(inst->FLASHCFG, NPCX_FLASHCFG_TRGFLEBLKSIZE, + BIT(config->erase_sz)); + SET_FIELD(inst->FLASHCFG, NPCX_FLASHCFG_FLREQSUP, + config->max_rd_sz); + inst->FLASHBASE = config->mapped_addr; + + return 0; +} + +static const struct espi_saf_driver_api espi_taf_npcx_driver_api = { + .config = espi_taf_npcx_configure, + .set_protection_regions = espi_taf_npcx_set_pr, + .activate = espi_taf_npcx_activate, + .get_channel_status = espi_taf_npcx_channel_ready, + .flash_read = espi_taf_npcx_flash_read, + .flash_write = espi_taf_npcx_flash_write, + .flash_erase = espi_taf_npcx_flash_erase, + .flash_unsuccess = espi_taf_npcx_flash_unsuccess, +}; + +static struct espi_taf_npcx_data npcx_espi_taf_data; + +static const struct espi_taf_npcx_config espi_taf_npcx_config = { + .base = DT_INST_REG_ADDR(0), + .mapped_addr = DT_INST_PROP(0, mapped_addr), + .rx_plsz = DT_PROP(DT_INST_PARENT(0), rx_plsize), + .erase_sz = DT_INST_STRING_TOKEN(0, erase_sz), + .max_rd_sz = DT_INST_STRING_TOKEN(0, max_read_sz), +}; + +DEVICE_DT_INST_DEFINE(0, &espi_taf_npcx_init, NULL, + &npcx_espi_taf_data, &espi_taf_npcx_config, + PRE_KERNEL_2, CONFIG_ESPI_INIT_PRIORITY, + &espi_taf_npcx_driver_api); diff --git a/dts/arm/nuvoton/npcx/npcx4.dtsi b/dts/arm/nuvoton/npcx/npcx4.dtsi index e18bd89f103..5cc63cb658e 100644 --- a/dts/arm/nuvoton/npcx/npcx4.dtsi +++ b/dts/arm/nuvoton/npcx/npcx4.dtsi @@ -306,6 +306,17 @@ buffer-tx-size = <128>; shi-cs-wui =<&wui_io53>; }; + + espi0: espi@4000a000 { + rx-plsize = <64>; + tx-plsize = <64>; + + espi_taf: espitaf@4000a000 { + compatible = "nuvoton,npcx-espi-taf"; + reg = <0x4000a000 0x2000>; + status = "disabled"; + }; + }; }; soc-if { diff --git a/dts/arm/nuvoton/npcx/npcx7.dtsi b/dts/arm/nuvoton/npcx/npcx7.dtsi index 29be4fcc1f3..be003127596 100644 --- a/dts/arm/nuvoton/npcx/npcx7.dtsi +++ b/dts/arm/nuvoton/npcx/npcx7.dtsi @@ -255,6 +255,11 @@ buffer-tx-size = <128>; shi-cs-wui =<&wui_io53>; }; + + espi0: espi@4000a000 { + rx-plsize = <64>; + tx-plsize = <16>; + }; }; soc-id { diff --git a/dts/arm/nuvoton/npcx/npcx9.dtsi b/dts/arm/nuvoton/npcx/npcx9.dtsi index f4716d7947e..e3004ab879d 100644 --- a/dts/arm/nuvoton/npcx/npcx9.dtsi +++ b/dts/arm/nuvoton/npcx/npcx9.dtsi @@ -283,6 +283,11 @@ buffer-tx-size = <128>; shi-cs-wui =<&wui_io53>; }; + + espi0: espi@4000a000 { + rx-plsize = <64>; + tx-plsize = <16>; + }; }; soc-id { diff --git a/dts/bindings/espi/nuvoton,npcx-espi-taf.yaml b/dts/bindings/espi/nuvoton,npcx-espi-taf.yaml new file mode 100644 index 00000000000..115f8e5e4a4 --- /dev/null +++ b/dts/bindings/espi/nuvoton,npcx-espi-taf.yaml @@ -0,0 +1,60 @@ +# Copyright (c) 2023 Nuvoton Technology Corporation. +# SPDX-License-Identifier: Apache-2.0 + +description: | + The target flash devices accessed by Nuvoton eSPI TAF controller. + + Representation: + + espi_taf: espitaf@4000a000 { + compatible = "nuvoton,npcx-espi-taf"; + reg = <0x4000a000 0x2000>; + + mapped-addr = <0x68000000>; + max-read-sz = "NPCX_ESPI_TAF_MAX_READ_REQ_64B"; + erase-sz = "NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_4KB"; + + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + }; + +compatible: "nuvoton,npcx-espi-taf" + +include: [espi-controller.yaml, pinctrl-device.yaml] + +properties: + mapped-addr: + type: int + description: | + Mapped memory address of direct read access for flash. + required: true + + erase-sz: + type: string + required: true + description: | + Erase block size of target flash. The default was 4KB Erase Block Size. + All Intel platforms require support for at least 4 KB Erase Block Size. + default: "NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_4KB" + enum: + - "NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_4KB" + - "NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_32KB" + - "NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_64KB" + - "NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_128KB" + + max-read-sz: + type: string + required: true + description: | + Maximum read request size of flash access channel. The default was 64 bytes. + This value is recommended in datasheet. + default: "NPCX_ESPI_TAF_MAX_READ_REQ_64B" + enum: + - "NPCX_ESPI_TAF_MAX_READ_REQ_64B" + - "NPCX_ESPI_TAF_MAX_READ_REQ_128B" + - "NPCX_ESPI_TAF_MAX_READ_REQ_256B" + - "NPCX_ESPI_TAF_MAX_READ_REQ_512B" + - "NPCX_ESPI_TAF_MAX_READ_REQ_1024B" + - "NPCX_ESPI_TAF_MAX_READ_REQ_2048B" + - "NPCX_ESPI_TAF_MAX_READ_REQ_4096B" diff --git a/dts/bindings/espi/nuvoton,npcx-espi.yaml b/dts/bindings/espi/nuvoton,npcx-espi.yaml index ebce305a3af..e53c3acb94b 100644 --- a/dts/bindings/espi/nuvoton,npcx-espi.yaml +++ b/dts/bindings/espi/nuvoton,npcx-espi.yaml @@ -30,3 +30,13 @@ properties: For example the WUI mapping on NPCX7 would be espi-rst-wui = <&wui_cr_sin1>; + + rx-plsize: + type: int + required: true + description: The maximum receive channel payload size. + + tx-plsize: + type: int + required: true + description: The maximum transmit channel payload size. diff --git a/include/zephyr/drivers/espi_saf.h b/include/zephyr/drivers/espi_saf.h index 9c6f47d1590..31fc23c0808 100644 --- a/include/zephyr/drivers/espi_saf.h +++ b/include/zephyr/drivers/espi_saf.h @@ -145,6 +145,8 @@ typedef int (*espi_saf_api_flash_write)(const struct device *dev, struct espi_saf_packet *pckt); typedef int (*espi_saf_api_flash_erase)(const struct device *dev, struct espi_saf_packet *pckt); +typedef int (*espi_saf_api_flash_unsuccess)(const struct device *dev, + struct espi_saf_packet *pckt); /* Callbacks and traffic intercept */ typedef int (*espi_saf_api_manage_callback)(const struct device *dev, struct espi_callback *callback, @@ -158,6 +160,7 @@ __subsystem struct espi_saf_driver_api { espi_saf_api_flash_read flash_read; espi_saf_api_flash_write flash_write; espi_saf_api_flash_erase flash_erase; + espi_saf_api_flash_unsuccess flash_unsuccess; espi_saf_api_manage_callback manage_callback; }; @@ -383,6 +386,35 @@ static inline int z_impl_espi_saf_flash_erase(const struct device *dev, return api->flash_erase(dev, pckt); } +/** + * @brief Response unsuccessful completion for slave attached flash. + * + * This routines provides an interface to response that transaction is + * invalid and return unsuccessful completion from target to controller. + * + * @param dev Pointer to the device structure for the driver instance. + * @param pckt Address of the representation of flash transaction. + * + * @retval -ENOTSUP eSPI flash logical channel transactions not supported. + * @retval -EBUSY eSPI flash channel is not ready or disabled by master. + * @retval -EIO General input / output error, failed request to master. + */ +__syscall int espi_saf_flash_unsuccess(const struct device *dev, + struct espi_saf_packet *pckt); + +static inline int z_impl_espi_saf_flash_unsuccess(const struct device *dev, + struct espi_saf_packet *pckt) +{ + const struct espi_saf_driver_api *api = + (const struct espi_saf_driver_api *)dev->api; + + if (!api->flash_unsuccess) { + return -ENOTSUP; + } + + return api->flash_unsuccess(dev, pckt); +} + /** * Callback model * diff --git a/soc/arm/nuvoton_npcx/common/reg/reg_access.h b/soc/arm/nuvoton_npcx/common/reg/reg_access.h index 4f302f51461..ae1d6a61694 100644 --- a/soc/arm/nuvoton_npcx/common/reg/reg_access.h +++ b/soc/arm/nuvoton_npcx/common/reg/reg_access.h @@ -27,4 +27,12 @@ ((reg) = ((reg) & (~(((1 << (f_size))-1) << (f_pos)))) \ | ((value) << (f_pos))) +#define GET_FIELD_POS(field) \ + _GET_FIELD_POS_(FIELD_POS(field)) +#define _GET_FIELD_POS_(f_ops) f_ops + +#define GET_FIELD_SZ(field) \ + _GET_FIELD_SZ_(FIELD_SIZE(field)) +#define _GET_FIELD_SZ_(f_ops) f_ops + #endif /* _NUVOTON_NPCX_REG_ACCESS_H */ diff --git a/soc/arm/nuvoton_npcx/common/reg/reg_def.h b/soc/arm/nuvoton_npcx/common/reg/reg_def.h index d6b081533df..76cab3a6624 100644 --- a/soc/arm/nuvoton_npcx/common/reg/reg_def.h +++ b/soc/arm/nuvoton_npcx/common/reg/reg_def.h @@ -625,14 +625,35 @@ struct espi_reg { volatile uint32_t reserved8[11]; /* 0x3FC: OOB Channel Control used in 'direct' mode */ volatile uint32_t OOBCTL_DIRECT; - /* 0x400 - 443: Flash Receive Buffer 0-16 */ - volatile uint32_t FLASHRXBUF[17]; - volatile uint32_t reserved9[15]; - /* 0x480 - 497: Flash Transmit Buffer 0-5 */ - volatile uint32_t FLASHTXBUF[6]; - volatile uint32_t reserved10[25]; + /* 0x400 - 443: Flash Receive Buffer 0-17 */ + volatile uint32_t FLASHRXBUF[18]; + volatile uint32_t reserved9[14]; + /* 0x480 - 497: Flash Transmit Buffer 0-16 */ + volatile uint32_t FLASHTXBUF[17]; + volatile uint32_t reserved10[14]; /* 0x4FC: Flash Channel Control used in 'direct' mode */ volatile uint32_t FLASHCTL_DIRECT; + volatile uint32_t reserved12[64]; + /* 0x600 - 63F */ + volatile uint32_t FLASH_PRTR_BADDR[16]; + /* 0x640 - 67F */ + volatile uint32_t FLASH_PRTR_HADDR[16]; + /* 0x680 - 6BF */ + volatile uint32_t FLASH_RGN_TAG_OVR[16]; + volatile uint32_t reserved13[80]; + /* 0x800 */ + volatile uint32_t FLASH_RPMC_CFG_1; + /* 0x804 */ + volatile uint32_t FLASH_RPMC_CFG_2; + /* 0x808 */ + volatile uint32_t RMAP_FLASH_OFFS; + /* 0x80C */ + volatile uint32_t RMAP_DST_BASE; + /* 0x810 */ + volatile uint32_t RMAP_WIN_SIZE; + /* 0x814 */ + volatile uint32_t FLASHBASE; + volatile uint32_t reserved14[58]; }; /* eSPI register fields */ @@ -648,6 +669,7 @@ struct espi_reg { #define NPCX_ESPICFG_HCHANS_FIELD FIELD(4, 4) #define NPCX_ESPICFG_IOMODE_FIELD FIELD(8, 2) #define NPCX_ESPICFG_MAXFREQ_FIELD FIELD(10, 3) +#define NPCX_ESPICFG_FLCHANMODE 16 #define NPCX_ESPICFG_PCCHN_SUPP 24 #define NPCX_ESPICFG_VWCHN_SUPP 25 #define NPCX_ESPICFG_OOBCHN_SUPP 26 @@ -657,7 +679,7 @@ struct espi_reg { #define NPCX_ESPIIE_BERRIE 2 #define NPCX_ESPIIE_OOBRXIE 3 #define NPCX_ESPIIE_FLASHRXIE 4 -#define NPCX_ESPIIE_SFLASHRDIE 5 +#define NPCX_ESPIIE_FLNACSIE 5 #define NPCX_ESPIIE_PERACCIE 6 #define NPCX_ESPIIE_DFRDIE 7 #define NPCX_ESPIIE_VWUPDIE 8 @@ -675,6 +697,7 @@ struct espi_reg { #define NPCX_ESPIWE_BERRWE 2 #define NPCX_ESPIWE_OOBRXWE 3 #define NPCX_ESPIWE_FLASHRXWE 4 +#define NPCX_ESPIWE_FLNACSWE 5 #define NPCX_ESPIWE_PERACCWE 6 #define NPCX_ESPIWE_DFRDWE 7 #define NPCX_ESPIWE_VWUPDWE 8 @@ -686,6 +709,7 @@ struct espi_reg { #define NPCX_ESPISTS_BERR 2 #define NPCX_ESPISTS_OOBRX 3 #define NPCX_ESPISTS_FLASHRX 4 +#define NPCX_ESPISTS_FLNACS 5 #define NPCX_ESPISTS_PERACC 6 #define NPCX_ESPISTS_DFRD 7 #define NPCX_ESPISTS_VWUPD 8 @@ -700,6 +724,14 @@ struct espi_reg { #define NPCX_ESPISTS_BMBURSTERR 22 #define NPCX_ESPISTS_BMBURSTDONE 23 #define NPCX_ESPISTS_ESPIRST_LVL 24 +#define NPCX_VWSWIRQ_IRQ_NUM FIELD(0, 7) +#define NPCX_VWSWIRQ_IRQ_LVL 7 +#define NPCX_VWSWIRQ_INDEX FIELD(8, 7) +#define NPCX_VWSWIRQ_INDEX_EN 15 +#define NPCX_VWSWIRQ_DIRTY 16 +#define NPCX_VWSWIRQ_ENPLTRST 17 +#define NPCX_VWSWIRQ_ENCDRST 19 +#define NPCX_VWSWIRQ_EDGE_IRQ 28 #define NPCX_VWEVMS_WIRE FIELD(0, 4) #define NPCX_VWEVMS_VALID FIELD(4, 4) #define NPCX_VWEVMS_IE 18 @@ -716,6 +748,9 @@ struct espi_reg { #define NPCX_FLASHCFG_FLASHBLERSSIZE FIELD(7, 3) #define NPCX_FLASHCFG_FLASHPLSIZE FIELD(10, 3) #define NPCX_FLASHCFG_FLASHREQSIZE FIELD(13, 3) +#define NPCX_FLASHCFG_FLCAPA FIELD(24, 2) +#define NPCX_FLASHCFG_TRGFLEBLKSIZE FIELD(16, 8) +#define NPCX_FLASHCFG_FLREQSUP FIELD(0, 3) #define NPCX_FLASHCTL_FLASH_NP_FREE 0 #define NPCX_FLASHCTL_FLASH_TX_AVAIL 1 #define NPCX_FLASHCTL_STRPHDR 2 @@ -725,10 +760,21 @@ struct espi_reg { #define NPCX_FLASHCTL_CRCEN 14 #define NPCX_FLASHCTL_CHKSUMSEL 15 #define NPCX_FLASHCTL_AMTEN 16 - +#define NPCX_FLASHCTL_SAF_AUTO_READ 18 +#define NPCX_FLASHCTL_AUTO_RD_DIS_CTL 19 +#define NPCX_FLASHCTL_BLK_FLASH_NP_FREE 20 +#define NPCX_FLASHBASE_FLBASE_ADDR FIELD(12, 15) +#define NPCX_FLASH_PRTR_BADDR FIELD(12, 15) +#define NPCX_FRGN_WPR 29 +#define SAF_PROT_LCK 31 +#define NPCX_FRGN_RPR 30 +#define NPCX_FLASH_PRTR_HADDR FIELD(12, 15) +#define NPCX_FLASH_TAG_OVR_RPR FIELD(16, 16) +#define NPCX_FLASH_TAG_OVR_WPR FIELD(0, 16) #define NPCX_ONLY_ESPI_REG1_UNLOCK_REG2 0x55 #define NPCX_ONLY_ESPI_REG1_LOCK_REG2 0 #define NPCX_ONLY_ESPI_REG2_TRANS_END_CONFIG 4 + /* * Mobile System Wake-Up Control (MSWC) device registers */ diff --git a/soc/arm/nuvoton_npcx/common/registers.c b/soc/arm/nuvoton_npcx/common/registers.c index 0405bee3567..d2e64d290ca 100644 --- a/soc/arm/nuvoton_npcx/common/registers.c +++ b/soc/arm/nuvoton_npcx/common/registers.c @@ -62,7 +62,7 @@ NPCX_REG_OFFSET_CHECK(twd_reg, TWMWD, 0x00e); NPCX_REG_OFFSET_CHECK(twd_reg, WDCP, 0x010); /* ESPI register structure check */ -NPCX_REG_SIZE_CHECK(espi_reg, 0x500); +NPCX_REG_SIZE_CHECK(espi_reg, 0x900); NPCX_REG_OFFSET_CHECK(espi_reg, FLASHCFG, 0x034); NPCX_REG_OFFSET_CHECK(espi_reg, NPCX_ONLY_ESPI_REG1, 0x0f0); NPCX_REG_OFFSET_CHECK(espi_reg, VWEVMS, 0x140); diff --git a/soc/arm/nuvoton_npcx/common/soc_espi_taf.h b/soc/arm/nuvoton_npcx/common/soc_espi_taf.h new file mode 100644 index 00000000000..a8755e080f7 --- /dev/null +++ b/soc/arm/nuvoton_npcx/common/soc_espi_taf.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2023 Nuvoton Technology Corporation. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef _NUVOTON_NPCX_SOC_ESPI_TAF_H_ +#define _NUVOTON_NPCX_SOC_ESPI_TAF_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* Transmit buffer for eSPI TAF transaction on NPCX */ +/* +-------------+--------------+--------------+---------------+ */ +/* | Byte 3 | Byte 2 | Byte 1 | Byte 0 | */ +/* +-------------+--------------+--------------+---------------+ */ +/* | Length | Tag |Length | Type | PKT_LEN | */ +/* | [7:0] | |[11:8] | | | */ +/* +-------------+--------------+--------------+---------------+ */ +/* | Data 3 | Data 2 | Data 1 | Data 0 | */ +/* +-------------+--------------+--------------+---------------+ */ +/* | Data 7 | Data 6 | Data 5 | Data 4 | */ +/* +-------------+--------------+--------------+---------------+ */ +/* | ... | ... | ... | ... | */ +/* +-------------+--------------+--------------+---------------+ */ +/* | Data 63 | Data 62 | Data 61 | Data 60 | */ +/* +-------------+--------------+--------------+---------------+ */ +/* PKT_LEN holds the sum of header (Type, Tag and Length) length */ +/* and data length */ + +/* + * NPCX_TAF_CMP_HEADER_LEN is the preamble length of Type, Length + * and Tag (i.e. byte 1~byte 3) for flash access completion packet + * on NPCX + */ +#define NPCX_TAF_CMP_HEADER_LEN 3 + +/* Successful Completion Without Data */ +#define CYC_SCS_CMP_WITHOUT_DATA 0x06 +/* Successful middle Completion With Data */ +#define CYC_SCS_CMP_WITH_DATA_MIDDLE 0x09 +/* Successful first Completion With Data */ +#define CYC_SCS_CMP_WITH_DATA_FIRST 0x0B +/* Successful last Completion With Data */ +#define CYC_SCS_CMP_WITH_DATA_LAST 0x0D +/* Successful only Completion With Data */ +#define CYC_SCS_CMP_WITH_DATA_ONLY 0x0F +/* Unsuccessful Completion Without Data */ +#define CYC_UNSCS_CMP_WITHOUT_DATA 0x08 +/* Unsuccessful Last Completion Without Data */ +#define CYC_UNSCS_CMP_WITHOUT_DATA_LAST 0x0C +/* Unsuccessful Only Completion Without Data */ +#define CYC_UNSCS_CMP_WITHOUT_DATA_ONLY 0x0E + +/* Timeout for checking transmit buffer available and no completion was sent */ +#define NPCX_FLASH_CHK_TIMEOUT 10000 + +/* Clear RSTBUFHEADS, FLASH_ACC_TX_AVAIL, and FLASH_ACC_NP_FREE */ +#define NPCX_FLASHCTL_ACCESS_MASK (~(BIT(NPCX_FLASHCTL_RSTBUFHEADS) | \ + BIT(NPCX_FLASHCTL_FLASH_NP_FREE) | \ + BIT(NPCX_FLASHCTL_FLASH_TX_AVAIL))) + +/* Flash Sharing Capability Support */ +#define NPCX_FLASH_SHARING_CAP_SUPP_CAF 0 +#define NPCX_FLASH_SHARING_CAP_SUPP_TAF 2 +#define NPCX_FLASH_SHARING_CAP_SUPP_TAF_AND_CAF 3 + +enum NPCX_ESPI_TAF_REQ { + NPCX_ESPI_TAF_REQ_READ, + NPCX_ESPI_TAF_REQ_WRITE, + NPCX_ESPI_TAF_REQ_ERASE, + NPCX_ESPI_TAF_REQ_RPMC_OP1, + NPCX_ESPI_TAF_REQ_RPMC_OP2, + NPCX_ESPI_TAF_REQ_UNKNOWN, +}; + +/* NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_4KB is default */ +enum NPCX_ESPI_TAF_ERASE_BLOCK_SIZE { + NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_1KB, + NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_2KB, + NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_4KB, + NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_8KB, + NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_16KB, + NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_32KB, + NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_64KB, + NPCX_ESPI_TAF_ERASE_BLOCK_SIZE_128KB, +}; + +/* NPCX_ESPI_TAF_MAX_READ_REQ_64B is default */ +enum NPCX_ESPI_TAF_MAX_READ_REQ { + NPCX_ESPI_TAF_MAX_READ_REQ_64B = 1, + NPCX_ESPI_TAF_MAX_READ_REQ_128B, + NPCX_ESPI_TAF_MAX_READ_REQ_256B, + NPCX_ESPI_TAF_MAX_READ_REQ_512B, + NPCX_ESPI_TAF_MAX_READ_REQ_1024B, + NPCX_ESPI_TAF_MAX_READ_REQ_2048B, + NPCX_ESPI_TAF_MAX_READ_REQ_4096B, +}; + +/* + * The configurations of SPI flash are set in FIU module. + * Thus, eSPI TAF driver of NPCX does not need additional hardware configuarations. + * Therefore, define an empty structure here to comply with espi_saf.h + */ +struct espi_saf_hw_cfg { +}; + +struct espi_saf_pr { + uint32_t start; + uint32_t end; + uint16_t override_r; + uint16_t override_w; + uint8_t master_bm_we; + uint8_t master_bm_rd; + uint8_t pr_num; + uint8_t flags; +}; + +struct espi_saf_protection { + size_t nregions; + const struct espi_saf_pr *pregions; +}; + +struct espi_taf_npcx_pckt { + uint8_t tag; + uint8_t *data; +}; + +struct espi_taf_pckt { + uint8_t type; + uint8_t tag; + uint32_t addr; + uint16_t len; + uint32_t src[16]; +}; + +struct npcx_taf_head { + uint8_t pkt_len; + uint8_t type; + uint8_t tag_hlen; + uint8_t llen; +}; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/soc/arm/nuvoton_npcx/npcx4/Kconfig.defconfig.series b/soc/arm/nuvoton_npcx/npcx4/Kconfig.defconfig.series index 377575b1d9f..1b692cf7621 100644 --- a/soc/arm/nuvoton_npcx/npcx4/Kconfig.defconfig.series +++ b/soc/arm/nuvoton_npcx/npcx4/Kconfig.defconfig.series @@ -14,6 +14,10 @@ config NUM_IRQS config CORTEX_M_SYSTICK default !NPCX_ITIM_TIMER +config ESPI_TAF_NPCX + default y + depends on ESPI_SAF + source "soc/arm/nuvoton_npcx/npcx4/Kconfig.defconfig.npcx4*" endif # SOC_SERIES_NPCX4 diff --git a/soc/arm/nuvoton_npcx/npcx4/soc.h b/soc/arm/nuvoton_npcx/npcx4/soc.h index 9c780ca034a..4ada738102c 100644 --- a/soc/arm/nuvoton_npcx/npcx4/soc.h +++ b/soc/arm/nuvoton_npcx/npcx4/soc.h @@ -53,6 +53,7 @@ #include #include #include +#include #include #include