diff options
author | Shawn Nematbakhsh <shawnn@chromium.org> | 2017-02-15 17:06:37 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-02-25 14:23:20 -0800 |
commit | 23bc38414ade30fb3e72ae8beefb657b47ca8288 (patch) | |
tree | a3bd50f2e039cee14e71a453190b4daaa5fc61c2 | |
parent | b7f8d9df654945827d6a21332e140ddecb8bdd1b (diff) | |
download | chrome-ec-23bc38414ade30fb3e72ae8beefb657b47ca8288.tar.gz |
pd: Store PD active state in battery-backed memory
Our previous idea to cut Rd for many reset cases cannot work if cr50
consistently resets the EC by asserting the reset pin shortly after
power-on. Therefore, make a decision based upon whether battery-backed
memory indicates we previously negotiated a PD power contract as a sink.
If we previously did not negotiate a contract, or if power was removed
from the device (causing battery-backed memory to wipe) then we can
assume that we don't have an active power contract.
BUG=chrome-os-partner:62952
BRANCH=reef
TEST=On reef, run "cutoff" on the console, reattach AC, and verify
device successfully wakes. Also verify Rp is dropped on console 'reboot'
and F3 + power from RW.
Change-Id: Ie300b9589cac6be7a69b77678bea6b1b6b25578c
Signed-off-by: Shawn Nematbakhsh <shawnn@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/443356
Commit-Ready: Shawn N <shawnn@chromium.org>
Tested-by: Shawn N <shawnn@chromium.org>
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Reviewed-by: Vincent Palatin <vpalatin@chromium.org>
-rw-r--r-- | chip/it83xx/registers.h | 6 | ||||
-rw-r--r-- | chip/it83xx/system.c | 6 | ||||
-rw-r--r-- | chip/mec1322/system.c | 28 | ||||
-rw-r--r-- | chip/npcx/system.c | 13 | ||||
-rw-r--r-- | chip/npcx/system_chip.h | 2 | ||||
-rw-r--r-- | chip/stm32/system.c | 8 | ||||
-rw-r--r-- | common/usb_pd_protocol.c | 33 | ||||
-rw-r--r-- | include/system.h | 3 |
8 files changed, 85 insertions, 14 deletions
diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h index 47f06991d3..4d5aec7131 100644 --- a/chip/it83xx/registers.h +++ b/chip/it83xx/registers.h @@ -1078,7 +1078,11 @@ enum bram_indices { BRAM_IDX_RESET_FLAGS2 = 2, BRAM_IDX_RESET_FLAGS3 = 3, - /* index 4 ~ 7 are reserved */ + /* PD state data for CONFIG_USB_PD_DUAL_ROLE uses 2 bytes */ + BRAM_IDX_PD0 = 4, + BRAM_IDX_PD1 = 5, + + /* index 6 ~ 7 are reserved */ BRAM_IDX_SCRATCHPAD = 8, BRAM_IDX_SCRATCHPAD1 = 9, diff --git a/chip/it83xx/system.c b/chip/it83xx/system.c index 055c586cd8..8ba3a970c1 100644 --- a/chip/it83xx/system.c +++ b/chip/it83xx/system.c @@ -232,6 +232,12 @@ static int bram_idx_lookup(enum system_bbram_idx idx) idx <= SYSTEM_BBRAM_IDX_VBNVBLOCK15) return BRAM_IDX_NVCONTEXT + idx - SYSTEM_BBRAM_IDX_VBNVBLOCK0; +#ifdef CONFIG_USB_PD_DUAL_ROLE + if (idx == SYSTEM_BBRAM_IDX_PD0) + return BRAM_IDX_PD0; + if (idx == SYSTEM_BBRAM_IDX_PD1) + return BRAM_IDX_PD1; +#endif return -1; } diff --git a/chip/mec1322/system.c b/chip/mec1322/system.c index 54ff2f45c8..4b2738e969 100644 --- a/chip/mec1322/system.c +++ b/chip/mec1322/system.c @@ -24,6 +24,8 @@ enum hibdata_index { HIBDATA_INDEX_SCRATCHPAD = 0, /* General-purpose scratchpad */ HIBDATA_INDEX_SAVED_RESET_FLAGS, /* Saved reset flags */ + HIBDATA_INDEX_PD0, /* USB-PD0 saved port state */ + HIBDATA_INDEX_PD1, /* USB-PD1 saved port state */ }; static void check_reset_cause(void) @@ -166,14 +168,26 @@ const char *system_get_chip_revision(void) return buf; } -int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) +static int bbram_idx_lookup(enum system_bbram_idx idx) { - enum hibdata_index hibdata; - switch (idx) { +#ifdef CONFIG_USB_PD_DUAL_ROLE + case SYSTEM_BBRAM_IDX_PD0: + return HIBDATA_INDEX_PD0; + case SYSTEM_BBRAM_IDX_PD1: + return HIBDATA_INDEX_PD1; +#endif default: - return EC_ERROR_UNIMPLEMENTED; + return -1; } +} + +int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) +{ + int hibdata = bbram_idx_lookup(idx); + + if (hibdata < 0) + return EC_ERROR_UNIMPLEMENTED; *value = MEC1322_VBAT_RAM(hibdata); return EC_SUCCESS; @@ -181,12 +195,10 @@ int system_get_bbram(enum system_bbram_idx idx, uint8_t *value) int system_set_bbram(enum system_bbram_idx idx, uint8_t value) { - enum hibdata_index hibdata; + int hibdata = bbram_idx_lookup(idx); - switch (idx) { - default: + if (hibdata < 0) return EC_ERROR_UNIMPLEMENTED; - } MEC1322_VBAT_RAM(hibdata) = value; return EC_SUCCESS; diff --git a/chip/npcx/system.c b/chip/npcx/system.c index bec553be53..335cb9a44a 100644 --- a/chip/npcx/system.c +++ b/chip/npcx/system.c @@ -87,7 +87,12 @@ void system_watchdog_reset(void) static int bbram_is_byte_access(enum bbram_data_index index) { return (index >= BBRM_DATA_INDEX_VBNVCNTXT && - index < BBRM_DATA_INDEX_RAMLOG); + index < BBRM_DATA_INDEX_RAMLOG) +#ifdef CONFIG_USB_PD_DUAL_ROLE + || index == BBRM_DATA_INDEX_PD0 + || index == BBRM_DATA_INDEX_PD1 +#endif + ; } /** @@ -158,6 +163,12 @@ static int bbram_idx_lookup(enum system_bbram_idx idx) idx <= SYSTEM_BBRAM_IDX_VBNVBLOCK15) return BBRM_DATA_INDEX_VBNVCNTXT + idx - SYSTEM_BBRAM_IDX_VBNVBLOCK0; +#ifdef CONFIG_USB_PD_DUAL_ROLE + if (idx == SYSTEM_BBRAM_IDX_PD0) + return BBRM_DATA_INDEX_PD0; + if (idx == SYSTEM_BBRAM_IDX_PD1) + return BBRM_DATA_INDEX_PD1; +#endif return -1; } diff --git a/chip/npcx/system_chip.h b/chip/npcx/system_chip.h index b15c030dc4..c32c163c6a 100644 --- a/chip/npcx/system_chip.h +++ b/chip/npcx/system_chip.h @@ -13,6 +13,8 @@ enum bbram_data_index { BBRM_DATA_INDEX_SCRATCHPAD = 0, /* General-purpose scratchpad */ BBRM_DATA_INDEX_SAVED_RESET_FLAGS = 4, /* Saved reset flags */ BBRM_DATA_INDEX_WAKE = 8, /* Wake reasons for hibernate */ + BBRM_DATA_INDEX_PD0 = 12, /* USB-PD saved port0 state */ + BBRM_DATA_INDEX_PD1 = 13, /* USB-PD saved port1 state */ BBRM_DATA_INDEX_VBNVCNTXT = 16, /* VbNvContext for ARM arch */ BBRM_DATA_INDEX_RAMLOG = 32, /* RAM log for Booter */ }; diff --git a/chip/stm32/system.c b/chip/stm32/system.c index 458b90402f..8acdc7a729 100644 --- a/chip/stm32/system.c +++ b/chip/stm32/system.c @@ -34,6 +34,8 @@ enum bkpdata_index { BKPDATA_INDEX_SAVED_PANIC_INFO, /* Saved panic data */ BKPDATA_INDEX_SAVED_PANIC_EXCEPTION, /* Saved panic exception code */ #endif + BKPDATA_INDEX_PD0, /* USB-PD saved port0 state */ + BKPDATA_INDEX_PD1, /* USB-PD saved port1 state */ }; /** @@ -346,6 +348,12 @@ static int bkpdata_index_lookup(enum system_bbram_idx idx, int *msb) return BKPDATA_INDEX_VBNV_CONTEXT0 + (idx - SYSTEM_BBRAM_IDX_VBNVBLOCK0) / 2; } +#ifdef CONFIG_USB_PD_DUAL_ROLE + if (idx == SYSTEM_BBRAM_IDX_PD0) + return BKPDATA_INDEX_PD0; + if (idx == SYSTEM_BBRAM_IDX_PD1) + return BKPDATA_INDEX_PD1; +#endif return -1; } diff --git a/common/usb_pd_protocol.c b/common/usb_pd_protocol.c index 51133b741b..b7b825dcb9 100644 --- a/common/usb_pd_protocol.c +++ b/common/usb_pd_protocol.c @@ -479,6 +479,25 @@ static int send_request(int port, uint32_t rdo) return bit_len; } + +static int pd_get_saved_active(int port) +{ + uint8_t val; + + if (system_get_bbram(port ? SYSTEM_BBRAM_IDX_PD1 : + SYSTEM_BBRAM_IDX_PD0, &val)) { + CPRINTS("PD NVRAM FAIL"); + return 0; + } + return !!val; +} + +static void pd_set_saved_active(int port, int val) +{ + if (system_set_bbram(port ? SYSTEM_BBRAM_IDX_PD1 : + SYSTEM_BBRAM_IDX_PD0, val)) + CPRINTS("PD NVRAM FAIL"); +} #endif /* CONFIG_USB_PD_DUAL_ROLE */ #ifdef CONFIG_COMMON_RUNTIME @@ -785,6 +804,9 @@ static void handle_data_request(int port, uint16_t head, /* explicit contract is now in place */ pd[port].flags |= PD_FLAGS_EXPLICIT_CONTRACT; +#ifdef CONFIG_USB_PD_DUAL_ROLE + pd_set_saved_active(port, 1); +#endif pd[port].requested_idx = RDO_POS(payload[0]); set_state(port, PD_STATE_SRC_ACCEPTED); return; @@ -1070,6 +1092,7 @@ static void handle_ctrl_request(int port, uint16_t head, } else if (pd[port].task_state == PD_STATE_SNK_REQUESTED) { /* explicit contract is now in place */ pd[port].flags |= PD_FLAGS_EXPLICIT_CONTRACT; + pd_set_saved_active(port, 1); set_state(port, PD_STATE_SNK_TRANSITION); #endif } @@ -1429,11 +1452,12 @@ static void pd_partner_port_reset(int port) uint64_t timeout; /* - * If we already ran RO, then PD comms were disabled, and we are - * already in a known state. Likewise, if the board is powering up, - * we're also in a known state. + * Check our battery-backed previous port state. If PD comms were + * active, and we didn't just lose power, make sure we + * don't boot into RO with a pre-existing power contract. */ - if (system_get_image_copy() != SYSTEM_IMAGE_RO || + if (!pd_get_saved_active(port) || + system_get_image_copy() != SYSTEM_IMAGE_RO || system_get_reset_flags() & (RESET_FLAG_BROWNOUT | RESET_FLAG_POWER_ON)) return; @@ -1444,6 +1468,7 @@ static void pd_partner_port_reset(int port) while (get_time().val < timeout && pd_is_vbus_present(port)) msleep(10); + pd_set_saved_active(port, 0); } #endif /* CONFIG_USB_PD_DUAL_ROLE */ diff --git a/include/system.h b/include/system.h index c3028e4a09..12b40e09ab 100644 --- a/include/system.h +++ b/include/system.h @@ -284,6 +284,9 @@ enum system_bbram_idx { * ... */ SYSTEM_BBRAM_IDX_VBNVBLOCK15 = 15, + /* PD state for CONFIG_USB_PD_DUAL_ROLE uses one byte per port */ + SYSTEM_BBRAM_IDX_PD0, + SYSTEM_BBRAM_IDX_PD1, }; /** |