Felix Held has submitted this change. ( https://review.coreboot.org/c/coreboot/+/61353 )
Change subject: soc/intel/common/block/pcie/rtd3: Add optional _OFF and _ON skip control ......................................................................
soc/intel/common/block/pcie/rtd3: Add optional _OFF and _ON skip control
- Optional feature to provide mechanism to skip _OFF and _On execution. - It is used for the device to skip _OFF and _ON during device driver reload. - OFSK is used to skip _OFF Method at the end of device driver removal. - ONSK is used to skip _ON Method at the beginning of driver loading. - General flow use case: 1. Device driver is removed by 'rmmod' command. 2. Device _RST is called. _RST perform reset. 3. Device increments OFSK in _RST to skip the following _OFF invoked by OSPM. 4. OSPM invokes _OFF at the end of driver removal. 5. _OFF sees OFSK and skips current execution and decrements OFSK so that _OFF will be executed normally next time. 6. _OFF increments ONSK to skip the following _ON invoked by OSPM. 7. Device driver is reloaded by 'insmod/modprobe' command. 8. OSPM invokes _ON at the beginning of driver loading. 9. _ON sees ONSK and skip current execution and decrements ONSK so that _ON will be executed normally next time.
- In normal case: When suspend, OSPM invokes _OFF. Since OFSK is zero, the device goes to deeper state as expected.
When resume, OSPM invokes _ON. Sinc ONSK is zero, the device goes to active state as expected.
- Generated changes:
PowerResource (RTD3, 0x00, 0x0000) Name (ONSK, Zero) Name (OFSK, Zero) ...
Method (_ON, 0, Serialized) // _ON_: Power On { If ((ONSK == Zero)) { ... } Else { ONSK-- } }
Method (_OFF, 0, Serialized) // _OFF: Power Off { If ((OFSK == Zero)) { ... } Else { OFSK-- ONSK++ } }
Test: Enable and verify OFSK and ONSK Name objects and the if-condition logic inside _OFF and _ON methods is added.
Signed-off-by: Cliff Huang cliff.huang@intel.com Change-Id: Ic32d151d65107bfc220258c383a575e40a496b6f Reviewed-on: https://review.coreboot.org/c/coreboot/+/61353 Tested-by: build bot (Jenkins) no-reply@coreboot.org Reviewed-by: Tim Wawrzynczak twawrzynczak@chromium.org --- M src/soc/intel/common/block/pcie/rtd3/chip.h M src/soc/intel/common/block/pcie/rtd3/rtd3.c 2 files changed, 62 insertions(+), 0 deletions(-)
Approvals: build bot (Jenkins): Verified Tim Wawrzynczak: Looks good to me, approved
diff --git a/src/soc/intel/common/block/pcie/rtd3/chip.h b/src/soc/intel/common/block/pcie/rtd3/chip.h index 7541bc3..652aaff 100644 --- a/src/soc/intel/common/block/pcie/rtd3/chip.h +++ b/src/soc/intel/common/block/pcie/rtd3/chip.h @@ -76,6 +76,12 @@ *-----------------------------------------------------------------------------------* */ enum acpi_pcie_rp_pm_emit ext_pm_support; + + /* + * Add support to skip _OFF and _ON execution when needed, such as reloading + * the device driver. + */ + bool skip_on_off_support; };
#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 260aa65..8a9b068 100644 --- a/src/soc/intel/common/block/pcie/rtd3/rtd3.c +++ b/src/soc/intel/common/block/pcie/rtd3/rtd3.c @@ -147,6 +147,13 @@ { acpigen_write_method_serialized("_ON", 0);
+ /* When this feature is enabled, ONSK indicates if the previous _OFF was + * skipped. If so, since the device was not in Off state, and the current + * _ON can be skipped as well. + */ + if (config->skip_on_off_support) + acpigen_write_if_lequal_namestr_int("ONSK", 0); + /* Disable modPHY power gating for PCH RPs. */ if (rp_type == PCIE_RP_PCH) pcie_rtd3_enable_modphy_pg(pcie_rp, PG_DISABLE); @@ -173,6 +180,16 @@ if (!config->disable_l23) pcie_rtd3_acpi_l23_exit();
+ 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. + */ + acpigen_write_else(); + acpigen_emit_byte(DECREMENT_OP); + acpigen_emit_namestring("ONSK"); + + acpigen_pop_len(); /* Else */ + } acpigen_pop_len(); /* Method */ }
@@ -183,6 +200,14 @@ { acpigen_write_method_serialized("_OFF", 0);
+ /* When this feature is enabled, ONSK is checked to see if the device + * wants _OFF to be skipped for once. ONSK is normally incremented in the + * device method, such as reset _RST, which is invoked during driver reload. + * In such case, _OFF needs to be avoided at the end of driver removal. + */ + if (config->skip_on_off_support) + acpigen_write_if_lequal_namestr_int("OFSK", 0); + /* Trigger L23 ready entry flow unless disabled by config. */ if (!config->disable_l23) pcie_rtd3_acpi_l23_entry(); @@ -209,6 +234,22 @@ acpigen_write_sleep(config->enable_off_delay_ms); }
+ 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 + * so that next _OFF will be executed normally until the device method + * increments OFSK again. + */ + acpigen_write_else(); + /* OFSK-- */ + acpigen_emit_byte(DECREMENT_OP); + acpigen_emit_namestring("OFSK"); + /* ONSK++ */ + acpigen_emit_byte(INCREMENT_OP); + acpigen_emit_namestring("ONSK"); + + acpigen_pop_len(); /* Else */ + } acpigen_pop_len(); /* Method */ }
@@ -391,6 +432,21 @@
/* ACPI Power Resource for controlling the attached device power. */ acpigen_write_power_res("RTD3", 0, 0, power_res_states, ARRAY_SIZE(power_res_states)); + + if (config->skip_on_off_support) { + /* OFSK: 0 = _OFF Method will be executed normally when called; + * >1 = _OFF will be skipped. + * _OFF Method to decrement OFSK and increment ONSK if the + * current execution is skipped. + * ONSK: 0 = _ON Method will be executed normally when called; + * >1 = _ONF will be skipped. + * _ON Method to decrement ONSK if the current execution is + * skipped. + */ + acpigen_write_name_integer("ONSK", 0); + acpigen_write_name_integer("OFSK", 0); + } + pcie_rtd3_acpi_method_status(config); pcie_rtd3_acpi_method_on(pcie_rp, config, rp_type); pcie_rtd3_acpi_method_off(pcie_rp, config, rp_type);