mb/google/bluey: Implement slow-to-fast charging transition logic

Update the charging flow to support a transition from slow charging
to fast charging based on the battery threshold.

Key changes:
- Pass boot_mode to launch_charger_applet() to allow mode-specific
  power management.
- In LB_BOOT_MODE_LOW_BATTERY_CHARGING, if the battery is above the
  critical threshold, issue an AP power-off to trigger a transition
  from slow to fast charging mode.
- Update handle_low_power_charging_boot() to default to slow charging
  for low-battery charging boots.

BUG=b:497622018
TEST=Verified Bluey correctly switches from slow charging to fast
charging once critical battery threshold is exceeded.

Change-Id: Ic65ab99360496c92a91795fce1352159066ab94e
Signed-off-by: Subrata Banik <subratabanik@google.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/91912
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Kapil Porwal <kapilporwal@google.com>
This commit is contained in:
Subrata Banik 2026-03-30 13:54:09 +05:30
commit eda62af9dd
4 changed files with 65 additions and 12 deletions

View file

@ -4,6 +4,7 @@
#define MAINBOARD_GOOGLE_BLUEY_BOARD_H
#include <assert.h>
#include <commonlib/coreboot_tables.h>
#include <gpio.h>
#define GPIO_AP_EC_INT GPIO(67)
@ -66,6 +67,7 @@ void configure_dam_on_system_state_change(bool poweron);
void enable_slow_battery_charging(void);
void disable_slow_battery_charging(void);
void launch_charger_applet(void);
bool platform_get_battery_soc_information(uint32_t *batt_pct);
void enable_fast_battery_charging(void);
#endif /* MAINBOARD_GOOGLE_BLUEY_BOARD_H */

View file

@ -61,6 +61,7 @@
#define DELAY_CHARGING_APPLET_MS 2000 /* 2sec */
#define CHARGING_RAIL_STABILIZATION_DELAY_MS 3000 /* 3sec */
#define LOW_BATTERY_CHARGING_LOOP_EXIT_MS (10 * 60 * 1000) /* 10min */
#define DELAY_CHARGING_ACTIVE_LB_MS 4000 /* 4sec */
enum charging_status {
@ -162,6 +163,7 @@ void launch_charger_applet(void)
static const long charging_enable_timeout_ms = CHARGING_RAIL_STABILIZATION_DELAY_MS;
struct stopwatch sw;
bool has_crossed_threshold = false;
bool has_entered_low_battery_mode = false;
printk(BIOS_INFO, "Inside %s. Initiating charging\n", __func__);
@ -191,10 +193,37 @@ void launch_charger_applet(void)
}
printk(BIOS_INFO, "Charging ready after %lld ms\n", stopwatch_duration_msecs(&sw));
static const long low_battery_charging_timeout_ms = LOW_BATTERY_CHARGING_LOOP_EXIT_MS;
uint32_t batt_pct;
if (!platform_get_battery_soc_information(&batt_pct)) {
printk(BIOS_WARNING, "Failed to get battery level\n");
return;
}
/*
* If the battery is at 0%, enter low-battery charging mode and
* start a timeout timer to prevent getting stuck in a dead-loop
* if the battery fails to charge.
*
* FIXME: b/497622018
*/
if (!batt_pct) {
has_entered_low_battery_mode = true;
stopwatch_init_msecs_expire(&sw, low_battery_charging_timeout_ms);
}
do {
/* Add static delay before reading the charging applet pre-requisites */
mdelay(DELAY_CHARGING_APPLET_MS);
if (has_entered_low_battery_mode) {
if (stopwatch_expired(&sw)) {
printk(BIOS_INFO, "Issuing power-off as switching from slow charging "
"to fast charging mode.\n");
configure_dam_on_system_state_change(false);
google_chromeec_ap_poweroff();
}
}
/*
* Issue a shutdown if not charging.
*/
@ -328,3 +357,14 @@ void enable_fast_battery_charging(void)
printk(BIOS_ERR, "LPASS bring-up failed; skipping fast charging.\n");
}
}
bool platform_get_battery_soc_information(uint32_t *batt_pct)
{
if (!CONFIG(EC_GOOGLE_CHROMEEC))
return false;
if (google_chromeec_read_batt_state_of_charge(batt_pct))
return false;
return true;
}

View file

@ -192,7 +192,22 @@ static void handle_low_power_charging_boot(void)
if (!pll_init_and_set(apss_ncc0, L_VAL_710P4MHz))
printk(BIOS_DEBUG, "CPU Frequency set to 710MHz\n");
enable_fast_battery_charging();
uint32_t batt_pct;
if (!platform_get_battery_soc_information(&batt_pct)) {
printk(BIOS_WARNING, "Failed to get battery level\n");
return;
}
/*
* Use slow charging for a completely depleted battery (0% SoC)
* to ensure stability; otherwise, enable fast charging.
*
* FIXME: b/497622018
*/
if (!batt_pct)
enable_slow_battery_charging();
else
enable_fast_battery_charging();
/*
* Disable the lightbar for Low-Battery or Off-Mode charging sequences.

View file

@ -105,15 +105,6 @@ int qclib_mainboard_override(struct qclib_cb_if_table *table)
return 0;
}
static void platform_dump_battery_soc_information(void)
{
uint32_t batt_pct;
if (google_chromeec_read_batt_state_of_charge(&batt_pct))
printk(BIOS_WARNING, "Failed to get battery level\n");
else
printk(BIOS_INFO, "Battery state-of-charge %d%%\n", batt_pct);
}
static void early_setup_usb_typec(void)
{
gpio_output(GPIO_USB_C1_RETIMER_RESET_L, 0);
@ -158,8 +149,13 @@ void platform_romstage_main(void)
/* Watchdog must be checked first to avoid erasing watchdog info later. */
check_wdog();
if (CONFIG(EC_GOOGLE_CHROMEEC) && CONFIG(CONSOLE_SERIAL))
platform_dump_battery_soc_information();
if (CONFIG(EC_GOOGLE_CHROMEEC) && CONFIG(CONSOLE_SERIAL)) {
uint32_t batt_pct;
if (platform_get_battery_soc_information(&batt_pct))
printk(BIOS_INFO, "Battery state-of-charge %d%%\n", batt_pct);
else
printk(BIOS_WARNING, "Failed to get battery level\n");
}
if (!qclib_check_dload_mode())
shrm_fw_load_reset();