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>
This commit is contained in:
Shawn Nematbakhsh
2017-02-15 17:06:37 -08:00
committed by chrome-bot
parent b7f8d9df65
commit 23bc38414a
8 changed files with 85 additions and 14 deletions

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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;
}
static int bbram_idx_lookup(enum system_bbram_idx idx)
{
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 -1;
}
}
int system_get_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;
}
*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;

View File

@@ -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;
}

View File

@@ -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 */
};

View File

@@ -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;
}

View File

@@ -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 */

View File

@@ -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,
};
/**