diff --git a/src/ec/google/chromeec/ec_commands.h b/src/ec/google/chromeec/ec_commands.h index 7c311a1f5a..7b1eeb23a2 100644 --- a/src/ec/google/chromeec/ec_commands.h +++ b/src/ec/google/chromeec/ec_commands.h @@ -5393,12 +5393,14 @@ enum ec_reboot_cmd { EC_REBOOT_HIBERNATE = 6, /* Hibernate EC */ EC_REBOOT_HIBERNATE_CLEAR_AP_OFF = 7, /* and clears AP_IDLE flag */ EC_REBOOT_COLD_AP_OFF = 8, /* Cold-reboot and don't boot AP */ + EC_REBOOT_NO_OP = 9, /* Do nothing but apply the flags. */ }; /* Flags for ec_params_reboot_ec.reboot_flags */ #define EC_REBOOT_FLAG_RESERVED0 BIT(0) /* Was recovery request */ #define EC_REBOOT_FLAG_ON_AP_SHUTDOWN BIT(1) /* Reboot after AP shutdown */ #define EC_REBOOT_FLAG_SWITCH_RW_SLOT BIT(2) /* Switch RW slot */ +#define EC_REBOOT_FLAG_CLEAR_AP_IDLE BIT(3) /* Clear AP_IDLE flag */ struct ec_params_reboot_ec { uint8_t cmd; /* enum ec_reboot_cmd */ diff --git a/src/mainboard/google/brya/Kconfig b/src/mainboard/google/brya/Kconfig index 78f0ad58f3..a7f459454a 100644 --- a/src/mainboard/google/brya/Kconfig +++ b/src/mainboard/google/brya/Kconfig @@ -61,6 +61,7 @@ config BOARD_GOOGLE_BASEBOARD_BRASK select SOC_INTEL_ALDERLAKE_PCH_P select SOC_INTEL_CSE_PRE_CPU_RESET_TELEMETRY select TPM_GOOGLE_CR50 + select CR50_RESET_CLEAR_EC_AP_IDLE_FLAG config BOARD_GOOGLE_BASEBOARD_NISSA def_bool n diff --git a/src/security/tpm/tss/vendor/cr50/Kconfig b/src/security/tpm/tss/vendor/cr50/Kconfig index 33a5cf3da1..6aa1b10550 100644 --- a/src/security/tpm/tss/vendor/cr50/Kconfig +++ b/src/security/tpm/tss/vendor/cr50/Kconfig @@ -40,4 +40,11 @@ config GOOGLE_TPM_IRQ_TIMEOUT_MS using Cr50 in order to support legacy pre-ready-IRQ cr50 factory images. Default to 750ms otherwise. +config CR50_RESET_CLEAR_EC_AP_IDLE_FLAG + def_bool n + help + Select this if the variant is a Chromebox/base. This allows AP to direct EC + to clear AP_IDLE flag after AP shutdown before triggering CR50 reset and + shutting down AP so that AP can boot up after CR50 reset. + endif diff --git a/src/vendorcode/google/chromeos/cr50_enable_update.c b/src/vendorcode/google/chromeos/cr50_enable_update.c index 6beea913ca..19f200605e 100644 --- a/src/vendorcode/google/chromeos/cr50_enable_update.c +++ b/src/vendorcode/google/chromeos/cr50_enable_update.c @@ -68,6 +68,19 @@ static int cr50_is_reset_needed(void) return 0; } +static void clear_ec_ap_idle(void) +{ + if (!CONFIG(CR50_RESET_CLEAR_EC_AP_IDLE_FLAG)) + return; + + /* Send EC command to clear AP_IDLE flag */ + if (!google_chromeec_reboot(EC_REBOOT_NO_OP, EC_REBOOT_FLAG_CLEAR_AP_IDLE | + EC_REBOOT_FLAG_ON_AP_SHUTDOWN)) + printk(BIOS_INFO, "Successfully clear AP_IDLE flag"); + else + printk(BIOS_ERR, "Failed to clear EC AP_IDLE flag"); +} + static void enable_update(void *unused) { int ret; @@ -156,8 +169,10 @@ static void enable_update(void *unused) } } - if (CONFIG(POWER_OFF_ON_CR50_UPDATE)) + if (CONFIG(POWER_OFF_ON_CR50_UPDATE)) { + clear_ec_ap_idle(); poweroff(); + } halt(); } BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_LOAD, BS_ON_ENTRY, enable_update, NULL);