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
Reviewed-on: https://review.coreboot.org/c/coreboot/+/73380
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Jérémy Compostella <jeremy.compostella@intel.com>
Reviewed-by: Bora Guvendik <bora.guvendik@intel.com>
This commit is contained in:
Cliff Huang 2023-03-02 10:03:32 -08:00 committed by Felix Held
parent 6d2d8ea80a
commit 69564f3de5
2 changed files with 32 additions and 2 deletions

View File

@ -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 @@ 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__ */

View File

@ -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. */