diff options
author | Yilun Lin <yllin@chromium.org> | 2019-11-22 15:59:47 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-12-17 08:29:18 +0000 |
commit | a2804b7cc86962a28ede119cda23ea1d13d49922 (patch) | |
tree | 61540774ee57638b315fcb864dd8e825388da4e4 | |
parent | c0fac86829c4bf0345c568584f3ab1a981866595 (diff) | |
download | chrome-ec-a2804b7cc86962a28ede119cda23ea1d13d49922.tar.gz |
baseboard/kukui: request high voltage PDO if battery current drops
Request a higher voltage PDO (> 5V), when we requested 5V PDO and
seeing a battery charging current drop.
Ideally, when CONFIG_USB_PD_PREFER_MV enabled, the system will
request 5V/3A PDO when system desired power under 15W. However,
mt6370 has bad bulking efficiency and stops itself from sinking
more power (only sink under around 11W). The bad bulking efficiency
is getting worse if the gap between VBUS and VBAT getting closer.
To overcome this, we need to watch the battery charging current when
we switch to 5V. If we see a current drop after that, this means
we are suffering the bulking issue, and slows down the charging.
In this time, we will request a high voltage PDO by setting
PD_PREFER_MV above 5000. After request a new PDO, It will attempts to
switch to 5V in a few seconds or minutes, and see if we are still
suffering the issue.
TEST=1. When there is a battery current drop while switching from 9V to
5V, PD can switch back to 9V.
2. When no battery current drop while switching from 9V to 5V, PD
won't switch back
3. ensure that pd_task can request 9V when board_get_desired_power()
is between 15W and 11W.
BUG=b:143318064 b:141903096 b:144073892
BRANCH=kukui
Change-Id: I6c2c0c948c417b81e70ca6c6d360b89b941f3888
Signed-off-by: Yilun Lin <yllin@chromium.org>
Signed-off-by: Eric Yilun Lin <yllin@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1899659
Reviewed-by: Ting Shen <phoenixshen@chromium.org>
-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); } |