drivers: espi: npcx: add espi taf support for npck3

This commit adds eSPI TAF support for npck3, including initialization
settings for flash operation mode. It also updates the mechanism to
release FLASH_NP_FREE, preventing a possible race condition between
automatic and standard requests.

Signed-off-by: Tom Chang <CHChang19@nuvoton.com>
diff --git a/drivers/espi/Kconfig.npcx b/drivers/espi/Kconfig.npcx
index 684a34c..c5c4e7b 100644
--- a/drivers/espi/Kconfig.npcx
+++ b/drivers/espi/Kconfig.npcx
@@ -103,11 +103,11 @@
 
 config ESPI_TAF_NPCX
 	bool "Nuvoton NPCX embedded controller (EC) ESPI TAF driver"
-	depends on ESPI_NPCX_NPCXN_V3
+	depends on ESPI_NPCX_NPCXN_V3 || ESPI_NPCX_NPCKN_V1
 	depends on FLASH
 	help
 	  This option enables the Intel Enhanced Serial Peripheral Interface
-	  Target Attached Flash (eSPI TAF) for NPCX4 family of processors.
+	  Target Attached Flash (eSPI TAF) for NPCX4/NPCK3 family of processors.
 
 choice ESPI_TAF_ACCESS_MODE_CHOICE
 	prompt "eSPI TAF Read Access Mode"
@@ -125,6 +125,15 @@
 
 endchoice
 
+config ESPI_TAF_TX_AVAIL_CHECK_TIME
+	int "Flash TX Available Check Time (microseconds)"
+	default 1000000
+	depends on ESPI_TAF_NPCX
+	help
+	  This option sets the time interval (in microseconds) for checking
+	  whether the host has sent a GET_FLASH_C command to retrieve the
+	  result.
+
 config ESPI_TAF_PR_NUM
 	int "Sets of protection region settings"
 	default 16
diff --git a/drivers/espi/espi_taf_npcx.c b/drivers/espi/espi_taf_npcx.c
index 665c8e0b..316f7ef 100644
--- a/drivers/espi/espi_taf_npcx.c
+++ b/drivers/espi/espi_taf_npcx.c
@@ -10,6 +10,7 @@
 #include <zephyr/drivers/espi.h>
 #include <zephyr/drivers/espi_saf.h>
 #include <zephyr/drivers/flash.h>
+#include <zephyr/dt-bindings/flash_controller/npcx_fiu_qspi.h>
 #ifdef CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT
 #include <zephyr/drivers/flash/npcx_flash_api_ex.h>
 #endif
@@ -39,7 +40,6 @@
 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;
 #ifdef CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT
@@ -74,9 +74,9 @@
 	((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 PROT_FLBASE_ADDR (							\
+	GET_FIELD(inst->FLASHBASE, NPCX_FLASH_PRTR_BADDR)		\
+	<< GET_FIELD_POS(NPCX_FLASH_PRTR_BADDR))
 
 #define PRTR_BADDR(i) (							\
 	GET_FIELD(inst->FLASH_PRTR_BADDR[i], NPCX_FLASH_PRTR_BADDR)	\
@@ -86,6 +86,11 @@
 	GET_FIELD(inst->FLASH_PRTR_HADDR[i], NPCX_FLASH_PRTR_HADDR)	\
 	<< GET_FIELD_POS(NPCX_FLASH_PRTR_HADDR)) | 0xFFF;
 
+#define DT_NODE_QUAD_PROP_OR(node)					\
+	COND_CODE_1(DT_NODE_HAS_PROP(node, quad_enable_requirements),	\
+		    (DT_PROP(node, quad_enable_requirements)),		\
+		    (("NONE")))
+
 static void espi_taf_get_pckt(const struct device *dev, struct espi_taf_npcx_data *pckt,
 			      struct espi_event event)
 {
@@ -104,6 +109,34 @@
 	}
 }
 
+#if defined(CONFIG_ESPI_NPCX_NPCKN_V1)
+static void espi_taf_fiu_mode_set(void)
+{
+	struct fiu_reg *const inst = (struct fiu_reg *)DT_INST_REG_ADDR_BY_NAME(0, fiu1);
+
+	if (strcmp(DT_NODE_QUAD_PROP_OR(NPCX_TAF_PRIME_FLASH_NODE), "NONE") != 0) {
+		/* Set quad read for FIU1 */
+		SET_FIELD(inst->SPI_FL_CFG, NPCX_SPI_FL_CFG_RD_MODE, NPCX_RD_MODE_FAST_DUAL);
+		inst->RESP_CFG |= BIT(NPCX_RESP_CFG_QUAD_EN);
+	}
+
+	if (DT_PROP(NPCX_TAF_PRIME_FLASH_NODE, enter_4byte_addr) != 0) {
+		int flags = DT_PROP(NPCX_TAF_PRIME_FLASH_NODE, qspi_flags);
+
+		/* Enable 4 byte address mode for FIU1 */
+		if ((flags & NPCX_QSPI_SHD_FLASH_SL) != 0) {
+			inst->FIU_4B_EN |= BIT(NPCX_MSR_FIU_4B_EN_SHD_4B);
+		} else if ((flags & NPCX_QSPI_PVT_FLASH_SL) != 0) {
+			inst->FIU_4B_EN |= BIT(NPCX_MSR_FIU_4B_EN_PVT_4B);
+		} else if ((flags & NPCX_QSPI_BKP_FLASH_SL) != 0) {
+			inst->FIU_4B_EN |= BIT(NPCX_MSR_FIU_4B_EN_BKP_4B);
+		} else {
+			LOG_ERR("No valid flash selected");
+		}
+	}
+}
+#endif
+
 #if defined(CONFIG_ESPI_TAF_MANUAL_MODE)
 /* 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,
@@ -116,7 +149,7 @@
 	uint32_t base, high;
 	bool rdpr;
 
-	flash_addr += FLBASE_ADDR;
+	flash_addr += PROT_FLBASE_ADDR;
 
 	for (i = 0; i < CONFIG_ESPI_TAF_PR_NUM; i++) {
 		base = PRTR_BADDR(i);
@@ -146,7 +179,7 @@
 	uint32_t base, high;
 	bool wrpr;
 
-	flash_addr += FLBASE_ADDR;
+	flash_addr += PROT_FLBASE_ADDR;
 
 	for (i = 0; i < CONFIG_ESPI_TAF_PR_NUM; i++) {
 		base = PRTR_BADDR(i);
@@ -187,8 +220,8 @@
 	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;
+	uint16_t offset;
+	uint32_t bitmask, rw_pr, override_rw;
 
 	if ((dev == NULL) || (pr == NULL)) {
 		return -EINVAL;
@@ -212,10 +245,11 @@
 			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;
+							 | rw_pr | PROT_FLBASE_ADDR;
 			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;
+			inst->FLASH_PRTR_HADDR[regnum] = (preg->end & bitmask) << offset
+							 | PROT_FLBASE_ADDR;
 		}
 
 		override_rw = (preg->override_r << 16) | preg->override_w;
@@ -230,8 +264,12 @@
 {
 	struct espi_reg *const inst = HAL_INSTANCE(dev);
 
+#ifdef CONFIG_ESPI_NPCX_NPCKN_V1
+	inst->FLASHCTL &= ~BIT(NPCX_FLASHCTL_SAF_PROT_LOCK);
+#else
 	inst->FLASHCTL &= ~BIT(NPCX_FLASHCTL_AUTO_RD_DIS_CTL);
 	inst->FLASHCTL &= ~BIT(NPCX_FLASHCTL_BLK_FLASH_NP_FREE);
+#endif
 
 	return 0;
 }
@@ -279,12 +317,14 @@
 static void taf_release_flash_np_free(const struct device *dev)
 {
 	struct espi_reg *const inst = HAL_INSTANCE(dev);
-	uint32_t tmp = inst->FLASHCTL;
+	uint32_t tmp;
 
-	/*
-	 * Clear FLASHCTL_FLASH_ACC_TX_AVAIL to avoid host puts a
-	 * GET_FLASH_C command at here.
-	 */
+	if (WAIT_FOR(!IS_BIT_SET(inst->FLASHCTL, NPCX_FLASHCTL_FLASH_ACC_TX_AVAIL),
+		CONFIG_ESPI_TAF_TX_AVAIL_CHECK_TIME, NULL) == false) {
+		LOG_ERR("Flash_ACC_TX_AVAIL is not cleared");
+	}
+
+	tmp = inst->FLASHCTL;
 	tmp &= NPCX_FLASHCTL_ACCESS_MASK;
 
 	/* Release FLASH_NP_FREE */
@@ -316,7 +356,7 @@
 	 * FLASH_ACC_TX_AVAIL.
 	 */
 	if (WAIT_FOR(!IS_BIT_SET(inst->FLASHCTL, NPCX_FLASHCTL_FLASH_ACC_TX_AVAIL),
-		     NPCX_FLASH_CHK_TIMEOUT, NULL) == false) {
+		     CONFIG_ESPI_TAF_TX_AVAIL_CHECK_TIME, NULL) == false) {
 		LOG_ERR("Check TX Queue Is Empty Timeout");
 		return -EBUSY;
 	}
@@ -342,7 +382,6 @@
 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 cycle_type = CYC_SCS_CMP_WITH_DATA_ONLY;
 	uint32_t total_len = pckt->len;
@@ -371,12 +410,12 @@
 		return -EINVAL;
 	}
 
-	if (total_len <= config->rx_plsz) {
+	if (total_len <= MAX_TX_PAYLOAD_SIZE) {
 		cycle_type = CYC_SCS_CMP_WITH_DATA_ONLY;
 		len = total_len;
 	} else {
 		cycle_type = CYC_SCS_CMP_WITH_DATA_FIRST;
-		len = config->rx_plsz;
+		len = MAX_TX_PAYLOAD_SIZE;
 	}
 
 	do {
@@ -423,7 +462,7 @@
 		total_len -= len;
 		addr += len;
 
-		if (total_len <= config->rx_plsz) {
+		if (total_len <= MAX_TX_PAYLOAD_SIZE) {
 			cycle_type = CYC_SCS_CMP_WITH_DATA_LAST;
 			len = total_len;
 		} else {
@@ -668,6 +707,7 @@
 
 int espi_taf_npcx_block(const struct device *dev, bool en_block)
 {
+#ifdef CONFIG_ESPI_NPCX_NPCXN_V3
 	struct espi_reg *const inst = HAL_INSTANCE(dev);
 
 	if (!IS_BIT_SET(inst->FLASHCTL, NPCX_FLASHCTL_SAF_AUTO_READ)) {
@@ -694,7 +734,7 @@
 		inst->FLASHCTL &= ~BIT(NPCX_FLASHCTL_AUTO_RD_DIS_CTL);
 		inst->ESPISTS |= BIT(NPCX_ESPISTS_AUTO_RD_DIS_STS);
 	}
-
+#endif
 	return 0;
 }
 
@@ -745,9 +785,19 @@
 		count_num = config->rpmc_cnt_num - 1;
 	}
 
+#if defined(CONFIG_ESPI_NPCX_NPCXN_V3)
 	SET_FIELD(inst->FLASH_RPMC_CFG_1, NPCX_FLASH_RPMC_CFG1_CNTR, count_num);
 	SET_FIELD(inst->FLASH_RPMC_CFG_1, NPCX_FLASH_RPMC_CFG1_OP1, config->rpmc_op1_code);
 	SET_FIELD(inst->FLASH_RPMC_CFG_1, NPCX_FLASH_RPMC_CFG1_TRGRPMCSUP, config->rpmc_cnt_num);
+#elif defined(CONFIG_ESPI_NPCX_NPCKN_V1)
+	SET_FIELD(inst->FLASHCFG2, NPCX_FLASHCFG2_RPMC1COUNT, count_num);
+	SET_FIELD(inst->FLASHCFG2, NPCX_FLASHCFG2_RPMC1OP1CODE, config->rpmc_op1_code);
+	SET_FIELD(inst->FLASHCFG, NPCX_FLASHCFG_TRGRPMCSUPP, config->rpmc_cnt_num);
+#endif
+#endif
+
+#if defined(CONFIG_ESPI_NPCX_NPCKN_V1)
+	espi_taf_fiu_mode_set();
 #endif
 
 	return 0;
@@ -763,7 +813,6 @@
 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),
 #ifdef CONFIG_ESPI_TAF_NPCX_RPMC_SUPPORT
diff --git a/soc/nuvoton/npcx/common/npckn/include/reg_def.h b/soc/nuvoton/npcx/common/npckn/include/reg_def.h
index d1ce638..e7bef8f 100644
--- a/soc/nuvoton/npcx/common/npckn/include/reg_def.h
+++ b/soc/nuvoton/npcx/common/npckn/include/reg_def.h
@@ -762,7 +762,10 @@
 #define NPCX_FLASHCFG_FLASHREQSIZE       FIELD(13, 3)
 #define NPCX_FLASHCFG_FLCAPA             FIELD(16, 2)
 #define NPCX_FLASHCFG_TRGFLEBLKSIZE      FIELD(18, 8)
+#define NPCX_FLASHCFG_TRGRPMCSUPP        FIELD(26, 6)
 #define NPCX_FLASHCFG_FLREQSUP           FIELD(0, 3)
+#define NPCX_FLASHCFG2_RPMC1OP1CODE      FIELD(24, 8)
+#define NPCX_FLASHCFG2_RPMC1COUNT        FIELD(20, 4)
 #define NPCX_FLASHCTL_FLASH_NP_FREE      0
 #define NPCX_FLASHCTL_FLASH_ACC_TX_AVAIL 1
 #define NPCX_FLASHCTL_STRPHDR            2
diff --git a/soc/nuvoton/npcx/common/soc_espi_taf.h b/soc/nuvoton/npcx/common/soc_espi_taf.h
index a838673..badfb9a 100644
--- a/soc/nuvoton/npcx/common/soc_espi_taf.h
+++ b/soc/nuvoton/npcx/common/soc_espi_taf.h
@@ -60,9 +60,6 @@
 /* ESPI TAF RPMC OP2 instruction */
 #define ESPI_TAF_RPMC_OP2_CMD                      0x96
 
-/* 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) | \