mb/google/bluey: Implement graceful critical battery shutdown

When a critical battery level is detected without a charger present,
the system must shutdown to protect the battery from deep discharge.
Previously, this was an immediate power-off with minimal feedback.

This patch improves the shutdown sequence by:
1.  Adding trigger_critical_battery_shutdown() to encapsulate the
    safety logic.
2.  Providing visual feedback by setting the ChromeOS LED to Red
    during early boot flow (at romstage) for user feedback..
3.  Logging an ELOG_TYPE_LOW_BATTERY_INDICATOR event to the event log
    for post-mortem analysis.
4.  Introducing a 5-second delay before power-off to ensure UART
    logs are flushed and the user can observe the LED alert.

The shutdown logic remains in ramstage to ensure the user is able to
see the low-battery notification before powering off the system.

TEST=Boot Bluey with battery < critical threshold and no charger:
- Observed LED turning Red.
- Observed "Critical battery level..." warning in serial log.
- System powered off after 5 seconds.
- Verified 'cbmem -l' showed the low battery event after next boot.

Change-Id: I52948eac87417bca895000cb10dbaa87bb6a9384
Signed-off-by: Subrata Banik <subratabanik@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/90850
Reviewed-by: Kapil Porwal <kapilporwal@google.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
Subrata Banik 2026-01-28 10:05:55 +00:00
commit 3c9077cb81
2 changed files with 33 additions and 0 deletions

View file

@ -11,6 +11,7 @@
#include <device/device.h>
#include <device/i2c_simple.h>
#include <ec/google/chromeec/ec.h>
#include <elog.h>
#include <gpio.h>
#include <soc/clock.h>
#include <soc/pcie.h>
@ -29,6 +30,8 @@
#define USB3_MODE_NORMAL_VAL 0x21
#define USB3_MODE_FLIP_VAL 0x23
#define LOW_BATTERY_SHUTDOWN_DELAY_SEC 5
void mainboard_usb_typec_configure(uint8_t port_num, bool inverse_polarity)
{
if (!CONFIG(MAINBOARD_HAS_PS8820_RETIMER))
@ -149,12 +152,38 @@ static void display_startup(void)
enable_mdss_clk();
}
static void trigger_critical_battery_shutdown(void)
{
printk(BIOS_WARNING, "Critical battery level detected without charger! Shutting down.\n");
if (!CONFIG(EC_GOOGLE_CHROMEEC))
return;
/* Set LED to Red to alert the user visually */
google_chromeec_set_lightbar_rgb(0xff, 0xff, 0x00, 0x00);
/* Log the event to CMOS/Flash for post-mortem analysis */
elog_add_event_byte(ELOG_TYPE_LOW_BATTERY_INDICATOR, ELOG_FW_ISSUE_SHUTDOWN);
/* Allow time for the log to flush and the user to see the LED change */
delay(LOW_BATTERY_SHUTDOWN_DELAY_SEC);
google_chromeec_ap_poweroff();
}
static void mainboard_init(struct device *dev)
{
configure_parallel_charging();
display_startup();
/*
* Low-battery boot indicator is done. Therefore, power off if battery
* is critical and not charging
*/
if (get_boot_mode() == LB_BOOT_MODE_LOW_BATTERY)
trigger_critical_battery_shutdown();
/* Skip mainboard initialization if boot mode is "low-battery" or "off-mode charging"*/
if (is_low_power_boot_with_charger())
return;

View file

@ -109,6 +109,10 @@ static void early_setup_usb(void)
void platform_romstage_main(void)
{
/* Set LED to Red to alert the user visually */
if (CONFIG(EC_GOOGLE_CHROMEEC) && google_chromeec_is_critically_low_on_battery())
google_chromeec_set_lightbar_rgb(0xff, 0xff, 0x00, 0x00);
/* Setup early USB related config */
early_setup_usb();