diff options
author | Alec Berg <alecaberg@chromium.org> | 2015-10-27 14:20:03 -0700 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2015-10-30 13:09:32 -0700 |
commit | e080de3c488063773c37ac89829996edd5506a49 (patch) | |
tree | 8a99d68be177ca50ec6e18a1472dba4dfa2b6061 | |
parent | 49d4254bd40a81b8f37014400bf5a50e7e581e4d (diff) | |
download | chrome-ec-e080de3c488063773c37ac89829996edd5506a49.tar.gz |
pd: add more power improvements to PD task
Added more improvements to power consumption when using
CONFIG_USB_PD_LOW_POWER. On the TCPC, when this option is
defined, then decrease the PD task wake interval when
we are presenting Rd, we don't have a connection, AND we
haven't dual-role toggled recently. This shouldn't affect
connection time because we will get an interrupt when VBUS
is detected.
Note: we can't use the low power task wake interval when
we are connected because we need to monitor CC line for
Rp change and we can't do this when we are presenting Rp
because we need to quickly detect loss of Rd.
BUG=chrome-os-partner:45010
BRANCH=none
TEST=tested on glados. verified we connect to a charger in
S0 and S5. and verified that in S5, we spend >99% of our
time in deepsleep (as measured by idlestats console command).
note, that when testing EC and PD must both define
CONFIG_USB_PD_LOW_POWER to get maximum power improvements.
Change-Id: I661110cc7021f6d17937688787ea4f5f4b82973d
Signed-off-by: Alec Berg <alecaberg@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/309310
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | common/usb_pd_protocol.c | 4 | ||||
-rw-r--r-- | common/usb_pd_tcpc.c | 42 |
2 files changed, 43 insertions, 3 deletions
diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 4cc0e0259a..fc063d24b9 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -1952,8 +1952,8 @@ void pd_task(void) break; case PD_STATE_SNK_DISCONNECTED: #ifdef CONFIG_USB_PD_LOW_POWER - timeout = drp_state == PD_DRP_TOGGLE_OFF ? MINUTE - : 10*MSEC; + timeout = drp_state != PD_DRP_TOGGLE_ON ? SECOND + : 10*MSEC; #else timeout = 10*MSEC; #endif diff --git a/common/usb_pd_tcpc.c b/common/usb_pd_tcpc.c index 99867e338a..0b13fb2c77 100644 --- a/common/usb_pd_tcpc.c +++ b/common/usb_pd_tcpc.c @@ -198,6 +198,14 @@ enum pd_tx_errors { }; /* + * If TCPM is not on this chip, and PD low power is defined, then use low + * power task delay logic. + */ +#if !defined(CONFIG_USB_POWER_DELIVERY) && defined(CONFIG_USB_PD_LOW_POWER) +#define TCPC_LOW_POWER +#endif + +/* * Receive message buffer size. Buffer physical size is RX_BUFFER_SIZE + 1, * but only RX_BUFFER_SIZE of that memory is used to store messages that can * be retrieved from TCPM. The last slot is a temporary buffer for collecting @@ -229,6 +237,11 @@ static struct pd_port_controller { uint8_t power_status; uint8_t power_status_mask; +#ifdef TCPC_LOW_POWER + /* Timestamp beyond which we allow low power task sampling */ + timestamp_t low_power_ts; +#endif + /* Last received */ int rx_head[RX_BUFFER_SIZE+1]; uint32_t rx_payload[RX_BUFFER_SIZE+1][7]; @@ -821,8 +834,21 @@ int tcpc_run(int port, int evt) if (pd[port].rx_enabled) pd_rx_enable_monitoring(port); - /* TODO: adjust timeout based on how often to sample CC */ +#ifdef TCPC_LOW_POWER + /* + * If we are presenting Rd with no connection, and timestamp is + * past the low power timestamp, then we don't need to sample + * CC lines as often. In this case, our connection delay should not + * actually increased because we will get an interrupt on VBUS detect. + */ + return (get_time().val >= pd[port].low_power_ts.val && + pd[port].cc_pull == TYPEC_CC_RD && + pd[port].cc_status[0] == TYPEC_CC_VOLT_OPEN && + pd[port].cc_status[1] == TYPEC_CC_VOLT_OPEN) ? 200 * MSEC : + 10 * MSEC; +#else return 10*MSEC; +#endif } #ifndef CONFIG_USB_POWER_DELIVERY @@ -906,6 +932,16 @@ int tcpc_set_cc(int port, int pull) pd_set_host_mode(port, pull == TYPEC_CC_RP); #endif +#ifdef TCPC_LOW_POWER + /* + * Reset the low power timestamp every time CC termination toggles, + * because we only want to go into low power mode when we are not + * dual-role toggling. + */ + pd[port].low_power_ts.val = get_time().val + + 2*(PD_T_DRP_SRC + PD_T_DRP_SNK); +#endif + /* * Before CC pull can be changed and the task can read the new * status, we should set the CC status to open, in case TCPM @@ -1050,6 +1086,10 @@ void tcpc_init(int port) pd_hw_init(port, PD_ROLE_DEFAULT); pd[port].cc_pull = PD_ROLE_DEFAULT == PD_ROLE_SOURCE ? TYPEC_CC_RP : TYPEC_CC_RD; +#ifdef TCPC_LOW_POWER + /* Don't use low power immediately after boot */ + pd[port].low_power_ts.val = get_time().val + SECOND; +#endif /* make sure PD monitoring is disabled initially */ pd[port].rx_enabled = 0; |