summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNico Huber <nico.huber@secunet.com>2021-06-15 17:19:10 +0200
committerWerner Zeh <werner.zeh@siemens.com>2021-06-17 05:46:49 +0000
commitdca081b5e6c7bfdba991d625c36141c01baad513 (patch)
tree06d2ed903d125c1a54a32badb8fd2d4fdbbafa7f
parent85c9dda1c4446163e4d01ef5defab3a415751107 (diff)
soc/intel/common/pmc: Avoid unnecessary writes of AFTERG3_EN
pmc_set_power_failure_state() is usually called twice, once upon boot (with `target_on == true`) and once from SMM when the system is shut down (with `target_on == false`). Assuming settings didn't change between these calls, there is only one case where we actually need to write the register value: when updating the state for the MAINBOARD_POWER_STATE_PREVIOUS feature. This suits us well as we want to avoid unnecessary writes so we don't clobber the value set upon boot from within SMM. Due to inaccessible option backends, SMM might not know the current option state. The assumption above, that the option value didn't change, may not be true if the user changed the option on purpose. In the future, one would have to reboot the machine for option changes to take effect. However, this doesn't seem to make a huge difference: One already needed a controlled shutdown for the update to take effect before. A reboot doesn't seem much more expensive. Change-Id: I58dd74b8b073f4f07db090bf7fddb14b5df8239a Signed-off-by: Nico Huber <nico.huber@secunet.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/55539 Reviewed-by: Angel Pons <th3fanbus@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r--src/soc/intel/common/block/pmc/pmclib.c23
1 files changed, 15 insertions, 8 deletions
diff --git a/src/soc/intel/common/block/pmc/pmclib.c b/src/soc/intel/common/block/pmc/pmclib.c
index aa5b3621f1..d3a21a17fd 100644
--- a/src/soc/intel/common/block/pmc/pmclib.c
+++ b/src/soc/intel/common/block/pmc/pmclib.c
@@ -581,31 +581,38 @@ void pmc_gpe_init(void)
void pmc_set_power_failure_state(const bool target_on)
{
- bool on;
-
const unsigned int state = get_uint_option("power_on_after_fail",
CONFIG_MAINBOARD_POWER_FAILURE_STATE);
+ /*
+ * On the shutdown path (target_on == false), we only need to
+ * update the register for MAINBOARD_POWER_STATE_PREVIOUS. For
+ * all other cases, we don't write the register to avoid clob-
+ * bering the value set on the boot path. This is necessary,
+ * for instance, when we can't access the option backend in SMM.
+ */
+
switch (state) {
case MAINBOARD_POWER_STATE_OFF:
+ if (!target_on)
+ break;
printk(BIOS_INFO, "Set power off after power failure.\n");
- on = false;
+ pmc_soc_set_afterg3_en(false);
break;
case MAINBOARD_POWER_STATE_ON:
+ if (!target_on)
+ break;
printk(BIOS_INFO, "Set power on after power failure.\n");
- on = true;
+ pmc_soc_set_afterg3_en(true);
break;
case MAINBOARD_POWER_STATE_PREVIOUS:
printk(BIOS_INFO, "Keep power state after power failure.\n");
- on = target_on;
+ pmc_soc_set_afterg3_en(target_on);
break;
default:
printk(BIOS_WARNING, "WARNING: Unknown power-failure state: %d\n", state);
- on = false;
break;
}
-
- pmc_soc_set_afterg3_en(on);
}
/* This function returns the highest assertion duration of the SLP_Sx assertion widths */