soc/intel/cmn/pmc: Add support for early power off

This commit adds support for early power off on Intel platforms
along with existing PMC based implementation to support power off
at later stage (like ramstage).

A new function, `platform_do_early_poweroff`, is added to the
pmclib to handle platform-specific early power off procedures.
This function is called before memory initialization (in romstage or
earlier).

Note: While Intel chipsets do not support power off before silicon
initialization, this change leverages Chrome EC APIs to enable power off
in romstage for low-battery boot on ChromeOS devices. Power off failures
in ramstage prior to FSP-S are outside the scope of this change.

BUG=b:339673254
TEST=Able to build and boot google/brox.

Change-Id: I39f516640b3f75ab4c6a09826922289c0533f79b
Signed-off-by: Subrata Banik <subratabanik@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/86336
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Karthik Ramasubramanian <kramasub@google.com>
Reviewed-by: Julius Werner <jwerner@chromium.org>
This commit is contained in:
Subrata Banik 2025-02-14 09:42:22 +00:00
commit 0fe338c88b

View file

@ -15,6 +15,7 @@
#include <intelblocks/gpio.h>
#include <intelblocks/tco.h>
#include <option.h>
#include <reset.h>
#include <security/vboot/vboot_common.h>
#include <soc/pci_devs.h>
#include <soc/pm.h>
@ -615,7 +616,8 @@ void vboot_platform_prepare_reboot(void)
pmc_write_pm1_control(pm1_cnt);
}
void poweroff(void)
/* Helper function to perform poweroff operation using PMC chipset register. */
static void pmc_control_poweroff(void)
{
pmc_enable_pm1_control(SLP_EN | (SLP_TYP_S5 << SLP_TYP_SHIFT));
@ -628,6 +630,19 @@ void poweroff(void)
halt();
}
void poweroff(void)
{
if (!ENV_ROMSTAGE_OR_BEFORE) {
pmc_control_poweroff();
} else if (CONFIG(HAVE_EARLY_POWEROFF_SUPPORT)) {
platform_do_early_poweroff();
} else {
printk(BIOS_EMERG, "This platform cannot be powered off until the silicon"
" initialization is complete, hanging!\n");
halt();
}
}
void pmc_gpe_init(void)
{
uint32_t gpio_cfg = 0;