diff options
author | Sam Hurst <shurst@google.com> | 2020-03-24 16:46:14 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-04-02 09:40:09 +0000 |
commit | 28f07760f384789a6a28801c0c42d9d61af2f99b (patch) | |
tree | 6a3b98e52fa4fa3d49909be781df1c7f77c92a45 /common/usb_pd_dual_role.c | |
parent | f648164f18293a2b3e2c5e0b766a8edef787ee9d (diff) | |
download | chrome-ec-28f07760f384789a6a28801c0c42d9d61af2f99b.tar.gz |
TCPMv2: Restore PD state after Sysjump
When a PD explicit contract is negotiated in RO,
the contract is maintained while performing a
sysjump to RW. This is done by serializing
the PD Power, Data, and VCONN Roles, along with
the explicit contract flag. After jumping to RW,
deserialization is performed by restoring the
power roles and setting the explicit contract
flag.
BUG=b:152350558,b:152027807,b:152967274
BRANCH=none
TEST=make -j buildall
Manual tests:
Used total phase to verify that charging voltage
was maintained across sysjump from RO to RW and
that DP was reestablished when a dock was used.
Tested that Kohaku booted properly without a
battery and a charger connected to port 0. This
test was repeated with a charger connected to port 1.
Signed-off-by: Sam Hurst <shurst@google.com>
Change-Id: I349c41f2279e9af9830564d44ac73ad8435f1f80
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2119131
Tested-by: Sam Hurst <shurst@google.com>
Reviewed-by: Denis Brockus <dbrockus@chromium.org>
Commit-Queue: Denis Brockus <dbrockus@chromium.org>
Diffstat (limited to 'common/usb_pd_dual_role.c')
-rw-r--r-- | common/usb_pd_dual_role.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/common/usb_pd_dual_role.c b/common/usb_pd_dual_role.c index 73e56f30eb..a424555b26 100644 --- a/common/usb_pd_dual_role.c +++ b/common/usb_pd_dual_role.c @@ -7,6 +7,7 @@ #include "charge_manager.h" #include "charge_state.h" +#include "system.h" #include "usb_common.h" #include "usb_pd.h" #include "util.h" @@ -391,3 +392,47 @@ bool pd_is_try_source_capable(void) return new_try_src; } #endif /* CONFIG_USB_PD_TRY_SRC */ + +static int get_bbram_idx(uint8_t port) +{ + if (port < MAX_SYSTEM_BBRAM_IDX_PD_PORTS) + return (port + SYSTEM_BBRAM_IDX_PD0); + + return -1; +} + +int pd_get_saved_port_flags(int port, uint8_t *flags) +{ + if (system_get_bbram(get_bbram_idx(port), flags) != EC_SUCCESS) { +#ifndef CHIP_HOST + ccprintf("PD NVRAM FAIL"); +#endif + return EC_ERROR_UNKNOWN; + } + + return EC_SUCCESS; +} + +static void pd_set_saved_port_flags(int port, uint8_t flags) +{ + if (system_set_bbram(get_bbram_idx(port), flags) != EC_SUCCESS) { +#ifndef CHIP_HOST + ccprintf("PD NVRAM FAIL"); +#endif + } +} + +void pd_update_saved_port_flags(int port, uint8_t flag, uint8_t do_set) +{ + uint8_t saved_flags; + + if (pd_get_saved_port_flags(port, &saved_flags) != EC_SUCCESS) + return; + + if (do_set) + saved_flags |= flag; + else + saved_flags &= ~flag; + + pd_set_saved_port_flags(port, saved_flags); +} |