From ef8e792fbbd5e5c1fd73fc96a422de2d3b1dec53 Mon Sep 17 00:00:00 2001 From: Sam Hurst Date: Wed, 11 Mar 2020 10:48:18 -0700 Subject: TCPMv2: Use a DPM_REQUEST message to trigger Port Discovery On reboot, while charging from a dongle, send a DPM_REQUEST message to trigger a Port Discover to enter an Alt Mode. And add a flag to signal that the Port Discovery should continue if it was interrupted by a message reception. BUG=b:149662829 BRANCH=none TEST=make -j buildall Manual tests: Tested with an apple dock and several other docks on kohaku Signed-off-by: Sam Hurst Change-Id: I058c4717758792c77c02c26a74f2d9e9c4954ba0 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2098566 Tested-by: Sam Hurst Tested-by: Aseda Aboagye Reviewed-by: Jett Rink Commit-Queue: Sam Hurst --- common/usbc/usb_pe_drp_sm.c | 52 ++++++++++++++++++++++++++++------ common/usbc/usb_prl_sm.c | 2 +- common/usbc/usb_tc_drp_acc_trysrc_sm.c | 32 ++++++--------------- include/usb_pe_sm.h | 1 + 4 files changed, 54 insertions(+), 33 deletions(-) diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index da542fe9ab..ae97ba4e28 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -110,6 +110,8 @@ #define PE_FLAGS_LOCALLY_INITIATED_AMS BIT(26) /* Flag to note the first message sent in PE_SRC_READY and PE_SNK_READY */ #define PE_FLAGS_FIRST_MSG BIT(27) +/* Flag to continue port discovery if it was interrupted */ +#define PE_FLAGS_DISCOVER_PORT_CONTINUE BIT(28) /* 6.7.3 Hard Reset Counter */ #define N_HARD_RESET_COUNT 2 @@ -912,6 +914,22 @@ static bool common_src_snk_dpm_requests(int port) DPM_REQUEST_SOFT_RESET_SEND); set_state_pe(port, PE_SEND_SOFT_RESET); return true; + } else if (PE_CHK_DPM_REQUEST(port, + DPM_REQUEST_PORT_DISCOVERY)) { + PE_CLR_DPM_REQUEST(port, + DPM_REQUEST_PORT_DISCOVERY); + if (!PE_CHK_FLAG(port, PE_FLAGS_MODAL_OPERATION)) { + /* + * Clear counters and reset timer to trigger a + * port discovery. + */ + PE_CLR_FLAG(port, PE_FLAGS_DISCOVER_PORT_IDENTITY_DONE); + pe[port].dr_swap_attempt_counter = 0; + pe[port].discover_port_identity_counter = 0; + pe[port].discover_port_identity_timer = get_time().val + + PD_T_DISCOVER_IDENTITY; + } + return true; } return false; @@ -1764,6 +1782,9 @@ static void pe_src_ready_run(int port) set_state_pe(port, PE_SEND_NOT_SUPPORTED); } } + } else if (PE_CHK_FLAG(port, PE_FLAGS_DISCOVER_PORT_CONTINUE)) { + PE_CLR_FLAG(port, PE_FLAGS_DISCOVER_PORT_CONTINUE); + set_state_pe(port, PE_VDM_REQUEST); } } @@ -2503,6 +2524,9 @@ static void pe_snk_ready_run(int port) set_state_pe(port, PE_SEND_NOT_SUPPORTED); } } + } else if (PE_CHK_FLAG(port, PE_FLAGS_DISCOVER_PORT_CONTINUE)) { + PE_CLR_FLAG(port, PE_FLAGS_DISCOVER_PORT_CONTINUE); + set_state_pe(port, PE_VDM_REQUEST); } } @@ -4157,16 +4181,28 @@ static void pe_vdm_request_run(int port) PE_FLAGS_VDM_REQUEST_BUSY); } } else { - /* Unexpected Message Received. */ + if ((sop == TCPC_TX_SOP || sop == TCPC_TX_SOP_PRIME) && + type == PD_CTRL_NOT_SUPPORTED && cnt == 0 && + ext == 0) { + /* Do not continue port discovery */ + PE_SET_FLAG(port, + PE_FLAGS_DISCOVER_PORT_IDENTITY_DONE); + } else { + /* Unexpected Message Received. */ - /* - * Reset PE_FLAGS_MSG_RECEIVED so Src.Ready or Snk.Ready - * can handle it. - */ - PE_SET_FLAG(port, PE_FLAGS_MSG_RECEIVED); + /* + * Reset PE_FLAGS_MSG_RECEIVED so Src.Ready or + * Snk.Ready can handle it. + */ + PE_SET_FLAG(port, PE_FLAGS_MSG_RECEIVED); - /* Port Disc. was interrupted. So don't try again. */ - PE_SET_FLAG(port, PE_FLAGS_DISCOVER_PORT_IDENTITY_DONE); + /* + * Continue port discovery after the unexpected + * message is handled + */ + PE_SET_FLAG(port, + PE_FLAGS_DISCOVER_PORT_CONTINUE); + } if (pe[port].power_role == PD_ROLE_SOURCE) set_state_pe(port, PE_SRC_READY); diff --git a/common/usbc/usb_prl_sm.c b/common/usbc/usb_prl_sm.c index 1cc5636118..7d83b51c0a 100644 --- a/common/usbc/usb_prl_sm.c +++ b/common/usbc/usb_prl_sm.c @@ -1298,7 +1298,7 @@ static void tch_wait_for_message_request_from_pe_run(const int port) (uint8_t *)emsg[port].buf, emsg[port].len); /* - * Pad length to 4-byte boundery and + * Pad length to 4-byte boundary and * convert to number of 32-bit objects. * Since the value is shifted right by 2, * no need to explicitly clear the lower diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index b66239ac97..e0dcb2e940 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -80,10 +80,8 @@ #define TC_FLAGS_DISC_IDENT_IN_PROGRESS BIT(21) /* Flag to note we should wake from LPM */ #define TC_FLAGS_WAKE_FROM_LPM BIT(22) -/* Flag to note a chipset power state has changed */ -#define TC_FLAGS_POWER_STATE_CHANGE BIT(23) /* Flag to note the TCPM supports auto toggle */ -#define TC_FLAGS_AUTO_TOGGLE_SUPPORTED BIT(24) +#define TC_FLAGS_AUTO_TOGGLE_SUPPORTED BIT(23) /* * Clear all flags except TC_FLAGS_AUTO_TOGGLE_SUPPORTED, @@ -1115,10 +1113,8 @@ void tc_event_check(int port, int evt) #ifdef CONFIG_POWER_COMMON if (IS_ENABLED(CONFIG_POWER_COMMON)) { - if (evt & PD_EVENT_POWER_STATE_CHANGE) { - TC_SET_FLAG(port, TC_FLAGS_POWER_STATE_CHANGE); + if (evt & PD_EVENT_POWER_STATE_CHANGE) handle_new_power_state(port); - } } #endif /* CONFIG_POWER_COMMON */ #ifdef CONFIG_USB_PD_ALT_MODE_DFP @@ -1264,6 +1260,10 @@ static void handle_new_power_state(int port) * again at boot up. */ set_usb_mux_with_current_data_role(port); + } else if (chipset_in_or_transitioning_to_state( + CHIPSET_STATE_ON)) { + /* Enter any previously exited alt modes */ + pe_dpm_request(port, DPM_REQUEST_PORT_DISCOVERY); } } } @@ -1890,21 +1890,6 @@ static void tc_attached_snk_entry(const int port) static void tc_attached_snk_run(const int port) { #ifdef CONFIG_USB_PE_SM - /* - * On device power ON, when charging from a Dock that has DP, enter any - * alt modes by briefly transitioning the Unattached.SNK state. This has - * no impact when charging from a regular charger. - * - * TODO(b/149662829): Implement a better solution for re-entering - * alt modes after a reboot. - */ - if (TC_CHK_FLAG(port, TC_FLAGS_POWER_STATE_CHANGE) && - chipset_in_state(CHIPSET_STATE_ON)) { - TC_CLR_FLAG(port, TC_FLAGS_POWER_STATE_CHANGE); - set_state_tc(port, TC_UNATTACHED_SNK); - return; - } - /* * Perform Hard Reset */ @@ -2862,8 +2847,7 @@ static void tc_low_power_mode_entry(const int port) static void tc_low_power_mode_run(const int port) { #ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE - if (TC_CHK_FLAG(port, TC_FLAGS_WAKE_FROM_LPM | - TC_FLAGS_POWER_STATE_CHANGE)) { + if (TC_CHK_FLAG(port, TC_FLAGS_WAKE_FROM_LPM)) { set_state_tc(port, TC_DRP_AUTO_TOGGLE); return; } @@ -2875,7 +2859,7 @@ static void tc_low_power_mode_exit(const int port) { CPRINTS("TCPC p%d Exit Low Power Mode", port); TC_CLR_FLAG(port, TC_FLAGS_LPM_REQUESTED | TC_FLAGS_LPM_ENGAGED | - TC_FLAGS_WAKE_FROM_LPM | TC_FLAGS_POWER_STATE_CHANGE); + TC_FLAGS_WAKE_FROM_LPM); reset_device_and_notify(port); tc_start_event_loop(port); } diff --git a/include/usb_pe_sm.h b/include/usb_pe_sm.h index ee4d8f3066..c22103efa4 100644 --- a/include/usb_pe_sm.h +++ b/include/usb_pe_sm.h @@ -41,6 +41,7 @@ enum pe_dpm_request { DPM_REQUEST_SRC_STARTUP = BIT(15), DPM_REQUEST_HARD_RESET_SEND = BIT(16), DPM_REQUEST_SOFT_RESET_SEND = BIT(17), + DPM_REQUEST_PORT_DISCOVERY = BIT(18), }; /** -- cgit v1.2.1