summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYilun Lin <yllin@chromium.org>2019-11-22 15:59:47 +0800
committerCommit Bot <commit-bot@chromium.org>2019-12-17 08:29:18 +0000
commita2804b7cc86962a28ede119cda23ea1d13d49922 (patch)
tree61540774ee57638b315fcb864dd8e825388da4e4
parentc0fac86829c4bf0345c568584f3ab1a981866595 (diff)
downloadchrome-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.c3
-rw-r--r--baseboard/kukui/charger_mt6370.c122
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);
}