diff --git a/src/mainboard/google/bluey/board.h b/src/mainboard/google/bluey/board.h index a4e0d31ce7..47515c605f 100644 --- a/src/mainboard/google/bluey/board.h +++ b/src/mainboard/google/bluey/board.h @@ -4,6 +4,7 @@ #define MAINBOARD_GOOGLE_BLUEY_BOARD_H #include +#include #include #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 */ diff --git a/src/mainboard/google/bluey/charging.c b/src/mainboard/google/bluey/charging.c index 596891e514..c5cf30ce8c 100644 --- a/src/mainboard/google/bluey/charging.c +++ b/src/mainboard/google/bluey/charging.c @@ -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; +} diff --git a/src/mainboard/google/bluey/mainboard.c b/src/mainboard/google/bluey/mainboard.c index 7f78fb0f0b..2090c3a782 100644 --- a/src/mainboard/google/bluey/mainboard.c +++ b/src/mainboard/google/bluey/mainboard.c @@ -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. diff --git a/src/mainboard/google/bluey/romstage.c b/src/mainboard/google/bluey/romstage.c index 3b63839d87..26e9a0fd72 100644 --- a/src/mainboard/google/bluey/romstage.c +++ b/src/mainboard/google/bluey/romstage.c @@ -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();