Cliff Huang has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/73380 )
Change subject: soc/intel/common/block/pcie/rtd3: Add root port mutex support ......................................................................
soc/intel/common/block/pcie/rtd3: Add root port mutex support
When 'use_rp_mutex' (default = 0) is set in the device tree, a root port mutex will be added. This mutex is used in _ON and _OFF method, where the GPIO reset and/or enable GPIO value is changed. The companion driver, such as WWAN driver, needs to acquire this root port mutex when accessing the same GPIO pins. Using this common mutex prevents those invoked methods from being called from different thread while one is not completed.
An example is that WWAN driver calling _RST method to reset the device and does remove/rescan for the device while the pm runtime work might call RTD3 _OFF.
For those root port without additional driver, this mutex is not needed.
BRANCH=firmware-brya-14505.B TEST=boot to OS and check the generated SSDT table for the root port. The RPMX mutex should be generated and _ON and _OFF should use this mutex.
Signed-off-by: Cliff Huang cliff.huang@intel.com Change-Id: Ibc077528692b2d7076132384fb7bd441be502511 --- M src/soc/intel/common/block/pcie/rtd3/chip.h M src/soc/intel/common/block/pcie/rtd3/rtd3.c 2 files changed, 69 insertions(+), 2 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/80/73380/1
diff --git a/src/soc/intel/common/block/pcie/rtd3/chip.h b/src/soc/intel/common/block/pcie/rtd3/chip.h index ff22adc..f247028 100644 --- a/src/soc/intel/common/block/pcie/rtd3/chip.h +++ b/src/soc/intel/common/block/pcie/rtd3/chip.h @@ -5,6 +5,8 @@
#include <acpi/acpi_device.h>
+#define RP_MUTEX_NAME "RPMX" + enum acpi_pcie_rp_pm_emit { ACPI_PCIE_RP_EMIT_NONE = 0x00, /* None */ ACPI_PCIE_RP_EMIT_L23 = 0x01, /* L23 */ @@ -86,6 +88,13 @@ * the device driver. */ bool skip_on_off_support; + + /* + * Indicates the root port mutex is used for _ON and _OFF, the companion device driver + * such as WWAN driver should also acquire this mutex in methods that access the same HW + * resource, such as PERST# GPIO pin. + */ + bool use_rp_mutex; };
#endif /* __SOC_INTEL_COMMON_BLOCK_PCIE_RTD3_CHIP_H__ */ diff --git a/src/soc/intel/common/block/pcie/rtd3/rtd3.c b/src/soc/intel/common/block/pcie/rtd3/rtd3.c index 1519e6f..6229c87 100644 --- a/src/soc/intel/common/block/pcie/rtd3/rtd3.c +++ b/src/soc/intel/common/block/pcie/rtd3/rtd3.c @@ -154,6 +154,12 @@ acpigen_write_return_op(ONE_OP); acpigen_write_if_end();
+ if (config->use_rp_mutex) { + acpigen_emit_ext_op(ACQUIRE_OP); + acpigen_emit_namestring(acpi_device_path_join(parent, RP_MUTEX_NAME)); + acpigen_emit_word(ACPI_MUTEX_NO_TIMEOUT); + } + /* Disable modPHY power gating for PCH RPs. */ if (rp_type == PCIE_RP_PCH) pcie_rtd3_enable_modphy_pg(pcie_rp, PG_DISABLE); @@ -180,6 +186,11 @@ if (!config->disable_l23) pcie_rtd3_acpi_l23_exit();
+ if (config->use_rp_mutex) { + acpigen_emit_ext_op(RELEASE_OP); + acpigen_emit_namestring(acpi_device_path_join(parent, RP_MUTEX_NAME)); + } + if (config->skip_on_off_support) { /* If current _ON is skipped, ONSK is decremented so that _ON will be * executed normally until _OFF is skipped again. @@ -196,8 +207,12 @@ static void pcie_rtd3_acpi_method_off(int pcie_rp, const struct soc_intel_common_block_pcie_rtd3_config *config, - enum pcie_rp_type rp_type) + enum pcie_rp_type rp_type, + const struct device *dev) + { + const struct device *parent = dev->bus->dev; + acpigen_write_method_serialized("_OFF", 0);
/* When this feature is enabled, ONSK is checked to see if the device @@ -208,6 +223,12 @@ if (config->skip_on_off_support) acpigen_write_if_lequal_namestr_int("OFSK", 0);
+ if (config->use_rp_mutex) { + acpigen_emit_ext_op(ACQUIRE_OP); + acpigen_emit_namestring(acpi_device_path_join(parent, RP_MUTEX_NAME)); + acpigen_emit_word(ACPI_MUTEX_NO_TIMEOUT); + } + /* Trigger L23 ready entry flow unless disabled by config. */ if (!config->disable_l23) pcie_rtd3_acpi_l23_entry(); @@ -234,6 +255,11 @@ acpigen_write_sleep(config->enable_off_delay_ms); }
+ if (config->use_rp_mutex) { + acpigen_emit_ext_op(RELEASE_OP); + acpigen_emit_namestring(acpi_device_path_join(parent, RP_MUTEX_NAME)); + } + if (config->skip_on_off_support) { /* If current _OFF is skipped, ONSK is incremented so that the * following _ON will also be skipped. In addition, OFSK is decremented @@ -422,6 +448,9 @@ /* The RTD3 power resource is added to the root port, not the device. */ acpigen_write_scope(scope);
+ if (config->use_rp_mutex) + acpigen_write_mutex(RP_MUTEX_NAME, 0); + if (config->desc) acpigen_write_name_string("_DDN", config->desc);
@@ -464,7 +493,7 @@
pcie_rtd3_acpi_method_status(config); pcie_rtd3_acpi_method_on(pcie_rp, config, rp_type, dev); - pcie_rtd3_acpi_method_off(pcie_rp, config, rp_type); + pcie_rtd3_acpi_method_off(pcie_rp, config, rp_type, dev); acpigen_pop_len(); /* PowerResource */
/* Indicate to the OS that device supports hotplug in D3. */