summaryrefslogtreecommitdiff
path: root/board/fizz
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2018-02-02 17:37:19 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-02-08 01:23:59 -0800
commitbb5f21ed1a773dcfa58e8482918c60521e00b538 (patch)
tree512fdb8cc22ef7d333b47fdf515f54705b5e0a1f /board/fizz
parent131b7dcc44e6b1918ce8872e1e0eeaf221920dd5 (diff)
downloadchrome-ec-bb5f21ed1a773dcfa58e8482918c60521e00b538.tar.gz
Fizz: Monitor input current (version 2.0)
Fizz has three FETs connected to three registers: PR257, PR258, PR7824. These control the thresholds of the current monitoring system. PR257 PR7824 PR258 For BJ (65W or 90W) off off off For 4.35A (87W) on off off For 3.25A (65W) off off on For 3.00A (60W) off on off The system power consumption is capped by PR259, which is stuffed differently depending on the SKU (65W v.s. 90W or U42 v.s. U22). So, we only need to monitor type-c adapters. For example: a 90W system powered by 65W type-c charger b 65W system powered by 60W type-c charger c 65W system powered by 87W type-c charger In a case such as (c), we actually do not need to monitor the current because the max is capped by PR259. AP is expected to read type-c adapter wattage from EC and control power consumption to avoid over-current or system browns out. The current monitoring system doesn't support less than 3A (e.g. 2.25A, 2.00A). These currents most likely won't be enough to power the system. However, if they're needed, EC can monitor PMON_PSYS and trigger H_PROCHOT by itself. BUG=b:72883633,b:64442692,b:72710630 BRANCH=none TEST=Boot Fizz on 60W/87W/BJ charger. Verify GPIOs are set as expected. Change-Id: Ic4c0e599f94b24b5e6c02bbf1998b0b89ecad7bf Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/900491 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
Diffstat (limited to 'board/fizz')
-rw-r--r--board/fizz/board.c113
-rw-r--r--board/fizz/gpio.inc5
-rw-r--r--board/fizz/usb_pd_policy.c64
3 files changed, 100 insertions, 82 deletions
diff --git a/board/fizz/board.c b/board/fizz/board.c
index 2861ee5fbe..6bbaf25e70 100644
--- a/board/fizz/board.c
+++ b/board/fizz/board.c
@@ -92,21 +92,14 @@ static void adp_in_deferred(void)
if (!level) {
/* BJ is inserted but the voltage isn't effective because PU3
* is still disabled. */
- pi.voltage = 19000;
- if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) {
- /* If type-c voltage is higher than BJ voltage, PU3 will
- * shut down due to reverse current protection. So, we
- * need to lower the voltage first. */
- if (charge_manager_get_charger_voltage() > pi.voltage) {
- pd_set_external_voltage_limit(
- CHARGE_PORT_TYPEC0, pi.voltage);
- hook_call_deferred(&adp_in_deferred_data,
- ADP_DEBOUNCE_MS * MSEC);
- return;
- }
- /* Set it to the default. Will be updated by AP. */
+ pi.voltage = 19500;
+ if (chipset_in_state(CHIPSET_STATE_ANY_OFF))
+ /*
+ * It doesn't matter what we set here because we'll
+ * brown out anyway when charge_manager switches
+ * input.
+ */
pi.current = 3330;
- }
}
charge_manager_update_charge(CHARGE_SUPPLIER_DEDICATED,
DEDICATED_CHARGE_PORT, &pi);
@@ -469,16 +462,15 @@ static void board_init(void)
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
-void board_set_charge_limit(int port, int supplier, int charge_ma,
- int max_ma, int charge_mv)
-{
- /* Turn on/off power shortage alert. Performs the same check as
- * system_can_boot_ap(). It's repeated here because charge_manager
- * hasn't updated charge_current/voltage when board_set_charge_limit
- * is called. */
- led_alert(charge_ma * charge_mv <
- CONFIG_CHARGER_LIMIT_POWER_THRESH_CHG_MW * 1000);
+/* Mapping to the old schematics */
+#define GPIO_U42_P GPIO_TYPE_C_60W
+#define GPIO_U22_C GPIO_TYPE_C_65W
+/*
+ * Board version 2.1 or before uses a different current monitoring circuitry.
+ */
+static void set_charge_limit(int charge_ma)
+{
/*
* We have two FETs connected to two registers: PR257 & PR258.
* These control thresholds of the over current monitoring system.
@@ -508,6 +500,81 @@ void board_set_charge_limit(int port, int supplier, int charge_ma,
}
}
+void board_set_charge_limit(int port, int supplier, int charge_ma,
+ int max_ma, int charge_mv)
+{
+ uint32_t brd_ver = 0;
+ int p87w = 0, p65w = 0, p60w = 0;
+
+ /*
+ * Turn on/off power shortage alert. Performs the same check as
+ * system_can_boot_ap(). It's repeated here because charge_manager
+ * hasn't updated charge_current/voltage when board_set_charge_limit
+ * is called.
+ */
+ led_alert(charge_ma * charge_mv <
+ CONFIG_CHARGER_LIMIT_POWER_THRESH_CHG_MW * 1000);
+
+ /*
+ * In terms of timing, this should always work because
+ * HOOK_PRIO_CHARGE_MANAGER_INIT is notified after HOOK_PRIO_INIT_I2C.
+ * If CBI isn't initialized or contains invalid data, we assume it's
+ * a new board.
+ */
+ if (cbi_get_board_version(&brd_ver) == EC_SUCCESS && brd_ver < 0x0202)
+ return set_charge_limit(charge_ma);
+ /*
+ * We have three FETs connected to three registers: PR257, PR258,
+ * PR7824. These control the thresholds of the current monitoring
+ * system.
+ *
+ * PR257 PR7824 PR258
+ * For BJ (65W or 90W) off off off
+ * For 4.35A (87W) on off off
+ * For 3.25A (65W) off off on
+ * For 3.00A (60W) off on off
+ *
+ * The system power consumption is capped by PR259, which is stuffed
+ * differently depending on the SKU (65W v.s. 90W or U42 v.s. U22).
+ * So, we only need to monitor type-c adapters. For example:
+ *
+ * a 90W system powered by 65W type-c charger
+ * b 65W system powered by 60W type-c charger
+ * c 65W system powered by 87W type-c charger
+ *
+ * In a case such as (c), we actually do not need to monitor the current
+ * because the max is capped by PR259.
+ *
+ * AP is expected to read type-c adapter wattage from EC and control
+ * power consumption to avoid over-current or system browns out.
+ *
+ */
+ if (supplier != CHARGE_SUPPLIER_DEDICATED) {
+ /* Apple 87W charger offers 4.3A @20V. */
+ if (charge_ma >= 4300) {
+ p87w = 1;
+ } else if (charge_ma >= 3250) {
+ p65w = 1;
+ } else if (charge_ma >= 3000) {
+ p60w = 1;
+ } else {
+ /*
+ * TODO:http://crosbug.com/p/65013352.
+ * The current monitoring system doesn't support lower
+ * current. These currents are most likely not enough to
+ * power the system. However, if they're needed, EC can
+ * monitor PMON_PSYS and trigger H_PROCHOT by itself.
+ */
+ p60w = 1;
+ CPRINTS("Current %dmA not supported", charge_ma);
+ }
+ }
+
+ gpio_set_level(GPIO_TYPE_C_87W, p87w);
+ gpio_set_level(GPIO_TYPE_C_65W, p65w);
+ gpio_set_level(GPIO_TYPE_C_60W, p60w);
+}
+
enum battery_present battery_is_present(void)
{
/* The GPIO is low when the battery is present */
diff --git a/board/fizz/gpio.inc b/board/fizz/gpio.inc
index f28d550e84..716cc35c7f 100644
--- a/board/fizz/gpio.inc
+++ b/board/fizz/gpio.inc
@@ -40,8 +40,9 @@ GPIO(CCD_MODE_ODL, PIN(6, 3), GPIO_INPUT) /* Case Closed Debug Mode */
GPIO(EC_HAVEN_RESET_ODL, PIN(0, 2), GPIO_ODR_HIGH) /* H1 Reset */
GPIO(ENTERING_RW, PIN(7, 6), GPIO_OUTPUT) /* EC Entering RW */
GPIO(PMIC_INT_L, PIN(6, 0), GPIO_INPUT) /* PMIC interrupt */
-GPIO(U42_P, PIN(3, 3), GPIO_OUTPUT | GPIO_PULL_DOWN)
-GPIO(U22_C, PIN(3, 4), GPIO_OUTPUT | GPIO_PULL_DOWN)
+GPIO(TYPE_C_60W, PIN(3, 3), GPIO_OUTPUT | GPIO_PULL_DOWN)
+GPIO(TYPE_C_65W, PIN(3, 4), GPIO_OUTPUT | GPIO_PULL_DOWN)
+GPIO(TYPE_C_87W, PIN(4, 4), GPIO_OUTPUT | GPIO_PULL_DOWN)
GPIO(POWER_RATE, PIN(7, 1), GPIO_INPUT) /* High: i3/5/7. Low: Celeron */
/* Fizz specific pins */
diff --git a/board/fizz/usb_pd_policy.c b/board/fizz/usb_pd_policy.c
index 1d87c7eb75..3a607c50d1 100644
--- a/board/fizz/usb_pd_policy.c
+++ b/board/fizz/usb_pd_policy.c
@@ -218,29 +218,6 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload,
return 0;
}
-#define CHARGE_PORT_SYSJUMP_TAG 0x4350 /* "CP" - Charge Port */
-#define CHARGE_PORT_HOOK_VERSION 1
-
-static int restore_active_charge_port(struct charge_port_info *cpi)
-{
- int version, size;
- const struct charge_port_info *prev;
-
- if (!(system_get_reset_flags() & RESET_FLAG_SYSJUMP))
- return EC_ERROR_UNCHANGED;
-
- prev = (const struct charge_port_info *)system_get_jump_tag(
- CHARGE_PORT_SYSJUMP_TAG, &version, &size);
- if (!prev || version != CHARGE_PORT_HOOK_VERSION ||
- size != sizeof(*prev))
- return EC_ERROR_INVAL;
-
- cpi->current = prev->current;
- cpi->voltage = prev->voltage;
-
- return EC_SUCCESS;
-}
-
/*
* Since fizz has no battery, it must source all of its power from either
* USB-C or the barrel jack (preferred). Fizz operates in continuous safe
@@ -274,14 +251,8 @@ static void board_charge_manager_init(void)
typec_set_input_current_limit(port, 3000, 5000);
break;
case CHARGE_PORT_BARRELJACK:
- /* TODO: Once transition from GPIO to CBI completes, get BJ
- * adapter info locally. No need to save & restore it. */
- if (restore_active_charge_port(&cpi)) {
- /* Set it to the default. Will be updated by AP. */
- CPRINTS("Previous charge info not found. Use default.");
- cpi.voltage = 19000;
- cpi.current = 3330;
- }
+ cpi.voltage = 19500;
+ cpi.current = 3330;
charge_manager_update_charge(CHARGE_SUPPLIER_DEDICATED,
DEDICATED_CHARGE_PORT, &cpi);
break;
@@ -290,24 +261,6 @@ static void board_charge_manager_init(void)
DECLARE_HOOK(HOOK_INIT, board_charge_manager_init,
HOOK_PRIO_CHARGE_MANAGER_INIT + 1);
-static void preserve_active_charge_port(void)
-{
- struct charge_port_info cpi;
-
- /* If it's not a dedicated charge port, we don't bother. Saving &
- * restoring PD charger info is a much bigger problem. */
- if (charge_manager_get_active_charge_port() != DEDICATED_CHARGE_PORT)
- return;
- cpi.current = charge_manager_get_charger_current();
- cpi.voltage = charge_manager_get_charger_voltage();
- CPRINTS("Saving charge port info: %dmA %dmV", cpi.current, cpi.voltage);
- cflush();
-
- system_add_jump_tag(CHARGE_PORT_SYSJUMP_TAG, CHARGE_PORT_HOOK_VERSION,
- sizeof(cpi), &cpi);
-}
-DECLARE_HOOK(HOOK_SYSJUMP, preserve_active_charge_port, HOOK_PRIO_DEFAULT);
-
int board_set_active_charge_port(int port)
{
const int active_port = charge_manager_get_active_charge_port();
@@ -326,6 +279,7 @@ int board_set_active_charge_port(int port)
switch (port) {
case CHARGE_PORT_TYPEC0:
+ /* This is connected to TP on board version 2.2+ thus no-op */
gpio_set_level(GPIO_USB_C0_CHARGE_L, 0);
gpio_set_level(GPIO_AC_JACK_CHARGE_L, 1);
gpio_enable_interrupt(GPIO_ADP_IN_L);
@@ -334,15 +288,11 @@ int board_set_active_charge_port(int port)
/* Make sure BJ adapter is sourcing power */
if (gpio_get_level(GPIO_ADP_IN_L))
return EC_ERROR_INVAL;
+ /* This will cause brown out when switching from type-c on
+ * board version 2.2+ thus the rest of the code is no-op. */
gpio_set_level(GPIO_AC_JACK_CHARGE_L, 0);
- /* If this is switching from type-c to BJ, we have to wait until
- * PU3 comes up to keep the system continuously powered.
- * NX20P5090 datasheet says turn-on time for 20V is 29 msec. */
- if (active_port == CHARGE_PORT_TYPEC0)
- msleep(30);
- /* We don't check type-c voltage here. If it's higher than
- * BJ voltage, we'll brown out due to the reverse current
- * protection of PU3. */
+ /* If type-c voltage > BJ voltage, we'll brown out due to the
+ * reverse current protection of PU3 but it's intended. */
gpio_set_level(GPIO_USB_C0_CHARGE_L, 1);
gpio_disable_interrupt(GPIO_ADP_IN_L);
break;