summaryrefslogtreecommitdiff
path: root/common/usbc
diff options
context:
space:
mode:
authorAbe Levkoy <alevkoy@chromium.org>2021-01-20 15:23:48 -0700
committerCommit Bot <commit-bot@chromium.org>2021-01-22 16:39:18 +0000
commit78aa2873a070efd2e97c3605297cd4752be98457 (patch)
treec45bf2c66bc24b334345cc8a24da3f401350a170 /common/usbc
parent337ecb7548dba920ba2881043fcfd9a307423a83 (diff)
downloadchrome-ec-78aa2873a070efd2e97c3605297cd4752be98457.tar.gz
dp_alt_mode: Exit DP mode on Exit Mode NAK
When a DP-related VDM sequence fails, the alt mode implementation returns to an inactive state. If this happens while the port is configured in DP alt mode, return the port to USB mode. BUG=b:176795458 TEST=Receive Exit Mode NAK on AP shutdown; re-enter DP mode after boot BRANCH=none Signed-off-by: Abe Levkoy <alevkoy@chromium.org> Change-Id: Ifa564cfb874297f40a8eecd2dd113e2b3c2ea389 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2638886 Reviewed-by: Keith Short <keithshort@chromium.org> Tested-by: Madhusudanarao Amara <madhusudanarao.amara@intel.corp-partner.google.com>
Diffstat (limited to 'common/usbc')
-rw-r--r--common/usbc/dp_alt_mode.c29
1 files changed, 18 insertions, 11 deletions
diff --git a/common/usbc/dp_alt_mode.c b/common/usbc/dp_alt_mode.c
index 7c004b5a0d..af5db7263b 100644
--- a/common/usbc/dp_alt_mode.c
+++ b/common/usbc/dp_alt_mode.c
@@ -95,13 +95,24 @@ static bool dp_response_valid(int port, enum tcpm_transmit_type type,
return true;
}
+static void dp_exit_to_usb_mode(int port)
+{
+ int opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT);
+
+ pd_dfp_exit_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT, opos);
+ set_usb_mux_with_current_data_role(port);
+
+ CPRINTS("C%d: Exited DP mode", port);
+ dp_state[port] = IS_ENABLED(CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY)
+ ? DP_START : DP_INACTIVE;
+}
+
void dp_vdm_acked(int port, enum tcpm_transmit_type type, int vdo_count,
uint32_t *vdm)
{
const struct svdm_amode_data *modep =
pd_get_amode_data(port, type, USB_SID_DISPLAYPORT);
const uint8_t vdm_cmd = PD_VDO_CMD(vdm[0]);
- int opos;
if (!dp_response_valid(port, type, "ACK", vdm_cmd))
return;
@@ -126,18 +137,10 @@ void dp_vdm_acked(int port, enum tcpm_transmit_type type, int vdo_count,
break;
case DP_ACTIVE:
/*
- * Request to exit mode successful, so put it in
+ * Request to exit mode successful, so put the module in an
* inactive state.
*/
- CPRINTS("C%d: Exited DP mode", port);
- dp_state[port] = IS_ENABLED(CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY)
- ? DP_START : DP_INACTIVE;
- opos = pd_alt_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT);
-
- /* Clear DisplayPort related signals */
- pd_dfp_exit_mode(port, TCPC_TX_SOP, USB_SID_DISPLAYPORT,
- opos);
- set_usb_mux_with_current_data_role(port);
+ dp_exit_to_usb_mode(port);
break;
case DP_ENTER_NAKED:
/*
@@ -186,6 +189,10 @@ void dp_vdm_naked(int port, enum tcpm_transmit_type type, uint8_t vdm_cmd)
*/
dp_entry_failed(port);
break;
+ case DP_ACTIVE:
+ /* Treat an Exit Mode NAK the same as an Exit Mode ACK. */
+ dp_exit_to_usb_mode(port);
+ break;
default:
CPRINTS("C%d: NAK for cmd %d in state %d", port,
vdm_cmd, dp_state[port]);