summaryrefslogtreecommitdiff
path: root/power
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 /power
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
Diffstat (limited to 'power')
-rw-r--r--power/sdm845.c51
1 files changed, 51 insertions, 0 deletions
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);