diff options
author | Denis Brockus <dbrockus@google.com> | 2020-03-26 10:46:44 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-03-26 21:01:07 +0000 |
commit | f257b119931beaf722f0245b3b44a96c9a3836a1 (patch) | |
tree | b4050c0dca51b06b609958cc1363d5df324d5028 | |
parent | c61fb94432340c1b2531d5d4ab23e46bcac8bc77 (diff) | |
download | chrome-ec-f257b119931beaf722f0245b3b44a96c9a3836a1.tar.gz |
zork: undo revert for zork on AutoDischargeDisconnect
The revert caused Zork to no longer boot in battery-less
mode. Doing a quick revert to locally unblock factory
and will look for a correct solution so both zork and
waddledoo function
BUG=b:152444591 b:150110431 b:150913968 b:151152817
BRANCH=none
TEST=verify trembyle and waddledoo
Signed-off-by: Denis Brockus <dbrockus@google.com>
Change-Id: I21d73206b252d0c22efb74de9318c11b019272d7
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2121629
Tested-by: Denis Brockus <dbrockus@chromium.org>
Reviewed-by: Edward Hill <ecgh@chromium.org>
Commit-Queue: Edward Hill <ecgh@chromium.org>
Auto-Submit: Denis Brockus <dbrockus@chromium.org>
-rw-r--r-- | baseboard/zork/baseboard.h | 1 | ||||
-rw-r--r-- | common/usbc/usb_tc_drp_acc_trysrc_sm.c | 85 | ||||
-rw-r--r-- | driver/tcpm/nct38xx.c | 36 | ||||
-rw-r--r-- | driver/tcpm/tcpci.c | 156 | ||||
-rw-r--r-- | driver/tcpm/tcpci.h | 4 | ||||
-rw-r--r-- | driver/tcpm/tcpm.h | 14 | ||||
-rw-r--r-- | include/config.h | 3 | ||||
-rw-r--r-- | include/usb_pd_tcpm.h | 22 |
8 files changed, 313 insertions, 8 deletions
diff --git a/baseboard/zork/baseboard.h b/baseboard/zork/baseboard.h index ae7ecae512..31050f7adc 100644 --- a/baseboard/zork/baseboard.h +++ b/baseboard/zork/baseboard.h @@ -125,6 +125,7 @@ #ifndef CONFIG_USB_PD_TCPMV2 #define CONFIG_USB_PD_TCPMV1 #else + #define CONFIG_ZORK_AUTO_DISCHARGE #define CONFIG_USB_PD_DECODE_SOP #define CONFIG_USB_DRP_ACC_TRYSRC diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index e0dcb2e940..7fffeb5bf8 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -1642,8 +1642,10 @@ static void tc_unattached_snk_entry(const int port) if (IS_ENABLED(CONFIG_BC12_DETECT_DATA_ROLE_TRIGGER)) bc12_role_change_handler(port); +#ifndef CONFIG_ZORK_AUTO_DISCHARGE /* VBus should be SafeV0, turn off auto discharge disconnect */ tcpm_enable_auto_discharge_disconnect(port, 0); +#endif if (IS_ENABLED(CONFIG_CHARGE_MANAGER)) charge_manager_update_dualrole(port, CAP_UNKNOWN); @@ -1694,6 +1696,19 @@ static void tc_unattached_snk_run(const int port) if (drp_state[port] == PD_DRP_TOGGLE_ON && TC_CHK_FLAG(port, TC_FLAGS_AUTO_TOGGLE_SUPPORTED) && cc_is_open(cc1, cc2)) { + +#ifdef CONFIG_ZORK_AUTO_DISCHARGE + /* + * We are disconnected and going to DRP + * PC.AutoDischargeDisconnect=0b + * Set RC.DRP=1b (DRP) + * Set RC.CC1=10b (Rd) + * Set RC.CC2=10b (Rd) + */ + tcpm_enable_auto_discharge_disconnect(port, 0); + tcpm_set_connection(port, TYPEC_CC_RD, 0); +#endif + set_state_tc(port, TC_DRP_AUTO_TOGGLE); return; } @@ -1720,6 +1735,15 @@ static void tc_unattached_snk_run(const int port) #ifdef CONFIG_USB_PD_TCPC_LOW_POWER else if (drp_state[port] == PD_DRP_FORCE_SINK || drp_state[port] == PD_DRP_TOGGLE_OFF) { + +#ifdef CONFIG_ZORK_AUTO_DISCHARGE + /* + * We are disconnecting without DRP. + * PC.AutoDischargeDisconnect=0b + */ + tcpm_enable_auto_discharge_disconnect(port, 0); +#endif + set_state_tc(port, TC_LOW_POWER_MODE); } #endif @@ -1883,8 +1907,10 @@ static void tc_attached_snk_entry(const int port) if (IS_ENABLED(CONFIG_USB_PE_SM)) tc_enable_pd(port, 1); +#ifndef CONFIG_ZORK_AUTO_DISCHARGE /* VBus should be powered, turn on auto discharge disconnect */ tcpm_enable_auto_discharge_disconnect(port, 1); +#endif } static void tc_attached_snk_run(const int port) @@ -2324,8 +2350,10 @@ static void tc_unattached_src_entry(const int port) if (IS_ENABLED(CONFIG_BC12_DETECT_DATA_ROLE_TRIGGER)) bc12_role_change_handler(port); +#ifndef CONFIG_ZORK_AUTO_DISCHARGE /* VBus should be SafeV0, turn off auto discharge disconnect */ tcpm_enable_auto_discharge_disconnect(port, 0); +#endif if (IS_ENABLED(CONFIG_USBC_PPC)) { /* There is no sink connected. */ @@ -2395,6 +2423,20 @@ static void tc_unattached_src_run(const int port) else if (drp_state[port] == PD_DRP_TOGGLE_ON && TC_CHK_FLAG(port, TC_FLAGS_AUTO_TOGGLE_SUPPORTED) && cc_is_open(cc1, cc2)) { + +#ifdef CONFIG_ZORK_AUTO_DISCHARGE + /* + * We are disconnected and going to DRP + * PC.AutoDischargeDisconnect=0b + * Set RC.DRP=1b (DRP) + * Set RC.RpValue=00b (smallest Rp to save power) + * Set RC.CC1=01b (Rp) + * Set RC.CC2=01b (Rp) + */ + tcpm_enable_auto_discharge_disconnect(port, 0); + tcpm_set_connection(port, TYPEC_CC_RP, 0); +#endif + set_state_tc(port, TC_DRP_AUTO_TOGGLE); } #endif @@ -2402,6 +2444,15 @@ static void tc_unattached_src_run(const int port) #ifdef CONFIG_USB_PD_TCPC_LOW_POWER else if (drp_state[port] == PD_DRP_FORCE_SOURCE || drp_state[port] == PD_DRP_TOGGLE_OFF) { + +#ifdef CONFIG_ZORK_AUTO_DISCHARGE + /* + * We are disconnecting without DRP. + * PC.AutoDischargeDisconnect=0b + */ + tcpm_enable_auto_discharge_disconnect(port, 0); +#endif + set_state_tc(port, TC_LOW_POWER_MODE); } #endif @@ -2581,8 +2632,10 @@ static void tc_attached_src_entry(const int port) if (IS_ENABLED(CONFIG_USBC_PPC)) ppc_sink_is_connected(port, 1); +#ifndef CONFIG_ZORK_AUTO_DISCHARGE /* VBus should be powered, turn on auto discharge disconnect */ tcpm_enable_auto_discharge_disconnect(port, 1); +#endif /* * Only notify if we're not performing a power role swap. During a @@ -2821,9 +2874,33 @@ static void tc_drp_auto_toggle_run(const int port) set_state_tc(port, PD_DEFAULT_STATE(port)); break; case DRP_TC_UNATTACHED_SNK: +#ifdef CONFIG_ZORK_AUTO_DISCHARGE + /* + * New SNK connection. + * Set RC.CC1 & RC.CC2 per decision + * Set RC.DRP=0 + * Set TCPC_CONTROl.PlugOrientation + * PC.AutoDischargeDisconnect=1b + */ + tcpm_set_connection(port, TYPEC_CC_RD, 1); + tcpm_enable_auto_discharge_disconnect(port, 1); +#endif + set_state_tc(port, TC_UNATTACHED_SNK); break; case DRP_TC_UNATTACHED_SRC: +#ifdef CONFIG_ZORK_AUTO_DISCHARGE + /* + * New SRC connection. + * Set RC.CC1 & RC.CC2 per decision + * Set RC.DRP=0 + * Set TCPC_CONTROl.PlugOrientation + * PC.AutoDischargeDisconnect=1b + */ + tcpm_set_connection(port, TYPEC_CC_RP, 1); + tcpm_enable_auto_discharge_disconnect(port, 1); +#endif + set_state_tc(port, TC_UNATTACHED_SRC); break; case DRP_TC_DRP_AUTO_TOGGLE: @@ -3150,7 +3227,11 @@ static void tc_cc_rd_entry(const int port) * Both CC1 and CC2 pins shall be independently terminated to * ground through Rd. */ +#ifndef CONFIG_ZORK_AUTO_DISCHARGE tcpm_set_new_connection(port, TYPEC_CC_RD); +#else + tcpm_set_cc(port, TYPEC_CC_RD); +#endif } @@ -3172,7 +3253,11 @@ static void tc_cc_rp_entry(const int port) * up through Rp. */ tcpm_select_rp_value(port, CONFIG_USB_PD_PULLUP); +#ifndef CONFIG_ZORK_AUTO_DISCHARGE tcpm_set_new_connection(port, TYPEC_CC_RP); +#else + tcpm_set_cc(port, TYPEC_CC_RP); +#endif } /** diff --git a/driver/tcpm/nct38xx.c b/driver/tcpm/nct38xx.c index 2069557e2c..d8bc52ee58 100644 --- a/driver/tcpm/nct38xx.c +++ b/driver/tcpm/nct38xx.c @@ -28,8 +28,8 @@ static int nct38xx_tcpm_init(int port) int reg; rv = tcpci_tcpm_init(port); - if (rv) - return rv; + if (rv) + return rv; /* * Write to the CONTROL_OUT_EN register to enable: @@ -78,13 +78,15 @@ static int nct38xx_tcpm_init(int port) /* Start VBus monitor */ rv = tcpc_write(port, TCPC_REG_COMMAND, TCPC_REG_COMMAND_ENABLE_VBUS_DETECT); + if (rv) + return rv; /* * Enable the Vendor Define alert event only when the IO expander * feature is defined */ if (IS_ENABLED(CONFIG_IO_EXPANDER_NCT38XX)) - rv |= tcpc_update16(port, + rv = tcpc_update16(port, TCPC_REG_ALERT_MASK, TCPC_REG_ALERT_VENDOR_DEF, MASK_SET); @@ -117,6 +119,7 @@ static void nct38xx_tcpc_alert(int port) } +#ifndef CONFIG_ZORK_AUTO_DISCHARGE #ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE static int nct38xx_set_new_connection(int port, enum tcpc_cc_pull pull) @@ -212,6 +215,28 @@ static int nct38xx_set_new_connection(int port, return EC_SUCCESS; } #endif +#else +static __maybe_unused int nct3807_tcpc_drp_toggle(int port) +{ + int rv; + + /* DRP will already be set with the correct pull on both CC lines */ + + /* Set up to catch LOOK4CONNECTION alerts */ + rv = tcpc_update8(port, + TCPC_REG_TCPC_CTRL, + TCPC_REG_TCPC_CTRL_EN_LOOK4CONNECTION_ALERT, + MASK_SET); + if (rv) + return rv; + + /* Set Look4Connection command */ + rv = tcpc_write(port, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_LOOK4CONNECTION); + + return rv; +} +#endif const struct tcpm_drv nct38xx_tcpm_drv = { .init = &nct38xx_tcpm_init, @@ -235,8 +260,13 @@ const struct tcpm_drv nct38xx_tcpm_drv = { .tcpc_enable_auto_discharge_disconnect = &tcpci_tcpc_enable_auto_discharge_disconnect, #ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE +#ifndef CONFIG_ZORK_AUTO_DISCHARGE .drp_toggle = &tcpci_tcpc_drp_toggle, .set_new_connection = &nct38xx_set_new_connection, +#else + .drp_toggle = &nct3807_tcpc_drp_toggle, + .set_connection = &tcpci_tcpc_set_connection, +#endif #endif #ifdef CONFIG_USBC_PPC .set_snk_ctrl = &tcpci_tcpm_set_snk_ctrl, diff --git a/driver/tcpm/tcpci.c b/driver/tcpm/tcpci.c index e23bd5ca46..80143de61d 100644 --- a/driver/tcpm/tcpci.c +++ b/driver/tcpm/tcpci.c @@ -16,6 +16,7 @@ #include "tcpm.h" #include "timer.h" #include "usb_charge.h" +#include "usb_common.h" #include "usb_mux.h" #include "usb_pd.h" #include "usb_pd_tcpc.h" @@ -364,17 +365,154 @@ int tcpci_set_role_ctrl(int port, int toggle, int rp, int pull) int tcpci_tcpc_drp_toggle(int port) { int rv; - - /* Set auto drp toggle */ + /* + * Set auto drp toggle + * NOTE: This should be done according to the last connection + * that we are disconnecting from. TCPCI Rev 2 spec figures + * 4-21 and 4-22 show: + * SNK => DRP should set CC lines to Rd/Rd + * SRC => DRP should set CC lines to Rp/Rp + * The function tcpci_tcpc_set_connection performs this action + * and it may be wise as chips can use this to make this the + * standard and remove this set_role_ctrl call. + */ rv = tcpci_set_role_ctrl(port, 1, TYPEC_RP_USB, TYPEC_CC_RD); + if (rv) + return rv; + +#ifdef CONFIG_ZORK_AUTO_DISCHARGE + /* Set up to catch LOOK4CONNECTION alerts */ + rv = tcpc_update8(port, + TCPC_REG_TCPC_CTRL, + TCPC_REG_TCPC_CTRL_EN_LOOK4CONNECTION_ALERT, + MASK_SET); + if (rv) + return rv; +#endif /* Set Look4Connection command */ - rv |= tcpc_write(port, TCPC_REG_COMMAND, - TCPC_REG_COMMAND_LOOK4CONNECTION); + rv = tcpc_write(port, TCPC_REG_COMMAND, + TCPC_REG_COMMAND_LOOK4CONNECTION); + + return rv; +} + +#ifdef CONFIG_ZORK_AUTO_DISCHARGE +int tcpci_tcpc_set_connection(int port, + enum tcpc_cc_pull pull, + int connect) +{ + int rv; + int role; + + /* + * Disconnecting will set the following and then return + * Set RC.DRP=1b (DRP) + * Set RC.RpValue=00b (smallest Rp to save power) + * Set RC.CC1=pull (Rd or Rp) + * Set RC.CC2=pull (Rd or Rp) + */ + if (!connect) { + tcpci_set_role_ctrl(port, 1, TYPEC_RP_USB, pull); + return EC_SUCCESS; + } + + /* Get the ROLE CONTROL value */ + rv = tcpc_read(port, TCPC_REG_ROLE_CTRL, &role); + if (rv) + return rv; + + if (role & TCPC_REG_ROLE_CTRL_DRP_MASK) { + enum tcpc_cc_pull cc1_pull, cc2_pull; + enum tcpc_cc_voltage_status cc1, cc2; + + enum tcpc_cc_polarity polarity; + + /* + * If DRP is set, the CC pins shall stay in + * Potential_Connect_as_Src or Potential_Connect_as_Sink + * until directed otherwise. + * + * Set RC.CC1 & RC.CC2 per potential decision + * Set RC.DRP=0 + */ + rv = tcpm_get_cc(port, &cc1, &cc2); + if (rv) + return rv; + switch (cc1) { + case TYPEC_CC_VOLT_OPEN: + cc1_pull = TYPEC_CC_OPEN; + break; + case TYPEC_CC_VOLT_RA: + cc1_pull = TYPEC_CC_RA; + break; + case TYPEC_CC_VOLT_RD: + cc1_pull = TYPEC_CC_RP; + break; + case TYPEC_CC_VOLT_RP_DEF: + case TYPEC_CC_VOLT_RP_1_5: + case TYPEC_CC_VOLT_RP_3_0: + cc1_pull = TYPEC_CC_RD; + break; + default: + return EC_ERROR_UNKNOWN; + } + + switch (cc2) { + case TYPEC_CC_VOLT_OPEN: + cc2_pull = TYPEC_CC_OPEN; + break; + case TYPEC_CC_VOLT_RA: + cc2_pull = TYPEC_CC_RA; + break; + case TYPEC_CC_VOLT_RD: + cc2_pull = TYPEC_CC_RP; + break; + case TYPEC_CC_VOLT_RP_DEF: + case TYPEC_CC_VOLT_RP_1_5: + case TYPEC_CC_VOLT_RP_3_0: + cc2_pull = TYPEC_CC_RD; + break; + default: + return EC_ERROR_UNKNOWN; + } + + /* Set the CC lines */ + rv = tcpc_write(port, TCPC_REG_ROLE_CTRL, + TCPC_REG_ROLE_CTRL_SET(0, + CONFIG_USB_PD_PULLUP, + cc1_pull, cc2_pull)); + if (rv) + return rv; + + /* Set TCPC_CONTROl.PlugOrientation */ + if (pull == TYPEC_CC_RD) + polarity = polarity_rm_dts( + get_snk_polarity(cc1, cc2)); + else + polarity = get_src_polarity(cc1, cc2); + + rv = tcpc_update8(port, TCPC_REG_TCPC_CTRL, + TCPC_REG_TCPC_CTRL_SET(1), + (polarity == POLARITY_CC1) ? MASK_CLR + : MASK_SET); + } else { + /* + * DRP is not set. This would happen if DRP is not enabled or + * was turned off and we did not have a connection. We have + * to manually turn off that we are looking for a connection + * and set both CC lines to the pull value. + */ + rv = tcpc_update8(port, + TCPC_REG_TCPC_CTRL, + TCPC_REG_TCPC_CTRL_EN_LOOK4CONNECTION_ALERT, + MASK_CLR); + } return rv; } #endif +#endif #ifdef CONFIG_USB_PD_TCPC_LOW_POWER int tcpci_enter_low_power_mode(int port) @@ -838,6 +976,7 @@ void tcpci_tcpc_alert(int port) int fault; if (tcpci_get_fault(port, &fault) == EC_SUCCESS && + fault != 0 && tcpci_handle_fault(port, fault) == EC_SUCCESS && tcpci_clear_fault(port, fault) == EC_SUCCESS) CPRINTS("C%d FAULT 0x%02X handled", port, fault); @@ -1016,7 +1155,6 @@ int tcpci_tcpm_init(int port) int error; int power_status; int tries = TCPM_INIT_TRIES; - int regval; if (port >= board_get_usb_pd_port_count()) return EC_ERROR_INVAL; @@ -1041,9 +1179,17 @@ int tcpci_tcpm_init(int port) * Alert assertion when CC_STATUS.Looking4Connection changes state. */ if (tcpc_config[port].flags & TCPC_FLAGS_TCPCI_REV2_0) { +#ifndef CONFIG_ZORK_AUTO_DISCHARGE + int regval; + error = tcpc_read(port, TCPC_REG_TCPC_CTRL, ®val); regval |= TCPC_REG_TCPC_CTRL_EN_LOOK4CONNECTION_ALERT; error |= tcpc_write(port, TCPC_REG_TCPC_CTRL, regval); +#else + error = tcpc_update8(port, TCPC_REG_TCPC_CTRL, + TCPC_REG_TCPC_CTRL_EN_LOOK4CONNECTION_ALERT, + MASK_SET); +#endif if (error) CPRINTS("C%d: Failed to init TCPC_CTRL!", port); } diff --git a/driver/tcpm/tcpci.h b/driver/tcpm/tcpci.h index 60bca01107..9034152e21 100644 --- a/driver/tcpm/tcpci.h +++ b/driver/tcpm/tcpci.h @@ -222,6 +222,10 @@ int tcpci_tcpm_release(int port); #ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE int tcpci_set_role_ctrl(int port, int toggle, int rp, int pull); int tcpci_tcpc_drp_toggle(int port); +#ifdef CONFIG_ZORK_AUTO_DISCHARGE +int tcpci_tcpc_set_connection(int port, enum tcpc_cc_pull pull, + int connect); +#endif #endif #ifdef CONFIG_USB_PD_TCPC_LOW_POWER int tcpci_enter_low_power_mode(int port); diff --git a/driver/tcpm/tcpm.h b/driver/tcpm/tcpm.h index 373fbf545f..0e3e2c62f5 100644 --- a/driver/tcpm/tcpm.h +++ b/driver/tcpm/tcpm.h @@ -178,6 +178,7 @@ static inline int tcpm_set_cc(int port, int pull) return tcpc_config[port].drv->set_cc(port, pull); } +#ifndef CONFIG_ZORK_AUTO_DISCHARGE static inline int tcpm_set_new_connection(int port, enum tcpc_cc_pull pull) { @@ -189,6 +190,19 @@ static inline int tcpm_set_new_connection(int port, else return tcpc->set_cc(port, pull); } +#else +static inline int tcpm_set_connection(int port, + enum tcpc_cc_pull pull, + int connect) +{ + const struct tcpm_drv *tcpc = tcpc_config[port].drv; + + if (IS_ENABLED(CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE) && + tcpc->set_connection) + return tcpc->set_connection(port, pull, connect); + return EC_SUCCESS; +} +#endif static inline int tcpm_set_polarity(int port, enum tcpc_cc_polarity polarity) { diff --git a/include/config.h b/include/config.h index e1be5db2ad..3729ce0f76 100644 --- a/include/config.h +++ b/include/config.h @@ -3672,6 +3672,9 @@ */ #undef CONFIG_USB_PD_TCPMV2 +/* Enables Zork Auto Discharge Disconnect Changes */ +#undef CONFIG_ZORK_AUTO_DISCHARGE + /* Enables PD Console commands */ #define CONFIG_USB_PD_CONSOLE_CMD diff --git a/include/usb_pd_tcpm.h b/include/usb_pd_tcpm.h index 4589fc4839..39eab7e63b 100644 --- a/include/usb_pd_tcpm.h +++ b/include/usb_pd_tcpm.h @@ -319,6 +319,7 @@ struct tcpm_drv { void (*tcpc_enable_auto_discharge_disconnect)(int port, int enable); +#ifndef CONFIG_ZORK_AUTO_DISCHARGE /** * Set new connection * There is a new connection. May have to handle differently @@ -335,6 +336,27 @@ struct tcpm_drv { */ int (*set_new_connection)(int port, enum tcpc_cc_pull pull); +#else + /** + * Set connection + * If this is a disconnect, set the ROLE_CONTROL, otherwise + * this is a new connection. May have to handle differently + * if we were performing auto-toggle. Allow a driver to do + * any work required to leave the unattached auto-toggle mode + * as well as setting the CC lines. If auto-toggle is not + * being used or was not the cause of the new connection + * detection then set both CC lines to the passed pull. + * + * @param port Type-C port number + * @param pull enum tcpc_cc_pull of CC lines + * @param connect Connect(1) or Disconnect(0) + * + * @return EC_SUCCESS or error + */ + int (*set_connection)(int port, + enum tcpc_cc_pull pull, + int connect); +#endif #ifdef CONFIG_USB_PD_DUAL_ROLE_AUTO_TOGGLE /** |