Skip to content

Commit 8bdbcbb

Browse files
Merge pull request zephyrproject-rtos#20 from FrameworkComputer/pr-fwk-main-sci-delay
drivers: espi: npcx: ensure the host receives the value from eSPI VW
2 parents e414f3a + 97f3ca9 commit 8bdbcbb

19 files changed

Lines changed: 867 additions & 796 deletions

File tree

drivers/espi/Kconfig.npcx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,19 @@ config ESPI_NPCX_PERIPHERAL_DEBUG_PORT_80_RING_BUF_SIZE
6060
The size of the ring buffer in byte used by the Port80 ISR to store
6161
Postcodes from Host.
6262

63+
config ESPI_NPCX_VWIRE_ENABLE_SEND_CHECK
64+
bool "Check the value was read by host after wire bits changed"
65+
help
66+
This option enables the function to check whether the host has read the value
67+
after the wire data changes.
68+
69+
config ESPI_NPCX_WIRE_SEND_TIMEOUT_US
70+
int "eSPI virtual wire send timeout count"
71+
default 1000
72+
help
73+
The times to check status after sending the eSPI virtual wire signal. The unit
74+
is microseconds (µs).
75+
6376
config ESPI_TAF_NPCX
6477
bool "Nuvoton NPCX embedded controller (EC) ESPI TAF driver"
6578
depends on SOC_SERIES_NPCX4
@@ -98,6 +111,14 @@ config ESPI_TAF_NPCX_RPMC_SUPPORT
98111
help
99112
This option enable the handler for eSPI TAF RPMC request.
100113

114+
config ESPI_TAF_NPCX_STS_AWAIT_TIMEOUT
115+
int "A timeout value in microseconds to wait for automatic read status"
116+
depends on ESPI_TAF_NPCX
117+
default 20000
118+
help
119+
This option specifies the timeout value in microseconds (us) for checking
120+
automatic read status.
121+
101122
# The default value 'y' for the existing options if ESPI_NPCX is selected.
102123
if ESPI_NPCX
103124

drivers/espi/espi_npcx.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -879,9 +879,25 @@ static int espi_npcx_send_vwire(const struct device *dev,
879879
if (signal >= ESPI_VWIRE_SIGNAL_TARGET_GPIO_0) {
880880
SET_FIELD(inst->VWGPSM[reg_idx], NPCX_VWEVSM_WIRE, val);
881881
reg_val = inst->VWGPSM[reg_idx];
882+
883+
if (IS_ENABLED(CONFIG_ESPI_NPCX_VWIRE_ENABLE_SEND_CHECK)) {
884+
if (!WAIT_FOR(!IS_BIT_SET(inst->VWGPSM[reg_idx], NPCX_VWEVSM_DIRTY),
885+
CONFIG_ESPI_NPCX_WIRE_SEND_TIMEOUT_US, NULL)) {
886+
LOG_ERR("%s signal %d timeout", __func__, signal);
887+
return -ETIMEDOUT;
888+
}
889+
}
882890
} else {
883891
SET_FIELD(inst->VWEVSM[reg_idx], NPCX_VWEVSM_WIRE, val);
884892
reg_val = inst->VWEVSM[reg_idx];
893+
894+
if (IS_ENABLED(CONFIG_ESPI_NPCX_VWIRE_ENABLE_SEND_CHECK)) {
895+
if (!WAIT_FOR(!IS_BIT_SET(inst->VWEVSM[reg_idx], NPCX_VWEVSM_DIRTY),
896+
CONFIG_ESPI_NPCX_WIRE_SEND_TIMEOUT_US, NULL)) {
897+
LOG_ERR("%s signal %d timeout", __func__, signal);
898+
return -ETIMEDOUT;
899+
}
900+
}
885901
}
886902

887903
LOG_DBG("Send VW: %s%d 0x%08X", reg_name, reg_idx, reg_val);

drivers/espi/espi_taf_npcx.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -666,6 +666,38 @@ static void espi_taf_event_handler(const struct device *dev, struct espi_callbac
666666
k_work_submit(&npcx_espi_taf_data.work);
667667
}
668668

669+
int espi_taf_npcx_block(const struct device *dev, bool en_block)
670+
{
671+
struct espi_reg *const inst = HAL_INSTANCE(dev);
672+
673+
if (!IS_BIT_SET(inst->FLASHCTL, NPCX_FLASHCTL_SAF_AUTO_READ)) {
674+
return 0;
675+
}
676+
677+
if (en_block) {
678+
if (WAIT_FOR(!IS_BIT_SET(inst->ESPISTS, NPCX_ESPISTS_FLAUTORDREQ),
679+
CONFIG_ESPI_TAF_NPCX_STS_AWAIT_TIMEOUT, NULL) == false) {
680+
LOG_ERR("Check Automatic Read Queue Empty Timeout");
681+
return -ETIMEDOUT;
682+
}
683+
684+
inst->FLASHCTL |= BIT(NPCX_FLASHCTL_AUTO_RD_DIS_CTL);
685+
686+
if (WAIT_FOR(IS_BIT_SET(inst->ESPISTS, NPCX_ESPISTS_AUTO_RD_DIS_STS),
687+
CONFIG_ESPI_TAF_NPCX_STS_AWAIT_TIMEOUT, NULL) == false) {
688+
inst->FLASHCTL &= ~BIT(NPCX_FLASHCTL_AUTO_RD_DIS_CTL);
689+
inst->ESPISTS |= BIT(NPCX_ESPISTS_AUTO_RD_DIS_STS);
690+
LOG_ERR("Check Automatic Read Disable Timeout");
691+
return -ETIMEDOUT;
692+
}
693+
} else {
694+
inst->FLASHCTL &= ~BIT(NPCX_FLASHCTL_AUTO_RD_DIS_CTL);
695+
inst->ESPISTS |= BIT(NPCX_ESPISTS_AUTO_RD_DIS_STS);
696+
}
697+
698+
return 0;
699+
}
700+
669701
int npcx_init_taf(const struct device *dev, sys_slist_t *callbacks)
670702
{
671703
espi_init_callback(&espi_taf_cb, espi_taf_event_handler, ESPI_BUS_TAF_NOTIFICATION);

soc/nuvoton/npcx/Kconfig.soc

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,17 @@ config SOC_FAMILY_NPCX
99
config SOC_FAMILY
1010
default "nuvoton_npcx" if SOC_FAMILY_NPCX
1111

12+
config NPCX_SOC_VARIANT_NPCXN
13+
bool
14+
select SOC_FAMILY_NPCX
15+
16+
config NPCX_SOC_VARIANT_NPCKN
17+
bool
18+
select SOC_FAMILY_NPCX
19+
20+
config NPCX_SOC_VARIANT
21+
string
22+
default "npcxn" if NPCX_SOC_VARIANT_NPCXN
23+
default "npckn" if NPCX_SOC_VARIANT_NPCKN
24+
1225
rsource "*/Kconfig.soc"

soc/nuvoton/npcx/common/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
# SPDX-License-Identifier: Apache-2.0
22

33
zephyr_include_directories(.)
4+
45
zephyr_sources_ifdef(CONFIG_PM power.c)
56
zephyr_sources(
67
scfg.c
7-
registers.c
8+
${CONFIG_NPCX_SOC_VARIANT}/registers.c
89
)
10+
zephyr_include_directories(${CONFIG_NPCX_SOC_VARIANT}/include)
911

1012
# Check for disabling header CRC.
1113
if (NOT DEFINED CONFIG_NPCX_HEADER_ENABLE_HEADER_CRC)
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
/*
2+
* Copyright (c) 2020 Nuvoton Technology Corporation.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#ifndef _NUVOTON_NPCX_CLOCK_DEF_H_
8+
#define _NUVOTON_NPCX_CLOCK_DEF_H_
9+
10+
#include <stdbool.h>
11+
#include <stdint.h>
12+
13+
#include <zephyr/devicetree.h>
14+
#include <soc_clock.h>
15+
16+
/* FMUL clock */
17+
#if (OFMCLK > (MAX_OFMCLK / 2))
18+
#define FMCLK (OFMCLK / 2) /* FMUL clock = OFMCLK/2 */
19+
#else
20+
#define FMCLK OFMCLK /* FMUL clock = OFMCLK */
21+
#endif
22+
23+
/* APBs source clock */
24+
#define APBSRC_CLK OFMCLK
25+
26+
/* AHB6 clock */
27+
#if (CORE_CLK > (MAX_OFMCLK / 2))
28+
#define AHB6DIV_VAL 1 /* AHB6_CLK = CORE_CLK/2 */
29+
#else
30+
#define AHB6DIV_VAL 0 /* AHB6_CLK = CORE_CLK */
31+
#endif
32+
33+
/* FIU clock divider */
34+
#if (CORE_CLK > (MAX_OFMCLK / 2))
35+
#define FIUDIV_VAL 1 /* FIU_CLK = CORE_CLK/2 */
36+
#else
37+
#define FIUDIV_VAL 0 /* FIU_CLK = CORE_CLK */
38+
#endif
39+
40+
#if defined(CONFIG_CLOCK_CONTROL_NPCX_SUPP_FIU1)
41+
#if (CORE_CLK > (MAX_OFMCLK / 2))
42+
#define FIU1DIV_VAL 1 /* FIU1_CLK = CORE_CLK/2 */
43+
#else
44+
#define FIU1DIV_VAL 0 /* FIU1_CLK = CORE_CLK */
45+
#endif
46+
#endif /* CONFIG_CLOCK_CONTROL_NPCX_SUPP_FIU1 */
47+
48+
/* I3C clock divider */
49+
#if (OFMCLK == MHZ(120)) /* MCLkD must between 40 mhz to 50 mhz*/
50+
#define MCLKD_SL 2 /* I3C_CLK = (MCLK / 3) */
51+
#elif (OFMCLK <= MHZ(100) && OFMCLK >= MHZ(80))
52+
#define MCLKD_SL 1 /* I3C_CLK = (MCLK / 2) */
53+
#else
54+
#define MCLKD_SL 0 /* I3C_CLK = MCLK */
55+
#endif
56+
57+
/* Get APB clock freq */
58+
#define NPCX_APB_CLOCK(no) (APBSRC_CLK / (APB##no##DIV_VAL + 1))
59+
60+
/*
61+
* Frequency multiplier M/N value definitions according to the requested
62+
* OFMCLK (Unit:Hz).
63+
*/
64+
#if (OFMCLK > (MAX_OFMCLK / 2))
65+
#define HFCGN_VAL 0x82 /* Set XF_RANGE as 1 */
66+
#else
67+
#define HFCGN_VAL 0x02
68+
#endif
69+
#if (OFMCLK == 120000000)
70+
#define HFCGMH_VAL 0x0E
71+
#define HFCGML_VAL 0x4E
72+
#elif (OFMCLK == 100000000)
73+
#define HFCGMH_VAL 0x0B
74+
#define HFCGML_VAL 0xEC
75+
#elif (OFMCLK == 96000000)
76+
#define HFCGMH_VAL 0x0B
77+
#define HFCGML_VAL 0x72
78+
#elif (OFMCLK == 90000000)
79+
#define HFCGMH_VAL 0x0A
80+
#define HFCGML_VAL 0xBA
81+
#elif (OFMCLK == 80000000)
82+
#define HFCGMH_VAL 0x09
83+
#define HFCGML_VAL 0x89
84+
#elif (OFMCLK == 66000000)
85+
#define HFCGMH_VAL 0x07
86+
#define HFCGML_VAL 0xDE
87+
#elif (OFMCLK == 50000000)
88+
#define HFCGMH_VAL 0x0B
89+
#define HFCGML_VAL 0xEC
90+
#elif (OFMCLK == 48000000)
91+
#define HFCGMH_VAL 0x0B
92+
#define HFCGML_VAL 0x72
93+
#else
94+
#error "Unsupported OFMCLK Frequency"
95+
#endif
96+
97+
/* Clock prescaler configurations in different series */
98+
#define VAL_HFCGP ((FPRED_VAL << 4) | AHB6DIV_VAL)
99+
#if defined(FIU1DIV_VAL)
100+
#define VAL_HFCBCD ((FIU1DIV_VAL << 4) | (FIUDIV_VAL << 2))
101+
#else
102+
#define VAL_HFCBCD (FIUDIV_VAL << 4)
103+
#endif /* FIU1DIV_VAL */
104+
#define VAL_HFCBCD1 (APB1DIV_VAL | (APB2DIV_VAL << 4))
105+
#if defined(APB4DIV_VAL)
106+
#define VAL_HFCBCD2 (APB3DIV_VAL | (APB4DIV_VAL << 4))
107+
#else
108+
#define VAL_HFCBCD2 APB3DIV_VAL
109+
#endif /* APB4DIV_VAL */
110+
/* I3C1~I3C3 share the same configuration */
111+
#define VAL_HFCBCD3 MCLKD_SL
112+
113+
#endif /* _NUVOTON_NPCX_CLOCK_DEF_H_ */

0 commit comments

Comments
 (0)