From 69564f3de5a3d9da5e3ddc33c513431a48d2aa31 Mon Sep 17 00:00:00 2001 From: Cliff Huang Date: Thu, 2 Mar 2023 10:03:32 -0800 Subject: soc/intel/common/block/pcie/rtd3: Add root port mutex support MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Change-Id: Ibc077528692b2d7076132384fb7bd441be502511 Reviewed-on: https://review.coreboot.org/c/coreboot/+/73380 Tested-by: build bot (Jenkins) Reviewed-by: Jérémy Compostella Reviewed-by: Bora Guvendik --- src/soc/intel/common/block/pcie/rtd3/chip.h | 9 +++++++++ src/soc/intel/common/block/pcie/rtd3/rtd3.c | 25 +++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 2 deletions(-) (limited to 'src/soc') diff --git a/src/soc/intel/common/block/pcie/rtd3/chip.h b/src/soc/intel/common/block/pcie/rtd3/chip.h index ff22adcf49..f247028a61 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 +#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 @@ struct soc_intel_common_block_pcie_rtd3_config { * 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 1519e6fd50..8b372ed839 100644 --- a/src/soc/intel/common/block/pcie/rtd3/rtd3.c +++ b/src/soc/intel/common/block/pcie/rtd3/rtd3.c @@ -154,6 +154,10 @@ pcie_rtd3_acpi_method_on(unsigned int pcie_rp, acpigen_write_return_op(ONE_OP); acpigen_write_if_end(); + if (config->use_rp_mutex) + acpigen_write_acquire(acpi_device_path_join(parent, RP_MUTEX_NAME), + 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 +184,9 @@ pcie_rtd3_acpi_method_on(unsigned int pcie_rp, if (!config->disable_l23) pcie_rtd3_acpi_l23_exit(); + if (config->use_rp_mutex) + acpigen_write_release(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 +203,12 @@ pcie_rtd3_acpi_method_on(unsigned int pcie_rp, 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 +219,10 @@ pcie_rtd3_acpi_method_off(int pcie_rp, if (config->skip_on_off_support) acpigen_write_if_lequal_namestr_int("OFSK", 0); + if (config->use_rp_mutex) + acpigen_write_acquire(acpi_device_path_join(parent, RP_MUTEX_NAME), + ACPI_MUTEX_NO_TIMEOUT); + /* Trigger L23 ready entry flow unless disabled by config. */ if (!config->disable_l23) pcie_rtd3_acpi_l23_entry(); @@ -234,6 +249,9 @@ pcie_rtd3_acpi_method_off(int pcie_rp, acpigen_write_sleep(config->enable_off_delay_ms); } + if (config->use_rp_mutex) + acpigen_write_release(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 +440,9 @@ static void pcie_rtd3_acpi_fill_ssdt(const struct device *dev) /* 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 +485,7 @@ static void pcie_rtd3_acpi_fill_ssdt(const struct device *dev) 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. */ -- cgit v1.2.3