summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Huang <derekhuang@google.com>2022-12-15 07:27:41 +0000
committerSubrata Banik <subratabanik@google.com>2023-01-10 09:33:47 +0000
commitda3812208ea24f9438b7631374d22fc3ccee14bd (patch)
treecbeca7f258d412fc6c8b18a0928475ecea38282a
parentb3ebf5ba0b8113b67fcf0e0c884abd1494acc20b (diff)
chromeos/cr50_enable_update.c: Clear EC AP_IDLE flag
When AP boots up after Cr50 firmware update and reboot, AP finds that Cr50 reset is required for Cr50 to pick the new firmware so it trigger Cr50 reset and power off the system, AP expects system will power on automatically after Cr50 reset. However this is not the case for Chromebox, Chromebox EC set AP_IDLE flag when system is shutting down, when AP_IDLE flag is set in EC, the system stays at S5/G3 and wait for power button presssend. It cause an issue in factory that the operator needs to press power button to power on the DUT after Cr50 firmware update. This patch sends EC command to direct EC to clear AP_IDLE flag after AP shutdown so AP can boot up when Cr50 reset. BUG=b:261119366 BRANCH=firmware-brya-14505.B TEST=DUT boots up after Cr50 firmware update in factory test flow Change-Id: If97ffbe65f4783f17f4747a87b0bf89a2b021a3b Signed-off-by: Derek Huang <derekhuang@google.com> Reviewed-on: https://review.coreboot.org/c/coreboot/+/70773 Reviewed-by: Subrata Banik <subratabanik@google.com> Reviewed-by: Eric Lai <eric_lai@quanta.corp-partner.google.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
-rw-r--r--src/ec/google/chromeec/ec_commands.h2
-rw-r--r--src/mainboard/google/brya/Kconfig1
-rw-r--r--src/security/tpm/tss/vendor/cr50/Kconfig7
-rw-r--r--src/vendorcode/google/chromeos/cr50_enable_update.c17
4 files changed, 26 insertions, 1 deletions
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);