diff options
-rw-r--r-- | common/build.mk | 1 | ||||
-rw-r--r-- | common/charge_state_v2.c | 46 | ||||
-rw-r--r-- | include/config.h | 8 | ||||
-rw-r--r-- | include/throttle_ap.h | 4 |
4 files changed, 56 insertions, 3 deletions
diff --git a/common/build.mk b/common/build.mk index 1a0f27e5bf..d64288b5ff 100644 --- a/common/build.mk +++ b/common/build.mk @@ -109,6 +109,7 @@ common-$(CONFIG_TABLET_MODE)+=tablet_mode.o common-$(CONFIG_TEMP_SENSOR)+=temp_sensor.o common-$(CONFIG_THROTTLE_AP)+=thermal.o throttle_ap.o common-$(CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT)+=throttle_ap.o +common-$(CONFIG_THROTTLE_AP_ON_BAT_VOLTAGE)+=throttle_ap.o common-$(CONFIG_TPM_I2CS)+=i2cs_tpm.o common-$(CONFIG_TPM_LOGGING)+=event_log.o tpm_log.o common-$(CONFIG_U2F)+=u2f.o diff --git a/common/charge_state_v2.c b/common/charge_state_v2.c index f237e84bc1..28ec48c3b0 100644 --- a/common/charge_state_v2.c +++ b/common/charge_state_v2.c @@ -55,6 +55,14 @@ (BAT_MAX_DISCHG_CURRENT * BAT_OCP_HYSTERESIS_PCT / 100) /* mA */ #endif /* CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT */ +#ifdef CONFIG_THROTTLE_AP_ON_BAT_VOLTAGE +#ifndef CONFIG_HOSTCMD_EVENTS +#error "CONFIG_THROTTLE_AP_ON_BAT_VOLTAGE needs CONFIG_HOSTCMD_EVENTS" +#endif /* CONFIG_HOSTCMD_EVENTS */ +#define BAT_UVP_TIMEOUT_US (60 * SECOND) +static timestamp_t uvp_throttle_start_time; +#endif /* CONFIG_THROTTLE_AP_ON_BAT_OLTAGE */ + static int charge_request(int voltage, int current); /* @@ -1320,7 +1328,7 @@ static int shutdown_on_critical_battery(void) * host events. We send these even if the AP is off, since the AP will read and * discard any events it doesn't care about the next time it wakes up. */ -static void notify_host_of_low_battery(void) +static void notify_host_of_low_battery_charge(void) { /* We can't tell what the current charge is. Assume it's okay. */ if (curr.batt.flags & BATT_FLAG_BAD_STATE_OF_CHARGE) @@ -1343,6 +1351,29 @@ static void set_charge_state(enum charge_state_v2 state) curr.state = state; } +static void notify_host_of_low_battery_voltage(void) +{ +#ifdef CONFIG_THROTTLE_AP_ON_BAT_VOLTAGE + if ((curr.batt.flags & BATT_FLAG_BAD_VOLTAGE) || + chipset_in_state(CHIPSET_STATE_ANY_OFF)) + return; + + if (curr.batt.voltage < BAT_LOW_VOLTAGE_THRESH) { + if (!uvp_throttle_start_time.val) { + throttle_ap(THROTTLE_ON, THROTTLE_SOFT, + THROTTLE_SRC_BAT_VOLTAGE); + } + uvp_throttle_start_time = get_time(); + } else if (uvp_throttle_start_time.val && + (get_time().val > uvp_throttle_start_time.val + + BAT_UVP_TIMEOUT_US)) { + throttle_ap(THROTTLE_OFF, THROTTLE_SOFT, + THROTTLE_SRC_BAT_VOLTAGE); + uvp_throttle_start_time.val = 0; + } +#endif +} + static void notify_host_of_over_current(struct batt_params *batt) { #ifdef CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT @@ -1400,6 +1431,16 @@ DECLARE_HOOK(HOOK_AC_CHANGE, charge_wakeup, HOOK_PRIO_DEFAULT); DECLARE_HOOK(HOOK_CHIPSET_STARTUP, board_base_reset, HOOK_PRIO_DEFAULT); #endif +#ifdef CONFIG_THROTTLE_AP_ON_BAT_VOLTAGE +static void bat_low_voltage_throttle_reset(void) +{ + uvp_throttle_start_time.val = 0; +} +DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, + bat_low_voltage_throttle_reset, + HOOK_PRIO_DEFAULT); +#endif + static int get_desired_input_current(enum battery_present batt_present, const struct charger_info * const info) { @@ -1702,7 +1743,8 @@ wait_for_it: /* Wait on the dynamic info until the static info is good. */ if (!need_static) update_dynamic_battery_info(); - notify_host_of_low_battery(); + notify_host_of_low_battery_charge(); + notify_host_of_low_battery_voltage(); /* And the EC console */ is_full = calc_is_full(); diff --git a/include/config.h b/include/config.h index 4511fb39ea..3264ffa195 100644 --- a/include/config.h +++ b/include/config.h @@ -2634,6 +2634,14 @@ #undef CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT /* + * Throttle the CPU when battery voltage drops below a defined threshold + * where the board still boots but some components don't function perfectly. + * When this feature is enabled, BAT_LOW_VOLTAGE_THRESH must be defined in + * board.h. + */ +#undef CONFIG_THROTTLE_AP_ON_BAT_VOLTAGE + +/* * If defined, dptf is enabled to manage thermals. * * NOTE: This doesn't mean that thermal control is completely taken care by diff --git a/include/throttle_ap.h b/include/throttle_ap.h index db651c432e..a149207667 100644 --- a/include/throttle_ap.h +++ b/include/throttle_ap.h @@ -31,6 +31,7 @@ enum throttle_type { enum throttle_sources { THROTTLE_SRC_THERMAL = 0, THROTTLE_SRC_BAT_DISCHG_CURRENT, + THROTTLE_SRC_BAT_VOLTAGE, }; /** @@ -44,7 +45,8 @@ enum throttle_sources { * @param source Which task is requesting throttling */ #if defined(CONFIG_THROTTLE_AP) || \ - defined(CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT) + defined(CONFIG_THROTTLE_AP_ON_BAT_DISCHG_CURRENT) || \ + defined(CONFIG_THROTTLE_AP_ON_BAT_VOLTAGE) void throttle_ap(enum throttle_level level, enum throttle_type type, |