summaryrefslogtreecommitdiff
path: root/src/soc/intel
diff options
context:
space:
mode:
Diffstat (limited to 'src/soc/intel')
-rw-r--r--src/soc/intel/common/block/pcie/rtd3/chip.h9
-rw-r--r--src/soc/intel/common/block/pcie/rtd3/rtd3.c25
2 files changed, 32 insertions, 2 deletions
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 <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__ */
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. */