diff options
Diffstat (limited to 'common/usbc/usb_pe_drp_sm.c')
-rw-r--r-- | common/usbc/usb_pe_drp_sm.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index 97a1d42f64..bc3dcf48e7 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -264,6 +264,7 @@ enum usb_pe_state { /* PD3.0 only states below here*/ /* DFP Data Reset States */ PE_DDR_SEND_DATA_RESET, + PE_DDR_DATA_RESET_RECEIVED, PE_DDR_WAIT_FOR_VCONN_OFF, PE_DDR_PERFORM_DATA_RESET, PE_FRS_SNK_SRC_START_AMS, @@ -403,6 +404,7 @@ __maybe_unused static __const_data const char * const pe_state_names[] = { #endif #ifdef CONFIG_USB_PD_DATA_RESET_MSG [PE_DDR_SEND_DATA_RESET] = "PE_DDR_Send_Data_Reset", + [PE_DDR_DATA_RESET_RECEIVED] = "PE_DDR_Data_Reset_Received", [PE_DDR_WAIT_FOR_VCONN_OFF] = "PE_DDR_Wait_For_VCONN_Off", [PE_DDR_PERFORM_DATA_RESET] = "PE_DDR_Perform_Data_Reset", #endif /* CONFIG_USB_PD_DATA_RESET_MSG */ @@ -461,6 +463,8 @@ GEN_NOT_SUPPORTED(PE_SNK_CHUNK_RECEIVED); #ifndef CONFIG_USB_PD_DATA_RESET_MSG GEN_NOT_SUPPORTED(PE_DDR_SEND_DATA_RESET); #define PE_DDR_SEND_DATA_RESET PE_DDR_SEND_DATA_RESET_NOT_SUPPORTED +GEN_NOT_SUPPORTED(PE_DDR_DATA_RESET_RECEIVED); +#define PE_DDR_DATA_RESET_RECEIVED PE_DDR_DATA_RESET_RECEIVED_NOT_SUPPORTED GEN_NOT_SUPPORTED(PE_DDR_WAIT_FOR_VCONN_OFF); #define PE_DDR_WAIT_FOR_VCONN_OFF PE_DDR_WAIT_FOR_VCONN_OFF_NOT_SUPPORTED GEN_NOT_SUPPORTED(PE_DDR_PERFORM_DATA_RESET); @@ -1145,6 +1149,7 @@ void pe_report_error(int port, enum pe_error e, enum tcpci_msg_type type) get_state_pe(port) == PE_VDM_IDENTITY_REQUEST_CBL) || (IS_ENABLED(CONFIG_USB_PD_DATA_RESET_MSG) && (get_state_pe(port) == PE_DDR_SEND_DATA_RESET || + get_state_pe(port) == PE_DDR_DATA_RESET_RECEIVED || get_state_pe(port) == PE_DDR_WAIT_FOR_VCONN_OFF || get_state_pe(port) == PE_DDR_PERFORM_DATA_RESET)) || (pe_in_frs_mode(port) && @@ -2735,6 +2740,19 @@ static void pe_src_ready_run(int port) pe_send_soft_reset(port, PD_HEADER_GET_SOP(rx_emsg[port].header)); return; +#ifdef CONFIG_USB_PD_DATA_RESET_MSG + case PD_CTRL_DATA_RESET: + if (pe[port].data_role == PD_ROLE_DFP) + set_state_pe(port, + PE_DDR_DATA_RESET_RECEIVED); + /* + * TODO(b/209628496): Support Data Reset as UFP + */ + else + set_state_pe(port, + PE_SEND_NOT_SUPPORTED); + return; +#endif /* CONFIG_USB_PD_DATA_RESET_MSG */ /* * Receiving an unknown or unsupported message * shall be responded to with a not supported message. @@ -3552,6 +3570,19 @@ static void pe_snk_ready_run(int port) set_state_pe(port, PE_SEND_NOT_SUPPORTED); return; +#ifdef CONFIG_USB_PD_DATA_RESET_MSG + case PD_CTRL_DATA_RESET: + if (pe[port].data_role == PD_ROLE_DFP) + set_state_pe(port, + PE_DDR_DATA_RESET_RECEIVED); + /* + * TODO(b/209628496): Support Data Reset as UFP + */ + else + set_state_pe(port, + PE_SEND_NOT_SUPPORTED); + return; +#endif /* CONFIG_USB_PD_DATA_RESET_MSG */ case PD_CTRL_NOT_SUPPORTED: /* Do nothing */ break; @@ -7121,6 +7152,40 @@ static void pe_ddr_send_data_reset_exit(int port) } /* + * PE_DDR_Data_Reset_Received + */ +static void pe_ddr_data_reset_received_entry(int port) +{ + print_current_state(port); + /* Send Data Reset message */ + send_ctrl_msg(port, TCPCI_MSG_SOP, PD_CTRL_ACCEPT); +} + +static void pe_ddr_data_reset_received_run(int port) +{ + if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) { + PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE); + if (tc_is_vconn_src(port)) + set_state_pe(port, PE_DDR_PERFORM_DATA_RESET); + else + set_state_pe(port, PE_DDR_WAIT_FOR_VCONN_OFF); + } else if (PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) { + PE_CLR_FLAG(port, PE_FLAGS_PROTOCOL_ERROR); + set_state_pe(port, PE_WAIT_FOR_ERROR_RECOVERY); + } +} + +static void pe_ddr_data_reset_received_exit(int port) +{ + /* + * Start DataResetFailTimer + * NOTE: This timer continues to run in every state until it is stopped + * or it times out. + */ + pd_timer_enable(port, PE_TIMER_DATA_RESET_FAIL, PD_T_DATA_RESET_FAIL); +} + +/* * PE_DDR_Wait_For_VCONN_Off */ static void pe_ddr_wait_for_vconn_off_entry(int port) @@ -7774,6 +7839,11 @@ static __const_data const struct usb_state pe_states[] = { .run = pe_ddr_send_data_reset_run, .exit = pe_ddr_send_data_reset_exit, }, + [PE_DDR_DATA_RESET_RECEIVED] = { + .entry = pe_ddr_data_reset_received_entry, + .run = pe_ddr_data_reset_received_run, + .exit = pe_ddr_data_reset_received_exit, + }, [PE_DDR_WAIT_FOR_VCONN_OFF] = { .entry = pe_ddr_wait_for_vconn_off_entry, .run = pe_ddr_wait_for_vconn_off_run, |