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>
This commit is contained in:
parent
4bc9ac7c29
commit
d1a74167a8
2 changed files with 62 additions and 0 deletions
|
|
@ -76,6 +76,12 @@ struct soc_intel_common_block_pcie_rtd3_config {
|
|||
*-----------------------------------------------------------------------------------*
|
||||
*/
|
||||
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__ */
|
||||
|
|
|
|||
|
|
@ -147,6 +147,13 @@ pcie_rtd3_acpi_method_on(unsigned int pcie_rp,
|
|||
{
|
||||
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 @@ pcie_rtd3_acpi_method_on(unsigned int pcie_rp,
|
|||
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 @@ pcie_rtd3_acpi_method_off(int pcie_rp,
|
|||
{
|
||||
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 @@ pcie_rtd3_acpi_method_off(int pcie_rp,
|
|||
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 @@ static void pcie_rtd3_acpi_fill_ssdt(const struct device *dev)
|
|||
|
||||
/* 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);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue