summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Hill <ecgh@chromium.org>2018-09-13 10:35:13 -0600
committerchrome-bot <chrome-bot@chromium.org>2018-09-17 21:34:40 -0700
commitaf25bde7900421a439260720752818da5a67915c (patch)
treec51cdfc1a8f382f243f1709d94692a4caff8b6ca
parente3b4438f26ba24d3bb97345da8717225436bbe0a (diff)
downloadchrome-ec-af25bde7900421a439260720752818da5a67915c.tar.gz
pd: Ensure TCPC exits low power mode
Ensure the TCPC is awake when leaving PD_STATE_DRP_AUTO_TOGGLE and when there is a new PD event to handle. Move the exit_low_power_mode() call from the PD_STATE_DRP_AUTO_TOGGLE case statement into set_state(), to catch all possible paths that exit the state. Add a new exit_low_power_mode() call to the top of the main task loop if there is a new event to handle. This allows the exit_low_power_mode() call to be removed from pd_update_dual_role_config() (since PD_EVENT_UPDATE_DUAL_ROLE is included in PD_EXIT_LOW_POWER_EVENT_MASK). Clear PD_FLAGS_LPM_REQUESTED when PD_FLAGS_LPM_ENGAGED is cleared in handle_device_access() and wake the PD task to ensure we will make another pass through the main task loop (and check the CC lines) before deciding to enter low power mode again. BRANCH=none BUG=b:111663127,b:112039224 TEST=PD and TCPC low power still work on Grunt Change-Id: I99063ce0d02af65de74f4c6f73f7a15600d2eac9 Signed-off-by: Edward Hill <ecgh@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1225352 Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com> Reviewed-by: Jett Rink <jettrink@chromium.org>
-rw-r--r--common/usb_pd_protocol.c27
-rw-r--r--include/usb_pd.h7
2 files changed, 22 insertions, 12 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c
index b77087e6f0..eddb310ce4 100644
--- a/common/usb_pd_protocol.c
+++ b/common/usb_pd_protocol.c
@@ -374,8 +374,14 @@ static void handle_device_access(int port)
pd[port].low_power_time = get_time().val + PD_LPM_DEBOUNCE_US;
if (pd[port].flags & PD_FLAGS_LPM_ENGAGED) {
- CPRINTS("TCPC p%d Exited Low Power Mode via bus access", port);
- pd[port].flags &= ~PD_FLAGS_LPM_ENGAGED;
+ CPRINTS("TCPC p%d Exit Low Power Mode", port);
+ pd[port].flags &= ~(PD_FLAGS_LPM_ENGAGED |
+ PD_FLAGS_LPM_REQUESTED);
+ /*
+ * Wake to ensure we make another pass through the main task
+ * loop after clearing the flags.
+ */
+ task_wake(PD_PORT_TO_TASK_ID(port));
}
}
@@ -560,6 +566,11 @@ static inline void set_state(int port, enum pd_states next_state)
if (last_state == next_state)
return;
+#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
+ if (next_state != PD_STATE_DRP_AUTO_TOGGLE)
+ exit_low_power_mode(port);
+#endif
+
#ifdef CONFIG_USB_PD_DUAL_ROLE
#ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE
/* Clear flag to allow DRP auto toggle when possible */
@@ -2129,11 +2140,6 @@ static void pd_update_dual_role_config(int port)
set_state(port, PD_STATE_SRC_DISCONNECTED);
tcpm_set_cc(port, TYPEC_CC_RP);
}
-
-#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
- /* When switching drp mode, make sure tcpc is out of standby mode */
- exit_low_power_mode(port);
-#endif
}
int pd_get_role(int port)
@@ -2598,6 +2604,8 @@ void pd_task(void *u)
evt = task_wait_event(timeout);
#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
+ if (evt & PD_EXIT_LOW_POWER_EVENT_MASK)
+ exit_low_power_mode(port);
if (evt & PD_EVENT_DEVICE_ACCESSED)
handle_device_access(port);
#endif
@@ -3817,11 +3825,6 @@ void pd_task(void *u)
/* Anything else, keep toggling */
next_state = PD_STATE_DRP_AUTO_TOGGLE;
-#ifdef CONFIG_USB_PD_TCPC_LOW_POWER
- if (next_state != PD_STATE_DRP_AUTO_TOGGLE)
- exit_low_power_mode(port);
-#endif
-
if (next_state == PD_STATE_SNK_DISCONNECTED) {
tcpm_set_cc(port, TYPEC_CC_RD);
pd_set_power_role(port, PD_ROLE_SINK);
diff --git a/include/usb_pd.h b/include/usb_pd.h
index 29299b8acf..76970cb044 100644
--- a/include/usb_pd.h
+++ b/include/usb_pd.h
@@ -49,6 +49,13 @@ enum pd_rx_errors {
#define PD_EVENT_DEVICE_ACCESSED (1<<7)
#define PD_EVENT_POWER_STATE_CHANGE (1<<8) /* Chipset power state changed */
+/* Ensure TCPC is out of low power mode before handling these events. */
+#define PD_EXIT_LOW_POWER_EVENT_MASK \
+ (PD_EVENT_CC | \
+ PD_EVENT_UPDATE_DUAL_ROLE | \
+ PD_EVENT_POWER_STATE_CHANGE | \
+ TASK_EVENT_WAKE)
+
/* --- PD data message helpers --- */
#define PDO_MAX_OBJECTS 7
#define PDO_MODES (PDO_MAX_OBJECTS - 1)