summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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);
}