summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWai-Hong Tam <waihong@google.com>2018-05-08 10:46:02 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-05-22 15:54:05 -0700
commit60b3b245c1667a5ebc42a5d6fcaec8b28d5a5ef7 (patch)
treeee7aa95cb5a282e879694b56d4b3d679c2bf929e
parentfc8b1ab52c6f5d556f91a3b8f4ce6a8ef437ae70 (diff)
downloadchrome-ec-60b3b245c1667a5ebc42a5d6fcaec8b28d5a5ef7.tar.gz
cheza: Check power enough and enable PP5000 when power-on AP
Remove the previous hack of force increasing the adapter current. The PP5000 rail is now turned on/off during power-on/off AP. Add a check to ensure it has enough power to enable the 5V rail and boot AP. If the battery is in low level or unplugged and the charger adapter doesn't supply enough power, don't boot AP and transition back to S5. The check may wait a while for PD negoiation. BRANCH=none BUG=b:79353631 TEST=On battery plugged and unplugged cases, checked the device can source VBUS to USB port-0 and port-1. TEST=Unplug battery and use a low-power adapter, can't boot up AP. See the "Not enough power to boot" message and transition to S5. Change-Id: Ie9b8dff6e10d97dffd554b382595e5e7a70875e6 Signed-off-by: Wai-Hong Tam <waihong@google.com> Reviewed-on: https://chromium-review.googlesource.com/1050607
-rw-r--r--board/cheza/board.c8
-rw-r--r--board/cheza/board.h2
-rw-r--r--board/cheza/gpio.inc8
-rw-r--r--power/sdm845.c51
4 files changed, 54 insertions, 15 deletions
diff --git a/board/cheza/board.c b/board/cheza/board.c
index d31dad343d..80039166ab 100644
--- a/board/cheza/board.c
+++ b/board/cheza/board.c
@@ -50,7 +50,6 @@ static void anx74xx_cable_det_interrupt(enum gpio_signal signal);
/* 8-bit I2C address */
#define DA9313_I2C_ADDR 0xd0
-#define CHARGER_I2C_ADDR 0x12
/* GPIO Interrupt Handlers */
static void tcpc_alert_event(enum gpio_signal signal)
@@ -234,13 +233,6 @@ static void board_init(void)
/* Enable BC1.2 interrupts */
gpio_enable_interrupt(GPIO_USB_C0_BC12_INT_L);
gpio_enable_interrupt(GPIO_USB_C1_BC12_INT_L);
-
- /*
- * Increase AdapterCurrentLimit{1,2} to max (6080mA)
- */
- i2c_write16(I2C_PORT_POWER, CHARGER_I2C_ADDR, 0x3B, 0x17c0);
- i2c_write16(I2C_PORT_POWER, CHARGER_I2C_ADDR, 0x3F, 0x17c0);
-
}
DECLARE_HOOK(HOOK_INIT, board_init, HOOK_PRIO_DEFAULT);
diff --git a/board/cheza/board.h b/board/cheza/board.h
index ad96a53d4c..f2d7b8fdd0 100644
--- a/board/cheza/board.h
+++ b/board/cheza/board.h
@@ -51,6 +51,7 @@
/* TODO(b/79163120): Use correct charger values, copied from Lux for rev-0 */
#define CONFIG_CHARGER_INPUT_CURRENT 512
#define CONFIG_CHARGER_MIN_BAT_PCT_FOR_POWER_ON 2
+#define CONFIG_CHARGER_MIN_POWER_MW_FOR_POWER_ON 7500
#define CONFIG_CHARGER_SENSE_RESISTOR 10
#define CONFIG_CHARGER_SENSE_RESISTOR_AC 20
@@ -97,6 +98,7 @@
#define CONFIG_CHIPSET_SDM845
#define CONFIG_CHIPSET_RESET_HOOK
#define CONFIG_POWER_COMMON
+#define CONFIG_POWER_PP5000_CONTROL
/* TODO(b/79348203): Enable EC hibernate */
#undef CONFIG_HIBERNATE
diff --git a/board/cheza/gpio.inc b/board/cheza/gpio.inc
index fec65254c0..84cea11804 100644
--- a/board/cheza/gpio.inc
+++ b/board/cheza/gpio.inc
@@ -48,13 +48,7 @@ GPIO(AP_EC_INT_L, PIN(A, 2), GPIO_INPUT) /* Interrupt line between
GPIO(SWITCHCAP_ON_L, PIN(D, 5), GPIO_OUT_HIGH) /* Enable switch cap. XXX: It's active-high */
GPIO(VBOB_EN, PIN(9, 5), GPIO_OUT_HIGH) /* Enable VBOB */
GPIO(EN_PP3300_A, PIN(A, 6), GPIO_OUT_HIGH) /* Enable PP3300 */
-/*
- * Before we have VBUS auto-detection, we hack to enable the BC1.2 switch,
- * for USB boot. Enabling PP5000 may cause power leak via VBUS (a USB device
- * may have a pullup on a data line) to block AP boot. Safer to disable PP5000.
- * TODO(waihong): Enable it when remove the BC1.2 hack.
- */
-GPIO(EN_PP5000_A, PIN(6, 7), GPIO_OUT_LOW) /* Enable PP5000 */
+GPIO(EN_PP5000, PIN(6, 7), GPIO_OUT_LOW) /* EN_PP5000_A: Enable PP5000 */
GPIO(BL_DISABLE_L, PIN(2, 6), GPIO_OUT_HIGH) /* EC_BL_DISABLE_L: Backlight disable signal from EC */
/* Sensors */
diff --git a/power/sdm845.c b/power/sdm845.c
index 24429c1f37..f6a22c54ae 100644
--- a/power/sdm845.c
+++ b/power/sdm845.c
@@ -22,6 +22,7 @@
* - If POWER_GOOD is dropped by the AP, then we power the AP off
*/
+#include "charge_state.h"
#include "chipset.h"
#include "common.h"
#include "gpio.h"
@@ -60,6 +61,12 @@
/* Wait for polling the AP on signal */
#define PMIC_POWER_AP_WAIT (1 * MSEC)
+/* The timeout of the check if the system can boot AP */
+#define CAN_BOOT_AP_CHECK_TIMEOUT (500 * MSEC)
+
+/* Wait for polling if the system can boot AP */
+#define CAN_BOOT_AP_CHECK_WAIT (100 * MSEC)
+
/* Delay between power-on the system and power-on the PMIC */
#define SYSTEM_POWER_ON_DELAY (10 * MSEC)
@@ -389,22 +396,66 @@ static void power_off(void)
/* Wait longer to ensure the PMIC/AP totally off */
usleep(SYSTEM_POWER_OFF_DELAY);
+ /* Turn off the 5V rail. */
+#ifdef CONFIG_POWER_PP5000_CONTROL
+ power_5v_enable(task_get_current(), 0);
+#else /* !defined(CONFIG_POWER_PP5000_CONTROL) */
+ gpio_set_level(GPIO_EN_PP5000, 0);
+#endif /* defined(CONFIG_POWER_PP5000_CONTROL) */
+
lid_opened = 0;
enable_sleep(SLEEP_MASK_AP_RUN);
CPRINTS("power shutdown complete");
}
/**
+ * Check if the power is enough to boot the AP.
+ */
+static int power_is_enough(void)
+{
+ timestamp_t poll_deadline;
+
+ /* If powered by adapter only, wait a while for PD negoiation. */
+ poll_deadline = get_time();
+ poll_deadline.val += CAN_BOOT_AP_CHECK_TIMEOUT;
+
+ /*
+ * Wait for PD negotiation. If a system with drained battery, don't
+ * waste the time and exit the loop.
+ */
+ while (!system_can_boot_ap() && !charge_want_shutdown() &&
+ get_time().val < poll_deadline.val) {
+ usleep(CAN_BOOT_AP_CHECK_WAIT);
+ }
+
+ return system_can_boot_ap() && !charge_want_shutdown();
+}
+
+/**
* Power on the AP
*/
static void power_on(void)
{
/*
+ * If no enough power, return and the state machine will transition
+ * back to S5.
+ */
+ if (!power_is_enough())
+ return;
+
+ /*
* When power_on() is called, we are at S5S3. Initialize components
* to ready state before AP is up.
*/
hook_notify(HOOK_CHIPSET_PRE_INIT);
+ /* Enable the 5V rail. */
+#ifdef CONFIG_POWER_PP5000_CONTROL
+ power_5v_enable(task_get_current(), 1);
+#else /* !defined(CONFIG_POWER_PP5000_CONTROL) */
+ gpio_set_level(GPIO_EN_PP5000, 1);
+#endif /* defined(CONFIG_POWER_PP5000_CONTROL) */
+
set_system_power(1);
usleep(SYSTEM_POWER_ON_DELAY);
set_pmic_pwron(1);