summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Nematbakhsh <shawnn@chromium.org>2017-02-15 17:06:37 -0800
committerChromeOS Commit Bot <chromeos-commit-bot@chromium.org>2017-02-27 19:19:49 +0000
commit88e8ffeddba51d17001ca81c05df2179305d1d82 (patch)
tree5537defb69fd99182f24c47365e6c426432a4e59
parent841076f725473e3b650985b0443558173108807f (diff)
downloadchrome-ec-88e8ffeddba51d17001ca81c05df2179305d1d82.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> Reviewed-on: https://chromium-review.googlesource.com/446873
-rw-r--r--chip/it83xx/registers.h6
-rw-r--r--chip/it83xx/system.c6
-rw-r--r--chip/mec1322/system.c28
-rw-r--r--chip/npcx/system.c13
-rw-r--r--chip/npcx/system_chip.h2
-rw-r--r--chip/stm32/system.c8
-rw-r--r--common/usb_pd_protocol.c33
-rw-r--r--include/system.h3
8 files changed, 85 insertions, 14 deletions
diff --git a/chip/it83xx/registers.h b/chip/it83xx/registers.h
index a90b5b72f2..e47c40e97c 100644
--- a/chip/it83xx/registers.h
+++ b/chip/it83xx/registers.h
@@ -1075,7 +1075,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 a747cbf866..97f2611493 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 466ebc50c9..0dfa92f44c 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 6726e143ed..dd3bf07ba6 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;
@@ -1055,6 +1077,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
}
@@ -1414,11 +1437,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;
@@ -1429,6 +1453,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 76db18053c..f8935f40e8 100644
--- a/include/system.h
+++ b/include/system.h
@@ -280,6 +280,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,
};
/**