summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYilun Lin <yllin@chromium.org>2019-11-06 17:10:04 +0800
committerCommit Bot <commit-bot@chromium.org>2019-12-17 08:29:21 +0000
commitd0057c5466b67610386ca18cf0eb401b938c60c5 (patch)
tree2dff42ad8d75b4eb587f8bffed5a73f141e3d7d1
parent5ec3b2791a405b18ff919bfd9a4283b1e03debda (diff)
downloadchrome-ec-d0057c5466b67610386ca18cf0eb401b938c60c5.tar.gz
baseboard/kukui: dynamic adjuct input current by thermal budget
Limit the charger input current if we are overheat, and loose the limit if the thermal in control. kukui/krane/kodama are suffering from thermal issue (>100 celsius degree in charger junction) and the solution was limit the system can only sink 5V/2A in S0. However, this cause slowing charging as well. We'd like to loose the 5V/2A charging limit and controls the thermal by restricting the charger input current. This CL only applies the limitation when PD voltage > 5V, because we don't see the overheat problem when krane charged with 5V. TEST=on krane, ensure the temperature of junction is always under 84 celsius degree; ensure the curve of battery current at charging is a smooth curve when PD voltage switching from high to low. BUG=b:141903096 b:144073892 BRANCH=kukui Change-Id: I9657f5a04897010d7018f910cb77b210147d8356 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/+/1899660 Reviewed-by: Ting Shen <phoenixshen@chromium.org>
-rw-r--r--baseboard/kukui/charger_mt6370.c111
-rw-r--r--baseboard/kukui/charger_mt6370.h8
-rw-r--r--board/kodama/board.c6
-rw-r--r--board/kukui/board.c6
4 files changed, 128 insertions, 3 deletions
diff --git a/baseboard/kukui/charger_mt6370.c b/baseboard/kukui/charger_mt6370.c
index 79da7a160a..2ad7627fd9 100644
--- a/baseboard/kukui/charger_mt6370.c
+++ b/baseboard/kukui/charger_mt6370.c
@@ -4,12 +4,14 @@
*/
#include "charge_manager.h"
+#include "charge_state_v2.h"
#include "charger_mt6370.h"
#include "console.h"
-#include "driver/tcpm/mt6370.h"
#include "driver/charger/rt946x.h"
+#include "driver/tcpm/mt6370.h"
#include "hooks.h"
#include "power.h"
+#include "timer.h"
#include "usb_common.h"
#include "usb_pd.h"
#include "util.h"
@@ -51,6 +53,15 @@ DECLARE_HOOK(HOOK_CHIPSET_RESUME, update_plt_resume, HOOK_PRIO_DEFAULT);
#define CPRINTS(format, args...) cprints(CC_CHARGER, format, ## args)
+/* wait time to evaluate charger thermal status */
+static timestamp_t thermal_wait_until;
+/* input current bound when charger throttled */
+static int throttled_ma = PD_MAX_CURRENT_MA;
+/* charge_ma in last board_set_charge_limit call */
+static int prev_charge_ma;
+/* charge_mv in last board_set_charge_limit call */
+static int prev_charge_mv;
+
#ifndef CONFIG_BATTERY_SMART
int board_cut_off_battery(void)
{
@@ -63,6 +74,91 @@ int board_cut_off_battery(void)
}
#endif
+static void board_set_charge_limit_throttle(int charge_ma, int charge_mv)
+{
+ charge_set_input_current_limit(
+ MIN(throttled_ma, MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT)),
+ charge_mv);
+}
+
+static void battery_thermal_control(struct charge_state_data *curr)
+{
+ int input_current, jc_temp;
+ static int skip_reset;
+ /*
+ * mt6370's input current setting is 50mA step, use 50 as well for
+ * easy value mapping.
+ */
+ const int k_p = 50;
+
+ if (charge_manager_get_charger_voltage() == 5000 ||
+ curr->state != ST_CHARGE) {
+ /* We already set the charge limit, do not reset it again. */
+ if (skip_reset)
+ return;
+ skip_reset = 1;
+ thermal_wait_until.val = 0;
+ throttled_ma = PD_MAX_CURRENT_MA;
+ board_set_charge_limit_throttle(prev_charge_ma, prev_charge_mv);
+ return;
+ }
+
+ skip_reset = 0;
+
+ if (thermal_wait_until.val == 0)
+ goto thermal_exit;
+
+ if (get_time().val < thermal_wait_until.val)
+ return;
+
+ /* If we fail to read adc, skip for this cycle. */
+ if (rt946x_get_adc(MT6370_ADC_TEMP_JC, &jc_temp))
+ return;
+
+ /* If we fail to read input curr limit, skip for this cycle. */
+ if (charger_get_input_current(&input_current))
+ return;
+
+ /*
+ * If input current limit is maximum, and we are under thermal budget,
+ * just skip.
+ */
+ if (input_current == PD_MAX_CURRENT_MA &&
+ jc_temp < thermal_bound.target + thermal_bound.err)
+ return;
+
+ /* If the temp is within +- err, thermal is under control */
+ if (jc_temp < thermal_bound.target + thermal_bound.err &&
+ jc_temp > thermal_bound.target - thermal_bound.err)
+ return;
+
+ /*
+ * PID algorithm (https://en.wikipedia.org/wiki/PID_controller),
+ * and operates on only P value.
+ */
+ throttled_ma =
+ MIN(PD_MAX_CURRENT_MA,
+ input_current + k_p * (thermal_bound.target - jc_temp));
+ board_set_charge_limit_throttle(throttled_ma, prev_charge_mv);
+
+thermal_exit:
+ thermal_wait_until.val = get_time().val + (3 * SECOND);
+}
+
+int command_jc(int argc, char **argv)
+{
+ static int prev_jc_temp;
+ int jc_temp;
+
+ if (rt946x_get_adc(MT6370_ADC_TEMP_JC, &jc_temp))
+ jc_temp = prev_jc_temp;
+
+ ccprintf("JC Temp: %d\n", jc_temp);
+ prev_jc_temp = jc_temp;
+ return EC_SUCCESS;
+}
+DECLARE_CONSOLE_COMMAND(jc, command_jc, "", "mt6370 junction temp");
+
/*
* 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
@@ -121,6 +217,12 @@ static void battery_desired_curr_dynamic(struct charge_state_data *curr)
charge_reset_stable_current_us(5 * MINUTE);
/* Rewrite the stable current to re-evalute desired watt */
charge_set_stable_current(prev_stable_current);
+
+ /*
+ * do not alter current by thermal if we just raising PD
+ * voltage
+ */
+ thermal_wait_until.val = get_time().val + (10 * SECOND);
} else {
pd_pref_config.mv = DEFAULT_PREFER_MV;
/*
@@ -148,6 +250,8 @@ void mt6370_charger_profile_override(struct charge_state_data *curr)
battery_desired_curr_dynamic(curr);
+ battery_thermal_control(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 &&
@@ -195,6 +299,7 @@ DECLARE_HOOK(HOOK_BATTERY_SOC_CHANGE,
void board_set_charge_limit(int port, int supplier, int charge_ma,
int max_ma, int charge_mv)
{
- charge_set_input_current_limit(
- MAX(charge_ma, CONFIG_CHARGER_INPUT_CURRENT), charge_mv);
+ prev_charge_ma = charge_ma;
+ prev_charge_mv = charge_mv;
+ board_set_charge_limit_throttle(charge_ma, charge_mv);
}
diff --git a/baseboard/kukui/charger_mt6370.h b/baseboard/kukui/charger_mt6370.h
index 9cf1b44d95..880b00a1a8 100644
--- a/baseboard/kukui/charger_mt6370.h
+++ b/baseboard/kukui/charger_mt6370.h
@@ -10,4 +10,12 @@
void mt6370_charger_profile_override(struct charge_state_data *curr);
+struct mt6370_thermal_bound {
+ /* mt6370 junction's thermal target in Celsius degree */
+ int target;
+ /* mt6370 junction's thermal evaluation error in Celsius degree */
+ int err;
+};
+
+extern struct mt6370_thermal_bound thermal_bound;
#endif
diff --git a/board/kodama/board.c b/board/kodama/board.c
index 7a221ace3d..bf6ec7dd84 100644
--- a/board/kodama/board.c
+++ b/board/kodama/board.c
@@ -10,6 +10,7 @@
#include "charge_ramp.h"
#include "charge_state.h"
#include "charger.h"
+#include "charger_mt6370.h"
#include "chipset.h"
#include "common.h"
#include "console.h"
@@ -97,6 +98,11 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
+struct mt6370_thermal_bound thermal_bound = {
+ .target = 75,
+ .err = 4,
+};
+
static void board_hpd_status(int port, int hpd_lvl, int hpd_irq)
{
/*
diff --git a/board/kukui/board.c b/board/kukui/board.c
index c3fc1fc9ce..8ff3e2cda0 100644
--- a/board/kukui/board.c
+++ b/board/kukui/board.c
@@ -10,6 +10,7 @@
#include "charge_ramp.h"
#include "charge_state.h"
#include "charger.h"
+#include "charger_mt6370.h"
#include "chipset.h"
#include "common.h"
#include "console.h"
@@ -103,6 +104,11 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
},
};
+struct mt6370_thermal_bound thermal_bound = {
+ .target = 80,
+ .err = 4,
+};
+
void board_set_dp_mux_control(int output_enable, int polarity)
{
if (board_get_version() >= 5)