Cliff Huang has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/73381 )
Change subject: drivers/wwan/fm: Use RTD3 root port mutex for reset methods ......................................................................
drivers/wwan/fm: Use RTD3 root port mutex for reset methods
The RTD3 driver should have its 'use_rp_mutex' set in the devicetree.
BRANCH=firmware-brya-14505.B TEST=boot to OS and check the generated SSDT table for the WWAN The RTD3 RPMX mutex should be used in the reset Methods
Signed-off-by: Cliff Huang cliff.huang@intel.com Change-Id: Ic3fe20c56b67c2b5177f55f4845610087a30dc7f --- M src/drivers/wwan/fm/acpi_fm350gl.c 1 file changed, 99 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/81/73381/1
diff --git a/src/drivers/wwan/fm/acpi_fm350gl.c b/src/drivers/wwan/fm/acpi_fm350gl.c index df91389..a072304 100644 --- a/src/drivers/wwan/fm/acpi_fm350gl.c +++ b/src/drivers/wwan/fm/acpi_fm350gl.c @@ -3,6 +3,7 @@ #include <acpi/acpigen.h> #include <acpi/acpi_device.h> #include "chip.h" +#include "soc/intel/common/block/include/intelblocks/acpi.h" #include "soc/intel/common/block/pcie/rtd3/chip.h"
/* FCPO# to RESET# delay time during WWAN ON */ @@ -56,6 +57,19 @@ { acpigen_write_method_serialized("FHRF", 1); { + char mutex_path[128]; + const struct soc_intel_common_block_pcie_rtd3_config *rtd3_config; + + rtd3_config = config_of(config->rtd3dev); + if (rtd3_config->use_rp_mutex) { + snprintf(mutex_path, sizeof(mutex_path), acpi_device_path_join(parent_dev, + RP_MUTEX_NAME)); + /* Acquire root port mutex in case FHRF is called directly and not called from _RST */ + acpigen_emit_ext_op(ACQUIRE_OP); + acpigen_emit_namestring(mutex_path); + acpigen_emit_word(ACPI_MUTEX_NO_TIMEOUT); + } + /* LOCAL0 = PERST# */ acpigen_get_tx_gpio(&config->perst_gpio); acpigen_write_if_lequal_op_int(LOCAL0_OP, 0); @@ -97,6 +111,12 @@ acpigen_write_if_end(); /* If */ } acpigen_pop_len(); /* Else */ + + /* release mutex if acquired by FHRF */ + if (rtd3_config->use_rp_mutex) { + acpigen_emit_ext_op(RELEASE_OP); + acpigen_emit_namestring(mutex_path); + } } acpigen_write_method_end(); /* Method */ } @@ -109,6 +129,19 @@ { acpigen_write_method_serialized("SHRF", 0); { + char mutex_path[128]; + const struct soc_intel_common_block_pcie_rtd3_config *rtd3_config; + + rtd3_config = config_of(config->rtd3dev); + if (rtd3_config->use_rp_mutex) { + snprintf(mutex_path, sizeof(mutex_path), acpi_device_path_join(parent_dev, + RP_MUTEX_NAME)); + /* Acquire root port mutex */ + acpigen_emit_ext_op(ACQUIRE_OP); + acpigen_emit_namestring(mutex_path); + acpigen_emit_word(ACPI_MUTEX_NO_TIMEOUT); + } + /* call rtd3 method to Disable ModPHY Power Gating. */ if (wwan_fm350gl_get_rtd3_method_support(config) & ACPI_PCIE_RP_EMIT_PSD0) { @@ -137,6 +170,12 @@ "L23D")); } acpigen_write_sleep(FM350GL_TIME_HW_INIT); + + if (rtd3_config->use_rp_mutex) { + /* release mutex */ + acpigen_emit_ext_op(RELEASE_OP); + acpigen_emit_namestring(mutex_path); + } } acpigen_write_method_end(); /* Method */ } @@ -150,6 +189,19 @@ { acpigen_write_method_serialized("_RST", 0); { + char mutex_path[128]; + const struct soc_intel_common_block_pcie_rtd3_config *rtd3_config; + + rtd3_config = config_of(config->rtd3dev); + if (rtd3_config->use_rp_mutex) { + snprintf(mutex_path, sizeof(mutex_path), acpi_device_path_join(parent_dev, + RP_MUTEX_NAME)); + /* Acquire root port mutex */ + acpigen_emit_ext_op(ACQUIRE_OP); + acpigen_emit_namestring(mutex_path); + acpigen_emit_word(ACPI_MUTEX_NO_TIMEOUT); + } + /* Perform 1st Half of FLDR Flow for soft reset: FHRF(0) */ acpigen_emit_namestring("FHRF"); acpigen_emit_byte(RESET_TYPE_WARM); @@ -158,6 +210,12 @@ /* Indicates that the following _Off will be skipped. */ acpigen_emit_byte(INCREMENT_OP); acpigen_emit_namestring(acpi_device_path_join(parent_dev, "RTD3.OFSK")); + + if (rtd3_config->use_rp_mutex) { + /* Release root port mutex */ + acpigen_emit_ext_op(RELEASE_OP); + acpigen_emit_namestring(mutex_path); + } } acpigen_write_method_end(); /* Method */ } @@ -171,6 +229,19 @@ { acpigen_write_method_serialized("_RST", 0); { + char mutex_path[128]; + const struct soc_intel_common_block_pcie_rtd3_config *rtd3_config; + + rtd3_config = config_of(config->rtd3dev); + if (rtd3_config->use_rp_mutex) { + snprintf(mutex_path, sizeof(mutex_path), acpi_device_path_join(parent_dev, + RP_MUTEX_NAME)); + /* Acquire root port mutex */ + acpigen_emit_ext_op(ACQUIRE_OP); + acpigen_emit_namestring(mutex_path); + acpigen_emit_word(ACPI_MUTEX_NO_TIMEOUT); + } + /* Perform 1st Half of FLDR Flow for cold reset: FHRF (1) */ acpigen_emit_namestring("FHRF"); acpigen_emit_byte(RESET_TYPE_COLD); @@ -180,6 +251,12 @@ driver removal */ acpigen_emit_byte(INCREMENT_OP); acpigen_emit_namestring(acpi_device_path_join(parent_dev, "RTD3.OFSK")); + + if (rtd3_config->use_rp_mutex) { + /* Release root port mutex */ + acpigen_emit_ext_op(RELEASE_OP); + acpigen_emit_namestring(mutex_path); + } } acpigen_write_method_end(); /* Method */ } @@ -211,6 +288,7 @@ const struct drivers_wwan_fm_config *config = config_of(dev); const struct device *parent = dev->bus->dev; const char *scope = acpi_device_path(parent); + const struct soc_intel_common_block_pcie_rtd3_config *rtd3_config;
if (!is_dev_enabled(parent)) { printk(BIOS_ERR, "%s: root port not enabled\n", __func__); @@ -226,6 +304,11 @@ __func__, scope); return; } + + rtd3_config = config_of(config->rtd3dev); + if (!rtd3_config->use_rp_mutex) + printk(BIOS_WARNING, "%s: Need to use root port mutex from RTD3\n", __func__); + printk(BIOS_INFO, "%s: Enable WWAN for %s (%s)\n", scope, dev_path(parent), config->desc ?: dev->chip_ops->name); acpigen_write_scope(scope);