diff options
-rw-r--r-- | baseboard/kukui/battery_mm8013.c | 3 | ||||
-rw-r--r-- | baseboard/kukui/charger_mt6370.c | 122 |
2 files changed, 101 insertions, 24 deletions
diff --git a/baseboard/kukui/battery_mm8013.c b/baseboard/kukui/battery_mm8013.c index 5c22675703..e7f422e561 100644 --- a/baseboard/kukui/battery_mm8013.c +++ b/baseboard/kukui/battery_mm8013.c @@ -105,9 +105,6 @@ int charger_profile_override(struct charge_state_data *curr) } } - if (curr->state != ST_CHARGE) - return 0; - switch (temp_zone) { case TEMP_ZONE_0: case TEMP_ZONE_1: diff --git a/baseboard/kukui/charger_mt6370.c b/baseboard/kukui/charger_mt6370.c index ee5f9131db..79da7a160a 100644 --- a/baseboard/kukui/charger_mt6370.c +++ b/baseboard/kukui/charger_mt6370.c @@ -3,6 +3,7 @@ * found in the LICENSE file. */ +#include "charge_manager.h" #include "charger_mt6370.h" #include "console.h" #include "driver/tcpm/mt6370.h" @@ -15,9 +16,22 @@ #define BAT_LEVEL_PD_LIMIT 85 #define SYSTEM_PLT_MW 3500 +/* + * b/143318064: Prefer a voltage above 5V to force it picks a voltage + * above 5V at first. If PREFER_MV is 5V, when desired power is around + * 15W ~ 11W, it would pick 5V/3A initially, and mt6370 can only sink + * around 10W, and cause a low charging efficiency. + */ +#define PREVENT_CURRENT_DROP_MV 6000 +#define DEFAULT_PREFER_MV 5000 +/* + * We empirically chose 300mA as the limit for when buck inefficiency is + * noticeable. + */ +#define STABLE_CURRENT_DELTA 300 struct pd_pref_config_t pd_pref_config = { - .mv = 5000, + .mv = PREVENT_CURRENT_DROP_MV, .cv = 70, .plt_mw = SYSTEM_PLT_MW, .type = PD_PREFER_BUCK, @@ -49,25 +63,98 @@ int board_cut_off_battery(void) } #endif +/* + * b/143318064: A workwround for mt6370 bad buck efficiency. + * If the delta of VBUS and VBAT(on krane, desired voltage 4.4V) is too small + * (i.e. < 500mV), the buck throughput will be bounded, and causing that we + * can't drain 5V/3A when battery SoC above around 40%. + * This function watches battery current. If we see battery current drops after + * switching from high voltage to 5V (This will happen if we enable + * CONFIG_USB_PD_PREFER_MV and set prefer votage to 5V), the charger will lost + * power due to the inefficiency (e.g. switch from 9V/1.67A = 15W to 5V/3A, + * but mt6370 would only sink less than 5V/2.4A = 12W), and we will request a + * higher voltage PDO to prevent a slow charging time. + */ +static void battery_desired_curr_dynamic(struct charge_state_data *curr) +{ + static int prev_stable_current = CHARGE_CURRENT_UNINITIALIZED; + static int prev_supply_voltage; + int supply_voltage; + int stable_current; + int delta_current; + + if (curr->state != ST_CHARGE) { + prev_supply_voltage = 0; + prev_stable_current = CHARGE_CURRENT_UNINITIALIZED; + /* + * Always force higher voltage on first PD negotiation. + * When desired power is around 15W ~ 11W, PD would pick + * 5V/3A initially, but mt6370 can't drain that much, and + * causes a low charging efficiency. + */ + pd_pref_config.mv = PREVENT_CURRENT_DROP_MV; + return; + } + + supply_voltage = charge_manager_get_charger_voltage(); + stable_current = charge_get_stable_current(); + + if (stable_current == CHARGE_CURRENT_UNINITIALIZED) + return; + + if (!prev_supply_voltage) + goto update_charge; + + delta_current = prev_stable_current - stable_current; + if (curr->batt.state_of_charge >= pd_pref_config.cv && + supply_voltage == DEFAULT_PREFER_MV && + prev_supply_voltage > supply_voltage && + delta_current > STABLE_CURRENT_DELTA) { + /* Raise perfer voltage above 5000mV */ + pd_pref_config.mv = PREVENT_CURRENT_DROP_MV; + /* + * Delay stable current evaluation for 5 mins if we see a + * current drop. It's a reasonable waiting time since that + * the battery desired current can't catch the gap that fast + * in the period. + */ + charge_reset_stable_current_us(5 * MINUTE); + /* Rewrite the stable current to re-evalute desired watt */ + charge_set_stable_current(prev_stable_current); + } else { + pd_pref_config.mv = DEFAULT_PREFER_MV; + /* + * If the power supply is plugged while battery full, + * the stable_current will always be 0 such that we are unable + * to switch to 5V. We force evaluating PDO to switch to 5V. + */ + if (prev_supply_voltage == supply_voltage && !stable_current && + !prev_stable_current && + supply_voltage != DEFAULT_PREFER_MV && + charge_manager_get_supplier() == CHARGE_SUPPLIER_PD) + pd_set_new_power_request( + charge_manager_get_active_charge_port()); + } + +update_charge: + prev_supply_voltage = supply_voltage; + prev_stable_current = stable_current; +} + void mt6370_charger_profile_override(struct charge_state_data *curr) { static int previous_chg_limit_mv; - int chg_limit_mv; + int chg_limit_mv = pd_get_max_voltage(); + + battery_desired_curr_dynamic(curr); /* Limit input (=VBUS) to 5V when soc > 85% and charge current < 1A. */ if (!(curr->batt.flags & BATT_FLAG_BAD_CURRENT) && - charge_get_percent() > BAT_LEVEL_PD_LIMIT && - curr->batt.current < 1000) { + charge_get_percent() > BAT_LEVEL_PD_LIMIT && + curr->batt.current < 1000 && power_get_state() != POWER_S0) chg_limit_mv = 5500; - } else if (power_get_state() == POWER_S0) { - /* - * b/134227872: limit power to 5V/2A in S0 to prevent - * overheat - */ - chg_limit_mv = 5500; - } else { + else chg_limit_mv = PD_MAX_VOLTAGE_MV; - } if (chg_limit_mv != previous_chg_limit_mv) CPRINTS("VBUS limited to %dmV", chg_limit_mv); @@ -108,13 +195,6 @@ DECLARE_HOOK(HOOK_BATTERY_SOC_CHANGE, void board_set_charge_limit(int port, int supplier, int charge_ma, int max_ma, int charge_mv) { - /* b/134227872: Limit input current to 2A in S0 to prevent overheat */ - if (power_get_state() == POWER_S0) - charge_set_input_current_limit( - MIN(charge_ma, RT946X_AICR_TYP2MAX(2000)), - charge_mv); - else - charge_set_input_current_limit( - MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT), - charge_mv); + charge_set_input_current_limit( + MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT), charge_mv); } |