diff options
author | CHLin <CHLIN56@nuvoton.com> | 2016-10-19 14:21:37 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2016-10-26 01:44:21 -0700 |
commit | 8d1a958263c806acee343d8b449e39cbddc99dc5 (patch) | |
tree | 69586327e04031e3e9b47a2da3cd11b30e86cb7e | |
parent | 5cfa02b03c2b90918fbbb238ab736758bd601281 (diff) | |
download | chrome-ec-8d1a958263c806acee343d8b449e39cbddc99dc5.tar.gz |
npcx: espi: Fix SMI/SCI virtual wire handling
When GPIOC6/GPIO76 are not selected as SMI/SCI function(ie. selected
as GPIO), the reading of SMIB/SCIB will be a fixed value. This means
it cannot reflect the actul SMI/SCI status. As a reault, use SET_BIT/
CLEAR_BIT macro to toggle SMIB/SCIB is not feasible. Firmware should
read the SMI/SCI status from VWEVSM(2) register before setting it.
This CL defines some macros to achieve it.
In the previous CL, SMI/SCI negative polarity is conditionally
disabled. However, the negative polarity is not used in current
firmware design. Set the SMI/SCI polarity as postive unconditionly by
default.
Modified drivers:
1. lpc.c: use macro NPCX_VW_SMI/NPCX_VW_SCI to generate Virtual wire.
use SMI/SCI postive polarity uncontionally by default.
2. register.h : define macro to handle SMI/SCI virtual wire.
BUG=chrome-os-partner:34346
BRANCH=none
TEST=make buildall; try hostevent on Wheatley and check virtual wire
signal is correct on logical analyzer.
Change-Id: Id4a7748addeaa3b35f280ff29f6fcd8a08b9894b
Signed-off-by: CHLin <CHLIN56@nuvoton.com>
Reviewed-on: https://chromium-review.googlesource.com/400161
Commit-Ready: CH Lin <chlin56@nuvoton.com>
Tested-by: CH Lin <chlin56@nuvoton.com>
Tested-by: Duncan Laurie <dlaurie@chromium.org>
Reviewed-by: Duncan Laurie <dlaurie@chromium.org>
-rw-r--r-- | chip/npcx/lpc.c | 43 | ||||
-rw-r--r-- | chip/npcx/registers.h | 15 |
2 files changed, 56 insertions, 2 deletions
diff --git a/chip/npcx/lpc.c b/chip/npcx/lpc.c index 7c08062e1e..d893218640 100644 --- a/chip/npcx/lpc.c +++ b/chip/npcx/lpc.c @@ -138,6 +138,21 @@ static void lpc_generate_smi(void) udelay(65); /* Set signal high, now that we've generated the edge */ gpio_set_level(GPIO_PCH_SMI_L, 1); +#elif defined(CONFIG_ESPI) + /* + * Don't use SET_BIT/CLEAR_BIT macro to toggle SMIB/SCIB to generate + * virtual wire. Use NPCX_VW_SMI/NPCX_VW_SCI macro instead. + * The reason is - if GPIOC6/CPIO76 are not selected as SMI/SCI, reading + * from SMIB/SCIB doesn't really reflect the SMI/SCI status. SMI/SCI + * status should be read from bit 1/0 in eSPI VMEVSM(2) register. + */ + NPCX_HIPMIC(PMC_ACPI) = NPCX_VW_SMI(1); + udelay(65); + /* Generate a falling edge */ + NPCX_HIPMIC(PMC_ACPI) = NPCX_VW_SMI(0); + udelay(65); + /* Set signal high */ + NPCX_HIPMIC(PMC_ACPI) = NPCX_VW_SMI(1); #else /* SET SMIB bit to pull SMI_L to high.*/ SET_BIT(NPCX_HIPMIC(PMC_ACPI), NPCX_HIPMIC_SMIB); @@ -167,6 +182,21 @@ static void lpc_generate_sci(void) udelay(65); /* Set signal high, now that we've generated the edge */ gpio_set_level(CONFIG_SCI_GPIO, 1); +#elif defined(CONFIG_ESPI) + /* + * Don't use SET_BIT/CLEAR_BIT macro to toggle SMIB/SCIB to generate + * virtual wire. Use NPCX_VW_SMI/NPCX_VW_SCI macro instead. + * The reason is - if GPIOC6/CPIO76 are not selected as SMI/SCI, reading + * from SMIB/SCIB doesn't really reflect the SMI/SCI status. SMI/SCI + * status should be read from bit 1/0 in eSPI VMEVSM(2) register. + */ + NPCX_HIPMIC(PMC_ACPI) = NPCX_VW_SCI(1); + udelay(65); + /* Generate a falling edge */ + NPCX_HIPMIC(PMC_ACPI) = NPCX_VW_SCI(0); + udelay(65); + /* Set signal high */ + NPCX_HIPMIC(PMC_ACPI) = NPCX_VW_SCI(1); #else /* Set SCIB bit to pull SCI_L to high.*/ SET_BIT(NPCX_HIPMIC(PMC_ACPI), NPCX_HIPMIC_SCIB); @@ -984,10 +1014,19 @@ static void lpc_init(void) SET_BIT(NPCX_GLUE_SDP_CTS, 0); #endif -#ifndef CONFIG_SCI_GPIO - /* Disable SMI/SCI Negative Polarity */ + /* + * Use SMI/SCI postive polarity as default. + * Negative polarity must be enabled in the case that SMI/SCI is + * generated automatically by hardware. In current design, + * SMI/SCI is conntrolled by FW. Use postive polarity is more + * intuitive. + */ CLEAR_BIT(NPCX_HIPMCTL(PMC_ACPI), NPCX_HIPMCTL_SCIPOL); CLEAR_BIT(NPCX_HIPMIC(PMC_ACPI), NPCX_HIPMIC_SMIPOL); + /* Set SMIB/SCIB to make sure SMI/SCI are high at init */ + NPCX_HIPMIC(PMC_ACPI) = NPCX_HIPMIC(PMC_ACPI) + | (1 << NPCX_HIPMIC_SMIB) | (1 << NPCX_HIPMIC_SCIB); +#ifndef CONFIG_SCI_GPIO /* * Allow SMI/SCI generated from PM module. * Either hardware autimatically generates, diff --git a/chip/npcx/registers.h b/chip/npcx/registers.h index 2889837b3b..4b85b9f228 100644 --- a/chip/npcx/registers.h +++ b/chip/npcx/registers.h @@ -1412,6 +1412,21 @@ enum ITIM16_MODULE_T { #define VWGPMS_FIELD(n, m, p, e) (VMGPMS_INX_EN(n) | VWGPMS_MODIFIED(m) | \ VWGPMS_PLTRST_EN(p) | VWGPMS_INT_EN(e)) +/* define macro to handle SMI/SCI Virtual Wire */ +/* Read SMI VWire status from VWEVSM(offset 2) register. */ +#define SMI_STATUS_MASK ((uint8_t) (NPCX_VWEVSM(2) & 0x00000002)) +/* + * Read SCI VWire status from VWEVSM(offset 2) register. + * Left shift 2 to meet the SCIB filed in HIPMIC register. + */ +#define SCI_STATUS_MASK (((uint8_t) (NPCX_VWEVSM(2) & 0x00000001)) << 2) +#define SCIB_MASK(v) (v << NPCX_HIPMIC_SCIB) +#define SMIB_MASK(v) (v << NPCX_HIPMIC_SMIB) +#define NPCX_VW_SCI(level) ((NPCX_HIPMIC(PM_CHAN_1) & 0xF9) | \ + SMI_STATUS_MASK | SCIB_MASK(level)) +#define NPCX_VW_SMI(level) ((NPCX_HIPMIC(PM_CHAN_1) & 0xF9) | \ + SCI_STATUS_MASK | SMIB_MASK(level)) + /* eSPI enumeration */ /* eSPI channels */ enum { |