From 9a5a9635b7af69ac2716498a6b826c7545b27ab6 Mon Sep 17 00:00:00 2001 From: Cliff Huang Date: Tue, 24 Jan 2023 17:05:17 -0800 Subject: src/soc/intel/common/block/pcie/rtd3: Fix root port _STA logic MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When enable_gpio is used as active low output, the _STA returns incorrect value. Also, simply the logic for _STA method. When enable pin is used for _STA: | polarity | tx value| get_tx_gpio() | State | | active high | 0 | 0 | 0 | | active high | 1 | 1(active) | 1 | | active low | 0 | 1(active) | 1 | | active low | 1 | 0 | 0 | When reset pin is used for _STA: | polarity | tx value| get_tx_gpio() | State | | active high | 0 | 0 | 1 | | active high | 1 | 1(active) | 0 | | active low | 0 | 1(active) | 0 | | active low | 1 | 0 | 1 | Generated _STA method: Ex: for using active low power enable GPIO pin GPPC_H17: Method (_STA, 0, NotSerialized) // _STA: Status { Local0 = \_SB.PCI0.GTXS (0x5C) Local0 ^= One Return (Local0) } TEST=Check the SSDT when booted to OS. Signed-off-by: Cliff Huang Change-Id: Ie6f1e7a5b3e9fd0ea00e1e5b54058a14c6e9e09e Reviewed-on: https://review.coreboot.org/c/coreboot/+/72421 Reviewed-by: Jérémy Compostella Tested-by: build bot (Jenkins) --- src/soc/intel/common/block/pcie/rtd3/rtd3.c | 45 +++++++++++++++++++---------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/soc/intel/common/block/pcie/rtd3/rtd3.c b/src/soc/intel/common/block/pcie/rtd3/rtd3.c index f9b587df3a..6eb647119c 100644 --- a/src/soc/intel/common/block/pcie/rtd3/rtd3.c +++ b/src/soc/intel/common/block/pcie/rtd3/rtd3.c @@ -260,25 +260,40 @@ pcie_rtd3_acpi_method_status(const struct soc_intel_common_block_pcie_rtd3_confi const struct acpi_gpio *gpio; acpigen_write_method("_STA", 0); + /* + * Depending on the board configuration we use either the "enable" or + * the "reset" pin to detect the status of the device. The logic for + * each pin is detailed below. + * + * 1. For the "enable" pin: + * | polarity | tx value | get_tx_gpio() | State | + * |-------------+----------+---------------+-------| + * | active high | 0 | 0 | 0 | + * | active high | 1 | 1(active) | 1 | + * | active low | 0 | 1(active) | 1 | + * | active low | 1 | 0 | 0 | + * + * 2. For the "reset" pin: + * | polarity | tx value | get_tx_gpio() | State | + * |-------------+----------+---------------+-------| + * | active high | 0 | 0 | 1 | + * | active high | 1 | 1(active) | 0 | + * | active low | 0 | 1(active) | 0 | + * | active low | 1 | 0 | 1 | + */ /* Use enable GPIO for status if provided, otherwise use reset GPIO. */ - if (config->enable_gpio.pin_count) + if (config->enable_gpio.pin_count) { gpio = &config->enable_gpio; - else + /* Read current GPIO state into Local0. */ + acpigen_get_tx_gpio(gpio); + } else { gpio = &config->reset_gpio; - - /* Read current GPIO value into Local0. */ - acpigen_get_tx_gpio(gpio); - - /* Ensure check works for both active low and active high GPIOs. */ - acpigen_write_store_int_to_op(gpio->active_low, LOCAL1_OP); - - acpigen_write_if_lequal_op_op(LOCAL0_OP, LOCAL1_OP); - acpigen_write_return_op(ZERO_OP); - acpigen_write_else(); - acpigen_write_return_op(ONE_OP); - acpigen_pop_len(); /* Else */ - + /* Read current GPIO state into Local0. */ + acpigen_get_tx_gpio(gpio); + acpigen_write_not(LOCAL0_OP, LOCAL0_OP); + } + acpigen_write_return_op(LOCAL0_OP); acpigen_pop_len(); /* Method */ } -- cgit v1.2.3