Enabling an eSPI channel(e.g. Peripheral Channel) during an eSPI transaction might cause the BMC eSPI module to transition to a wrong state and therefore respond with FATAL_ERROR on incoming transaction. Add workaround to avoid the module getting into the wrong state.
Signed-off-by: Stanley Chu <ys...@nuvoton.com> Signed-off-by: Jim Liu <jjl...@nuvoton.com> --- drivers/misc/npcm_host_intf.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/drivers/misc/npcm_host_intf.c b/drivers/misc/npcm_host_intf.c index 58bab888c3c..2c89bd7a167 100644 --- a/drivers/misc/npcm_host_intf.c +++ b/drivers/misc/npcm_host_intf.c @@ -22,6 +22,8 @@ /* ESPI Register offsets */ #define ESPICFG 0x4 #define ESPIHINDP 0x80 +#define ESPI_TEN 0xF0 +#define ESPI_ENG 0xF1 /* MFSEL bit fileds */ #define MFSEL1_LPCSEL BIT(26) @@ -40,6 +42,9 @@ #define AUTO_HS2 BIT(12) #define AUTO_HS3 BIT(16) +#define ESPI_TEN_ENABLE 0x55 +#define ESPI_TEN_DISABLE 0 + static int npcm_host_intf_bind(struct udevice *dev) { struct regmap *syscon; @@ -83,6 +88,13 @@ static int npcm_host_intf_bind(struct udevice *dev) val &= ~(CHSUPP_MASK | IOMODE_MASK | MAXFREQ_MASK); val |= IOMODE_SDQ | MAXFREQ_33MHZ | FIELD_PREP(CHSUPP_MASK, ch_supp); writel(val, base + ESPICFG); + + if (device_is_compatible(dev, "nuvoton,npcm845-host-intf")) { + /* Workaround: avoid eSPI module getting into wrong state */ + writeb(ESPI_TEN_ENABLE, base + ESPI_TEN); + writeb(BIT(6), base + ESPI_ENG); + writeb(ESPI_TEN_DISABLE, base + ESPI_TEN); + } } else if (!strcmp(type, "lpc")) { /* Select LPC pin function */ regmap_update_bits(syscon, MFSEL4, MFSEL4_ESPISEL, 0); -- 2.34.1