diff --git a/src/mainboard/google/guybrush/variants/baseboard/devicetree.cb b/src/mainboard/google/guybrush/variants/baseboard/devicetree.cb index 2d7eaec6c6..04e6e994be 100644 --- a/src/mainboard/google/guybrush/variants/baseboard/devicetree.cb +++ b/src/mainboard/google/guybrush/variants/baseboard/devicetree.cb @@ -42,7 +42,16 @@ chip soc/amd/cezanne .oob_ch_en = 0, .flash_ch_en = 0, - .vw_irq_polarity = ESPI_VW_IRQ_LEVEL_HIGH(1), + /* + * b/218874489 - This should really be ESPI_VW_IRQ_LEVEL_HIGH, + * but eSPI gets configured in verstage which is in RO. + * We have already locked RO for guybrush devices so we need + * make it so x86 coreboot re-initializes the vw_irq_polarity. + * This leaves another problem, verstage also runs in S0i3, but + * we don't run any other x86 coreboot stages, so we need to + * figure out a way to reset the eSPI polarity. + */ + .vw_irq_polarity = ESPI_VW_IRQ_LEVEL_LOW(1), }" # Enable S0i3 support diff --git a/src/mainboard/google/skyrim/variants/baseboard/include/baseboard/ec.h b/src/mainboard/google/skyrim/variants/baseboard/include/baseboard/ec.h index ea6b93eef2..b8b466b6a8 100644 --- a/src/mainboard/google/skyrim/variants/baseboard/include/baseboard/ec.h +++ b/src/mainboard/google/skyrim/variants/baseboard/include/baseboard/ec.h @@ -64,6 +64,7 @@ #define SIO_EC_MEMMAP_ENABLE /* EC Memory Map Resources */ #define SIO_EC_HOST_ENABLE /* EC Host Interface Resources */ #define SIO_EC_ENABLE_PS2K /* Enable PS/2 Keyboard */ +#define SIO_EC_PS2K_IRQ Interrupt (ResourceConsumer, Level, ActiveLow, Shared) {1} /* Enable EC sync interrupt */ #define EC_ENABLE_SYNC_IRQ_GPIO diff --git a/src/mainboard/google/zork/variants/baseboard/devicetree_dalboz.cb b/src/mainboard/google/zork/variants/baseboard/devicetree_dalboz.cb index 68eb6ea588..69146041e8 100644 --- a/src/mainboard/google/zork/variants/baseboard/devicetree_dalboz.cb +++ b/src/mainboard/google/zork/variants/baseboard/devicetree_dalboz.cb @@ -227,7 +227,13 @@ chip soc/amd/picasso .oob_ch_en = 0, .flash_ch_en = 0, - .vw_irq_polarity = ESPI_VW_IRQ_LEVEL_HIGH(1) | ESPI_VW_IRQ_LEVEL_HIGH(12), + /* + * b/160595155 - These should really be ESPI_VW_IRQ_LEVEL_HIGH, + * but eSPI gets configured in verstage which is in RO. + * We have already locked RO for zork devices so we need + * make it so x86 coreboot re-initializes the vw_irq_polarity. + */ + .vw_irq_polarity = ESPI_VW_IRQ_LEVEL_LOW(1) | ESPI_VW_IRQ_LEVEL_LOW(12), }" register "i2c_scl_reset" = "GPIO_I2C2_SCL | GPIO_I2C3_SCL" diff --git a/src/mainboard/google/zork/variants/baseboard/devicetree_trembyle.cb b/src/mainboard/google/zork/variants/baseboard/devicetree_trembyle.cb index 4bb42dea1c..96e66aff1c 100644 --- a/src/mainboard/google/zork/variants/baseboard/devicetree_trembyle.cb +++ b/src/mainboard/google/zork/variants/baseboard/devicetree_trembyle.cb @@ -225,7 +225,13 @@ chip soc/amd/picasso .oob_ch_en = 0, .flash_ch_en = 0, - .vw_irq_polarity = ESPI_VW_IRQ_LEVEL_HIGH(1) | ESPI_VW_IRQ_LEVEL_HIGH(12), + /* + * b/160595155 - These should really be ESPI_VW_IRQ_LEVEL_HIGH, + * but eSPI gets configured in verstage which is in RO. + * We have already locked RO for zork devices so we need + * make it so x86 coreboot re-initializes the vw_irq_polarity. + */ + .vw_irq_polarity = ESPI_VW_IRQ_LEVEL_LOW(1) | ESPI_VW_IRQ_LEVEL_LOW(12), }" register "i2c_scl_reset" = "GPIO_I2C2_SCL | GPIO_I2C3_SCL" diff --git a/src/soc/amd/common/block/include/amdblocks/espi.h b/src/soc/amd/common/block/include/amdblocks/espi.h index 971768853a..296ae4e1e3 100644 --- a/src/soc/amd/common/block/include/amdblocks/espi.h +++ b/src/soc/amd/common/block/include/amdblocks/espi.h @@ -36,13 +36,43 @@ #define ESPI_OOB_CH_EN (1 << 1) #define ESPI_FLASH_CH_EN (1 << 0) -/* Virtual wire interrupt polarity. eSPI interrupts are active level high signals. The - polarity register inverts the incoming signal if the associated bit with the irq is - 0. */ -#define ESPI_VW_IRQ_LEVEL_HIGH(x) (1 << (x)) -#define ESPI_VW_IRQ_LEVEL_LOW(x) (0 << (x)) -#define ESPI_VW_IRQ_EDGE_HIGH(x) (1 << (x)) -#define ESPI_VW_IRQ_EDGE_LOW(x) (0 << (x)) +/* + * Internally the SoC uses active low signals for the IRQs. This means what when + * the eSPI controller comes out of reset, it's driving its IRQ lines high. + * In order to avoid any spurious interrupts the IO-APIC must be configured to + * trigger on active low signals. The PIC is only capable of triggering on + * active high signals so the hardware has an inverter that converts the signals + * before they feed into the PIC. + * + * +----------+ Active Low + * | | | +--------+ + * | IO-APIC <------+ | +-----+ LPC | + * | | | <---+---> | +--------+ + * +----------+ | | + * | +-----+ | +--------+ + * +---+ AND <---+-----+ eSPI | + * | +-----+ | +--------+ + * +----------+ | | + * | | +--v--+ | +--------+ + * | PIC <---+ NOT | +-----+ PIR | + * | | ^ +-----+ +--------+ + * +----------+ | + * | Active High + * + * The eSPI controller has an inverter that is applied to incoming Virtual Wire + * IRQ messages. This allows eSPI peripherals to use active high signaling. + * If the peripheral uses active low signaling like the SoC does internally, the + * inverter can be disabled. + * + * The polarity register has the following behavior: + * 0: Invert the incoming VW IRQ before outputting to the AND gates. + * 1: Do not invert the incoming VW IRQ, but route it directly to the AND + * gates. + */ +#define ESPI_VW_IRQ_LEVEL_HIGH(x) (0 << (x)) +#define ESPI_VW_IRQ_LEVEL_LOW(x) (1 << (x)) +#define ESPI_VW_IRQ_EDGE_HIGH(x) (0 << (x)) +#define ESPI_VW_IRQ_EDGE_LOW(x) (1 << (x)) enum espi_io_mode { ESPI_IO_MODE_SINGLE = ESPI_IO_MODE_VALUE(0),