diff options
Diffstat (limited to 'common/usbc')
-rw-r--r-- | common/usbc/build.mk | 2 | ||||
-rw-r--r-- | common/usbc/dp_alt_mode.c | 74 | ||||
-rw-r--r-- | common/usbc/tbt_alt_mode.c | 398 | ||||
-rw-r--r-- | common/usbc/usb_mode.c | 144 | ||||
-rw-r--r-- | common/usbc/usb_pd_console.c | 75 | ||||
-rw-r--r-- | common/usbc/usb_pd_dp_ufp.c | 54 | ||||
-rw-r--r-- | common/usbc/usb_pd_dpm.c | 344 | ||||
-rw-r--r-- | common/usbc/usb_pd_host.c | 45 | ||||
-rw-r--r-- | common/usbc/usb_pd_timer.c | 133 | ||||
-rw-r--r-- | common/usbc/usb_pe_ctvpd_sm.c | 57 | ||||
-rw-r--r-- | common/usbc/usb_pe_drp_sm.c | 1040 | ||||
-rw-r--r-- | common/usbc/usb_pe_private.h | 84 | ||||
-rw-r--r-- | common/usbc/usb_prl_sm.c | 285 | ||||
-rw-r--r-- | common/usbc/usb_retimer_fw_update.c | 188 | ||||
-rw-r--r-- | common/usbc/usb_sm.c | 30 | ||||
-rw-r--r-- | common/usbc/usb_tc_ctvpd_sm.c | 68 | ||||
-rw-r--r-- | common/usbc/usb_tc_drp_acc_trysrc_sm.c | 398 | ||||
-rw-r--r-- | common/usbc/usb_tc_vpd_sm.c | 21 | ||||
-rw-r--r-- | common/usbc/usbc_pd_policy.c | 10 | ||||
-rw-r--r-- | common/usbc/usbc_task.c | 7 |
20 files changed, 2068 insertions, 1389 deletions
diff --git a/common/usbc/build.mk b/common/usbc/build.mk index 60e2347741..15c9f06001 100644 --- a/common/usbc/build.mk +++ b/common/usbc/build.mk @@ -1,4 +1,4 @@ -# Copyright 2019 The Chromium OS Authors. All rights reserved. +# Copyright 2019 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. diff --git a/common/usbc/dp_alt_mode.c b/common/usbc/dp_alt_mode.c index 5cf3c03ba8..0f2a42ec2a 100644 --- a/common/usbc/dp_alt_mode.c +++ b/common/usbc/dp_alt_mode.c @@ -1,4 +1,4 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. +/* Copyright 2020 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -11,8 +11,8 @@ #include <stdbool.h> #include <stdint.h> -#include "assert.h" #include "atomic.h" +#include "builtin/assert.h" #include "console.h" #include "usb_common.h" #include "usb_dp_alt_mode.h" @@ -20,8 +20,8 @@ #include "usb_pd_tcpm.h" #ifdef CONFIG_COMMON_RUNTIME -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) #else #define CPRINTF(format, args...) #define CPRINTS(format, args...) @@ -47,24 +47,20 @@ static enum dp_states dp_state[CONFIG_USB_PD_PORT_MAX_COUNT]; * Default of 0 indicates no command expected. */ static const uint8_t state_vdm_cmd[DP_STATE_COUNT] = { - [DP_START] = CMD_ENTER_MODE, - [DP_ENTER_ACKED] = CMD_DP_STATUS, - [DP_PREPARE_CONFIG] = CMD_DP_CONFIG, - [DP_PREPARE_EXIT] = CMD_EXIT_MODE, + [DP_START] = CMD_ENTER_MODE, [DP_ENTER_ACKED] = CMD_DP_STATUS, + [DP_PREPARE_CONFIG] = CMD_DP_CONFIG, [DP_PREPARE_EXIT] = CMD_EXIT_MODE, [DP_ENTER_RETRY] = CMD_ENTER_MODE, }; /* * Track if we're retrying due to an Enter Mode NAK */ -#define DP_FLAG_RETRY BIT(0) +#define DP_FLAG_RETRY BIT(0) static atomic_t dpm_dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; -#define DP_SET_FLAG(port, flag) \ - atomic_or(&dpm_dp_flags[port], (flag)) -#define DP_CLR_FLAG(port, flag) \ - atomic_clear_bits(&dpm_dp_flags[port], (flag)) +#define DP_SET_FLAG(port, flag) atomic_or(&dpm_dp_flags[port], (flag)) +#define DP_CLR_FLAG(port, flag) atomic_clear_bits(&dpm_dp_flags[port], (flag)) #define DP_CHK_FLAG(port, flag) (dpm_dp_flags[port] & (flag)) bool dp_is_active(int port) @@ -72,6 +68,11 @@ bool dp_is_active(int port) return dp_state[port] == DP_ACTIVE || dp_state[port] == DP_PREPARE_EXIT; } +bool dp_is_idle(int port) +{ + return dp_state[port] == DP_INACTIVE || dp_state[port] == DP_START; +} + void dp_init(int port) { dp_state[port] = DP_START; @@ -80,8 +81,7 @@ void dp_init(int port) bool dp_entry_is_done(int port) { - return dp_state[port] == DP_ACTIVE || - dp_state[port] == DP_INACTIVE; + return dp_state[port] == DP_ACTIVE || dp_state[port] == DP_INACTIVE; } static void dp_entry_failed(int port) @@ -91,8 +91,8 @@ static void dp_entry_failed(int port) dpm_dp_flags[port] = 0; } -static bool dp_response_valid(int port, enum tcpci_msg_type type, - char *cmdt, int vdm_cmd) +static bool dp_response_valid(int port, enum tcpci_msg_type type, char *cmdt, + int vdm_cmd) { enum dp_states st = dp_state[port]; @@ -103,7 +103,8 @@ static bool dp_response_valid(int port, enum tcpci_msg_type type, if (type != TCPCI_MSG_SOP || (st != DP_INACTIVE && state_vdm_cmd[st] != vdm_cmd)) { CPRINTS("C%d: Received unexpected DP VDM %s (cmd %d) from" - " %s in state %d", port, cmdt, vdm_cmd, + " %s in state %d", + port, cmdt, vdm_cmd, type == TCPCI_MSG_SOP ? "port partner" : "cable plug", st); dp_entry_failed(port); @@ -120,17 +121,17 @@ static void dp_exit_to_usb_mode(int port) set_usb_mux_with_current_data_role(port); CPRINTS("C%d: Exited DP mode", port); - /* - * If the EC exits an alt mode autonomously, don't try to enter it again. If - * the AP commands the EC to exit DP mode, it might command the EC to enter - * again later, so leave the state machine ready for that possibility. - */ - dp_state[port] = IS_ENABLED(CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY) - ? DP_START : DP_INACTIVE; + /* + * If the EC exits an alt mode autonomously, don't try to enter it + * again. If the AP commands the EC to exit DP mode, it might command + * the EC to enter again later, so leave the state machine ready for + * that possibility. + */ + dp_state[port] = DP_INACTIVE; } void dp_vdm_acked(int port, enum tcpci_msg_type type, int vdo_count, - uint32_t *vdm) + uint32_t *vdm) { const struct svdm_amode_data *modep = pd_get_amode_data(port, type, USB_SID_DISPLAYPORT); @@ -180,8 +181,8 @@ void dp_vdm_acked(int port, enum tcpci_msg_type type, int vdo_count, break; default: /* Invalid or unexpected negotiation state */ - CPRINTF("%s called with invalid state %d\n", - __func__, dp_state[port]); + CPRINTF("%s called with invalid state %d\n", __func__, + dp_state[port]); dp_entry_failed(port); break; } @@ -216,8 +217,8 @@ void dp_vdm_naked(int port, enum tcpci_msg_type type, uint8_t vdm_cmd) dp_exit_to_usb_mode(port); break; default: - CPRINTS("C%d: NAK for cmd %d in state %d", port, - vdm_cmd, dp_state[port]); + CPRINTS("C%d: NAK for cmd %d in state %d", port, vdm_cmd, + dp_state[port]); dp_entry_failed(port); break; } @@ -226,8 +227,8 @@ void dp_vdm_naked(int port, enum tcpci_msg_type type, uint8_t vdm_cmd) enum dpm_msg_setup_status dp_setup_next_vdm(int port, int *vdo_count, uint32_t *vdm) { - const struct svdm_amode_data *modep = pd_get_amode_data(port, - TCPCI_MSG_SOP, USB_SID_DISPLAYPORT); + const struct svdm_amode_data *modep = + pd_get_amode_data(port, TCPCI_MSG_SOP, USB_SID_DISPLAYPORT); int vdo_count_ret; if (*vdo_count < VDO_MAX_SIZE) @@ -238,7 +239,7 @@ enum dpm_msg_setup_status dp_setup_next_vdm(int port, int *vdo_count, case DP_ENTER_RETRY: /* Enter the first supported mode for DisplayPort. */ vdm[0] = pd_dfp_enter_mode(port, TCPCI_MSG_SOP, - USB_SID_DISPLAYPORT, 0); + USB_SID_DISPLAYPORT, 0); if (vdm[0] == 0) return MSG_SETUP_ERROR; /* CMDT_INIT is 0, so this is a no-op */ @@ -311,8 +312,7 @@ enum dpm_msg_setup_status dp_setup_next_vdm(int port, int *vdo_count, return MSG_SETUP_MUX_WAIT; case DP_PREPARE_EXIT: /* DPM should call setup only after safe state is set */ - vdm[0] = VDO(USB_SID_DISPLAYPORT, - 1, /* structured */ + vdm[0] = VDO(USB_SID_DISPLAYPORT, 1, /* structured */ CMD_EXIT_MODE); vdm[0] |= VDO_OPOS(modep->opos); @@ -326,8 +326,8 @@ enum dpm_msg_setup_status dp_setup_next_vdm(int port, int *vdo_count, */ return MSG_SETUP_ERROR; default: - CPRINTF("%s called with invalid state %d\n", - __func__, dp_state[port]); + CPRINTF("%s called with invalid state %d\n", __func__, + dp_state[port]); return MSG_SETUP_ERROR; } diff --git a/common/usbc/tbt_alt_mode.c b/common/usbc/tbt_alt_mode.c index 5baf9d1a73..d1ad031fad 100644 --- a/common/usbc/tbt_alt_mode.c +++ b/common/usbc/tbt_alt_mode.c @@ -1,4 +1,4 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. +/* Copyright 2020 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -14,6 +14,7 @@ #include "compile_time_macros.h" #include "console.h" #include "tcpm/tcpm.h" +#include "typec_control.h" #include "usb_common.h" #include "usb_mux.h" #include "usb_pd.h" @@ -57,8 +58,8 @@ */ #ifdef CONFIG_COMMON_RUNTIME -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) #else #define CPRINTF(format, args...) #define CPRINTS(format, args...) @@ -70,8 +71,8 @@ * with a partner. It may be fixed in b/159495742, in which case this * logic is unneeded. */ -#define TBT_FLAG_RETRY_DONE BIT(0) -#define TBT_FLAG_EXIT_DONE BIT(1) +#define TBT_FLAG_RETRY_DONE BIT(0) +#define TBT_FLAG_EXIT_DONE BIT(1) #define TBT_FLAG_CABLE_ENTRY_DONE BIT(2) static uint8_t tbt_flags[CONFIG_USB_PD_PORT_MAX_COUNT]; @@ -123,14 +124,12 @@ void tbt_init(int port) bool tbt_is_active(int port) { - return tbt_state[port] != TBT_INACTIVE && - tbt_state[port] != TBT_START; + return tbt_state[port] != TBT_INACTIVE && tbt_state[port] != TBT_START; } bool tbt_entry_is_done(int port) { - return tbt_state[port] == TBT_ACTIVE || - tbt_state[port] == TBT_INACTIVE; + return tbt_state[port] == TBT_ACTIVE || tbt_state[port] == TBT_INACTIVE; } bool tbt_cable_entry_is_done(int port) @@ -140,13 +139,15 @@ bool tbt_cable_entry_is_done(int port) static void tbt_exit_done(int port) { - /* - * If the EC exits an alt mode autonomously, don't try to enter it again. If - * the AP commands the EC to exit DP mode, it might command the EC to enter - * again later, so leave the state machine ready for that possibility. - */ - tbt_state[port] = IS_ENABLED(CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY) - ? TBT_START : TBT_INACTIVE; + /* + * If the EC exits an alt mode autonomously, don't try to enter it + * again. If the AP commands the EC to exit DP mode, it might command + * the EC to enter again later, so leave the state machine ready for + * that possibility. + */ + tbt_state[port] = IS_ENABLED(CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY) ? + TBT_START : + TBT_INACTIVE; TBT_CLR_FLAG(port, TBT_FLAG_RETRY_DONE); TBT_CLR_FLAG(port, TBT_FLAG_CABLE_ENTRY_DONE); @@ -159,10 +160,47 @@ static void tbt_exit_done(int port) tbt_prints("alt mode protocol failed!", port); } -void tbt_exit_mode_request(int port) +static bool tbt_is_lrd_active_cable(int port) { union tbt_mode_resp_cable cable_mode_resp; + cable_mode_resp.raw_value = + pd_get_tbt_mode_vdo(port, TCPCI_MSG_SOP_PRIME); + if (get_usb_pd_cable_type(port) == IDH_PTYPE_PCABLE && + cable_mode_resp.tbt_active_passive == TBT_CABLE_ACTIVE) + return true; + + return false; +} + +/* Check if this port requires SOP' mode entry and exit */ +static bool tbt_sop_prime_needed(int port) +{ + /* + * We require SOP' entry if cable is + * active cable, or + * an LRD cable (passive in DiscoverIdentity, active in TBT mode) + */ + if (get_usb_pd_cable_type(port) == IDH_PTYPE_ACABLE || + tbt_is_lrd_active_cable(port)) + return true; + return false; +} + +/* Check if this port requires SOP'' mode entry and exit */ +static bool tbt_sop_prime_prime_needed(int port) +{ + const struct pd_discovery *disc; + + disc = pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME); + if (get_usb_pd_cable_type(port) == IDH_PTYPE_ACABLE && + disc->identity.product_t1.a_rev20.sop_p_p) + return true; + return false; +} + +void tbt_exit_mode_request(int port) +{ TBT_SET_FLAG(port, TBT_FLAG_RETRY_DONE); TBT_CLR_FLAG(port, TBT_FLAG_EXIT_DONE); /* @@ -172,26 +210,24 @@ void tbt_exit_mode_request(int port) * TODO (b/156749387): Remove once data reset feature is in place. */ if (tbt_state[port] == TBT_ENTER_SOP) { - cable_mode_resp.raw_value = - pd_get_tbt_mode_vdo(port, TCPCI_MSG_SOP_PRIME); - /* * For Linear re-driver cables, the port enters USB4 mode * with Thunderbolt mode for SOP prime. Hence, on request to * exit, only exit Thunderbolt mode SOP prime */ - tbt_state[port] = - cable_mode_resp.tbt_active_passive == TBT_CABLE_ACTIVE ? - TBT_EXIT_SOP_PRIME : TBT_EXIT_SOP_PRIME_PRIME; + tbt_state[port] = tbt_sop_prime_prime_needed(port) ? + TBT_EXIT_SOP_PRIME_PRIME : + TBT_EXIT_SOP_PRIME; } } -static bool tbt_response_valid(int port, enum tcpci_msg_type type, - char *cmdt, int vdm_cmd) +static bool tbt_response_valid(int port, enum tcpci_msg_type type, char *cmdt, + int vdm_cmd) { enum tbt_states st = tbt_state[port]; union tbt_mode_resp_cable cable_mode_resp = { - .raw_value = pd_get_tbt_mode_vdo(port, TCPCI_MSG_SOP_PRIME) }; + .raw_value = pd_get_tbt_mode_vdo(port, TCPCI_MSG_SOP_PRIME) + }; /* * Check for an unexpected response. @@ -216,71 +252,50 @@ static void tbt_retry_enter_mode(int port) TBT_SET_FLAG(port, TBT_FLAG_RETRY_DONE); } -/* Send Exit Mode to SOP''(if supported), or SOP' */ -static void tbt_active_cable_exit_mode(int port) -{ - const struct pd_discovery *disc; - - disc = pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME); - - if (disc->identity.product_t1.a_rev20.sop_p_p) - tbt_state[port] = TBT_EXIT_SOP_PRIME_PRIME; - else - tbt_state[port] = TBT_EXIT_SOP_PRIME; -} - bool tbt_cable_entry_required_for_usb4(int port) { const struct pd_discovery *disc_sop_prime; - union tbt_mode_resp_cable cable_mode_resp; - /* Request to enter Thunderbolt mode for the cable prior to entering - * USB4 mode if - - * 1. Thunderbolt Mode SOP' VDO active/passive bit (B25) is - * TBT_CABLE_ACTIVE or - * 2. It's an active cable with VDM version < 2.0 or - * VDO version < 1.3 - */ if (tbt_cable_entry_is_done(port)) return false; - cable_mode_resp.raw_value = - pd_get_tbt_mode_vdo(port, TCPCI_MSG_SOP_PRIME); - - if (cable_mode_resp.tbt_active_passive == TBT_CABLE_ACTIVE) + /* + * For some cables, the TCPM may need to enter TBT mode with the + * cable to support USB4 mode with the partner. Request to enter + * Thunderbolt mode for the cable prior to entering USB4 for + * the port partner if + * 1. The cable advertises itself as passive in its Identity VDO + * but active in its TBT mode VDO, or + * 2. The cable advertises itself as active, but its PD support + * is not new enough to support Enter_USB. + */ + if (tbt_is_lrd_active_cable(port)) return true; if (get_usb_pd_cable_type(port) == IDH_PTYPE_ACABLE) { disc_sop_prime = pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME); if (pd_get_vdo_ver(port, TCPCI_MSG_SOP_PRIME) < VDM_VER20 || disc_sop_prime->identity.product_t1.a_rev30.vdo_ver < - VDO_VERSION_1_3) + VDO_VERSION_1_3) return true; } return false; } void intel_vdm_acked(int port, enum tcpci_msg_type type, int vdo_count, - uint32_t *vdm) + uint32_t *vdm) { - const struct pd_discovery *disc; const uint8_t vdm_cmd = PD_VDO_CMD(vdm[0]); int opos_sop, opos_sop_prime; - union tbt_mode_resp_cable cable_mode_resp; if (!tbt_response_valid(port, type, "ACK", vdm_cmd)) return; - disc = pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME); - switch (tbt_state[port]) { case TBT_ENTER_SOP_PRIME: tbt_prints("enter mode SOP'", port); - cable_mode_resp.raw_value = - pd_get_tbt_mode_vdo(port, TCPCI_MSG_SOP_PRIME); /* For LRD cables, Enter mode SOP' -> Enter mode SOP */ - if (disc->identity.product_t1.a_rev20.sop_p_p && - cable_mode_resp.tbt_active_passive != TBT_CABLE_ACTIVE) { + if (tbt_sop_prime_prime_needed(port)) { tbt_state[port] = TBT_ENTER_SOP_PRIME_PRIME; } else { TBT_SET_FLAG(port, TBT_FLAG_CABLE_ENTRY_DONE); @@ -308,8 +323,11 @@ void intel_vdm_acked(int port, enum tcpci_msg_type type, int vdo_count, if (opos_sop > 0) pd_dfp_exit_mode(port, TCPCI_MSG_SOP, USB_VID_INTEL, opos_sop); - if (get_usb_pd_cable_type(port) == IDH_PTYPE_ACABLE) { - tbt_active_cable_exit_mode(port); + + if (tbt_sop_prime_prime_needed(port)) { + tbt_state[port] = TBT_EXIT_SOP_PRIME_PRIME; + } else if (tbt_sop_prime_needed(port)) { + tbt_state[port] = TBT_EXIT_SOP_PRIME; } else { set_usb_mux_with_current_data_role(port); if (TBT_CHK_FLAG(port, TBT_FLAG_RETRY_DONE)) @@ -330,13 +348,12 @@ void intel_vdm_acked(int port, enum tcpci_msg_type type, int vdo_count, * Exit mode process is complete; go to inactive state. */ tbt_exit_done(port); - opos_sop_prime = - pd_alt_mode(port, TCPCI_MSG_SOP_PRIME, - USB_VID_INTEL); + opos_sop_prime = pd_alt_mode(port, TCPCI_MSG_SOP_PRIME, + USB_VID_INTEL); /* Clear Thunderbolt related signals */ pd_dfp_exit_mode(port, TCPCI_MSG_SOP_PRIME, - USB_VID_INTEL, opos_sop_prime); + USB_VID_INTEL, opos_sop_prime); set_usb_mux_with_current_data_role(port); } else { tbt_retry_enter_mode(port); @@ -351,8 +368,8 @@ void intel_vdm_acked(int port, enum tcpci_msg_type type, int vdo_count, break; default: /* Invalid or unexpected negotiation state */ - CPRINTF("%s called with invalid state %d\n", - __func__, tbt_state[port]); + CPRINTF("%s called with invalid state %d\n", __func__, + tbt_state[port]); tbt_exit_done(port); break; } @@ -378,9 +395,12 @@ void intel_vdm_naked(int port, enum tcpci_msg_type type, uint8_t vdm_cmd) case TBT_EXIT_SOP: /* Exit SOP got NAK'ed */ tbt_prints("exit mode SOP failed", port); - if (get_usb_pd_cable_type(port) == IDH_PTYPE_ACABLE) - tbt_active_cable_exit_mode(port); - else { + + if (tbt_sop_prime_prime_needed(port)) { + tbt_state[port] = TBT_EXIT_SOP_PRIME_PRIME; + } else if (tbt_sop_prime_needed(port)) { + tbt_state[port] = TBT_EXIT_SOP_PRIME; + } else { set_usb_mux_with_current_data_role(port); if (TBT_CHK_FLAG(port, TBT_FLAG_RETRY_DONE)) /* Retried enter mode, still failed, give up */ @@ -406,8 +426,8 @@ void intel_vdm_naked(int port, enum tcpci_msg_type type, uint8_t vdm_cmd) } break; default: - CPRINTS("C%d: NAK for cmd %d in state %d", port, - vdm_cmd, tbt_state[port]); + CPRINTS("C%d: NAK for cmd %d in state %d", port, vdm_cmd, + tbt_state[port]); tbt_exit_done(port); break; } @@ -416,7 +436,7 @@ void intel_vdm_naked(int port, enum tcpci_msg_type type, uint8_t vdm_cmd) static bool tbt_mode_is_supported(int port, int vdo_count) { const struct pd_discovery *disc = - pd_get_am_discovery(port, TCPCI_MSG_SOP); + pd_get_am_discovery(port, TCPCI_MSG_SOP); if (!disc->identity.idh.modal_support) return false; @@ -430,8 +450,8 @@ static bool tbt_mode_is_supported(int port, int vdo_count) * SVID USB_VID_INTEL to enter Thunderbolt alt mode */ if (get_usb_pd_cable_type(port) == IDH_PTYPE_ACABLE && - !pd_is_mode_discovered_for_svid( - port, TCPCI_MSG_SOP_PRIME, USB_VID_INTEL)) + !pd_is_mode_discovered_for_svid(port, TCPCI_MSG_SOP_PRIME, + USB_VID_INTEL)) return false; return true; @@ -443,7 +463,6 @@ enum dpm_msg_setup_status tbt_setup_next_vdm(int port, int *vdo_count, { struct svdm_amode_data *modep; int vdo_count_ret = 0; - union tbt_mode_resp_cable cable_mode_resp; *tx_type = TCPCI_MSG_SOP; @@ -467,12 +486,8 @@ enum dpm_msg_setup_status tbt_setup_next_vdm(int port, int *vdo_count, */ usb_mux_set_safe_mode(port); - cable_mode_resp.raw_value = - pd_get_tbt_mode_vdo(port, TCPCI_MSG_SOP_PRIME); - /* Active cable and LRD cables send Enter Mode SOP' first */ - if (get_usb_pd_cable_type(port) == IDH_PTYPE_ACABLE || - cable_mode_resp.tbt_active_passive == TBT_CABLE_ACTIVE) { + if (tbt_sop_prime_needed(port)) { tbt_state[port] = TBT_ENTER_SOP_PRIME; } else { /* Passive cable send Enter Mode SOP */ @@ -486,14 +501,12 @@ enum dpm_msg_setup_status tbt_setup_next_vdm(int port, int *vdo_count, *tx_type = TCPCI_MSG_SOP_PRIME; break; case TBT_ENTER_SOP_PRIME_PRIME: - vdo_count_ret = - enter_tbt_compat_mode( - port, TCPCI_MSG_SOP_PRIME_PRIME, vdm); + vdo_count_ret = enter_tbt_compat_mode( + port, TCPCI_MSG_SOP_PRIME_PRIME, vdm); *tx_type = TCPCI_MSG_SOP_PRIME_PRIME; break; case TBT_ENTER_SOP: - vdo_count_ret = - enter_tbt_compat_mode(port, TCPCI_MSG_SOP, vdm); + vdo_count_ret = enter_tbt_compat_mode(port, TCPCI_MSG_SOP, vdm); break; case TBT_ACTIVE: /* @@ -515,43 +528,38 @@ enum dpm_msg_setup_status tbt_setup_next_vdm(int port, int *vdo_count, return MSG_SETUP_MUX_WAIT; case TBT_EXIT_SOP: /* DPM will only call this after safe state set is done */ - modep = pd_get_amode_data(port, - TCPCI_MSG_SOP, USB_VID_INTEL); + modep = pd_get_amode_data(port, TCPCI_MSG_SOP, USB_VID_INTEL); if (!(modep && modep->opos)) return MSG_SETUP_ERROR; vdm[0] = VDO(USB_VID_INTEL, 1, CMD_EXIT_MODE) | - VDO_OPOS(modep->opos) | - VDO_CMDT(CMDT_INIT) | - VDO_SVDM_VERS( - pd_get_vdo_ver(port, TCPCI_MSG_SOP)); + VDO_OPOS(modep->opos) | VDO_CMDT(CMDT_INIT) | + VDO_SVDM_VERS(pd_get_vdo_ver(port, TCPCI_MSG_SOP)); vdo_count_ret = 1; break; case TBT_EXIT_SOP_PRIME_PRIME: - modep = pd_get_amode_data(port, - TCPCI_MSG_SOP_PRIME, USB_VID_INTEL); + modep = pd_get_amode_data(port, TCPCI_MSG_SOP_PRIME, + USB_VID_INTEL); if (!(modep && modep->opos)) return MSG_SETUP_ERROR; vdm[0] = VDO(USB_VID_INTEL, 1, CMD_EXIT_MODE) | - VDO_OPOS(modep->opos) | - VDO_CMDT(CMDT_INIT) | - VDO_SVDM_VERS(pd_get_vdo_ver(port, - TCPCI_MSG_SOP_PRIME_PRIME)); + VDO_OPOS(modep->opos) | VDO_CMDT(CMDT_INIT) | + VDO_SVDM_VERS(pd_get_vdo_ver( + port, TCPCI_MSG_SOP_PRIME_PRIME)); vdo_count_ret = 1; *tx_type = TCPCI_MSG_SOP_PRIME_PRIME; break; case TBT_EXIT_SOP_PRIME: - modep = pd_get_amode_data(port, - TCPCI_MSG_SOP_PRIME, USB_VID_INTEL); + modep = pd_get_amode_data(port, TCPCI_MSG_SOP_PRIME, + USB_VID_INTEL); if (!(modep && modep->opos)) return MSG_SETUP_ERROR; vdm[0] = VDO(USB_VID_INTEL, 1, CMD_EXIT_MODE) | - VDO_OPOS(modep->opos) | - VDO_CMDT(CMDT_INIT) | - VDO_SVDM_VERS(pd_get_vdo_ver(port, - TCPCI_MSG_SOP_PRIME)); + VDO_OPOS(modep->opos) | VDO_CMDT(CMDT_INIT) | + VDO_SVDM_VERS( + pd_get_vdo_ver(port, TCPCI_MSG_SOP_PRIME)); vdo_count_ret = 1; *tx_type = TCPCI_MSG_SOP_PRIME; break; @@ -559,8 +567,8 @@ enum dpm_msg_setup_status tbt_setup_next_vdm(int port, int *vdo_count, /* Thunderbolt mode is inactive */ return MSG_SETUP_UNSUPPORTED; default: - CPRINTF("%s called with invalid state %d\n", - __func__, tbt_state[port]); + CPRINTF("%s called with invalid state %d\n", __func__, + tbt_state[port]); return MSG_SETUP_ERROR; } @@ -571,3 +579,177 @@ enum dpm_msg_setup_status tbt_setup_next_vdm(int port, int *vdo_count, return MSG_SETUP_UNSUPPORTED; } + +uint32_t pd_get_tbt_mode_vdo(int port, enum tcpci_msg_type type) +{ + uint32_t tbt_mode_vdo[PDO_MODES]; + + return pd_get_mode_vdo_for_svid(port, type, USB_VID_INTEL, + tbt_mode_vdo) ? + tbt_mode_vdo[0] : + 0; +} + +void set_tbt_compat_mode_ready(int port) +{ + if (IS_ENABLED(CONFIG_USBC_SS_MUX) && + IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE)) { + /* Connect the SBU and USB lines to the connector. */ + typec_set_sbu(port, true); + + /* Set usb mux to Thunderbolt-compatible mode */ + usb_mux_set(port, USB_PD_MUX_TBT_COMPAT_ENABLED, + USB_SWITCH_CONNECT, + polarity_rm_dts(pd_get_polarity(port))); + } +} + +/* + * Ref: USB Type-C Cable and Connector Specification + * Figure F-1 TBT3 Discovery Flow + */ +static bool is_tbt_cable_superspeed(int port) +{ + const struct pd_discovery *disc; + + if (!IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE) || + !IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) + return false; + + disc = pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME); + + /* Product type is Active cable, hence don't check for speed */ + if (disc->identity.idh.product_type == IDH_PTYPE_ACABLE) + return true; + + if (disc->identity.idh.product_type != IDH_PTYPE_PCABLE) + return false; + + if (IS_ENABLED(CONFIG_USB_PD_REV30) && + pd_get_rev(port, TCPCI_MSG_SOP_PRIME) == PD_REV30) + return disc->identity.product_t1.p_rev30.ss == + USB_R30_SS_U32_U40_GEN1 || + disc->identity.product_t1.p_rev30.ss == + USB_R30_SS_U32_U40_GEN2 || + disc->identity.product_t1.p_rev30.ss == + USB_R30_SS_U40_GEN3; + + return disc->identity.product_t1.p_rev20.ss == USB_R20_SS_U31_GEN1 || + disc->identity.product_t1.p_rev20.ss == USB_R20_SS_U31_GEN1_GEN2; +} + +static enum tbt_compat_cable_speed usb_rev30_to_tbt_speed(enum usb_rev30_ss ss) +{ + switch (ss) { + case USB_R30_SS_U32_U40_GEN1: + return TBT_SS_U31_GEN1; + case USB_R30_SS_U32_U40_GEN2: + return TBT_SS_U32_GEN1_GEN2; + case USB_R30_SS_U40_GEN3: + return TBT_SS_TBT_GEN3; + default: + return TBT_SS_U32_GEN1_GEN2; + } +} + +enum tbt_compat_cable_speed get_tbt_cable_speed(int port) +{ + union tbt_mode_resp_cable cable_mode_resp; + enum tbt_compat_cable_speed max_tbt_speed; + enum tbt_compat_cable_speed cable_tbt_speed; + + if (!is_tbt_cable_superspeed(port)) + return TBT_SS_RES_0; + + cable_mode_resp.raw_value = + pd_get_tbt_mode_vdo(port, TCPCI_MSG_SOP_PRIME); + max_tbt_speed = board_get_max_tbt_speed(port); + + /* + * Ref: TBT4 PD Discovery Flow Application Notes Revision 0.9, Figure 2 + * For passive cable, if cable doesn't support USB_VID_INTEL, enter + * Thunderbolt alternate mode with speed from USB Highest Speed field of + * the Passive Cable VDO + * For active cable, if the cable doesn't support USB_VID_INTEL, do not + * enter Thunderbolt alternate mode. + */ + if (!cable_mode_resp.raw_value) { + const struct pd_discovery *disc; + + if (get_usb_pd_cable_type(port) == IDH_PTYPE_ACABLE) + return TBT_SS_RES_0; + + disc = pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME); + cable_tbt_speed = usb_rev30_to_tbt_speed( + disc->identity.product_t1.p_rev30.ss); + } else { + cable_tbt_speed = cable_mode_resp.tbt_cable_speed; + } + + return max_tbt_speed < cable_tbt_speed ? max_tbt_speed : + cable_tbt_speed; +} + +/* Note: Assumes that pins have already been set in safe state */ +int enter_tbt_compat_mode(int port, enum tcpci_msg_type sop, uint32_t *payload) +{ + union tbt_dev_mode_enter_cmd enter_dev_mode = { .raw_value = 0 }; + union tbt_mode_resp_device dev_mode_resp; + union tbt_mode_resp_cable cable_mode_resp; + enum tcpci_msg_type enter_mode_sop = + sop == TCPCI_MSG_SOP_PRIME_PRIME ? TCPCI_MSG_SOP_PRIME : sop; + + /* Table F-12 TBT3 Cable Enter Mode Command */ + /* + * The port doesn't query Discover SOP'' to the cable so, the port + * doesn't have opos for SOP''. Hence, send Enter Mode SOP'' with same + * opos and revision as SOP'. + */ + payload[0] = pd_dfp_enter_mode(port, enter_mode_sop, USB_VID_INTEL, 0) | + VDO_CMDT(CMDT_INIT) | + VDO_SVDM_VERS(pd_get_vdo_ver(port, enter_mode_sop)); + + /* For TBT3 Cable Enter Mode Command, number of Objects is 1 */ + if ((sop == TCPCI_MSG_SOP_PRIME) || (sop == TCPCI_MSG_SOP_PRIME_PRIME)) + return 1; + + dev_mode_resp.raw_value = pd_get_tbt_mode_vdo(port, TCPCI_MSG_SOP); + cable_mode_resp.raw_value = + pd_get_tbt_mode_vdo(port, TCPCI_MSG_SOP_PRIME); + + /* Table F-13 TBT3 Device Enter Mode Command */ + enter_dev_mode.vendor_spec_b1 = dev_mode_resp.vendor_spec_b1; + enter_dev_mode.vendor_spec_b0 = dev_mode_resp.vendor_spec_b0; + enter_dev_mode.intel_spec_b0 = dev_mode_resp.intel_spec_b0; + + if (get_usb_pd_cable_type(port) == IDH_PTYPE_ACABLE || + cable_mode_resp.tbt_active_passive == TBT_CABLE_ACTIVE) + enter_dev_mode.cable = TBT_ENTER_ACTIVE_CABLE; + + enter_dev_mode.lsrx_comm = cable_mode_resp.lsrx_comm; + enter_dev_mode.retimer_type = cable_mode_resp.retimer_type; + enter_dev_mode.tbt_cable = cable_mode_resp.tbt_cable; + enter_dev_mode.tbt_rounded = cable_mode_resp.tbt_rounded; + enter_dev_mode.tbt_cable_speed = get_tbt_cable_speed(port); + enter_dev_mode.tbt_alt_mode = TBT_ALTERNATE_MODE; + + payload[1] = enter_dev_mode.raw_value; + + /* For TBT3 Device Enter Mode Command, number of Objects are 2 */ + return 2; +} + +enum tbt_compat_rounded_support get_tbt_rounded_support(int port) +{ + union tbt_mode_resp_cable cable_mode_resp = { + .raw_value = pd_get_tbt_mode_vdo(port, TCPCI_MSG_SOP_PRIME) + }; + + /* tbt_rounded_support is zero when uninitialized */ + return cable_mode_resp.tbt_rounded; +} + +__overridable enum tbt_compat_cable_speed board_get_max_tbt_speed(int port) +{ + return TBT_SS_TBT_GEN3; +} diff --git a/common/usbc/usb_mode.c b/common/usbc/usb_mode.c index e7c385c59c..8f4824e4e9 100644 --- a/common/usbc/usb_mode.c +++ b/common/usbc/usb_mode.c @@ -1,4 +1,4 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. +/* Copyright 2020 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -26,8 +26,8 @@ #include "usbc_ppc.h" #ifdef CONFIG_COMMON_RUNTIME -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) #else #define CPRINTF(format, args...) #define CPRINTS(format, args...) @@ -117,7 +117,7 @@ static void usb4_debug_prints(int port, enum usb4_mode_status usb4_status) bool enter_usb_entry_is_done(int port) { return usb4_state[port] == USB4_ACTIVE || - usb4_state[port] == USB4_INACTIVE; + usb4_state[port] == USB4_INACTIVE; } void usb4_exit_mode_request(int port) @@ -153,7 +153,7 @@ static bool enter_usb_response_valid(int port, enum tcpci_msg_type type) * Check for an unexpected response. */ if (get_usb_pd_cable_type(port) == IDH_PTYPE_PCABLE && - type != TCPCI_MSG_SOP) { + type != TCPCI_MSG_SOP) { enter_usb_failed(port); return false; } @@ -163,7 +163,7 @@ static bool enter_usb_response_valid(int port, enum tcpci_msg_type type) bool enter_usb_port_partner_is_capable(int port) { const struct pd_discovery *disc = - pd_get_am_discovery(port, TCPCI_MSG_SOP); + pd_get_am_discovery(port, TCPCI_MSG_SOP); if (usb4_state[port] == USB4_INACTIVE) return false; @@ -185,7 +185,7 @@ bool enter_usb_cable_is_capable(int port) if (pd_get_vdo_ver(port, TCPCI_MSG_SOP_PRIME) >= VDM_VER20 && disc_sop_prime->identity.product_t1.a_rev30.vdo_ver >= - VDO_VERSION_1_3) { + VDO_VERSION_1_3) { union active_cable_vdo2_rev30 a2_rev30 = disc_sop_prime->identity.product_t2.a2_rev30; /* @@ -195,25 +195,25 @@ bool enter_usb_cable_is_capable(int port) */ if (a2_rev30.usb_40_support == USB4_NOT_SUPPORTED) return false; - /* - * For VDM version < 2.0 or VDO version < 1.3, do not enter USB4 - * mode if the cable - - * doesn't support modal operation or - * doesn't support Intel SVID or - * doesn't have rounded support. - */ + /* + * For VDM version < 2.0 or VDO version < 1.3, do not + * enter USB4 mode if the cable - doesn't support modal + * operation or doesn't support Intel SVID or doesn't + * have rounded support. + */ } else { const struct pd_discovery *disc = pd_get_am_discovery(port, TCPCI_MSG_SOP); union tbt_mode_resp_cable cable_mode_resp = { - .raw_value = pd_get_tbt_mode_vdo(port, - TCPCI_MSG_SOP_PRIME) }; + .raw_value = pd_get_tbt_mode_vdo( + port, TCPCI_MSG_SOP_PRIME) + }; if (!disc->identity.idh.modal_support || - !pd_is_mode_discovered_for_svid(port, - TCPCI_MSG_SOP_PRIME, USB_VID_INTEL) || + !pd_is_mode_discovered_for_svid( + port, TCPCI_MSG_SOP_PRIME, USB_VID_INTEL) || cable_mode_resp.tbt_rounded != - TBT_GEN3_GEN4_ROUNDED_NON_ROUNDED) + TBT_GEN3_GEN4_ROUNDED_NON_ROUNDED) return false; } } else { @@ -288,7 +288,7 @@ uint32_t enter_usb_setup_next_msg(int port, enum tcpci_msg_type *type) if (pd_get_vdo_ver(port, TCPCI_MSG_SOP_PRIME) < VDM_VER20 || disc_sop_prime->identity.product_t1.a_rev30.vdo_ver < - VDO_VERSION_1_3 || + VDO_VERSION_1_3 || get_usb_pd_cable_type(port) == IDH_PTYPE_PCABLE) { usb4_state[port] = USB4_ENTER_SOP; } else { @@ -312,3 +312,107 @@ uint32_t enter_usb_setup_next_msg(int port, enum tcpci_msg_type *type) } return get_enter_usb_msg_payload(port); } + +/* + * For Cable rev 3.0: USB4 cable speed is set according to speed supported by + * the port and the response received from the cable, whichever is least. + * + * For Cable rev 2.0: If get_tbt_cable_speed() is less than + * TBT_SS_U31_GEN1, return USB_R30_SS_U2_ONLY speed since the board + * doesn't support superspeed else the USB4 cable speed is set according to + * the cable response. + */ +enum usb_rev30_ss get_usb4_cable_speed(int port) +{ + enum tbt_compat_cable_speed tbt_speed = get_tbt_cable_speed(port); + enum usb_rev30_ss max_usb4_speed; + + if (tbt_speed < TBT_SS_U31_GEN1) + return USB_R30_SS_U2_ONLY; + + /* + * Converting Thunderbolt-Compatible board speed to equivalent USB4 + * speed. + */ + max_usb4_speed = tbt_speed == TBT_SS_TBT_GEN3 ? USB_R30_SS_U40_GEN3 : + USB_R30_SS_U32_U40_GEN2; + + if ((get_usb_pd_cable_type(port) == IDH_PTYPE_ACABLE) && + pd_get_rev(port, TCPCI_MSG_SOP_PRIME) == PD_REV30) { + const struct pd_discovery *disc = + pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME); + union active_cable_vdo1_rev30 a_rev30 = + disc->identity.product_t1.a_rev30; + + if (a_rev30.vdo_ver >= VDO_VERSION_1_3) { + return max_usb4_speed < a_rev30.ss ? max_usb4_speed : + a_rev30.ss; + } + } + + return max_usb4_speed; +} + +uint32_t get_enter_usb_msg_payload(int port) +{ + /* + * Ref: USB Power Delivery Specification Revision 3.0, Version 2.0 + * Table 6-47 Enter_USB Data Object + */ + union enter_usb_data_obj eudo; + const struct pd_discovery *disc; + union tbt_mode_resp_cable cable_mode_resp; + + if (!IS_ENABLED(CONFIG_USB_PD_USB4)) + return 0; + + disc = pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME); + eudo.mode = USB_PD_40; + eudo.usb4_drd_cap = IS_ENABLED(CONFIG_USB_PD_USB4_DRD); + eudo.usb3_drd_cap = IS_ENABLED(CONFIG_USB_PD_USB32_DRD); + eudo.cable_speed = get_usb4_cable_speed(port); + + if (disc->identity.idh.product_type == IDH_PTYPE_ACABLE) { + if (pd_get_rev(port, TCPCI_MSG_SOP_PRIME) == PD_REV30) { + enum retimer_active_element active_element = + disc->identity.product_t2.a2_rev30.active_elem; + eudo.cable_type = active_element == ACTIVE_RETIMER ? + CABLE_TYPE_ACTIVE_RETIMER : + CABLE_TYPE_ACTIVE_REDRIVER; + } else { + cable_mode_resp.raw_value = + pd_get_tbt_mode_vdo(port, TCPCI_MSG_SOP_PRIME); + + eudo.cable_type = cable_mode_resp.retimer_type == + USB_RETIMER ? + CABLE_TYPE_ACTIVE_RETIMER : + CABLE_TYPE_ACTIVE_REDRIVER; + } + } else { + cable_mode_resp.raw_value = + pd_get_tbt_mode_vdo(port, TCPCI_MSG_SOP_PRIME); + + eudo.cable_type = cable_mode_resp.tbt_active_passive == + TBT_CABLE_ACTIVE ? + CABLE_TYPE_ACTIVE_REDRIVER : + CABLE_TYPE_PASSIVE; + } + + switch (disc->identity.product_t1.p_rev20.vbus_cur) { + case USB_VBUS_CUR_3A: + eudo.cable_current = USB4_CABLE_CURRENT_3A; + break; + case USB_VBUS_CUR_5A: + eudo.cable_current = USB4_CABLE_CURRENT_5A; + break; + default: + eudo.cable_current = USB4_CABLE_CURRENT_INVALID; + break; + } + eudo.pcie_supported = IS_ENABLED(CONFIG_USB_PD_PCIE_TUNNELING); + eudo.dp_supported = IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP); + eudo.tbt_supported = IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE); + eudo.host_present = 1; + + return eudo.raw_value; +} diff --git a/common/usbc/usb_pd_console.c b/common/usbc/usb_pd_console.c index 6b1ea259eb..027a0d66c5 100644 --- a/common/usbc/usb_pd_console.c +++ b/common/usbc/usb_pd_console.c @@ -1,4 +1,4 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. +/* Copyright 2020 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -16,7 +16,8 @@ #ifndef TEST_USB_PD_CONSOLE static #endif -int command_pd(int argc, char **argv) + int + command_pd(int argc, const char **argv) { int port; char *e; @@ -43,7 +44,7 @@ int command_pd(int argc, char **argv) return EC_SUCCESS; } } else if (IS_ENABLED(CONFIG_USB_PD_TRY_SRC) && - !strcasecmp(argv[1], "trysrc")) { + !strcasecmp(argv[1], "trysrc")) { enum try_src_override_t ov = tc_get_try_src_override(); if (argc >= 3) { @@ -111,7 +112,7 @@ int command_pd(int argc, char **argv) else if (!strcasecmp(argv[3], "data")) pd_dpm_request(port, DPM_REQUEST_DR_SWAP); else if (IS_ENABLED(CONFIG_USBC_VCONN_SWAP) && - !strcasecmp(argv[3], "vconn")) + !strcasecmp(argv[3], "vconn")) pd_dpm_request(port, DPM_REQUEST_VCONN_SWAP); else return EC_ERROR_PARAM3; @@ -135,60 +136,66 @@ int command_pd(int argc, char **argv) case PD_DRP_FORCE_SOURCE: ccprintf("force source\n"); break; - cflush(); + cflush(); } } else { if (!strcasecmp(argv[3], "on")) pd_set_dual_role(port, - PD_DRP_TOGGLE_ON); + PD_DRP_TOGGLE_ON); else if (!strcasecmp(argv[3], "off")) pd_set_dual_role(port, - PD_DRP_TOGGLE_OFF); + PD_DRP_TOGGLE_OFF); else if (!strcasecmp(argv[3], "freeze")) pd_set_dual_role(port, PD_DRP_FREEZE); else if (!strcasecmp(argv[3], "sink")) pd_set_dual_role(port, - PD_DRP_FORCE_SINK); + PD_DRP_FORCE_SINK); else if (!strcasecmp(argv[3], "source")) pd_set_dual_role(port, - PD_DRP_FORCE_SOURCE); + PD_DRP_FORCE_SOURCE); else return EC_ERROR_PARAM4; } return EC_SUCCESS; + } else if (!strcasecmp(argv[2], "suspend")) { + pd_comm_enable(port, 0); + pd_set_suspend(port, 1); + } else if (!strcasecmp(argv[2], "resume")) { + pd_comm_enable(port, 1); + pd_set_suspend(port, 0); } } if (!strcasecmp(argv[2], "state")) { cflush(); - ccprintf("Port C%d CC%d, %s - Role: %s-%s", - port, pd_get_polarity(port) + 1, - pd_comm_is_enabled(port) ? "Enable" : "Disable", - pd_get_power_role(port) == - PD_ROLE_SOURCE ? "SRC" : "SNK", - pd_get_data_role(port) == PD_ROLE_DFP ? "DFP" : "UFP"); + ccprintf("Port C%d CC%d, %s - Role: %s-%s", port, + pd_get_polarity(port) + 1, + pd_comm_is_enabled(port) ? "Enable" : "Disable", + pd_get_power_role(port) == PD_ROLE_SOURCE ? "SRC" : + "SNK", + pd_get_data_role(port) == PD_ROLE_DFP ? "DFP" : "UFP"); if (IS_ENABLED(CONFIG_USBC_VCONN)) ccprintf("%s ", tc_is_vconn_src(port) ? "-VC" : ""); ccprintf("TC State: %s, Flags: 0x%04x", - tc_get_current_state(port), - tc_get_flags(port)); + tc_get_current_state(port), tc_get_flags(port)); if (IS_ENABLED(CONFIG_USB_PE_SM)) ccprintf(" PE State: %s, Flags: 0x%04x\n", - pe_get_current_state(port), - pe_get_flags(port)); + pe_get_current_state(port), + pe_get_flags(port)); else ccprintf("\n"); cflush(); } else if (!strcasecmp(argv[2], "srccaps")) { pd_srccaps_dump(port); + } else if (!strcasecmp(argv[2], "cc")) { + ccprintf("Port C%d CC%d\n", port, pd_get_task_cc_state(port)); } - if (IS_ENABLED(CONFIG_CMD_PD_TIMER) && - !strcasecmp(argv[2], "timer")) { + if (IS_ENABLED(CONFIG_CMD_PD_TIMER) && !strcasecmp(argv[2], "timer")) { pd_timer_dump(port); } @@ -196,22 +203,24 @@ int command_pd(int argc, char **argv) } #ifndef TEST_USB_PD_CONSOLE DECLARE_CONSOLE_COMMAND(pd, command_pd, - "version" - "\ndump [0|1|2|3]" + "version" + "\ndump [0|1|2|3]" #ifdef CONFIG_USB_PD_TRY_SRC - "\ntrysrc [0|1|2]" + "\ntrysrc [0|1|2]" #endif - "\n\t<port> state" - "\n\t<port> srccaps" + "\n\t<port> state" + "\n\t<port> srccaps" + "\n\t<port> cc" #ifdef CONFIG_CMD_PD_TIMER - "\n\t<port> timer" + "\n\t<port> timer" #endif /* CONFIG_CMD_PD_TIMER */ #ifdef CONFIG_USB_PD_DUAL_ROLE - "|tx|charger|dev" - "\n\t<port> disable|enable|soft|hard" - "\n\t<port> dualrole [on|off|freeze|sink|source]" - "\n\t<port> swap [power|data|vconn]" + "|tx|charger|dev" + "\n\t<port> disable|enable|soft|hard" + "\n\t<port> suspend|resume" + "\n\t<port> dualrole [on|off|freeze|sink|source]" + "\n\t<port> swap [power|data|vconn]" #endif /* CONFIG_USB_PD_DUAL_ROLE */ - , - "USB PD"); + , + "USB PD"); #endif diff --git a/common/usbc/usb_pd_dp_ufp.c b/common/usbc/usb_pd_dp_ufp.c index 0009b5c710..d88ee17aaf 100644 --- a/common/usbc/usb_pd_dp_ufp.c +++ b/common/usbc/usb_pd_dp_ufp.c @@ -1,4 +1,4 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. +/* Copyright 2021 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -15,9 +15,8 @@ #include "usb_pd.h" #include "usb_pd_dp_ufp.h" - -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) enum hpd_state { LOW_WAIT, @@ -105,17 +104,17 @@ static void hpd_to_dp_attention(void) * the DP_STATUS VDO. */ svdm_header = VDO_SVDM_VERS(pd_get_vdo_ver(port, TCPCI_MSG_SOP)) | - VDO_OPOS(opos) | CMD_ATTENTION; + VDO_OPOS(opos) | CMD_ATTENTION; vdm[0] = VDO(USB_SID_DISPLAYPORT, 1, svdm_header); vdm[1] = VDO_DP_STATUS((evt == hpd_irq), /* IRQ_HPD */ - (evt != hpd_low), /* HPD_HI|LOW */ - 0, /* request exit DP */ - 0, /* request exit USB */ - dock_get_mf_preference(), /* MF pref */ - 1, /* enabled */ - 0, /* power low */ - 0x2); + (evt != hpd_low), /* HPD_HI|LOW */ + 0, /* request exit DP */ + 0, /* request exit USB */ + dock_get_mf_preference(), /* MF pref */ + 1, /* enabled */ + 0, /* power low */ + 0x2); /* Send request to DPM to send an attention VDM */ pd_request_vdm_attention(port, vdm, ARRAY_SIZE(vdm)); @@ -154,10 +153,10 @@ static void hpd_queue_event(enum hpd_event evt) * are kept in the queue. */ if (evt == hpd_irq) { - if ((hpd.count >= HPD_QUEUE_DEPTH) || ((hpd.count >= 2) && - (hpd.queue[hpd.count - 2] == hpd_irq))) { - CPRINTS("hpd: discard hpd: count - %d", - hpd.count); + if ((hpd.count >= HPD_QUEUE_DEPTH) || + ((hpd.count >= 2) && + (hpd.queue[hpd.count - 2] == hpd_irq))) { + CPRINTS("hpd: discard hpd: count - %d", hpd.count); return; } } @@ -238,13 +237,13 @@ static void hpd_to_pd_converter(int level, uint64_t ts) */ if (!level) { /* Still low, now wait for IRQ or LOW determination */ - hpd.timer = ts + (HPD_T_IRQ_MAX_PULSE - - HPD_T_IRQ_MIN_PULSE); + hpd.timer = ts + + (HPD_T_IRQ_MAX_PULSE - HPD_T_IRQ_MIN_PULSE); hpd.state = IRQ_CHECK; } else { uint64_t irq_ts = hpd.timer + HPD_T_IRQ_MAX_PULSE - - HPD_T_IRQ_MIN_PULSE; + HPD_T_IRQ_MIN_PULSE; /* * If hpd is high now, this must have been an edge * event, but still need to determine if the pulse width @@ -271,7 +270,7 @@ static void hpd_to_pd_converter(int level, uint64_t ts) if (ts <= hpd.timer) { hpd_queue_event(hpd_irq); } - } else if (ts > hpd.timer) { + } else if (ts > hpd.timer) { hpd.state = LOW_WAIT; hpd_queue_event(hpd_low); } @@ -287,7 +286,7 @@ static void manage_hpd(void) int level; uint64_t ts = get_time().val; uint32_t num_hpd_events = (hpd.edges.head - hpd.edges.tail) & - EDGE_QUEUE_MASK; + EDGE_QUEUE_MASK; /* * HPD edges are detected via GPIO interrupts. The ISR routine adds edge @@ -305,7 +304,7 @@ static void manage_hpd(void) } if (num_hpd_events) { - while(num_hpd_events-- > 0) { + while (num_hpd_events-- > 0) { int idx = hpd.edges.tail; level = hpd.edges.buffer[idx].level; @@ -331,9 +330,8 @@ static void manage_hpd(void) * a DP_ATTENTION message if a DP_CONFIG message has been * received and have passed the minimum spacing interval. */ - if (hpd.send_enable && - ((get_time().val - hpd.last_send_ts) > - HPD_T_MIN_DP_ATTEN)) { + if (hpd.send_enable && ((get_time().val - hpd.last_send_ts) > + HPD_T_MIN_DP_ATTEN)) { /* Generate DP_ATTENTION event pending in queue */ hpd_to_dp_attention(); } else { @@ -352,7 +350,7 @@ static void manage_hpd(void) * the minimum time spacing. */ callback_us = HPD_T_MIN_DP_ATTEN - - (get_time().val - hpd.last_send_ts); + (get_time().val - hpd.last_send_ts); if (callback_us <= 0 || callback_us > HPD_T_MIN_DP_ATTEN) callback_us = HPD_T_MIN_DP_ATTEN; @@ -403,7 +401,7 @@ void usb_pd_hpd_converter_enable(int enable) hpd.state = LOW_WAIT; hpd.count = 0; hpd.timer = 0; - hpd.last_send_ts = 0; + hpd.last_send_ts = 0; hpd.send_enable = 0; /* Reset hpd signal edges queue */ @@ -427,7 +425,7 @@ void usb_pd_hpd_converter_enable(int enable) void usb_pd_hpd_edge_event(int signal) { - int next_head = (hpd.edges.head + 1) & EDGE_QUEUE_MASK; + int next_head = (hpd.edges.head + 1) & EDGE_QUEUE_MASK; struct hpd_mark mark; /* Get current timestamp and level */ diff --git a/common/usbc/usb_pd_dpm.c b/common/usbc/usb_pd_dpm.c index 159331171e..8141e92fd7 100644 --- a/common/usbc/usb_pd_dpm.c +++ b/common/usbc/usb_pd_dpm.c @@ -1,4 +1,4 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. +/* Copyright 2020 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -8,12 +8,15 @@ * Refer to USB PD 3.0 spec, version 2.0, sections 8.2 and 8.3 */ +#include "builtin/assert.h" #include "charge_state.h" +#include "chipset.h" #include "compile_time_macros.h" #include "console.h" #include "ec_commands.h" #include "hooks.h" #include "power.h" +#include "power_button.h" #include "system.h" #include "task.h" #include "tcpm/tcpm.h" @@ -23,8 +26,9 @@ #include "usb_mux.h" #include "usb_pd.h" #include "usb_pd_dpm.h" -#include "usb_pd_tcpm.h" #include "usb_pd_pdo.h" +#include "usb_pd_tcpm.h" +#include "usb_pd_timer.h" #include "usb_pe_sm.h" #include "usb_tbt_alt_mode.h" @@ -33,8 +37,8 @@ #endif #ifdef CONFIG_COMMON_RUNTIME -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) #else #define CPRINTF(format, args...) #define CPRINTS(format, args...) @@ -48,6 +52,7 @@ static struct { uint32_t vdm_attention[DPM_ATTENION_MAX_VDO]; int vdm_cnt; mutex_t vdm_attention_mutex; + enum dpm_pd_button_state pd_button_state; } dpm[CONFIG_USB_PD_PORT_MAX_COUNT]; #define DPM_SET_FLAG(port, flag) atomic_or(&dpm[(port)].flags, (flag)) @@ -55,16 +60,18 @@ static struct { #define DPM_CHK_FLAG(port, flag) (dpm[(port)].flags & (flag)) /* Flags for internal DPM state */ -#define DPM_FLAG_MODE_ENTRY_DONE BIT(0) -#define DPM_FLAG_EXIT_REQUEST BIT(1) -#define DPM_FLAG_ENTER_DP BIT(2) -#define DPM_FLAG_ENTER_TBT BIT(3) -#define DPM_FLAG_ENTER_USB4 BIT(4) -#define DPM_FLAG_ENTER_ANY (DPM_FLAG_ENTER_DP | DPM_FLAG_ENTER_TBT \ - | DPM_FLAG_ENTER_USB4) -#define DPM_FLAG_SEND_ATTENTION BIT(5) +#define DPM_FLAG_MODE_ENTRY_DONE BIT(0) +#define DPM_FLAG_EXIT_REQUEST BIT(1) +#define DPM_FLAG_ENTER_DP BIT(2) +#define DPM_FLAG_ENTER_TBT BIT(3) +#define DPM_FLAG_ENTER_USB4 BIT(4) +#define DPM_FLAG_ENTER_ANY \ + (DPM_FLAG_ENTER_DP | DPM_FLAG_ENTER_TBT | DPM_FLAG_ENTER_USB4) +#define DPM_FLAG_SEND_ATTENTION BIT(5) #define DPM_FLAG_DATA_RESET_REQUESTED BIT(6) -#define DPM_FLAG_DATA_RESET_DONE BIT(7) +#define DPM_FLAG_DATA_RESET_DONE BIT(7) +#define DPM_FLAG_PD_BUTTON_PRESSED BIT(8) +#define DPM_FLAG_PD_BUTTON_RELEASED BIT(9) #ifdef CONFIG_ZEPHYR static int init_vdm_attention_mutex(const struct device *dev) @@ -81,6 +88,11 @@ static int init_vdm_attention_mutex(const struct device *dev) SYS_INIT(init_vdm_attention_mutex, POST_KERNEL, 50); #endif /* CONFIG_ZEPHYR */ +__overridable bool board_is_tbt_usb4_port(int port) +{ + return true; +} + enum ec_status pd_request_vdm_attention(int port, const uint32_t *data, int vdo_count) { @@ -120,17 +132,22 @@ enum ec_status pd_request_enter_mode(int port, enum typec_mode mode) return EC_RES_INVALID_PARAM; /* Only one enter request may be active at a time. */ - if (DPM_CHK_FLAG(port, DPM_FLAG_ENTER_DP | - DPM_FLAG_ENTER_TBT | - DPM_FLAG_ENTER_USB4)) + if (DPM_CHK_FLAG(port, DPM_FLAG_ENTER_DP | DPM_FLAG_ENTER_TBT | + DPM_FLAG_ENTER_USB4)) return EC_RES_BUSY; switch (mode) { case TYPEC_MODE_DP: + if (dp_is_idle(port)) + dp_init(port); DPM_SET_FLAG(port, DPM_FLAG_ENTER_DP); break; #ifdef CONFIG_USB_PD_TBT_COMPAT_MODE case TYPEC_MODE_TBT: + /* TODO(b/235984702#comment21): Refactor alt mode modules + * to better support mode reentry. */ + if (dp_is_idle(port)) + dp_init(port); DPM_SET_FLAG(port, DPM_FLAG_ENTER_TBT); break; #endif /* CONFIG_USB_PD_TBT_COMPAT_MODE */ @@ -153,19 +170,20 @@ enum ec_status pd_request_enter_mode(int port, enum typec_mode mode) void dpm_init(int port) { dpm[port].flags = 0; + dpm[port].pd_button_state = DPM_PD_BUTTON_IDLE; } void dpm_mode_exit_complete(int port) { DPM_CLR_FLAG(port, DPM_FLAG_MODE_ENTRY_DONE | DPM_FLAG_EXIT_REQUEST | - DPM_FLAG_SEND_ATTENTION); + DPM_FLAG_SEND_ATTENTION); } static void dpm_set_mode_entry_done(int port) { DPM_SET_FLAG(port, DPM_FLAG_MODE_ENTRY_DONE); DPM_CLR_FLAG(port, DPM_FLAG_ENTER_DP | DPM_FLAG_ENTER_TBT | - DPM_FLAG_ENTER_USB4); + DPM_FLAG_ENTER_USB4); } void dpm_set_mode_exit_request(int port) @@ -210,7 +228,7 @@ static bool dpm_mode_entry_requested(int port, enum typec_mode mode) } void dpm_vdm_acked(int port, enum tcpci_msg_type type, int vdo_count, - uint32_t *vdm) + uint32_t *vdm) { const uint16_t svid = PD_VDO_VID(vdm[0]); @@ -227,12 +245,12 @@ void dpm_vdm_acked(int port, enum tcpci_msg_type type, int vdo_count, } default: CPRINTS("C%d: Received unexpected VDM ACK for SVID %d", port, - svid); + svid); } } void dpm_vdm_naked(int port, enum tcpci_msg_type type, uint16_t svid, - uint8_t vdm_cmd) + uint8_t vdm_cmd) { switch (svid) { case USB_SID_DISPLAYPORT: @@ -245,7 +263,7 @@ void dpm_vdm_naked(int port, enum tcpci_msg_type type, uint16_t svid, } default: CPRINTS("C%d: Received unexpected VDM NAK for SVID %d", port, - svid); + svid); } } @@ -261,16 +279,15 @@ static void dpm_attempt_mode_entry(int port) uint32_t vdm[VDO_MAX_SIZE]; enum tcpci_msg_type tx_type = TCPCI_MSG_SOP; bool enter_mode_requested = - IS_ENABLED(CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY) ? false : true; + IS_ENABLED(CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY) ? false : true; enum dpm_msg_setup_status status = MSG_SETUP_UNSUPPORTED; if (pd_get_data_role(port) != PD_ROLE_DFP) { - if (DPM_CHK_FLAG(port, DPM_FLAG_ENTER_DP | - DPM_FLAG_ENTER_TBT | - DPM_FLAG_ENTER_USB4)) + if (DPM_CHK_FLAG(port, DPM_FLAG_ENTER_DP | DPM_FLAG_ENTER_TBT | + DPM_FLAG_ENTER_USB4)) DPM_CLR_FLAG(port, DPM_FLAG_ENTER_DP | - DPM_FLAG_ENTER_TBT | - DPM_FLAG_ENTER_USB4); + DPM_FLAG_ENTER_TBT | + DPM_FLAG_ENTER_USB4); /* * TODO(b/168030639): Notify the AP that the enter mode request * failed. @@ -298,9 +315,9 @@ static void dpm_attempt_mode_entry(int port) return; if (dp_entry_is_done(port) || - (IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE) && - tbt_entry_is_done(port)) || - (IS_ENABLED(CONFIG_USB_PD_USB4) && enter_usb_entry_is_done(port))) { + (IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE) && + tbt_entry_is_done(port)) || + (IS_ENABLED(CONFIG_USB_PD_USB4) && enter_usb_entry_is_done(port))) { dpm_set_mode_entry_done(port); return; } @@ -314,24 +331,23 @@ static void dpm_attempt_mode_entry(int port) return; if (IS_ENABLED(CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY) && - IS_ENABLED(CONFIG_USB_PD_DATA_RESET_MSG) && - DPM_CHK_FLAG(port, DPM_FLAG_ENTER_ANY) && - !DPM_CHK_FLAG(port, DPM_FLAG_DATA_RESET_REQUESTED) && - !DPM_CHK_FLAG(port, DPM_FLAG_DATA_RESET_DONE)) { + IS_ENABLED(CONFIG_USB_PD_DATA_RESET_MSG) && + DPM_CHK_FLAG(port, DPM_FLAG_ENTER_ANY) && + !DPM_CHK_FLAG(port, DPM_FLAG_DATA_RESET_REQUESTED) && + !DPM_CHK_FLAG(port, DPM_FLAG_DATA_RESET_DONE)) { pd_dpm_request(port, DPM_REQUEST_DATA_RESET); DPM_SET_FLAG(port, DPM_FLAG_DATA_RESET_REQUESTED); return; } if (IS_ENABLED(CONFIG_USB_PD_REQUIRE_AP_MODE_ENTRY) && - IS_ENABLED(CONFIG_USB_PD_DATA_RESET_MSG) && - !DPM_CHK_FLAG(port, DPM_FLAG_DATA_RESET_DONE)) { + IS_ENABLED(CONFIG_USB_PD_DATA_RESET_MSG) && + !DPM_CHK_FLAG(port, DPM_FLAG_DATA_RESET_DONE)) { return; } /* Check if port, port partner and cable support USB4. */ - if (IS_ENABLED(CONFIG_USB_PD_USB4) && - board_is_tbt_usb4_port(port) && + if (IS_ENABLED(CONFIG_USB_PD_USB4) && board_is_tbt_usb4_port(port) && enter_usb_port_partner_is_capable(port) && enter_usb_cable_is_capable(port) && dpm_mode_entry_requested(port, TYPEC_MODE_USB4)) { @@ -351,14 +367,13 @@ static void dpm_attempt_mode_entry(int port) /* If not, check if they support Thunderbolt alt mode. */ if (IS_ENABLED(CONFIG_USB_PD_TBT_COMPAT_MODE) && - board_is_tbt_usb4_port(port) && - pd_is_mode_discovered_for_svid(port, TCPCI_MSG_SOP, - USB_VID_INTEL) && - dpm_mode_entry_requested(port, TYPEC_MODE_TBT)) { + board_is_tbt_usb4_port(port) && + pd_is_mode_discovered_for_svid(port, TCPCI_MSG_SOP, + USB_VID_INTEL) && + dpm_mode_entry_requested(port, TYPEC_MODE_TBT)) { enter_mode_requested = true; vdo_count = ARRAY_SIZE(vdm); - status = tbt_setup_next_vdm(port, &vdo_count, vdm, - &tx_type); + status = tbt_setup_next_vdm(port, &vdo_count, vdm, &tx_type); } /* If not, check if they support DisplayPort alt mode. */ @@ -381,7 +396,7 @@ static void dpm_attempt_mode_entry(int port) * just mark setup done and get out of here. */ if (status != MSG_SETUP_SUCCESS && - !DPM_CHK_FLAG(port, DPM_FLAG_MODE_ENTRY_DONE)) { + !DPM_CHK_FLAG(port, DPM_FLAG_MODE_ENTRY_DONE)) { if (enter_mode_requested) { /* * TODO(b/168030639): Notify the AP that mode entry @@ -427,9 +442,8 @@ static void dpm_attempt_mode_exit(int port) * is not supported, exit active modes individually. */ if (IS_ENABLED(CONFIG_USB_PD_DATA_RESET_MSG)) { - if (!DPM_CHK_FLAG(port, DPM_FLAG_DATA_RESET_REQUESTED) - && !DPM_CHK_FLAG(port, - DPM_FLAG_DATA_RESET_DONE)) { + if (!DPM_CHK_FLAG(port, DPM_FLAG_DATA_RESET_REQUESTED) && + !DPM_CHK_FLAG(port, DPM_FLAG_DATA_RESET_DONE)) { pd_dpm_request(port, DPM_REQUEST_DATA_RESET); DPM_SET_FLAG(port, DPM_FLAG_DATA_RESET_REQUESTED); return; @@ -495,6 +509,118 @@ static void dpm_send_attention_vdm(int port) DPM_CLR_FLAG(port, DPM_FLAG_SEND_ATTENTION); } +void dpm_handle_alert(int port, uint32_t ado) +{ + if (ado & ADO_EXTENDED_ALERT_EVENT) { + /* Extended Alert */ + if (pd_get_data_role(port) == PD_ROLE_DFP && + (ADO_EXTENDED_ALERT_EVENT_TYPE & ado) == + ADO_POWER_BUTTON_PRESS) { + DPM_SET_FLAG(port, DPM_FLAG_PD_BUTTON_PRESSED); + } else if (pd_get_data_role(port) == PD_ROLE_DFP && + (ADO_EXTENDED_ALERT_EVENT_TYPE & ado) == + ADO_POWER_BUTTON_RELEASE) { + DPM_SET_FLAG(port, DPM_FLAG_PD_BUTTON_RELEASED); + } + } +} + +static void dpm_run_pd_button_sm(int port) +{ +#ifdef CONFIG_AP_POWER_CONTROL + if (!IS_ENABLED(CONFIG_POWER_BUTTON_X86) && + !IS_ENABLED(CONFIG_CHIPSET_SC7180) && + !IS_ENABLED(CONFIG_CHIPSET_SC7280)) { + /* Insufficient chipset API support for USB PD power button. */ + DPM_CLR_FLAG(port, DPM_FLAG_PD_BUTTON_PRESSED); + DPM_CLR_FLAG(port, DPM_FLAG_PD_BUTTON_RELEASED); + return; + } + + /* + * Check for invalid flag combination. Alerts can only send a press or + * release event at once and only one flag should be set. If press and + * release flags are both set, we cannot know the order they were + * received. Clear the flags, disable the timer and return to an idle + * state. + */ + if (DPM_CHK_FLAG(port, DPM_FLAG_PD_BUTTON_PRESSED) && + DPM_CHK_FLAG(port, DPM_FLAG_PD_BUTTON_RELEASED)) { + DPM_CLR_FLAG(port, DPM_FLAG_PD_BUTTON_PRESSED | + DPM_FLAG_PD_BUTTON_RELEASED); + pd_timer_disable(port, DPM_TIMER_PD_BUTTON_SHORT_PRESS); + pd_timer_disable(port, DPM_TIMER_PD_BUTTON_LONG_PRESS); + dpm[port].pd_button_state = DPM_PD_BUTTON_IDLE; + return; + } + + switch (dpm[port].pd_button_state) { + case DPM_PD_BUTTON_IDLE: + if (DPM_CHK_FLAG(port, DPM_FLAG_PD_BUTTON_PRESSED)) { + pd_timer_enable(port, DPM_TIMER_PD_BUTTON_SHORT_PRESS, + CONFIG_USB_PD_SHORT_PRESS_MAX_MS * + MSEC); + pd_timer_enable(port, DPM_TIMER_PD_BUTTON_LONG_PRESS, + CONFIG_USB_PD_LONG_PRESS_MAX_MS * MSEC); + dpm[port].pd_button_state = DPM_PD_BUTTON_PRESSED; + } + break; + case DPM_PD_BUTTON_PRESSED: + if (DPM_CHK_FLAG(port, DPM_FLAG_PD_BUTTON_PRESSED)) { + pd_timer_enable(port, DPM_TIMER_PD_BUTTON_SHORT_PRESS, + CONFIG_USB_PD_SHORT_PRESS_MAX_MS * + MSEC); + pd_timer_enable(port, DPM_TIMER_PD_BUTTON_LONG_PRESS, + CONFIG_USB_PD_LONG_PRESS_MAX_MS * MSEC); + } else if (pd_timer_is_expired( + port, DPM_TIMER_PD_BUTTON_LONG_PRESS)) { + pd_timer_disable(port, DPM_TIMER_PD_BUTTON_SHORT_PRESS); + pd_timer_disable(port, DPM_TIMER_PD_BUTTON_LONG_PRESS); + dpm[port].pd_button_state = DPM_PD_BUTTON_IDLE; + } else if (DPM_CHK_FLAG(port, DPM_FLAG_PD_BUTTON_RELEASED)) { + if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) { + /* + * Wake chipset on any button press when the + * system is off. + */ + chipset_power_on(); + } else if (chipset_in_state( + CHIPSET_STATE_ANY_SUSPEND) || + chipset_in_state(CHIPSET_STATE_ON)) { + if (pd_timer_is_expired( + port, + DPM_TIMER_PD_BUTTON_SHORT_PRESS)) { + /* + * Shutdown chipset on long USB PD power + * button press. + */ + chipset_force_shutdown( + CHIPSET_SHUTDOWN_BUTTON); + } else { + /* + * Simulate a short power button press + * on short USB PD power button press. + * This will wake the system from + * suspend, or bring up the power UI + * when the system is on. + */ + power_button_simulate_press( + USB_PD_SHORT_BUTTON_PRESS_MS); + } + } + pd_timer_disable(port, DPM_TIMER_PD_BUTTON_SHORT_PRESS); + pd_timer_disable(port, DPM_TIMER_PD_BUTTON_LONG_PRESS); + dpm[port].pd_button_state = DPM_PD_BUTTON_IDLE; + } + break; + } +#endif /* CONFIG_AP_POWER_CONTROL */ + + /* After checking flags, clear them. */ + DPM_CLR_FLAG(port, DPM_FLAG_PD_BUTTON_PRESSED); + DPM_CLR_FLAG(port, DPM_FLAG_PD_BUTTON_RELEASED); +} + void dpm_run(int port) { if (pd_get_data_role(port) == PD_ROLE_DFP) { @@ -503,6 +629,9 @@ void dpm_run(int port) dpm_attempt_mode_exit(port); else if (!DPM_CHK_FLAG(port, DPM_FLAG_MODE_ENTRY_DONE)) dpm_attempt_mode_entry(port); + + /* Run USB PD Power button state machine */ + dpm_run_pd_button_sm(port); } else { /* Run UFP related DPM requests */ if (DPM_CHK_FLAG(port, DPM_FLAG_SEND_ATTENTION)) @@ -523,7 +652,7 @@ void dpm_run(int port) * Note: request bitmasks should be accessed atomically as other ports may alter * them */ -static uint32_t max_current_claimed; +static uint32_t max_current_claimed; K_MUTEX_DEFINE(max_current_claimed_lock); /* Ports with PD sink needing > 1.5 A */ @@ -533,7 +662,10 @@ static atomic_t source_frs_max_requested; /* Ports with non-PD sinks, so current requirements are unknown */ static atomic_t non_pd_sink_max_requested; -#define LOWEST_PORT(p) __builtin_ctz(p) /* Undefined behavior if p == 0 */ +/* BIST shared test mode */ +static bool bist_shared_mode_enabled; + +#define LOWEST_PORT(p) __builtin_ctz(p) /* Undefined behavior if p == 0 */ static int count_port_bits(uint32_t bitmask) { @@ -568,12 +700,19 @@ static void balance_source_ports(void) if (deferred_waiting) return; + /* + * Turn off all shared power logic while BIST shared test mode is active + * on the system. + */ + if (bist_shared_mode_enabled) + return; + mutex_lock(&max_current_claimed_lock); /* Remove any ports which no longer require 3.0 A */ - removed_ports = max_current_claimed & ~(sink_max_pdo_requested | - source_frs_max_requested | - non_pd_sink_max_requested); + removed_ports = max_current_claimed & + ~(sink_max_pdo_requested | source_frs_max_requested | + non_pd_sink_max_requested); max_current_claimed &= ~removed_ports; /* Allocate 3.0 A to new PD sink ports that need it */ @@ -582,7 +721,7 @@ static void balance_source_ports(void) int new_max_port = LOWEST_PORT(new_ports); if (count_port_bits(max_current_claimed) < - CONFIG_USB_PD_3A_PORTS) { + CONFIG_USB_PD_3A_PORTS) { max_current_claimed |= BIT(new_max_port); typec_select_src_current_limit_rp(new_max_port, TYPEC_RP_3A0); @@ -590,7 +729,8 @@ static void balance_source_ports(void) /* Always downgrade non-PD ports first */ int rem_non_pd = LOWEST_PORT(non_pd_sink_max_requested & max_current_claimed); - typec_select_src_current_limit_rp(rem_non_pd, + typec_select_src_current_limit_rp( + rem_non_pd, typec_get_default_current_limit_rp(rem_non_pd)); max_current_claimed &= ~BIT(rem_non_pd); @@ -602,7 +742,7 @@ static void balance_source_ports(void) } else if (source_frs_max_requested & max_current_claimed) { /* Downgrade lowest FRS port from 3.0 A slot */ int rem_frs = LOWEST_PORT(source_frs_max_requested & - max_current_claimed); + max_current_claimed); pd_dpm_request(rem_frs, DPM_REQUEST_FRS_DET_DISABLE); max_current_claimed &= ~BIT(rem_frs); @@ -624,14 +764,15 @@ static void balance_source_ports(void) int new_frs_port = LOWEST_PORT(new_ports); if (count_port_bits(max_current_claimed) < - CONFIG_USB_PD_3A_PORTS) { + CONFIG_USB_PD_3A_PORTS) { max_current_claimed |= BIT(new_frs_port); pd_dpm_request(new_frs_port, DPM_REQUEST_FRS_DET_ENABLE); } else if (non_pd_sink_max_requested & max_current_claimed) { int rem_non_pd = LOWEST_PORT(non_pd_sink_max_requested & max_current_claimed); - typec_select_src_current_limit_rp(rem_non_pd, + typec_select_src_current_limit_rp( + rem_non_pd, typec_get_default_current_limit_rp(rem_non_pd)); max_current_claimed &= ~BIT(rem_non_pd); @@ -653,7 +794,7 @@ static void balance_source_ports(void) int new_max_port = LOWEST_PORT(new_ports); if (count_port_bits(max_current_claimed) < - CONFIG_USB_PD_3A_PORTS) { + CONFIG_USB_PD_3A_PORTS) { max_current_claimed |= BIT(new_max_port); typec_select_src_current_limit_rp(new_max_port, TYPEC_RP_3A0); @@ -741,7 +882,7 @@ void dpm_evaluate_request_rdo(int port, uint32_t rdo) return; op_ma = (rdo >> 10) & 0x3FF; - if ((BIT(port) && sink_max_pdo_requested) && (op_ma <= 150)) { + if ((BIT(port) & sink_max_pdo_requested) && (op_ma <= 150)) { /* * sink_max_pdo_requested will be set when we get 5V/3A sink * capability from port partner. If port partner only request @@ -766,8 +907,8 @@ void dpm_remove_sink(int port) atomic_clear_bits(&non_pd_sink_max_requested, BIT(port)); /* Restore selected default Rp on the port */ - typec_select_src_current_limit_rp(port, - typec_get_default_current_limit_rp(port)); + typec_select_src_current_limit_rp( + port, typec_get_default_current_limit_rp(port)); balance_source_ports(); } @@ -788,16 +929,83 @@ void dpm_remove_source(int port) balance_source_ports(); } +void dpm_bist_shared_mode_enter(int port) +{ + /* + * From 6.4.3.3.1 BIST Shared Test Mode Entry: + * + * "When any Master Port in a shared capacity group receives a BIST + * Message with a BIST Shared Test Mode Entry BIST Data Object, while + * in the PE_SRC_Ready State, the UUT Shall enter a compliance test + * mode where the maximum source capability is always offered on every + * port, regardless of the availability of shared power i.e. all shared + * power management is disabled. + * . . . + * On entering this mode, the UUT Shall send a new Source_Capabilities + * Message from each Port in the shared capacity group within + * tBISTSharedTestMode. The Tester will not exceed the shared capacity + * during this mode." + */ + + /* Shared mode is unnecessary without at least one 3.0 A port */ + if (CONFIG_USB_PD_3A_PORTS == 0) + return; + + /* Enter mode only if this port had been in PE_SRC_Ready */ + if (pd_get_power_role(port) != PD_ROLE_SOURCE) + return; + + bist_shared_mode_enabled = true; + + /* Trigger new source caps on all source ports */ + for (int i = 0; i < board_get_usb_pd_port_count(); i++) { + if (pd_get_power_role(i) == PD_ROLE_SOURCE) + typec_select_src_current_limit_rp(i, TYPEC_RP_3A0); + } +} + +void dpm_bist_shared_mode_exit(int port) +{ + /* + * From 6.4.3.3.2 BIST Shared Test Mode Exit: + * + * "Upon receipt of a BIST Message, with a BIST Shared Test Mode Exit + * BIST Data Object, the UUT Shall return a GoodCRC Message and Shall + * exit the BIST Shared Capacity Test Mode. + * . . . + * On exiting the mode, the UUT May send a new Source_Capabilities + * Message to each port in the shared capacity group or the UUT May + * perform ErrorRecovery on each port." + */ + + /* Shared mode is unnecessary without at least one 3.0 A port */ + if (CONFIG_USB_PD_3A_PORTS == 0) + return; + + /* Do nothing if Exit was received with no Entry */ + if (!bist_shared_mode_enabled) + return; + + bist_shared_mode_enabled = false; + + /* Declare error recovery bankruptcy */ + for (int i = 0; i < board_get_usb_pd_port_count(); i++) { + pd_set_error_recovery(i); + } +} + /* * Note: all ports receive the 1.5 A source offering until they are found to * match a criteria on the 3.0 A priority list (ex. through sink capability * probing), at which point they will be offered a new 3.0 A source capability. + * + * All ports must be offered our full capability while in BIST shared test mode. */ __overridable int dpm_get_source_pdo(const uint32_t **src_pdo, const int port) { /* Max PDO may not exist on boards which don't offer 3 A */ #if CONFIG_USB_PD_3A_PORTS > 0 - if (max_current_claimed & BIT(port)) { + if (max_current_claimed & BIT(port) || bist_shared_mode_enabled) { *src_pdo = pd_src_pdo_max; return pd_src_pdo_max_cnt; } @@ -812,7 +1020,7 @@ int dpm_get_source_current(const int port) if (pd_get_power_role(port) == PD_ROLE_SINK) return 0; - if (max_current_claimed & BIT(port)) + if (max_current_claimed & BIT(port) || bist_shared_mode_enabled) return 3000; else if (typec_get_default_current_limit_rp(port) == TYPEC_RP_1A5) return 1500; @@ -820,8 +1028,8 @@ int dpm_get_source_current(const int port) return 500; } -__overridable enum pd_sdb_power_indicator board_get_pd_sdb_power_indicator( -enum pd_sdb_power_state power_state) +__overridable enum pd_sdb_power_indicator +board_get_pd_sdb_power_indicator(enum pd_sdb_power_state power_state) { /* * LED on for S0 and blinking for S0ix/S3. @@ -856,7 +1064,7 @@ static uint8_t get_status_internal_temp(void) else if (temp_c < 2) temp_c = 1; - return (uint8_t) temp_c; + return (uint8_t)temp_c; #else return 0; #endif diff --git a/common/usbc/usb_pd_host.c b/common/usbc/usb_pd_host.c index d6bd61057f..5d22e8ecd3 100644 --- a/common/usbc/usb_pd_host.c +++ b/common/usbc/usb_pd_host.c @@ -1,4 +1,4 @@ -/* Copyright 2020 The Chromium OS Authors. All rights reserved. +/* Copyright 2020 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. * @@ -15,8 +15,8 @@ #include "usb_pd_tcpm.h" #include "util.h" -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) /* Retrieve all discovery results for the given port and transmit type */ static enum ec_status hc_typec_discovery(struct host_cmd_handler_args *args) @@ -35,8 +35,8 @@ static enum ec_status hc_typec_discovery(struct host_cmd_handler_args *args) if (p->partner_type > TYPEC_PARTNER_SOP_PRIME) return EC_RES_INVALID_PARAM; - type = p->partner_type == TYPEC_PARTNER_SOP ? - TCPCI_MSG_SOP : TCPCI_MSG_SOP_PRIME; + type = p->partner_type == TYPEC_PARTNER_SOP ? TCPCI_MSG_SOP : + TCPCI_MSG_SOP_PRIME; /* * Clear out access mask so we can track if tasks have touched data @@ -61,8 +61,9 @@ static enum ec_status hc_typec_discovery(struct host_cmd_handler_args *args) if (pd_get_modes_discovery(p->port, type) == PD_DISC_COMPLETE) { int svid_i; - int max_resp_svids = (args->response_max - args->response_size)/ - sizeof(struct svid_mode_info); + int max_resp_svids = + (args->response_max - args->response_size) / + sizeof(struct svid_mode_info); if (disc->svid_cnt > max_resp_svids) { CPRINTS("Warn: SVIDS exceeded HC response"); @@ -74,7 +75,7 @@ static enum ec_status hc_typec_discovery(struct host_cmd_handler_args *args) for (svid_i = 0; svid_i < r->svid_count; svid_i++) { r->svids[svid_i].svid = disc->svids[svid_i].svid; r->svids[svid_i].mode_count = - disc->svids[svid_i].mode_cnt; + disc->svids[svid_i].mode_cnt; memcpy(r->svids[svid_i].mode_vdo, disc->svids[svid_i].mode_vdo, sizeof(r->svids[svid_i].mode_vdo)); @@ -96,14 +97,12 @@ static enum ec_status hc_typec_discovery(struct host_cmd_handler_args *args) return EC_RES_SUCCESS; } -DECLARE_HOST_COMMAND(EC_CMD_TYPEC_DISCOVERY, - hc_typec_discovery, +DECLARE_HOST_COMMAND(EC_CMD_TYPEC_DISCOVERY, hc_typec_discovery, EC_VER_MASK(0)); /* Default to feature unavailable, with boards supporting it overriding */ __overridable enum ec_status - board_set_tbt_ufp_reply(int port, - enum typec_tbt_ufp_reply reply) +board_set_tbt_ufp_reply(int port, enum typec_tbt_ufp_reply reply) { return EC_RES_UNAVAILABLE; } @@ -111,6 +110,7 @@ __overridable enum ec_status static enum ec_status hc_typec_control(struct host_cmd_handler_args *args) { const struct ec_params_typec_control *p = args->params; + mux_state_t mode; if (p->port >= board_get_usb_pd_port_count()) return EC_RES_INVALID_PARAM; @@ -127,11 +127,13 @@ static enum ec_status hc_typec_control(struct host_cmd_handler_args *args) case TYPEC_CONTROL_COMMAND_TBT_UFP_REPLY: return board_set_tbt_ufp_reply(p->port, p->tbt_ufp_reply); case TYPEC_CONTROL_COMMAND_USB_MUX_SET: + /* The EC will fill in polarity, so filter flip out */ + mode = p->mux_params.mux_flags & ~USB_PD_MUX_POLARITY_INVERTED; + if (!IS_ENABLED(CONFIG_USB_MUX_AP_CONTROL)) return EC_RES_INVALID_PARAM; - /* TODO: Check if AP wants to set usb mode or polarity */ - usb_mux_set_single(p->port, p->mux_params.mux_index, - p->mux_params.mux_flags, + + usb_mux_set_single(p->port, p->mux_params.mux_index, mode, USB_SWITCH_CONNECT, polarity_rm_dts(pd_get_polarity(p->port))); return EC_RES_SUCCESS; @@ -139,7 +141,6 @@ static enum ec_status hc_typec_control(struct host_cmd_handler_args *args) return EC_RES_INVALID_PARAM; } - return EC_RES_SUCCESS; } DECLARE_HOST_COMMAND(EC_CMD_TYPEC_CONTROL, hc_typec_control, EC_VER_MASK(0)); @@ -177,13 +178,15 @@ static enum ec_status hc_typec_status(struct host_cmd_handler_args *args) r->events = pd_get_events(p->port); r->sop_revision = r->sop_connected ? - PD_STATUS_REV_SET_MAJOR(pd_get_rev(p->port, TCPCI_MSG_SOP)) : 0; + PD_STATUS_REV_SET_MAJOR( + pd_get_rev(p->port, TCPCI_MSG_SOP)) : + 0; r->sop_prime_revision = pd_get_identity_discovery(p->port, TCPCI_MSG_SOP_PRIME) == - PD_DISC_COMPLETE ? - PD_STATUS_REV_SET_MAJOR(pd_get_rev(p->port, - TCPCI_MSG_SOP_PRIME)) - : 0; + PD_DISC_COMPLETE ? + PD_STATUS_REV_SET_MAJOR( + pd_get_rev(p->port, TCPCI_MSG_SOP_PRIME)) : + 0; r->source_cap_count = pd_get_src_cap_cnt(p->port); memcpy(r->source_cap_pdos, pd_get_src_caps(p->port), diff --git a/common/usbc/usb_pd_timer.c b/common/usbc/usb_pd_timer.c index a1859ac9e9..a6ec07125d 100644 --- a/common/usbc/usb_pd_timer.c +++ b/common/usbc/usb_pd_timer.c @@ -1,4 +1,4 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. +/* Copyright 2021 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -14,36 +14,35 @@ #include "usb_pd_timer.h" #include "usb_tc_sm.h" -#define MAX_PD_PORTS CONFIG_USB_PD_PORT_MAX_COUNT -#define MAX_PD_TIMERS PD_TIMER_COUNT +#define MAX_PD_PORTS CONFIG_USB_PD_PORT_MAX_COUNT +#define MAX_PD_TIMERS PD_TIMER_COUNT #define PD_TIMERS_ALL_MASK (UINT64_MAX >> (64 - PD_TIMER_COUNT)) -#define MAX_EXPIRE (0x7FFFFFFF) -#define NO_TIMEOUT (-1) -#define EXPIRE_NOW (0) +#define MAX_EXPIRE (0x7FFFFFFF) +#define NO_TIMEOUT (-1) +#define EXPIRE_NOW (0) #define PD_SET_ACTIVE(p, bit) \ - atomic_set_bit(timer_active, (p) * PD_TIMER_COUNT + (bit)) + atomic_set_bit(timer_active, (p)*PD_TIMER_COUNT + (bit)) #define PD_CLR_ACTIVE(p, bit) \ - atomic_clear_bit(timer_active, (p) * PD_TIMER_COUNT + (bit)) + atomic_clear_bit(timer_active, (p)*PD_TIMER_COUNT + (bit)) #define PD_CHK_ACTIVE(p, bit) \ - atomic_test_bit(timer_active, (p) * PD_TIMER_COUNT + (bit)) + atomic_test_bit(timer_active, (p)*PD_TIMER_COUNT + (bit)) #define PD_SET_DISABLED(p, bit) \ - atomic_set_bit(timer_disabled, (p) * PD_TIMER_COUNT + (bit)) + atomic_set_bit(timer_disabled, (p)*PD_TIMER_COUNT + (bit)) #define PD_CLR_DISABLED(p, bit) \ - atomic_clear_bit(timer_disabled, (p) * PD_TIMER_COUNT + (bit)) + atomic_clear_bit(timer_disabled, (p)*PD_TIMER_COUNT + (bit)) #define PD_CHK_DISABLED(p, bit) \ - atomic_test_bit(timer_disabled, (p) * PD_TIMER_COUNT + (bit)) + atomic_test_bit(timer_disabled, (p)*PD_TIMER_COUNT + (bit)) -test_mockable_static -ATOMIC_DEFINE(timer_active, PD_TIMER_COUNT * MAX_PD_PORTS); -test_mockable_static -ATOMIC_DEFINE(timer_disabled, PD_TIMER_COUNT * MAX_PD_PORTS); +test_mockable_static ATOMIC_DEFINE(timer_active, PD_TIMER_COUNT *MAX_PD_PORTS); +test_mockable_static ATOMIC_DEFINE(timer_disabled, + PD_TIMER_COUNT *MAX_PD_PORTS); static uint64_t timer_expires[MAX_PD_PORTS][PD_TIMER_COUNT]; /* @@ -52,42 +51,43 @@ static uint64_t timer_expires[MAX_PD_PORTS][PD_TIMER_COUNT]; static int count[MAX_PD_PORTS]; static int max_count[MAX_PD_PORTS]; -__maybe_unused static __const_data const char * const pd_timer_names[] = { - [PE_TIMER_BIST_CONT_MODE] = "PE-BIST_CONT_MODE", +__maybe_unused static __const_data const char *const pd_timer_names[] = { + [DPM_TIMER_PD_BUTTON_LONG_PRESS] = "DPM-PD_BUTTON_LONG_PRESS", + [DPM_TIMER_PD_BUTTON_SHORT_PRESS] = "DPM-PD_BUTTON_SHORT_PRESS", + [PE_TIMER_BIST_CONT_MODE] = "PE-BIST_CONT_MODE", [PE_TIMER_CHUNKING_NOT_SUPPORTED] = "PE-CHUNKING_NOT_SUPPORTED", - [PE_TIMER_DISCOVER_IDENTITY] = "PE-DISCOVER_IDENTITY", - [PE_TIMER_NO_RESPONSE] = "PE-NO_RESPONSE", - [PE_TIMER_PR_SWAP_WAIT] = "PE-PR_SWAP_WAIT", - [PE_TIMER_PS_HARD_RESET] = "PE-PS_HARD_RESET", - [PE_TIMER_PS_SOURCE] = "PE-PS_SOURCE", - [PE_TIMER_PS_TRANSITION] = "PE-PS_TRANSITION", - [PE_TIMER_SENDER_RESPONSE] = "PE-SENDER_RESPONSE", - [PE_TIMER_SINK_REQUEST] = "PE-SINK_REQUEST", - [PE_TIMER_SOURCE_CAP] = "PE-SOURCE_CAP", - [PE_TIMER_SRC_TRANSITION] = "PE-SRC_TRANSITION", - [PE_TIMER_SWAP_SOURCE_START] = "PE-SWAP_SOURCE_START", - [PE_TIMER_TIMEOUT] = "PE-TIMEOUT", - [PE_TIMER_VCONN_ON] = "PE-VCONN_ON", - [PE_TIMER_VDM_RESPONSE] = "PE-VDM_RESPONSE", - [PE_TIMER_WAIT_AND_ADD_JITTER] = "PE-WAIT_AND_ADD_JITTER", - [PE_TIMER_VCONN_DISCHARGE] = "PE-VCONN_DISCHARGE", - [PE_TIMER_VCONN_REAPPLIED] = "PE-VCONN_REAPPLIED", - [PE_TIMER_DATA_RESET_FAIL] = "PE-DATA_RESET_FAIL", - - [PR_TIMER_CHUNK_SENDER_REQUEST] = "PR-CHUNK_SENDER_REQUEST", + [PE_TIMER_DISCOVER_IDENTITY] = "PE-DISCOVER_IDENTITY", + [PE_TIMER_NO_RESPONSE] = "PE-NO_RESPONSE", + [PE_TIMER_PR_SWAP_WAIT] = "PE-PR_SWAP_WAIT", + [PE_TIMER_PS_HARD_RESET] = "PE-PS_HARD_RESET", + [PE_TIMER_PS_SOURCE] = "PE-PS_SOURCE", + [PE_TIMER_PS_TRANSITION] = "PE-PS_TRANSITION", + [PE_TIMER_SENDER_RESPONSE] = "PE-SENDER_RESPONSE", + [PE_TIMER_SINK_REQUEST] = "PE-SINK_REQUEST", + [PE_TIMER_SOURCE_CAP] = "PE-SOURCE_CAP", + [PE_TIMER_SRC_TRANSITION] = "PE-SRC_TRANSITION", + [PE_TIMER_SWAP_SOURCE_START] = "PE-SWAP_SOURCE_START", + [PE_TIMER_TIMEOUT] = "PE-TIMEOUT", + [PE_TIMER_VCONN_ON] = "PE-VCONN_ON", + [PE_TIMER_VDM_RESPONSE] = "PE-VDM_RESPONSE", + [PE_TIMER_WAIT_AND_ADD_JITTER] = "PE-WAIT_AND_ADD_JITTER", + [PE_TIMER_VCONN_DISCHARGE] = "PE-VCONN_DISCHARGE", + [PE_TIMER_VCONN_REAPPLIED] = "PE-VCONN_REAPPLIED", + [PE_TIMER_DATA_RESET_FAIL] = "PE-DATA_RESET_FAIL", + + [PR_TIMER_CHUNK_SENDER_REQUEST] = "PR-CHUNK_SENDER_REQUEST", [PR_TIMER_CHUNK_SENDER_RESPONSE] = "PR-CHUNK_SENDER_RESPONSE", - [PR_TIMER_HARD_RESET_COMPLETE] = "PR-HARD_RESET_COMPLETE", - [PR_TIMER_SINK_TX] = "PR-SINK_TX", - [PR_TIMER_TCPC_TX_TIMEOUT] = "PR-TCPC_TX_TIMEOUT", - - [TC_TIMER_CC_DEBOUNCE] = "TC-CC_DEBOUNCE", - [TC_TIMER_LOW_POWER_EXIT_TIME] = "TC-LOW_POWER_EXIT_TIME", - [TC_TIMER_LOW_POWER_TIME] = "TC-LOW_POWER_TIME", - [TC_TIMER_NEXT_ROLE_SWAP] = "TC-NEXT_ROLE_SWAP", - [TC_TIMER_PD_DEBOUNCE] = "TC-PD_DEBOUNCE", - [TC_TIMER_TIMEOUT] = "TC-TIMEOUT", - [TC_TIMER_TRY_WAIT_DEBOUNCE] = "TC-TRY_WAIT_DEBOUNCE", - [TC_TIMER_VBUS_DEBOUNCE] = "TC-VBUS_DEBOUNCE", + [PR_TIMER_HARD_RESET_COMPLETE] = "PR-HARD_RESET_COMPLETE", + [PR_TIMER_SINK_TX] = "PR-SINK_TX", + [PR_TIMER_TCPC_TX_TIMEOUT] = "PR-TCPC_TX_TIMEOUT", + [TC_TIMER_CC_DEBOUNCE] = "TC-CC_DEBOUNCE", + [TC_TIMER_LOW_POWER_EXIT_TIME] = "TC-LOW_POWER_EXIT_TIME", + [TC_TIMER_LOW_POWER_TIME] = "TC-LOW_POWER_TIME", + [TC_TIMER_NEXT_ROLE_SWAP] = "TC-NEXT_ROLE_SWAP", + [TC_TIMER_PD_DEBOUNCE] = "TC-PD_DEBOUNCE", + [TC_TIMER_TIMEOUT] = "TC-TIMEOUT", + [TC_TIMER_TRY_WAIT_DEBOUNCE] = "TC-TRY_WAIT_DEBOUNCE", + [TC_TIMER_VBUS_DEBOUNCE] = "TC-VBUS_DEBOUNCE", }; /***************************************************************************** @@ -171,17 +171,21 @@ void pd_timer_disable_range(int port, enum pd_timer_range range) enum pd_task_timer timer; switch (range) { + case DPM_TIMER_RANGE: + start = DPM_TIMER_START; + end = DPM_TIMER_END; + break; case PE_TIMER_RANGE: - start = PE_TIMER_START; - end = PE_TIMER_END; + start = PE_TIMER_START; + end = PE_TIMER_END; break; case PR_TIMER_RANGE: - start = PR_TIMER_START; - end = PR_TIMER_END; + start = PR_TIMER_START; + end = PR_TIMER_END; break; case TC_TIMER_RANGE: - start = TC_TIMER_START; - end = TC_TIMER_END; + start = TC_TIMER_START; + end = TC_TIMER_END; break; default: return; @@ -253,8 +257,8 @@ test_mockable_static void pd_timer_dump(int port) int timer; uint64_t now = get_time().val; - ccprints("Timers(%d): cur=%d max=%d", - port, count[port], max_count[port]); + ccprints("Timers(%d): cur=%d max=%d", port, count[port], + max_count[port]); for (timer = 0; timer < PD_TIMER_COUNT; ++timer) { if (pd_timer_is_disabled(port, timer)) { @@ -265,14 +269,13 @@ test_mockable_static void pd_timer_dump(int port) if (now < timer_expires[port][timer]) delta = timer_expires[port][timer] - now; - ccprints("[%2d] Active: %s (%d%s)", - timer, pd_timer_names[timer], (uint32_t)delta, - tc_event_loop_is_paused(port) - ? "-PAUSED" - : ""); + ccprints("[%2d] Active: %s (%d%s)", timer, + pd_timer_names[timer], (uint32_t)delta, + tc_event_loop_is_paused(port) ? "-PAUSED" : + ""); } else { - ccprints("[%2d] Inactive: %s", - timer, pd_timer_names[timer]); + ccprints("[%2d] Inactive: %s", timer, + pd_timer_names[timer]); } } } diff --git a/common/usbc/usb_pe_ctvpd_sm.c b/common/usbc/usb_pe_ctvpd_sm.c index 346a57a461..f3f3d8af9b 100644 --- a/common/usbc/usb_pe_ctvpd_sm.c +++ b/common/usbc/usb_pe_ctvpd_sm.c @@ -1,4 +1,4 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. +/* Copyright 2019 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -167,55 +167,48 @@ static void pe_request_run(const int port) /* Prepare to send ACK */ /* VDM Header */ - payload[0] = VDO( - USB_VID_GOOGLE, - 1, /* Structured VDM */ - VDO_SVDM_VERS(1) | - VDO_CMDT(CMDT_RSP_ACK) | - CMD_DISCOVER_IDENT); + payload[0] = VDO(USB_VID_GOOGLE, 1, /* Structured VDM */ + VDO_SVDM_VERS(1) | VDO_CMDT(CMDT_RSP_ACK) | + CMD_DISCOVER_IDENT); /* ID Header VDO */ - payload[1] = VDO_IDH( - 0, /* Not a USB Host */ - 1, /* Capable of being enumerated as USB Device */ - IDH_PTYPE_VPD, - 0, /* Modal Operation Not Supported */ - USB_VID_GOOGLE); + payload[1] = VDO_IDH(0, /* Not a USB Host */ + 1, /* Capable of being enumerated as USB + Device */ + IDH_PTYPE_VPD, 0, /* Modal Operation Not + Supported */ + USB_VID_GOOGLE); /* Cert State VDO */ payload[2] = 0; /* Product VDO */ - payload[3] = VDO_PRODUCT( - CONFIG_USB_PID, - USB_BCD_DEVICE); + payload[3] = VDO_PRODUCT(CONFIG_USB_PID, USB_BCD_DEVICE); /* VPD VDO */ payload[4] = VDO_VPD( - VPD_HW_VERSION, - VPD_FW_VERSION, - VPD_MAX_VBUS_20V, - IS_ENABLED(CONFIG_USB_CTVPD) ? VPD_CT_CURRENT - : 0, - IS_ENABLED(CONFIG_USB_CTVPD) ? VPD_VBUS_IMP( - VPD_VBUS_IMPEDANCE) - : 0, - IS_ENABLED(CONFIG_USB_CTVPD) ? VPD_GND_IMP( - VPD_GND_IMPEDANCE) - : 0, - IS_ENABLED(CONFIG_USB_CTVPD) ? VPD_CTS_SUPPORTED - : VPD_CTS_NOT_SUPPORTED); + VPD_HW_VERSION, VPD_FW_VERSION, VPD_MAX_VBUS_20V, + IS_ENABLED(CONFIG_USB_CTVPD) ? VPD_CT_CURRENT : 0, + IS_ENABLED(CONFIG_USB_CTVPD) ? + VPD_VBUS_IMP(VPD_VBUS_IMPEDANCE) : + 0, + IS_ENABLED(CONFIG_USB_CTVPD) ? + VPD_GND_IMP(VPD_GND_IMPEDANCE) : + 0, + IS_ENABLED(CONFIG_USB_CTVPD) ? VPD_CTS_SUPPORTED : + VPD_CTS_NOT_SUPPORTED); /* 20 bytes, 5 data objects */ tx_emsg[port].len = 20; /* Set to highest revision supported by both ports. */ prl_set_rev(port, TCPCI_MSG_SOP_PRIME, - (PD_HEADER_REV(header) > PD_REV30) ? - PD_REV30 : PD_HEADER_REV(header)); + (PD_HEADER_REV(header) > PD_REV30) ? + PD_REV30 : + PD_HEADER_REV(header)); /* Send the ACK */ prl_send_data_msg(port, TCPCI_MSG_SOP_PRIME, - PD_DATA_VENDOR_DEF); + PD_DATA_VENDOR_DEF); } } diff --git a/common/usbc/usb_pe_drp_sm.c b/common/usbc/usb_pe_drp_sm.c index baa2c98ec8..1094e4180c 100644 --- a/common/usbc/usb_pe_drp_sm.c +++ b/common/usbc/usb_pe_drp_sm.c @@ -1,4 +1,4 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. +/* Copyright 2019 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -6,6 +6,7 @@ #include "atomic.h" #include "battery.h" #include "battery_smart.h" +#include "builtin/assert.h" #include "charge_manager.h" #include "charge_state.h" #include "common.h" @@ -15,6 +16,7 @@ #include "ec_commands.h" #include "hooks.h" #include "host_command.h" +#include "power_button.h" #include "stdbool.h" #include "system.h" #include "task.h" @@ -47,41 +49,42 @@ */ #ifdef CONFIG_COMMON_RUNTIME -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) #else #define CPRINTF(format, args...) #define CPRINTS(format, args...) #endif -#define CPRINTF_LX(x, format, args...) \ - do { \ - if (pe_debug_level >= x) \ - CPRINTF(format, ## args); \ +#define CPRINTF_LX(x, format, args...) \ + do { \ + if (pe_debug_level >= x) \ + CPRINTF(format, ##args); \ } while (0) -#define CPRINTF_L1(format, args...) CPRINTF_LX(1, format, ## args) -#define CPRINTF_L2(format, args...) CPRINTF_LX(2, format, ## args) -#define CPRINTF_L3(format, args...) CPRINTF_LX(3, format, ## args) - -#define CPRINTS_LX(x, format, args...) \ - do { \ - if (pe_debug_level >= x) \ - CPRINTS(format, ## args); \ +#define CPRINTF_L1(format, args...) CPRINTF_LX(1, format, ##args) +#define CPRINTF_L2(format, args...) CPRINTF_LX(2, format, ##args) +#define CPRINTF_L3(format, args...) CPRINTF_LX(3, format, ##args) + +#define CPRINTS_LX(x, format, args...) \ + do { \ + if (pe_debug_level >= x) \ + CPRINTS(format, ##args); \ } while (0) -#define CPRINTS_L1(format, args...) CPRINTS_LX(1, format, ## args) -#define CPRINTS_L2(format, args...) CPRINTS_LX(2, format, ## args) -#define CPRINTS_L3(format, args...) CPRINTS_LX(3, format, ## args) - -#define PE_SET_FN(port, _fn) atomic_or(ATOMIC_ELEM(pe[port].flags_a, (_fn)), \ - ATOMIC_MASK(_fn)) -#define PE_CLR_FN(port, _fn) atomic_clear_bits(ATOMIC_ELEM(pe[port].flags_a, \ - (_fn)), ATOMIC_MASK(_fn)) -#define PE_CHK_FN(port, _fn) (pe[port].flags_a[ATOMIC_ELEM(0, (_fn))] & \ - ATOMIC_MASK(_fn)) - -#define PE_SET_FLAG(port, name) PE_SET_FN(port, (name ## _FN)) -#define PE_CLR_FLAG(port, name) PE_CLR_FN(port, (name ## _FN)) -#define PE_CHK_FLAG(port, name) PE_CHK_FN(port, (name ## _FN)) +#define CPRINTS_L1(format, args...) CPRINTS_LX(1, format, ##args) +#define CPRINTS_L2(format, args...) CPRINTS_LX(2, format, ##args) +#define CPRINTS_L3(format, args...) CPRINTS_LX(3, format, ##args) + +#define PE_SET_FN(port, _fn) \ + atomic_or(ATOMIC_ELEM(pe[port].flags_a, (_fn)), ATOMIC_MASK(_fn)) +#define PE_CLR_FN(port, _fn) \ + atomic_clear_bits(ATOMIC_ELEM(pe[port].flags_a, (_fn)), \ + ATOMIC_MASK(_fn)) +#define PE_CHK_FN(port, _fn) \ + (pe[port].flags_a[ATOMIC_ELEM(0, (_fn))] & ATOMIC_MASK(_fn)) + +#define PE_SET_FLAG(port, name) PE_SET_FN(port, (name##_FN)) +#define PE_CLR_FLAG(port, name) PE_CLR_FN(port, (name##_FN)) +#define PE_CHK_FLAG(port, name) PE_CHK_FN(port, (name##_FN)) /* * TODO(b/229655319): support more than 32 bits @@ -99,10 +102,11 @@ #define PE_CHK_DPM_REQUEST(port, req) (pe[port].dpm_request & (req)) /* Message flags which should not persist on returning to ready state */ -#define PE_MASK_READY_CLR (BIT(PE_FLAGS_LOCALLY_INITIATED_AMS_FN) | \ - BIT(PE_FLAGS_MSG_DISCARDED_FN) | \ - BIT(PE_FLAGS_VDM_REQUEST_TIMEOUT_FN) | \ - BIT(PE_FLAGS_INTERRUPTIBLE_AMS_FN)) +#define PE_MASK_READY_CLR \ + (BIT(PE_FLAGS_LOCALLY_INITIATED_AMS_FN) | \ + BIT(PE_FLAGS_MSG_DISCARDED_FN) | \ + BIT(PE_FLAGS_VDM_REQUEST_TIMEOUT_FN) | \ + BIT(PE_FLAGS_INTERRUPTIBLE_AMS_FN)) /* * Combination to check whether a reply to a message was received. Our message @@ -113,8 +117,9 @@ * on the same run cycle. With chunking, received message will take an * additional cycle to be flagged. */ -#define PE_CHK_REPLY(port) (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED) && \ - !PE_CHK_FLAG(port, PE_FLAGS_MSG_DISCARDED)) +#define PE_CHK_REPLY(port) \ + (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED) && \ + !PE_CHK_FLAG(port, PE_FLAGS_MSG_DISCARDED)) /* 6.7.3 Hard Reset Counter */ #define N_HARD_RESET_COUNT 2 @@ -136,20 +141,20 @@ * solely from VCONN. Limit the number of retries without a contract to * ensure we attempt some cable discovery after a contract is in place. */ -#define N_DISCOVER_IDENTITY_PRECONTRACT_LIMIT 2 +#define N_DISCOVER_IDENTITY_PRECONTRACT_LIMIT 2 /* * Once this limit of SOP' Discover Identity messages has been set, downgrade * to PD 2.0 in case the cable is non-compliant about GoodCRC-ing higher * revisions. This limit should be higher than the precontract limit. */ -#define N_DISCOVER_IDENTITY_PD3_0_LIMIT 4 +#define N_DISCOVER_IDENTITY_PD3_0_LIMIT 4 /* * tDiscoverIdentity is only defined while an explicit contract is in place, so * extend the interval between retries pre-contract. */ -#define PE_T_DISCOVER_IDENTITY_NO_CONTRACT (200*MSEC) +#define PE_T_DISCOVER_IDENTITY_NO_CONTRACT (200 * MSEC) /* * Only VCONN source can communicate with the cable plug. Hence, try VCONN swap @@ -278,6 +283,7 @@ enum usb_pe_state { PE_GIVE_BATTERY_STATUS, PE_GIVE_STATUS, PE_SEND_ALERT, + PE_ALERT_RECEIVED, PE_SRC_CHUNK_RECEIVED, PE_SNK_CHUNK_RECEIVED, PE_VCS_FORCE_VCONN, @@ -316,15 +322,14 @@ static const struct usb_state pe_states[]; * If we can't print or the CONFIG_USB_PD_DEBUG_LEVEL is defined to be 0 * then the DEBUG LABELS will be removed from the build. */ -#if defined(CONFIG_COMMON_RUNTIME) && \ - (!defined(CONFIG_USB_PD_DEBUG_LEVEL) || \ - (CONFIG_USB_PD_DEBUG_LEVEL > 0)) +#if defined(CONFIG_COMMON_RUNTIME) && (!defined(CONFIG_USB_PD_DEBUG_LEVEL) || \ + (CONFIG_USB_PD_DEBUG_LEVEL > 0)) #define USB_PD_DEBUG_LABELS #endif /* List of human readable state names for console debugging */ -__maybe_unused static __const_data const char * const pe_state_names[] = { - /* Super States */ +__maybe_unused static __const_data const char *const pe_state_names[] = { +/* Super States */ #ifdef CONFIG_USB_PD_REV30 [PE_PRS_FRS_SHARED] = "SS:PE_PRS_FRS_SHARED", #endif @@ -381,7 +386,7 @@ __maybe_unused static __const_data const char * const pe_state_names[] = { #endif [PE_VDM_IDENTITY_REQUEST_CBL] = "PE_VDM_Identity_Request_Cbl", [PE_INIT_PORT_VDM_IDENTITY_REQUEST] = - "PE_INIT_PORT_VDM_Identity_Request", + "PE_INIT_PORT_VDM_Identity_Request", [PE_INIT_VDM_SVIDS_REQUEST] = "PE_INIT_VDM_SVIDs_Request", [PE_INIT_VDM_MODES_REQUEST] = "PE_INIT_VDM_Modes_Request", [PE_VDM_REQUEST_DPM] = "PE_VDM_Request_DPM", @@ -389,12 +394,12 @@ __maybe_unused static __const_data const char * const pe_state_names[] = { [PE_HANDLE_CUSTOM_VDM_REQUEST] = "PE_Handle_Custom_Vdm_Request", [PE_WAIT_FOR_ERROR_RECOVERY] = "PE_Wait_For_Error_Recovery", [PE_BIST_TX] = "PE_Bist_TX", - [PE_DEU_SEND_ENTER_USB] = "PE_DEU_Send_Enter_USB", + [PE_DEU_SEND_ENTER_USB] = "PE_DEU_Send_Enter_USB", [PE_DR_GET_SINK_CAP] = "PE_DR_Get_Sink_Cap", [PE_DR_SNK_GIVE_SOURCE_CAP] = "PE_DR_SNK_Give_Source_Cap", [PE_DR_SRC_GET_SOURCE_CAP] = "PE_DR_SRC_Get_Source_Cap", - /* PD3.0 only states below here*/ +/* PD3.0 only states below here*/ #ifdef CONFIG_USB_PD_REV30 [PE_FRS_SNK_SRC_START_AMS] = "PE_FRS_SNK_SRC_Start_Ams", [PE_GET_REVISION] = "PE_Get_Revision", @@ -403,6 +408,7 @@ __maybe_unused static __const_data const char * const pe_state_names[] = { [PE_GIVE_BATTERY_STATUS] = "PE_Give_Battery_Status", [PE_GIVE_STATUS] = "PE_Give_Status", [PE_SEND_ALERT] = "PE_Send_Alert", + [PE_ALERT_RECEIVED] = "PE_Alert_Received", #else [PE_SRC_CHUNK_RECEIVED] = "PE_SRC_Chunk_Received", [PE_SNK_CHUNK_RECEIVED] = "PE_SNK_Chunk_Received", @@ -416,7 +422,7 @@ __maybe_unused static __const_data const char * const pe_state_names[] = { [PE_UDR_TURN_OFF_VCONN] = "PE_UDR_Turn_Off_VCONN", [PE_UDR_SEND_PS_RDY] = "PE_UDR_Send_Ps_Rdy", [PE_UDR_WAIT_FOR_DATA_RESET_COMPLETE] = - "PE_UDR_Wait_For_Data_Reset_Complete", + "PE_UDR_Wait_For_Data_Reset_Complete", [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", @@ -451,6 +457,8 @@ GEN_NOT_SUPPORTED(PE_SNK_CHUNK_RECEIVED); #define PE_SNK_CHUNK_RECEIVED PE_SNK_CHUNK_RECEIVED_NOT_SUPPORTED GEN_NOT_SUPPORTED(PE_GET_REVISION); #define PE_GET_REVISION PE_GET_REVISION_NOT_SUPPORTED +GEN_NOT_SUPPORTED(PE_ALERT_RECEIVED); +#define PE_ALERT_RECEIVED PE_ALERT_RECEIVED_NOT_SUPPORTED #endif /* CONFIG_USB_PD_REV30 */ #if !defined(CONFIG_USBC_VCONN) || !defined(CONFIG_USB_PD_REV30) @@ -529,12 +537,12 @@ static enum sm_local_state local_state[CONFIG_USB_PD_PORT_MAX_COUNT]; * what ever is needed to handle the Discard. */ enum pe_msg_check { - PE_MSG_SEND_PENDING = BIT(0), - PE_MSG_SENT = BIT(1), - PE_MSG_DISCARDED = BIT(2), + PE_MSG_SEND_PENDING = BIT(0), + PE_MSG_SENT = BIT(1), + PE_MSG_DISCARDED = BIT(2), - PE_MSG_SEND_COMPLETED = BIT(3) | PE_MSG_SENT, - PE_MSG_DPM_DISCARDED = BIT(4) | PE_MSG_DISCARDED, + PE_MSG_SEND_COMPLETED = BIT(3) | PE_MSG_SENT, + PE_MSG_DPM_DISCARDED = BIT(4) | PE_MSG_DISCARDED, }; static void pe_sender_response_msg_entry(const int port); static enum pe_msg_check pe_sender_response_msg_run(const int port); @@ -543,6 +551,8 @@ static void pe_sender_response_msg_exit(const int port); /* Debug log level - higher number == more log */ #ifdef CONFIG_USB_PD_DEBUG_LEVEL static const enum debug_level pe_debug_level = CONFIG_USB_PD_DEBUG_LEVEL; +#elif defined(CONFIG_USB_PD_INITIAL_DEBUG_LEVEL) +static enum debug_level pe_debug_level = CONFIG_USB_PD_INITIAL_DEBUG_LEVEL; #else static enum debug_level pe_debug_level = DEBUG_LEVEL_1; #endif @@ -654,7 +664,7 @@ static struct policy_engine { /* Attached ChromeOS device id, RW hash, and current RO / RW image */ uint16_t dev_id; - uint32_t dev_rw_hash[PD_RW_HASH_SIZE/4]; + uint32_t dev_rw_hash[PD_RW_HASH_SIZE / 4]; enum ec_image current_image; } pe[CONFIG_USB_PD_PORT_MAX_COUNT]; @@ -713,8 +723,8 @@ static inline void send_data_msg(int port, enum tcpci_msg_type type, prl_send_data_msg(port, type, msg); } -static __maybe_unused inline void send_ext_data_msg( - int port, enum tcpci_msg_type type, enum pd_ext_msg_type msg) +static __maybe_unused inline void +send_ext_data_msg(int port, enum tcpci_msg_type type, enum pd_ext_msg_type msg) { /* Clear any previous TX status before sending a new message */ PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE); @@ -744,15 +754,15 @@ static void init_cable_rev(int port) * also be PD 2.0 */ if (prl_get_rev(port, TCPCI_MSG_SOP) == PD_REV20) { - /* - * If the cable supports PD 3.0, but the port partner supports PD 2.0, - * redo the cable discover with PD 2.0 - */ + /* + * If the cable supports PD 3.0, but the port partner supports + * PD 2.0, redo the cable discover with PD 2.0 + */ if (prl_get_rev(port, TCPCI_MSG_SOP_PRIME) == PD_REV30 && pd_get_identity_discovery(port, TCPCI_MSG_SOP_PRIME) == - PD_DISC_COMPLETE) { + PD_DISC_COMPLETE) { pd_set_identity_discovery(port, TCPCI_MSG_SOP_PRIME, - PD_DISC_NEEDED); + PD_DISC_NEEDED); } set_cable_rev(port, PD_REV20); } @@ -850,8 +860,8 @@ void pe_run(int port, int evt, int en) DPM_REQUEST_HARD_RESET_SEND); set_state_pe(port, PE_WAIT_FOR_ERROR_RECOVERY); } else { - pe_set_dpm_curr_request(port, - DPM_REQUEST_HARD_RESET_SEND); + pe_set_dpm_curr_request( + port, DPM_REQUEST_HARD_RESET_SEND); pe_set_hard_reset(port); } } @@ -864,7 +874,7 @@ void pe_run(int port, int evt, int en) * make sure to handle it immediately. */ if (IS_ENABLED(CONFIG_USB_PD_REV30) && - PE_CHK_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_SIGNALED)) { + PE_CHK_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_SIGNALED)) { PE_CLR_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_SIGNALED); set_state_pe(port, PE_FRS_SNK_SRC_START_AMS); } @@ -968,13 +978,13 @@ static void pe_set_frs_enable(int port, int enable) pd_set_frs_enable(port, enable); if (enable) { - int curr_limit = *pd_get_snk_caps(port) - & PDO_FIXED_FRS_CURR_MASK; + int curr_limit = *pd_get_snk_caps(port) & + PDO_FIXED_FRS_CURR_MASK; - typec_select_src_current_limit_rp(port, - curr_limit == - PDO_FIXED_FRS_CURR_3A0_AT_5V ? - TYPEC_RP_3A0 : TYPEC_RP_1A5); + typec_select_src_current_limit_rp( + port, curr_limit == PDO_FIXED_FRS_CURR_3A0_AT_5V ? + TYPEC_RP_3A0 : + TYPEC_RP_1A5); PE_SET_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_ENABLED); } else { PE_CLR_FLAG(port, PE_FLAGS_FAST_ROLE_SWAP_ENABLED); @@ -1026,7 +1036,7 @@ void pe_set_snk_caps(int port, int cnt, uint32_t *snk_caps) memcpy(pe[port].snk_caps, snk_caps, sizeof(uint32_t) * cnt); } -const uint32_t * const pd_get_snk_caps(int port) +const uint32_t *const pd_get_snk_caps(int port) { return pe[port].snk_caps; } @@ -1066,12 +1076,12 @@ static bool pe_can_send_sop_prime(int port) if (PE_CHK_FLAG(port, PE_FLAGS_EXPLICIT_CONTRACT)) { if (prl_get_rev(port, TCPCI_MSG_SOP) == PD_REV20) return tc_is_vconn_src(port) && - pe[port].data_role == PD_ROLE_DFP; + pe[port].data_role == PD_ROLE_DFP; else return tc_is_vconn_src(port); } else { return tc_is_vconn_src(port) && - pe[port].power_role == PD_ROLE_SOURCE; + pe[port].power_role == PD_ROLE_SOURCE; } } else { return false; @@ -1146,9 +1156,9 @@ static bool pe_check_outgoing_discard(int port) * Version 2.0 Specification. */ if (PE_CHK_FLAG(port, PE_FLAGS_MSG_DISCARDED) && - PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { + PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { enum tcpci_msg_type sop = - PD_HEADER_GET_SOP(rx_emsg[port].header); + PD_HEADER_GET_SOP(rx_emsg[port].header); PE_CLR_FLAG(port, PE_FLAGS_MSG_DISCARDED); PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); @@ -1190,28 +1200,26 @@ void pe_report_error(int port, enum pe_error e, enum tcpci_msg_type type) * TODO(b/150774779): TCPMv2: Improve pe_error documentation */ if ((get_state_pe(port) == PE_SRC_SEND_CAPABILITIES || - get_state_pe(port) == PE_SRC_TRANSITION_SUPPLY || - get_state_pe(port) == PE_PRS_SNK_SRC_EVALUATE_SWAP || - get_state_pe(port) == PE_PRS_SNK_SRC_SOURCE_ON || - get_state_pe(port) == PE_PRS_SRC_SNK_WAIT_SOURCE_ON || - get_state_pe(port) == PE_SRC_DISABLED || - get_state_pe(port) == PE_SRC_DISCOVERY || - get_state_pe(port) == PE_VCS_CBL_SEND_SOFT_RESET || - get_state_pe(port) == PE_VDM_IDENTITY_REQUEST_CBL) || - (IS_ENABLED(CONFIG_USB_PD_DATA_RESET_MSG) && - (get_state_pe(port) == PE_UDR_SEND_DATA_RESET || - get_state_pe(port) == PE_UDR_DATA_RESET_RECEIVED || - get_state_pe(port) == PE_UDR_TURN_OFF_VCONN || - get_state_pe(port) == PE_UDR_SEND_PS_RDY || - get_state_pe(port) == - PE_UDR_WAIT_FOR_DATA_RESET_COMPLETE || - 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) && - get_state_pe(port) == PE_PRS_SNK_SRC_SEND_SWAP) - ) { + get_state_pe(port) == PE_SRC_TRANSITION_SUPPLY || + get_state_pe(port) == PE_PRS_SNK_SRC_EVALUATE_SWAP || + get_state_pe(port) == PE_PRS_SNK_SRC_SOURCE_ON || + get_state_pe(port) == PE_PRS_SRC_SNK_WAIT_SOURCE_ON || + get_state_pe(port) == PE_SRC_DISABLED || + get_state_pe(port) == PE_SRC_DISCOVERY || + get_state_pe(port) == PE_VCS_CBL_SEND_SOFT_RESET || + get_state_pe(port) == PE_VDM_IDENTITY_REQUEST_CBL) || + (IS_ENABLED(CONFIG_USB_PD_DATA_RESET_MSG) && + (get_state_pe(port) == PE_UDR_SEND_DATA_RESET || + get_state_pe(port) == PE_UDR_DATA_RESET_RECEIVED || + get_state_pe(port) == PE_UDR_TURN_OFF_VCONN || + get_state_pe(port) == PE_UDR_SEND_PS_RDY || + get_state_pe(port) == PE_UDR_WAIT_FOR_DATA_RESET_COMPLETE || + 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) && + get_state_pe(port) == PE_PRS_SNK_SRC_SEND_SWAP)) { PE_SET_FLAG(port, PE_FLAGS_PROTOCOL_ERROR); task_wake(PD_PORT_TO_TASK_ID(port)); return; @@ -1234,10 +1242,10 @@ void pe_report_error(int port, enum pe_error e, enum tcpci_msg_type type) */ /* All error types besides transmit errors are Protocol Errors. */ if ((e != ERR_TCH_XMIT && - !PE_CHK_FLAG(port, PE_FLAGS_INTERRUPTIBLE_AMS)) - || e == ERR_TCH_XMIT - || (!PE_CHK_FLAG(port, PE_FLAGS_EXPLICIT_CONTRACT) && - type == TCPCI_MSG_SOP)) { + !PE_CHK_FLAG(port, PE_FLAGS_INTERRUPTIBLE_AMS)) || + e == ERR_TCH_XMIT || + (!PE_CHK_FLAG(port, PE_FLAGS_EXPLICIT_CONTRACT) && + type == TCPCI_MSG_SOP)) { pe_send_soft_reset(port, type); } /* @@ -1262,7 +1270,7 @@ void pe_got_soft_reset(int port) } __overridable bool pd_can_charge_from_device(int port, const int pdo_cnt, - const uint32_t *pdos) + const uint32_t *pdos) { /* * Don't attempt to charge from a device we have no SrcCaps from. Or, if @@ -1292,9 +1300,7 @@ __overridable bool pd_can_charge_from_device(int port, const int pdo_cnt, * Get max power that the partner offers (not necessarily what * this board will request) */ - pd_find_pdo_index(pdo_cnt, pdos, - PD_REV3_MAX_VOLTAGE, - &max_pdo); + pd_find_pdo_index(pdo_cnt, pdos, PD_REV3_MAX_VOLTAGE, &max_pdo); pd_extract_pdo_power(max_pdo, &max_ma, &max_mv, &unused); max_mw = max_ma * max_mv / 1000; @@ -1351,14 +1357,15 @@ void pe_message_sent(int port) } void pd_send_vdm(int port, uint32_t vid, int cmd, const uint32_t *data, - int count) + int count) { /* Copy VDM Header */ pe[port].vdm_data[0] = - VDO(vid, ((vid & USB_SID_PD) == USB_SID_PD) ? 1 : - (PD_VDO_CMD(cmd) <= CMD_ATTENTION), - VDO_SVDM_VERS(pd_get_vdo_ver(port, TCPCI_MSG_SOP)) | - cmd); + VDO(vid, + ((vid & USB_SID_PD) == USB_SID_PD) ? + 1 : + (PD_VDO_CMD(cmd) <= CMD_ATTENTION), + VDO_SVDM_VERS(pd_get_vdo_ver(port, TCPCI_MSG_SOP)) | cmd); /* * Copy VDOs after the VDM Header. Note that the count refers to VDO @@ -1485,21 +1492,21 @@ static void pe_update_waiting_batt_flag(void) * flag and perform Hard Reset. */ PE_CLR_FLAG(i, PE_FLAGS_SNK_WAITING_BATT); - CPRINTS("C%d: Battery has enough charge (%d%%) " \ - "to withstand a hard reset", i, batt_soc); + CPRINTS("C%d: Battery has enough charge (%d%%) " + "to withstand a hard reset", + i, batt_soc); pd_dpm_request(i, DPM_REQUEST_HARD_RESET_SEND); } } } DECLARE_HOOK(HOOK_BATTERY_SOC_CHANGE, pe_update_waiting_batt_flag, - HOOK_PRIO_DEFAULT); + HOOK_PRIO_DEFAULT); #endif /* * Private functions */ -static void pe_set_dpm_curr_request(const int port, - const int request) +static void pe_set_dpm_curr_request(const int port, const int request) { PE_CLR_DPM_REQUEST(port, request); pe[port].dpm_curr_request = request; @@ -1527,33 +1534,24 @@ test_export_static enum usb_pe_state get_state_pe(const int port) */ static bool common_src_snk_dpm_requests(int port) { - if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES) && - PE_CHK_DPM_REQUEST(port, DPM_REQUEST_SEND_ALERT)) { - pe_set_dpm_curr_request(port, DPM_REQUEST_SEND_ALERT); - set_state_pe(port, PE_SEND_ALERT); - return true; - } else if (IS_ENABLED(CONFIG_USBC_VCONN) && - PE_CHK_DPM_REQUEST(port, DPM_REQUEST_VCONN_SWAP)) { + if (IS_ENABLED(CONFIG_USBC_VCONN) && + PE_CHK_DPM_REQUEST(port, DPM_REQUEST_VCONN_SWAP)) { pe_set_dpm_curr_request(port, DPM_REQUEST_VCONN_SWAP); set_state_pe(port, PE_VCS_SEND_SWAP); return true; - } else if (PE_CHK_DPM_REQUEST(port, - DPM_REQUEST_BIST_TX)) { + } else if (PE_CHK_DPM_REQUEST(port, DPM_REQUEST_BIST_TX)) { pe_set_dpm_curr_request(port, DPM_REQUEST_BIST_TX); set_state_pe(port, PE_BIST_TX); return true; - } else if (PE_CHK_DPM_REQUEST(port, - DPM_REQUEST_SNK_STARTUP)) { + } else if (PE_CHK_DPM_REQUEST(port, DPM_REQUEST_SNK_STARTUP)) { pe_set_dpm_curr_request(port, DPM_REQUEST_SNK_STARTUP); set_state_pe(port, PE_SNK_STARTUP); return true; - } else if (PE_CHK_DPM_REQUEST(port, - DPM_REQUEST_SRC_STARTUP)) { + } else if (PE_CHK_DPM_REQUEST(port, DPM_REQUEST_SRC_STARTUP)) { pe_set_dpm_curr_request(port, DPM_REQUEST_SRC_STARTUP); set_state_pe(port, PE_SRC_STARTUP); return true; - } else if (PE_CHK_DPM_REQUEST(port, - DPM_REQUEST_SOFT_RESET_SEND)) { + } else if (PE_CHK_DPM_REQUEST(port, DPM_REQUEST_SOFT_RESET_SEND)) { pe_set_dpm_curr_request(port, DPM_REQUEST_SOFT_RESET_SEND); /* Currently only support sending soft reset to SOP */ pe_send_soft_reset(port, TCPCI_MSG_SOP); @@ -1593,14 +1591,13 @@ static bool common_src_snk_dpm_requests(int port) dpm_set_mode_exit_request(port); return true; } else if (PE_CHK_DPM_REQUEST(port, DPM_REQUEST_GET_SNK_CAPS)) { - pe_set_dpm_curr_request(port, - DPM_REQUEST_GET_SNK_CAPS); + pe_set_dpm_curr_request(port, DPM_REQUEST_GET_SNK_CAPS); set_state_pe(port, PE_DR_GET_SINK_CAP); return true; } else if (PE_CHK_DPM_REQUEST(port, DPM_REQUEST_SOP_PRIME_SOFT_RESET_SEND)) { pe_set_dpm_curr_request(port, - DPM_REQUEST_SOP_PRIME_SOFT_RESET_SEND); + DPM_REQUEST_SOP_PRIME_SOFT_RESET_SEND); pe[port].tx_type = TCPCI_MSG_SOP_PRIME; set_state_pe(port, PE_VCS_CBL_SEND_SOFT_RESET); return true; @@ -1617,8 +1614,9 @@ static bool common_src_snk_dpm_requests(int port) set_state_pe(port, PE_DRS_SEND_SWAP); return true; } else if (IS_ENABLED(CONFIG_USB_PD_DATA_RESET_MSG) && - PE_CHK_DPM_REQUEST(port, DPM_REQUEST_DATA_RESET)) { + PE_CHK_DPM_REQUEST(port, DPM_REQUEST_DATA_RESET)) { if (prl_get_rev(port, TCPCI_MSG_SOP) < PD_REV30) { + PE_CLR_DPM_REQUEST(port, DPM_REQUEST_DATA_RESET); dpm_data_reset_complete(port); return false; } @@ -1631,9 +1629,22 @@ static bool common_src_snk_dpm_requests(int port) return true; } else if (IS_ENABLED(CONFIG_USB_PD_REV30) && PE_CHK_DPM_REQUEST(port, DPM_REQUEST_GET_REVISION)) { + if (prl_get_rev(port, TCPCI_MSG_SOP) < PD_REV30) { + PE_CLR_DPM_REQUEST(port, DPM_REQUEST_GET_REVISION); + return false; + } pe_set_dpm_curr_request(port, DPM_REQUEST_GET_REVISION); set_state_pe(port, PE_GET_REVISION); return true; + } else if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES) && + PE_CHK_DPM_REQUEST(port, DPM_REQUEST_SEND_ALERT)) { + if (prl_get_rev(port, TCPCI_MSG_SOP) < PD_REV30) { + PE_CLR_DPM_REQUEST(port, DPM_REQUEST_SEND_ALERT); + return false; + } + pe_set_dpm_curr_request(port, DPM_REQUEST_SEND_ALERT); + set_state_pe(port, PE_SEND_ALERT); + return true; } return false; @@ -1654,9 +1665,9 @@ static bool source_dpm_requests(int port) * DPM_REQURST_FRS_DET_DISABLE */ PE_CLR_DPM_REQUEST(port, DPM_REQUEST_NEW_POWER_LEVEL | - DPM_REQUEST_SOURCE_CAP | - DPM_REQUEST_FRS_DET_ENABLE | - DPM_REQUEST_FRS_DET_DISABLE); + DPM_REQUEST_SOURCE_CAP | + DPM_REQUEST_FRS_DET_ENABLE | + DPM_REQUEST_FRS_DET_DISABLE); if (pe[port].dpm_request) { uint32_t dpm_request = pe[port].dpm_request; @@ -1668,8 +1679,7 @@ static bool source_dpm_requests(int port) set_state_pe(port, PE_PRS_SRC_SNK_SEND_SWAP); return true; } else if (PE_CHK_DPM_REQUEST(port, DPM_REQUEST_GOTO_MIN)) { - pe_set_dpm_curr_request(port, - DPM_REQUEST_GOTO_MIN); + pe_set_dpm_curr_request(port, DPM_REQUEST_GOTO_MIN); set_state_pe(port, PE_SRC_TRANSITION_SUPPLY); return true; } else if (PE_CHK_DPM_REQUEST(port, @@ -1679,21 +1689,18 @@ static bool source_dpm_requests(int port) set_state_pe(port, PE_SRC_SEND_CAPABILITIES); return true; } else if (PE_CHK_DPM_REQUEST(port, DPM_REQUEST_GET_SRC_CAPS)) { - pe_set_dpm_curr_request(port, - DPM_REQUEST_GET_SRC_CAPS); + pe_set_dpm_curr_request(port, DPM_REQUEST_GET_SRC_CAPS); set_state_pe(port, PE_DR_SRC_GET_SOURCE_CAP); return true; } else if (PE_CHK_DPM_REQUEST(port, DPM_REQUEST_SEND_PING)) { - pe_set_dpm_curr_request(port, - DPM_REQUEST_SEND_PING); + pe_set_dpm_curr_request(port, DPM_REQUEST_SEND_PING); set_state_pe(port, PE_SRC_PING); return true; } else if (common_src_snk_dpm_requests(port)) { return true; } - CPRINTF("Unhandled DPM Request %x received\n", - dpm_request); + CPRINTF("Unhandled DPM Request %x received\n", dpm_request); PE_CLR_DPM_REQUEST(port, dpm_request); PE_CLR_FLAG(port, PE_FLAGS_LOCALLY_INITIATED_AMS); } @@ -1714,8 +1721,8 @@ static bool sink_dpm_requests(int port) * DPM_REQUEST_SEND_PING */ PE_CLR_DPM_REQUEST(port, DPM_REQUEST_GOTO_MIN | - DPM_REQUEST_SRC_CAP_CHANGE | - DPM_REQUEST_SEND_PING); + DPM_REQUEST_SRC_CAP_CHANGE | + DPM_REQUEST_SEND_PING); if (pe[port].dpm_request) { uint32_t dpm_request = pe[port].dpm_request; @@ -1727,8 +1734,7 @@ static bool sink_dpm_requests(int port) set_state_pe(port, PE_PRS_SNK_SRC_SEND_SWAP); return true; } else if (PE_CHK_DPM_REQUEST(port, DPM_REQUEST_SOURCE_CAP)) { - pe_set_dpm_curr_request(port, - DPM_REQUEST_SOURCE_CAP); + pe_set_dpm_curr_request(port, DPM_REQUEST_SOURCE_CAP); set_state_pe(port, PE_SNK_GET_SOURCE_CAP); return true; } else if (PE_CHK_DPM_REQUEST(port, @@ -1775,13 +1781,12 @@ static void print_current_state(const int port) { const char *mode = ""; - if (IS_ENABLED(CONFIG_USB_PD_REV30) && - pe_in_frs_mode(port)) + if (IS_ENABLED(CONFIG_USB_PD_REV30) && pe_in_frs_mode(port)) mode = " FRS-MODE"; if (IS_ENABLED(USB_PD_DEBUG_LABELS)) CPRINTS_L1("C%d: %s%s", port, - pe_state_names[get_state_pe(port)], mode); + pe_state_names[get_state_pe(port)], mode); else CPRINTS("C%d: pe-st%d", port, get_state_pe(port)); } @@ -1817,20 +1822,20 @@ static void pe_send_request_msg(int port) * might need adjusting. */ if ((get_usb_pd_cable_type(port) == IDH_PTYPE_VPD) && - is_vpd_ct_supported(port)) { - union vpd_vdo vpd = pd_get_am_discovery(port, - TCPCI_MSG_SOP_PRIME)->identity.product_t1.vpd; + is_vpd_ct_supported(port)) { + union vpd_vdo vpd = + pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME) + ->identity.product_t1.vpd; /* The raw vpd_vdo is passed to pd_build_request */ vpd_vdo = vpd.raw_value; } /* Build and send request RDO */ - pd_build_request(vpd_vdo, &rdo, &curr_limit, - &supply_voltage, port); + pd_build_request(vpd_vdo, &rdo, &curr_limit, &supply_voltage, port); - CPRINTF("C%d: Req [%d] %dmV %dmA", port, RDO_POS(rdo), - supply_voltage, curr_limit); + CPRINTF("C%d: Req [%d] %dmV %dmA", port, RDO_POS(rdo), supply_voltage, + curr_limit); if (rdo & RDO_CAP_MISMATCH) CPRINTF(" Mismatch"); CPRINTF("\n"); @@ -1931,18 +1936,35 @@ __maybe_unused static bool pe_attempt_port_discovery(int port) return false; /* Apply Port Discovery DR Swap Policy */ - if (port_discovery_dr_swap_policy(port, pe[port].data_role, - PE_CHK_FLAG(port, PE_FLAGS_DR_SWAP_TO_DFP))) { + if (port_discovery_dr_swap_policy( + port, pe[port].data_role, + PE_CHK_FLAG(port, PE_FLAGS_DR_SWAP_TO_DFP))) { PE_SET_FLAG(port, PE_FLAGS_LOCALLY_INITIATED_AMS); PE_CLR_FLAG(port, PE_FLAGS_DR_SWAP_TO_DFP); set_state_pe(port, PE_DRS_SEND_SWAP); return true; } + /* + * An edge case of DR Swap fail (port still UFP) and partner in PD 2.0. + * PD 2.0 allows only DFP to initiate Discover Identity, but partner may + * reject a DR Swap. + */ + if (pe[port].data_role == PD_ROLE_UFP && + prl_get_rev(port, TCPCI_MSG_SOP) == PD_REV20) { + pd_set_identity_discovery(port, TCPCI_MSG_SOP, PD_DISC_FAIL); + pd_set_identity_discovery(port, TCPCI_MSG_SOP_PRIME, + PD_DISC_FAIL); + pd_notify_event(port, PD_STATUS_EVENT_SOP_DISC_DONE); + pd_notify_event(port, PD_STATUS_EVENT_SOP_PRIME_DISC_DONE); + PE_SET_FLAG(port, PE_FLAGS_VDM_SETUP_DONE); + return false; + } + /* Apply Port Discovery VCONN Swap Policy */ if (IS_ENABLED(CONFIG_USBC_VCONN) && - port_discovery_vconn_swap_policy(port, - PE_CHK_FLAG(port, PE_FLAGS_VCONN_SWAP_TO_ON))) { + port_discovery_vconn_swap_policy( + port, PE_CHK_FLAG(port, PE_FLAGS_VCONN_SWAP_TO_ON))) { PE_SET_FLAG(port, PE_FLAGS_LOCALLY_INITIATED_AMS); PE_CLR_FLAG(port, PE_FLAGS_VCONN_SWAP_TO_ON); set_state_pe(port, PE_VCS_SEND_SWAP); @@ -1961,36 +1983,35 @@ __maybe_unused static bool pe_attempt_port_discovery(int port) */ if (pd_timer_is_expired(port, PE_TIMER_DISCOVER_IDENTITY)) { if (pd_get_identity_discovery(port, TCPCI_MSG_SOP_PRIME) == - PD_DISC_NEEDED) { + PD_DISC_NEEDED) { pe[port].tx_type = TCPCI_MSG_SOP_PRIME; set_state_pe(port, PE_VDM_IDENTITY_REQUEST_CBL); return true; } else if (pd_get_identity_discovery(port, TCPCI_MSG_SOP) == - PD_DISC_NEEDED && - pe_can_send_sop_vdm(port, CMD_DISCOVER_IDENT)) { + PD_DISC_NEEDED && + pe_can_send_sop_vdm(port, CMD_DISCOVER_IDENT)) { pe[port].tx_type = TCPCI_MSG_SOP; - set_state_pe(port, - PE_INIT_PORT_VDM_IDENTITY_REQUEST); + set_state_pe(port, PE_INIT_PORT_VDM_IDENTITY_REQUEST); return true; } else if (pd_get_svids_discovery(port, TCPCI_MSG_SOP) == - PD_DISC_NEEDED && - pe_can_send_sop_vdm(port, CMD_DISCOVER_SVID)) { + PD_DISC_NEEDED && + pe_can_send_sop_vdm(port, CMD_DISCOVER_SVID)) { pe[port].tx_type = TCPCI_MSG_SOP; set_state_pe(port, PE_INIT_VDM_SVIDS_REQUEST); return true; } else if (pd_get_modes_discovery(port, TCPCI_MSG_SOP) == - PD_DISC_NEEDED && - pe_can_send_sop_vdm(port, CMD_DISCOVER_MODES)) { + PD_DISC_NEEDED && + pe_can_send_sop_vdm(port, CMD_DISCOVER_MODES)) { pe[port].tx_type = TCPCI_MSG_SOP; set_state_pe(port, PE_INIT_VDM_MODES_REQUEST); return true; - } else if (pd_get_svids_discovery(port, TCPCI_MSG_SOP_PRIME) - == PD_DISC_NEEDED) { + } else if (pd_get_svids_discovery(port, TCPCI_MSG_SOP_PRIME) == + PD_DISC_NEEDED) { pe[port].tx_type = TCPCI_MSG_SOP_PRIME; set_state_pe(port, PE_INIT_VDM_SVIDS_REQUEST); return true; } else if (pd_get_modes_discovery(port, TCPCI_MSG_SOP_PRIME) == - PD_DISC_NEEDED) { + PD_DISC_NEEDED) { pe[port].tx_type = TCPCI_MSG_SOP_PRIME; set_state_pe(port, PE_INIT_VDM_MODES_REQUEST); return true; @@ -2000,8 +2021,8 @@ __maybe_unused static bool pe_attempt_port_discovery(int port) return false; } -bool pd_setup_vdm_request(int port, enum tcpci_msg_type tx_type, - uint32_t *vdm, uint32_t vdo_cnt) +bool pd_setup_vdm_request(int port, enum tcpci_msg_type tx_type, uint32_t *vdm, + uint32_t vdo_cnt) { if (vdo_cnt < VDO_HDR_SIZE || vdo_cnt > VDO_MAX_SIZE) return false; @@ -2014,7 +2035,7 @@ bool pd_setup_vdm_request(int port, enum tcpci_msg_type tx_type, } int pd_dev_store_rw_hash(int port, uint16_t dev_id, uint32_t *rw_hash, - uint32_t current_image) + uint32_t current_image) { pe[port].dev_id = dev_id; memcpy(pe[port].dev_rw_hash, rw_hash, PD_RW_HASH_SIZE); @@ -2038,7 +2059,7 @@ int pd_dev_store_rw_hash(int port, uint16_t dev_id, uint32_t *rw_hash, } void pd_dev_get_rw_hash(int port, uint16_t *dev_id, uint8_t *rw_hash, - uint32_t *current_image) + uint32_t *current_image) { *dev_id = pe[port].dev_id; *current_image = pe[port].current_image; @@ -2079,7 +2100,7 @@ static void pe_update_wait_and_add_jitter_timer(int port) pd_timer_is_disabled(port, PE_TIMER_WAIT_AND_ADD_JITTER)) { pd_timer_enable(port, PE_TIMER_WAIT_AND_ADD_JITTER, SRC_SNK_READY_HOLD_OFF_US + - (get_time().le.lo & 0xf) * 23 * MSEC); + (get_time().le.lo & 0xf) * 23 * MSEC); } } @@ -2263,8 +2284,7 @@ static void pe_src_startup_entry(int port) /* Request partner sink caps if a feature requires them */ if (IS_ENABLED(CONFIG_USB_PD_HOST_CMD) || - CONFIG_USB_PD_3A_PORTS > 0 || - IS_ENABLED(CONFIG_USB_PD_FRS)) + CONFIG_USB_PD_3A_PORTS > 0 || IS_ENABLED(CONFIG_USB_PD_FRS)) pd_dpm_request(port, DPM_REQUEST_GET_SNK_CAPS); /* @@ -2273,7 +2293,6 @@ static void pe_src_startup_entry(int port) * revision 3.0 */ pd_dpm_request(port, DPM_REQUEST_GET_REVISION); - } } @@ -2336,6 +2355,19 @@ static void pe_src_discovery_run(int port) set_state_pe(port, PE_SRC_SEND_CAPABILITIES); return; } else if (!PE_CHK_FLAG(port, PE_FLAGS_PD_CONNECTION)) { + /* + * Cable identity may be discovered without a PD + * contract in place. If it has been discovered, notify + * the AP. + */ + if (pd_get_identity_discovery(port, + TCPCI_MSG_SOP_PRIME) == + PD_DISC_COMPLETE) { + pd_notify_event( + port, + PD_STATUS_EVENT_SOP_PRIME_DISC_DONE); + } + set_state_pe(port, PE_SRC_DISABLED); return; } @@ -2347,11 +2379,11 @@ static void pe_src_discovery_run(int port) * requests properly. */ if (pd_get_identity_discovery(port, TCPCI_MSG_SOP_PRIME) == - PD_DISC_NEEDED - && pd_timer_is_expired(port, PE_TIMER_DISCOVER_IDENTITY) - && pe_can_send_sop_prime(port) - && (pe[port].discover_identity_counter < - N_DISCOVER_IDENTITY_PRECONTRACT_LIMIT)) { + PD_DISC_NEEDED && + pd_timer_is_expired(port, PE_TIMER_DISCOVER_IDENTITY) && + pe_can_send_sop_prime(port) && + (pe[port].discover_identity_counter < + N_DISCOVER_IDENTITY_PRECONTRACT_LIMIT)) { pe[port].tx_type = TCPCI_MSG_SOP_PRIME; set_state_pe(port, PE_VDM_IDENTITY_REQUEST_CBL); return; @@ -2441,15 +2473,14 @@ static void pe_src_send_capabilities_run(int port) * Request Message Received? */ if (PD_HEADER_CNT(rx_emsg[port].header) > 0 && - PD_HEADER_TYPE(rx_emsg[port].header) == - PD_DATA_REQUEST) { - + PD_HEADER_TYPE(rx_emsg[port].header) == PD_DATA_REQUEST) { /* * Set to highest revision supported by both * ports. */ prl_set_rev(port, TCPCI_MSG_SOP, - MIN(PD_REVISION, PD_HEADER_REV(rx_emsg[port].header))); + MIN(PD_REVISION, + PD_HEADER_REV(rx_emsg[port].header))); init_cable_rev(port); @@ -2620,7 +2651,7 @@ static void pe_src_transition_supply_run(int port) if (!pe_is_explicit_contract(port)) { PE_SET_FLAG(port, PE_FLAGS_FIRST_MSG); pd_timer_disable(port, - PE_TIMER_WAIT_AND_ADD_JITTER); + PE_TIMER_WAIT_AND_ADD_JITTER); } /* NOTE: Second pass through this code block */ @@ -2680,13 +2711,13 @@ static void extended_message_not_supported(int port, uint32_t *payload) uint16_t ext_header = GET_EXT_HEADER(*payload); if (IS_ENABLED(CONFIG_USB_PD_REV30) && - !IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES) && - PD_EXT_HEADER_CHUNKED(ext_header) && - PD_EXT_HEADER_DATA_SIZE(ext_header) > - PD_MAX_EXTENDED_MSG_CHUNK_LEN) { - set_state_pe(port, - pe[port].power_role == PD_ROLE_SOURCE ? - PE_SRC_CHUNK_RECEIVED : PE_SNK_CHUNK_RECEIVED); + !IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES) && + PD_EXT_HEADER_CHUNKED(ext_header) && + PD_EXT_HEADER_DATA_SIZE(ext_header) > + PD_MAX_EXTENDED_MSG_CHUNK_LEN) { + set_state_pe(port, pe[port].power_role == PD_ROLE_SOURCE ? + PE_SRC_CHUNK_RECEIVED : + PE_SNK_CHUNK_RECEIVED); return; } @@ -2753,18 +2784,24 @@ static void pe_src_ready_run(int port) break; case PD_DATA_VENDOR_DEF: if (PD_HEADER_TYPE(rx_emsg[port].header) == - PD_DATA_VENDOR_DEF) { + PD_DATA_VENDOR_DEF) { if (PD_VDO_SVDM(*payload)) { set_state_pe(port, - PE_VDM_RESPONSE); + PE_VDM_RESPONSE); } else - set_state_pe(port, - PE_HANDLE_CUSTOM_VDM_REQUEST); + set_state_pe( + port, + PE_HANDLE_CUSTOM_VDM_REQUEST); } return; case PD_DATA_BIST: set_state_pe(port, PE_BIST_TX); return; +#ifdef CONFIG_USB_PD_REV30 + case PD_DATA_ALERT: + set_state_pe(port, PE_ALERT_RECEIVED); + return; +#endif /* CONFIG_USB_PD_REV30 */ default: set_state_pe(port, PE_SEND_NOT_SUPPORTED); return; @@ -2789,7 +2826,7 @@ static void pe_src_ready_run(int port) break; case PD_CTRL_PR_SWAP: set_state_pe(port, - PE_PRS_SRC_SNK_EVALUATE_SWAP); + PE_PRS_SRC_SNK_EVALUATE_SWAP); return; case PD_CTRL_DR_SWAP: if (PE_CHK_FLAG(port, @@ -2803,10 +2840,10 @@ static void pe_src_ready_run(int port) case PD_CTRL_VCONN_SWAP: if (IS_ENABLED(CONFIG_USBC_VCONN)) set_state_pe(port, - PE_VCS_EVALUATE_SWAP); + PE_VCS_EVALUATE_SWAP); else set_state_pe(port, - PE_SEND_NOT_SUPPORTED); + PE_SEND_NOT_SUPPORTED); return; /* * USB PD 3.0 6.8.1: @@ -2817,16 +2854,19 @@ static void pe_src_ready_run(int port) case PD_CTRL_REJECT: case PD_CTRL_WAIT: case PD_CTRL_PS_RDY: - pe_send_soft_reset(port, - PD_HEADER_GET_SOP(rx_emsg[port].header)); + 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, + set_state_pe( + port, PE_DDR_DATA_RESET_RECEIVED); else - set_state_pe(port, + set_state_pe( + port, PE_UDR_DATA_RESET_RECEIVED); return; #endif /* CONFIG_USB_PD_DATA_RESET_MSG */ @@ -2835,10 +2875,11 @@ static void pe_src_ready_run(int port) set_state_pe(port, PE_GIVE_STATUS); return; #endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ - /* - * Receiving an unknown or unsupported message - * shall be responded to with a not supported message. - */ + /* + * Receiving an unknown or unsupported message + * shall be responded to with a not supported + * message. + */ default: set_state_pe(port, PE_SEND_NOT_SUPPORTED); @@ -2868,7 +2909,6 @@ static void pe_src_ready_run(int port) if (pd_timer_is_disabled(port, PE_TIMER_WAIT_AND_ADD_JITTER) || pd_timer_is_expired(port, PE_TIMER_WAIT_AND_ADD_JITTER)) { - PE_CLR_FLAG(port, PE_FLAGS_FIRST_MSG); pd_timer_disable(port, PE_TIMER_WAIT_AND_ADD_JITTER); @@ -2898,7 +2938,7 @@ static void pe_src_disabled_entry(int port) print_current_state(port); if ((get_usb_pd_cable_type(port) == IDH_PTYPE_VPD) && - is_vpd_ct_supported(port)) { + is_vpd_ct_supported(port)) { /* * Inform the Device Policy Manager that a Charge-Through VCONN * Powered Device was detected. @@ -2988,10 +3028,9 @@ static void pe_src_hard_reset_entry(int port) pd_timer_enable(port, PE_TIMER_PS_HARD_RESET, PD_T_PS_HARD_RESET); /* Clear error flags */ - PE_CLR_MASK(port, - BIT(PE_FLAGS_VDM_REQUEST_NAKED_FN) | - BIT(PE_FLAGS_PROTOCOL_ERROR_FN) | - BIT(PE_FLAGS_VDM_REQUEST_BUSY_FN)); + PE_CLR_MASK(port, BIT(PE_FLAGS_VDM_REQUEST_NAKED_FN) | + BIT(PE_FLAGS_PROTOCOL_ERROR_FN) | + BIT(PE_FLAGS_VDM_REQUEST_BUSY_FN)); } static void pe_src_hard_reset_run(int port) @@ -3158,9 +3197,8 @@ static void pe_snk_startup_entry(int port) * Swap, then the Policy Engine Shall do the following: * - Send a Get_Sink_Cap Message */ - if (IS_ENABLED(CONFIG_USB_PD_HOST_CMD) || - CONFIG_USB_PD_3A_PORTS > 0 || - IS_ENABLED(CONFIG_USB_PD_FRS)) + if (IS_ENABLED(CONFIG_USB_PD_HOST_CMD) || CONFIG_USB_PD_3A_PORTS > 0 || + IS_ENABLED(CONFIG_USB_PD_FRS)) pd_dpm_request(port, DPM_REQUEST_GET_SNK_CAPS); /* @@ -3169,7 +3207,6 @@ static void pe_snk_startup_entry(int port) * revision 3.0 */ pd_dpm_request(port, DPM_REQUEST_GET_REVISION); - } static void pe_snk_startup_run(int port) @@ -3264,7 +3301,7 @@ static void pe_snk_evaluate_capability_entry(int port) /* Set to highest revision supported by both ports. */ prl_set_rev(port, TCPCI_MSG_SOP, - MIN(PD_REVISION, PD_HEADER_REV(rx_emsg[port].header))); + MIN(PD_REVISION, PD_HEADER_REV(rx_emsg[port].header))); init_cable_rev(port); @@ -3385,7 +3422,7 @@ static void pe_snk_select_capability_run(int port) * Reject or Wait Message Received */ else if (type == PD_CTRL_REJECT || - type == PD_CTRL_WAIT) { + type == PD_CTRL_WAIT) { if (type == PD_CTRL_WAIT) PE_SET_FLAG(port, PE_FLAGS_WAIT); @@ -3403,7 +3440,8 @@ static void pe_snk_select_capability_run(int port) * to PE_SNK_Wait_For_Capabilities */ else - set_state_pe(port, + set_state_pe( + port, PE_SNK_WAIT_FOR_CAPABILITIES); return; } @@ -3464,8 +3502,7 @@ static void pe_snk_transition_sink_run(int port) * PS_RDY message received */ if ((PD_HEADER_CNT(rx_emsg[port].header) == 0) && - (PD_HEADER_TYPE(rx_emsg[port].header) == - PD_CTRL_PS_RDY)) { + (PD_HEADER_TYPE(rx_emsg[port].header) == PD_CTRL_PS_RDY)) { /* * Set first message flag to trigger a wait and add * jitter delay when operating in PD2.0 mode. @@ -3488,8 +3525,8 @@ static void pe_snk_transition_sink_run(int port) * already available */ if (pd_get_snk_cap_cnt(port) > 0) - dpm_evaluate_sink_fixed_pdo(port, - *pd_get_snk_caps(port)); + dpm_evaluate_sink_fixed_pdo( + port, *pd_get_snk_caps(port)); set_state_pe(port, PE_SNK_READY); } else { @@ -3515,13 +3552,13 @@ static void pe_snk_transition_sink_run(int port) static void pe_snk_transition_sink_exit(int port) { /* Transition Sink's power supply to the new power level */ - pd_set_input_current_limit(port, - pe[port].curr_limit, pe[port].supply_voltage); + pd_set_input_current_limit(port, pe[port].curr_limit, + pe[port].supply_voltage); if (IS_ENABLED(CONFIG_CHARGE_MANAGER)) /* Set ceiling based on what's negotiated */ - charge_manager_set_ceil(port, - CEIL_REQUESTOR_PD, pe[port].curr_limit); + charge_manager_set_ceil(port, CEIL_REQUESTOR_PD, + pe[port].curr_limit); pd_timer_disable(port, PE_TIMER_PS_TRANSITION); @@ -3530,7 +3567,6 @@ static void pe_snk_transition_sink_exit(int port) dps_update_stabilized_time(port); } - /** * PE_SNK_Ready State */ @@ -3551,8 +3587,7 @@ static void pe_snk_ready_entry(int port) */ if (PE_CHK_FLAG(port, PE_FLAGS_WAIT)) { PE_CLR_FLAG(port, PE_FLAGS_WAIT); - pd_timer_enable(port, PE_TIMER_SINK_REQUEST, - PD_T_SINK_REQUEST); + pd_timer_enable(port, PE_TIMER_SINK_REQUEST, PD_T_SINK_REQUEST); } /* @@ -3596,23 +3631,28 @@ static void pe_snk_ready_run(int port) else if (cnt > 0) { switch (type) { case PD_DATA_SOURCE_CAP: - set_state_pe(port, - PE_SNK_EVALUATE_CAPABILITY); + set_state_pe(port, PE_SNK_EVALUATE_CAPABILITY); break; case PD_DATA_VENDOR_DEF: if (PD_HEADER_TYPE(rx_emsg[port].header) == - PD_DATA_VENDOR_DEF) { + PD_DATA_VENDOR_DEF) { if (PD_VDO_SVDM(*payload)) set_state_pe(port, - PE_VDM_RESPONSE); + PE_VDM_RESPONSE); else - set_state_pe(port, - PE_HANDLE_CUSTOM_VDM_REQUEST); + set_state_pe( + port, + PE_HANDLE_CUSTOM_VDM_REQUEST); } break; case PD_DATA_BIST: set_state_pe(port, PE_BIST_TX); break; +#ifdef CONFIG_USB_PD_REV30 + case PD_DATA_ALERT: + set_state_pe(port, PE_ALERT_RECEIVED); + return; +#endif /* CONFIG_USB_PD_REV30 */ default: set_state_pe(port, PE_SEND_NOT_SUPPORTED); } @@ -3638,30 +3678,32 @@ static void pe_snk_ready_run(int port) return; case PD_CTRL_PR_SWAP: set_state_pe(port, - PE_PRS_SNK_SRC_EVALUATE_SWAP); + PE_PRS_SNK_SRC_EVALUATE_SWAP); return; case PD_CTRL_DR_SWAP: if (PE_CHK_FLAG(port, PE_FLAGS_MODAL_OPERATION)) pe_set_hard_reset(port); else set_state_pe(port, - PE_DRS_EVALUATE_SWAP); + PE_DRS_EVALUATE_SWAP); return; case PD_CTRL_VCONN_SWAP: if (IS_ENABLED(CONFIG_USBC_VCONN)) set_state_pe(port, - PE_VCS_EVALUATE_SWAP); + PE_VCS_EVALUATE_SWAP); else set_state_pe(port, - PE_SEND_NOT_SUPPORTED); + 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, + set_state_pe( + port, PE_DDR_DATA_RESET_RECEIVED); else - set_state_pe(port, + set_state_pe( + port, PE_UDR_DATA_RESET_RECEIVED); return; #endif /* CONFIG_USB_PD_DATA_RESET_MSG */ @@ -3682,8 +3724,9 @@ static void pe_snk_ready_run(int port) case PD_CTRL_REJECT: case PD_CTRL_WAIT: case PD_CTRL_PS_RDY: - pe_send_soft_reset(port, - PD_HEADER_GET_SOP(rx_emsg[port].header)); + pe_send_soft_reset( + port, PD_HEADER_GET_SOP( + rx_emsg[port].header)); return; /* * Receiving an unknown or unsupported message @@ -3735,7 +3778,6 @@ static void pe_snk_ready_run(int port) /* No DPM requests; attempt mode entry/exit if needed */ dpm_run(port); - } } @@ -3756,7 +3798,7 @@ static void pe_snk_hard_reset_entry(int port) * Source is non-responsive. */ if (PE_CHK_FLAG(port, PE_FLAGS_SNK_WAIT_CAP_TIMEOUT) && - pe[port].hard_reset_counter > N_HARD_RESET_COUNT) { + pe[port].hard_reset_counter > N_HARD_RESET_COUNT) { set_state_pe(port, PE_SRC_DISABLED); return; } @@ -3776,13 +3818,13 @@ static void pe_snk_hard_reset_entry(int port) if (IS_ENABLED(CONFIG_BATTERY) && (battery_is_present() == BP_NO) && IS_ENABLED(CONFIG_CHARGE_MANAGER) && ((port == charge_manager_get_active_charge_port() || - (charge_manager_get_active_charge_port() == CHARGE_PORT_NONE))) && + (charge_manager_get_active_charge_port() == CHARGE_PORT_NONE))) && system_get_reset_flags() & EC_RESET_FLAG_SYSJUMP) { CPRINTS("C%d: Disabling port to avoid brown out, " - "please reboot EC to enable port again", port); + "please reboot EC to enable port again", + port); set_state_pe(port, PE_SRC_DISABLED); return; - } #ifdef CONFIG_USB_PD_RESET_MIN_BATT_SOC @@ -3803,19 +3845,18 @@ static void pe_snk_hard_reset_entry(int port) if (batt_soc < CONFIG_USB_PD_RESET_MIN_BATT_SOC || battery_get_disconnect_state() != BATTERY_NOT_DISCONNECTED) { PE_SET_FLAG(port, PE_FLAGS_SNK_WAITING_BATT); - CPRINTS("C%d: Battery low %d%%! Stay in disabled state " \ - "until battery level reaches %d%%", port, batt_soc, - CONFIG_USB_PD_RESET_MIN_BATT_SOC); + CPRINTS("C%d: Battery low %d%%! Stay in disabled state " + "until battery level reaches %d%%", + port, batt_soc, CONFIG_USB_PD_RESET_MIN_BATT_SOC); set_state_pe(port, PE_SRC_DISABLED); return; } #endif - PE_CLR_MASK(port, - BIT(PE_FLAGS_SNK_WAIT_CAP_TIMEOUT_FN) | - BIT(PE_FLAGS_VDM_REQUEST_NAKED_FN) | - BIT(PE_FLAGS_PROTOCOL_ERROR_FN) | - BIT(PE_FLAGS_VDM_REQUEST_BUSY_FN)); + PE_CLR_MASK(port, BIT(PE_FLAGS_SNK_WAIT_CAP_TIMEOUT_FN) | + BIT(PE_FLAGS_VDM_REQUEST_NAKED_FN) | + BIT(PE_FLAGS_PROTOCOL_ERROR_FN) | + BIT(PE_FLAGS_VDM_REQUEST_BUSY_FN)); /* Request the generation of Hard Reset Signaling by the PHY Layer */ prl_execute_hard_reset(port); @@ -3832,11 +3873,11 @@ static void pe_snk_hard_reset_entry(int port) /* Transition Sink's power supply to the new power level */ pd_set_input_current_limit(port, pe[port].curr_limit, - pe[port].supply_voltage); + pe[port].supply_voltage); if (IS_ENABLED(CONFIG_CHARGE_MANAGER)) /* Set ceiling based on what's negotiated */ charge_manager_set_ceil(port, CEIL_REQUESTOR_PD, - pe[port].curr_limit); + pe[port].curr_limit); } } @@ -3943,8 +3984,8 @@ static void pe_send_soft_reset_run(int port) * unexpected incoming message type */ /* Send Soft Reset message */ - send_ctrl_msg(port, - pe[port].soft_reset_sop, PD_CTRL_SOFT_RESET); + send_ctrl_msg(port, pe[port].soft_reset_sop, + PD_CTRL_SOFT_RESET); return; } @@ -3978,10 +4019,9 @@ static void pe_send_soft_reset_run(int port) if ((ext == 0) && (cnt == 0) && (type == PD_CTRL_ACCEPT)) { if (pe[port].power_role == PD_ROLE_SINK) set_state_pe(port, - PE_SNK_WAIT_FOR_CAPABILITIES); + PE_SNK_WAIT_FOR_CAPABILITIES); else - set_state_pe(port, - PE_SRC_SEND_CAPABILITIES); + set_state_pe(port, PE_SRC_SEND_CAPABILITIES); return; } } @@ -3991,7 +4031,7 @@ static void pe_send_soft_reset_run(int port) * Response Timer Timeout or Protocol Layer or Protocol Error */ if (pd_timer_is_expired(port, PE_TIMER_SENDER_RESPONSE) || - PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) { + PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) { PE_CLR_FLAG(port, PE_FLAGS_PROTOCOL_ERROR); pe_set_hard_reset(port); return; @@ -4014,7 +4054,7 @@ static void pe_soft_reset_entry(int port) send_ctrl_msg(port, TCPCI_MSG_SOP, PD_CTRL_ACCEPT); } -static void pe_soft_reset_run(int port) +static void pe_soft_reset_run(int port) { if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) { PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE); @@ -4054,7 +4094,6 @@ static void pe_send_not_supported_run(int port) if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) { PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE); pe_set_ready_state(port); - } } @@ -4176,32 +4215,28 @@ static void pe_give_battery_cap_entry(int port) */ msg[BCDB_FULL_CAP] = 0xffff; - if (IS_ENABLED(HAS_TASK_HOSTCMD) && *host_get_memmap(EC_MEMMAP_BATTERY_VERSION) != 0) { int design_volt, design_cap, full_cap; - design_volt = *(int *)host_get_memmap( - EC_MEMMAP_BATT_DVLT); - design_cap = *(int *)host_get_memmap( - EC_MEMMAP_BATT_DCAP); - full_cap = *(int *)host_get_memmap( - EC_MEMMAP_BATT_LFCC); + design_volt = + *(int *)host_get_memmap(EC_MEMMAP_BATT_DVLT); + design_cap = + *(int *)host_get_memmap(EC_MEMMAP_BATT_DCAP); + full_cap = *(int *)host_get_memmap(EC_MEMMAP_BATT_LFCC); /* * Wh = (c * v) / 1000000 * 10th of a Wh = Wh * 10 */ msg[BCDB_DESIGN_CAP] = DIV_ROUND_NEAREST( - (design_cap * design_volt), - 100000); + (design_cap * design_volt), 100000); /* * Wh = (c * v) / 1000000 * 10th of a Wh = Wh * 10 */ msg[BCDB_FULL_CAP] = DIV_ROUND_NEAREST( - (design_cap * full_cap), - 100000); + (design_cap * full_cap), 100000); } else { uint32_t v; uint32_t c; @@ -4213,24 +4248,19 @@ static void pe_give_battery_cap_entry(int port) * 10th of a Wh = Wh * 10 */ msg[BCDB_DESIGN_CAP] = - DIV_ROUND_NEAREST( - (c * v), - 100000); + DIV_ROUND_NEAREST((c * v), + 100000); } - if (battery_full_charge_capacity(&c) - == 0) { + if (battery_full_charge_capacity(&c) == 0) { /* * Wh = (c * v) / 1000000 * 10th of a Wh = Wh * 10 */ - msg[BCDB_FULL_CAP] = - DIV_ROUND_NEAREST( - (c * v), - 100000); + msg[BCDB_FULL_CAP] = DIV_ROUND_NEAREST( + (c * v), 100000); } } - } /* Valid battery selected */ msg[BCDB_BATT_TYPE] = 0; @@ -4286,24 +4316,23 @@ static void pe_give_battery_status_entry(int port) if (IS_ENABLED(HAS_TASK_HOSTCMD) && *host_get_memmap(EC_MEMMAP_BATTERY_VERSION) != 0) { v = *(int *)host_get_memmap( - EC_MEMMAP_BATT_DVLT); - c = *(int *)host_get_memmap( - EC_MEMMAP_BATT_CAP); + EC_MEMMAP_BATT_DVLT); + c = *(int *)host_get_memmap(EC_MEMMAP_BATT_CAP); /* * Wh = (c * v) / 1000000 * 10th of a Wh = Wh * 10 */ - *msg = BSDO_CAP(DIV_ROUND_NEAREST((c * v), - 100000)); + *msg = BSDO_CAP( + DIV_ROUND_NEAREST((c * v), 100000)); } else if (battery_design_voltage(&v) == 0 && battery_remaining_capacity(&c) == 0) { /* * Wh = (c * v) / 1000000 * 10th of a Wh = Wh * 10 */ - *msg = BSDO_CAP(DIV_ROUND_NEAREST((c * v), - 100000)); + *msg = BSDO_CAP( + DIV_ROUND_NEAREST((c * v), 100000)); } /* Battery is present */ @@ -4377,7 +4406,6 @@ static void pe_give_status_run(int port) } } - /** * PE_SRC_Send_Source_Alert and * PE_SNK_Send_Sink_Alert @@ -4411,6 +4439,20 @@ static void pe_send_alert_run(int port) pe_set_ready_state(port); } } + +/** + * PE_SNK_Source_Alert_Received and + * PE_SRC_Sink_Alert_Received + */ +static void pe_alert_received_entry(int port) +{ + uint32_t *ado = (uint32_t *)rx_emsg[port].buf; + + print_current_state(port); + dpm_handle_alert(port, *ado); + pe_set_ready_state(port); +} + #endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ /** @@ -4539,8 +4581,8 @@ static void pe_drs_send_swap_run(int port) set_state_pe(port, PE_DRS_CHANGE); return; } else if ((type == PD_CTRL_REJECT) || - (type == PD_CTRL_WAIT) || - (type == PD_CTRL_NOT_SUPPORTED)) { + (type == PD_CTRL_WAIT) || + (type == PD_CTRL_NOT_SUPPORTED)) { pe_set_ready_state(port); return; } @@ -4742,8 +4784,7 @@ static void pe_prs_src_snk_wait_source_on_run(int port) static void pe_prs_src_snk_wait_source_on_exit(int port) { pd_timer_disable(port, PE_TIMER_PS_SOURCE); - tc_pr_swap_complete(port, - PE_CHK_FLAG(port, PE_FLAGS_PR_SWAP_COMPLETE)); + tc_pr_swap_complete(port, PE_CHK_FLAG(port, PE_FLAGS_PR_SWAP_COMPLETE)); } /** @@ -4794,7 +4835,7 @@ static void pe_prs_src_snk_send_swap_run(int port) pe[port].src_snk_pr_swap_counter = 0; tc_request_power_swap(port); set_state_pe(port, - PE_PRS_SRC_SNK_TRANSITION_TO_OFF); + PE_PRS_SRC_SNK_TRANSITION_TO_OFF); } else if (type == PD_CTRL_REJECT) { pe[port].src_snk_pr_swap_counter = 0; set_state_pe(port, PE_SRC_READY); @@ -4802,7 +4843,7 @@ static void pe_prs_src_snk_send_swap_run(int port) if (pe[port].src_snk_pr_swap_counter < N_SNK_SRC_PR_SWAP_COUNT) { PE_SET_FLAG(port, - PE_FLAGS_WAITING_PR_SWAP); + PE_FLAGS_WAITING_PR_SWAP); pd_timer_enable(port, PE_TIMER_PR_SWAP_WAIT, PD_T_PR_SWAP_WAIT); @@ -4902,8 +4943,7 @@ static void pe_prs_snk_src_transition_to_off_entry(int port) { print_current_state(port); - if (!IS_ENABLED(CONFIG_USB_PD_REV30) || - !pe_in_frs_mode(port)) + if (!IS_ENABLED(CONFIG_USB_PD_REV30) || !pe_in_frs_mode(port)) tc_snk_power_off(port); pd_timer_enable(port, PE_TIMER_PS_SOURCE, PD_T_PS_SOURCE_OFF); @@ -4970,8 +5010,7 @@ static void pe_prs_snk_src_assert_rp_run(int port) { /* Wait until TypeC is in the Attached.SRC state */ if (tc_is_attached_src(port)) { - if (!IS_ENABLED(CONFIG_USB_PD_REV30) || - !pe_in_frs_mode(port)) { + if (!IS_ENABLED(CONFIG_USB_PD_REV30) || !pe_in_frs_mode(port)) { /* Contract is invalid now */ pe_invalidate_explicit_contract(port); } @@ -5032,8 +5071,7 @@ static void pe_prs_snk_src_source_on_run(int port) static void pe_prs_snk_src_source_on_exit(int port) { pd_timer_disable(port, PE_TIMER_PS_SOURCE); - tc_pr_swap_complete(port, - PE_CHK_FLAG(port, PE_FLAGS_PR_SWAP_COMPLETE)); + tc_pr_swap_complete(port, PE_CHK_FLAG(port, PE_FLAGS_PR_SWAP_COMPLETE)); } /** @@ -5056,11 +5094,9 @@ static void pe_prs_snk_src_send_swap_entry(int port) * Request the Protocol Layer to send a FR_Swap Message. */ if (IS_ENABLED(CONFIG_USB_PD_REV30)) { - send_ctrl_msg(port, - TCPCI_MSG_SOP, - pe_in_frs_mode(port) - ? PD_CTRL_FR_SWAP - : PD_CTRL_PR_SWAP); + send_ctrl_msg(port, TCPCI_MSG_SOP, + pe_in_frs_mode(port) ? PD_CTRL_FR_SWAP : + PD_CTRL_PR_SWAP); } else { send_ctrl_msg(port, TCPCI_MSG_SOP, PD_CTRL_PR_SWAP); } @@ -5113,12 +5149,13 @@ static void pe_prs_snk_src_send_swap_run(int port) set_state_pe(port, PE_PRS_SNK_SRC_TRANSITION_TO_OFF); } else if ((type == PD_CTRL_REJECT) || - (type == PD_CTRL_WAIT)) { + (type == PD_CTRL_WAIT)) { if (IS_ENABLED(CONFIG_USB_PD_REV30)) - set_state_pe(port, - pe_in_frs_mode(port) - ? PE_WAIT_FOR_ERROR_RECOVERY - : PE_SNK_READY); + set_state_pe( + port, + pe_in_frs_mode(port) ? + PE_WAIT_FOR_ERROR_RECOVERY : + PE_SNK_READY); else set_state_pe(port, PE_SNK_READY); } @@ -5133,10 +5170,9 @@ static void pe_prs_snk_src_send_swap_run(int port) */ if (pd_timer_is_expired(port, PE_TIMER_SENDER_RESPONSE)) { if (IS_ENABLED(CONFIG_USB_PD_REV30)) - set_state_pe(port, - pe_in_frs_mode(port) - ? PE_WAIT_FOR_ERROR_RECOVERY - : PE_SNK_READY); + set_state_pe(port, pe_in_frs_mode(port) ? + PE_WAIT_FOR_ERROR_RECOVERY : + PE_SNK_READY); else set_state_pe(port, PE_SNK_READY); return; @@ -5147,9 +5183,8 @@ static void pe_prs_snk_src_send_swap_run(int port) * has not been received). A soft reset Shall Not be initiated in * this case. */ - if (IS_ENABLED(CONFIG_USB_PD_REV30) && - pe_in_frs_mode(port) && - PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) { + if (IS_ENABLED(CONFIG_USB_PD_REV30) && pe_in_frs_mode(port) && + 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); } @@ -5269,6 +5304,18 @@ static void pe_bist_tx_entry(int port) */ if (tcpc_set_bist_test_mode(port, true) != EC_SUCCESS) CPRINTS("C%d: Failed to enter BIST Test Mode", port); + } else if (IS_ENABLED(CONFIG_USB_PD_REV30) && + mode == BIST_SHARED_MODE_ENTER) { + /* Notify the DPM and return to ready */ + dpm_bist_shared_mode_enter(port); + pe_set_ready_state(port); + return; + } else if (IS_ENABLED(CONFIG_USB_PD_REV30) && + mode == BIST_SHARED_MODE_EXIT) { + /* Notify the DPM and return to ready */ + dpm_bist_shared_mode_exit(port); + pe_set_ready_state(port); + return; } else { /* Ignore unsupported BIST messages. */ pe_set_ready_state(port); @@ -5415,10 +5462,10 @@ static enum vdm_response_result parse_vdm_response_common(int port) cnt = PD_HEADER_CNT(rx_emsg[port].header); ext = PD_HEADER_EXT(rx_emsg[port].header); - if (sop == pe[port].tx_type && type == PD_DATA_VENDOR_DEF && cnt >= 1 - && ext == 0) { + if (sop == pe[port].tx_type && type == PD_DATA_VENDOR_DEF && cnt >= 1 && + ext == 0) { if (PD_VDO_CMDT(payload[0]) == CMDT_RSP_ACK && - cnt >= pe[port].vdm_ack_min_data_objects) { + cnt >= pe[port].vdm_ack_min_data_objects) { /* Handle ACKs in state-specific code. */ return VDM_RESULT_ACK; } else if (PD_VDO_CMDT(payload[0]) == CMDT_RSP_NAK) { @@ -5430,7 +5477,7 @@ static enum vdm_response_result parse_vdm_response_common(int port) * tVDMBusy */ CPRINTS("C%d: Partner BUSY, request will be retried", - port); + port); pd_timer_enable(port, PE_TIMER_DISCOVER_IDENTITY, PD_T_VDM_BUSY); @@ -5448,11 +5495,11 @@ static enum vdm_response_result parse_vdm_response_common(int port) * Partner gave us an incorrect size or command; mark discovery * as failed. */ - CPRINTS("C%d: Unexpected VDM response: 0x%04x 0x%04x", - port, rx_emsg[port].header, payload[0]); + CPRINTS("C%d: Unexpected VDM response: 0x%04x 0x%04x", port, + rx_emsg[port].header, payload[0]); return VDM_RESULT_NAK; } else if (sop == pe[port].tx_type && ext == 0 && cnt == 0 && - type == PD_CTRL_NOT_SUPPORTED) { + type == PD_CTRL_NOT_SUPPORTED) { /* * A NAK would be more expected here, but Not Supported is still * allowed with the same meaning. @@ -5483,16 +5530,16 @@ static void pe_vdm_send_request_entry(int port) if ((pe[port].tx_type == TCPCI_MSG_SOP_PRIME || pe[port].tx_type == TCPCI_MSG_SOP_PRIME_PRIME) && - !tc_is_vconn_src(port) && port_discovery_vconn_swap_policy(port, - BIT(PE_FLAGS_VCONN_SWAP_TO_ON_FN))) { + !tc_is_vconn_src(port) && + port_discovery_vconn_swap_policy( + port, BIT(PE_FLAGS_VCONN_SWAP_TO_ON_FN))) { if (port_try_vconn_swap(port)) return; } /* All VDM sequences are Interruptible */ - PE_SET_MASK(port, - BIT(PE_FLAGS_LOCALLY_INITIATED_AMS_FN) | - BIT(PE_FLAGS_INTERRUPTIBLE_AMS_FN)); + PE_SET_MASK(port, BIT(PE_FLAGS_LOCALLY_INITIATED_AMS_FN) | + BIT(PE_FLAGS_INTERRUPTIBLE_AMS_FN)); } static void pe_vdm_send_request_run(int port) @@ -5504,8 +5551,7 @@ static void pe_vdm_send_request_run(int port) /* Start no response timer */ /* TODO(b/155890173): Support DPM-supplied timeout */ - pd_timer_enable(port, PE_TIMER_VDM_RESPONSE, - PD_T_VDM_SNDR_RSP); + pd_timer_enable(port, PE_TIMER_VDM_RESPONSE, PD_T_VDM_SNDR_RSP); } if (PE_CHK_FLAG(port, PE_FLAGS_MSG_DISCARDED)) { @@ -5523,8 +5569,7 @@ static void pe_vdm_send_request_run(int port) */ if (pd_timer_is_expired(port, PE_TIMER_VDM_RESPONSE)) { CPRINTF("VDM %s Response Timeout\n", - pe[port].tx_type == TCPCI_MSG_SOP ? - "Port" : "Cable"); + pe[port].tx_type == TCPCI_MSG_SOP ? "Port" : "Cable"); /* * Flag timeout so child state can mark appropriate discovery * item as failed. @@ -5572,8 +5617,8 @@ static void pe_vdm_identity_request_cbl_entry(int port) } msg[0] = VDO(USB_SID_PD, 1, - VDO_SVDM_VERS(pd_get_vdo_ver(port, pe[port].tx_type)) | - CMD_DISCOVER_IDENT); + VDO_SVDM_VERS(pd_get_vdo_ver(port, pe[port].tx_type)) | + CMD_DISCOVER_IDENT); tx_emsg[port].len = sizeof(uint32_t); send_data_msg(port, pe[port].tx_type, PD_DATA_VENDOR_DEF); @@ -5590,7 +5635,7 @@ static void pe_vdm_identity_request_cbl_entry(int port) static void pe_vdm_identity_request_cbl_run(int port) { /* Retrieve the message information */ - uint32_t *payload = (uint32_t *) rx_emsg[port].buf; + uint32_t *payload = (uint32_t *)rx_emsg[port].buf; int sop = PD_HEADER_GET_SOP(rx_emsg[port].header); uint8_t type = PD_HEADER_TYPE(rx_emsg[port].header); uint8_t cnt = PD_HEADER_CNT(rx_emsg[port].header); @@ -5623,9 +5668,8 @@ static void pe_vdm_identity_request_cbl_run(int port) * state. */ if (get_last_state_pe(port) == PE_SRC_DISCOVERY && - (sop != pe[port].tx_type || - type != PD_DATA_VENDOR_DEF || - cnt == 0 || ext != 0)) { + (sop != pe[port].tx_type || type != PD_DATA_VENDOR_DEF || + cnt == 0 || ext != 0)) { /* * Unexpected non-VDM received: Before an explicit * contract, an unexpected message shall generate a soft @@ -5689,10 +5733,9 @@ static void pe_vdm_identity_request_cbl_exit(int port) * Not send any further SOP’/SOP’’ Messages. */ if (pe[port].discover_identity_counter >= N_DISCOVER_IDENTITY_COUNT) - pd_set_identity_discovery(port, pe[port].tx_type, - PD_DISC_FAIL); + pd_set_identity_discovery(port, pe[port].tx_type, PD_DISC_FAIL); else if (pe[port].discover_identity_counter == - N_DISCOVER_IDENTITY_PD3_0_LIMIT) + N_DISCOVER_IDENTITY_PD3_0_LIMIT) /* * Downgrade to PD 2.0 if the partner hasn't replied before * all retries are exhausted in case the cable is @@ -5703,8 +5746,9 @@ static void pe_vdm_identity_request_cbl_exit(int port) /* * Set discover identity timer unless BUSY case already did so. */ - if (pd_get_identity_discovery(port, pe[port].tx_type) == PD_DISC_NEEDED - && pd_timer_is_expired(port, PE_TIMER_DISCOVER_IDENTITY)) { + if (pd_get_identity_discovery(port, pe[port].tx_type) == + PD_DISC_NEEDED && + pd_timer_is_expired(port, PE_TIMER_DISCOVER_IDENTITY)) { /* * The tDiscoverIdentity timer is used during an explicit * contract when discovering whether a cable is PD capable. @@ -5714,17 +5758,18 @@ static void pe_vdm_identity_request_cbl_exit(int port) * power the SOP' responder from VBUS instead of VCONN. */ pd_timer_enable(port, PE_TIMER_DISCOVER_IDENTITY, - pe_is_explicit_contract(port) - ? PD_T_DISCOVER_IDENTITY - : PE_T_DISCOVER_IDENTITY_NO_CONTRACT); + pe_is_explicit_contract(port) ? + PD_T_DISCOVER_IDENTITY : + PE_T_DISCOVER_IDENTITY_NO_CONTRACT); } /* Do not attempt further discovery if identity discovery failed. */ if (pd_get_identity_discovery(port, pe[port].tx_type) == PD_DISC_FAIL) { pd_set_svids_discovery(port, pe[port].tx_type, PD_DISC_FAIL); - pd_notify_event(port, pe[port].tx_type == TCPCI_MSG_SOP ? - PD_STATUS_EVENT_SOP_DISC_DONE : - PD_STATUS_EVENT_SOP_PRIME_DISC_DONE); + pd_notify_event(port, + pe[port].tx_type == TCPCI_MSG_SOP ? + PD_STATUS_EVENT_SOP_DISC_DONE : + PD_STATUS_EVENT_SOP_PRIME_DISC_DONE); } } @@ -5743,8 +5788,8 @@ static void pe_init_port_vdm_identity_request_entry(int port) print_current_state(port); msg[0] = VDO(USB_SID_PD, 1, - VDO_SVDM_VERS(pd_get_vdo_ver(port, pe[port].tx_type)) | - CMD_DISCOVER_IDENT); + VDO_SVDM_VERS(pd_get_vdo_ver(port, pe[port].tx_type)) | + CMD_DISCOVER_IDENT); tx_emsg[port].len = sizeof(uint32_t); send_data_msg(port, pe[port].tx_type, PD_DATA_VENDOR_DEF); @@ -5771,7 +5816,7 @@ static void pe_init_port_vdm_identity_request_run(int port) break; case VDM_RESULT_ACK: { /* Retrieve the message information. */ - uint32_t *payload = (uint32_t *) rx_emsg[port].buf; + uint32_t *payload = (uint32_t *)rx_emsg[port].buf; int sop = PD_HEADER_GET_SOP(rx_emsg[port].header); uint8_t cnt = PD_HEADER_CNT(rx_emsg[port].header); @@ -5779,7 +5824,7 @@ static void pe_init_port_vdm_identity_request_run(int port) dfp_consume_identity(port, sop, cnt, payload); break; - } + } case VDM_RESULT_NAK: /* PE_INIT_PORT_VDM_IDENTITY_NAKed embedded here */ pd_set_identity_discovery(port, pe[port].tx_type, PD_DISC_FAIL); @@ -5809,9 +5854,10 @@ static void pe_init_port_vdm_identity_request_exit(int port) /* Do not attempt further discovery if identity discovery failed. */ if (pd_get_identity_discovery(port, pe[port].tx_type) == PD_DISC_FAIL) { pd_set_svids_discovery(port, pe[port].tx_type, PD_DISC_FAIL); - pd_notify_event(port, pe[port].tx_type == TCPCI_MSG_SOP ? - PD_STATUS_EVENT_SOP_DISC_DONE : - PD_STATUS_EVENT_SOP_PRIME_DISC_DONE); + pd_notify_event(port, + pe[port].tx_type == TCPCI_MSG_SOP ? + PD_STATUS_EVENT_SOP_DISC_DONE : + PD_STATUS_EVENT_SOP_PRIME_DISC_DONE); } } @@ -5838,8 +5884,8 @@ static void pe_init_vdm_svids_request_entry(int port) } msg[0] = VDO(USB_SID_PD, 1, - VDO_SVDM_VERS(pd_get_vdo_ver(port, pe[port].tx_type)) | - CMD_DISCOVER_SVID); + VDO_SVDM_VERS(pd_get_vdo_ver(port, pe[port].tx_type)) | + CMD_DISCOVER_SVID); tx_emsg[port].len = sizeof(uint32_t); send_data_msg(port, pe[port].tx_type, PD_DATA_VENDOR_DEF); @@ -5866,14 +5912,14 @@ static void pe_init_vdm_svids_request_run(int port) break; case VDM_RESULT_ACK: { /* Retrieve the message information. */ - uint32_t *payload = (uint32_t *) rx_emsg[port].buf; + uint32_t *payload = (uint32_t *)rx_emsg[port].buf; int sop = PD_HEADER_GET_SOP(rx_emsg[port].header); uint8_t cnt = PD_HEADER_CNT(rx_emsg[port].header); /* PE_INIT_VDM_SVIDs_ACKed embedded here */ dfp_consume_svids(port, sop, cnt, payload); break; - } + } case VDM_RESULT_NAK: /* PE_INIT_VDM_SVIDs_NAKed embedded here */ pd_set_svids_discovery(port, pe[port].tx_type, PD_DISC_FAIL); @@ -5902,9 +5948,10 @@ static void pe_init_vdm_svids_request_exit(int port) /* If SVID discovery failed, discovery is done at this point */ if (pd_get_svids_discovery(port, pe[port].tx_type) == PD_DISC_FAIL) - pd_notify_event(port, pe[port].tx_type == TCPCI_MSG_SOP ? - PD_STATUS_EVENT_SOP_DISC_DONE : - PD_STATUS_EVENT_SOP_PRIME_DISC_DONE); + pd_notify_event(port, + pe[port].tx_type == TCPCI_MSG_SOP ? + PD_STATUS_EVENT_SOP_DISC_DONE : + PD_STATUS_EVENT_SOP_PRIME_DISC_DONE); } /** @@ -5935,14 +5982,14 @@ static void pe_init_vdm_modes_request_entry(int port) * is still disabled, there's nothing left to try. */ pd_set_modes_discovery(port, pe[port].tx_type, svid, - PD_DISC_FAIL); + PD_DISC_FAIL); set_state_pe(port, get_last_state_pe(port)); return; } - msg[0] = VDO((uint16_t) svid, 1, - VDO_SVDM_VERS(pd_get_vdo_ver(port, pe[port].tx_type)) | - CMD_DISCOVER_MODES); + msg[0] = VDO((uint16_t)svid, 1, + VDO_SVDM_VERS(pd_get_vdo_ver(port, pe[port].tx_type)) | + CMD_DISCOVER_MODES); tx_emsg[port].len = sizeof(uint32_t); send_data_msg(port, pe[port].tx_type, PD_DATA_VENDOR_DEF); @@ -5978,10 +6025,10 @@ static void pe_init_vdm_modes_request_run(int port) break; case VDM_RESULT_ACK: { /* Retrieve the message information. */ - uint32_t *payload = (uint32_t *) rx_emsg[port].buf; + uint32_t *payload = (uint32_t *)rx_emsg[port].buf; int sop = PD_HEADER_GET_SOP(rx_emsg[port].header); uint8_t cnt = PD_HEADER_CNT(rx_emsg[port].header); - uint16_t response_svid = (uint16_t) PD_VDO_VID(payload[0]); + uint16_t response_svid = (uint16_t)PD_VDO_VID(payload[0]); /* * Accept ACK if the request and response SVIDs are equal; @@ -5995,12 +6042,12 @@ static void pe_init_vdm_modes_request_run(int port) dfp_consume_modes(port, sop, cnt, payload); break; } - } + } /* Fall Through */ case VDM_RESULT_NAK: /* PE_INIT_VDM_Modes_NAKed embedded here */ pd_set_modes_discovery(port, pe[port].tx_type, requested_svid, - PD_DISC_FAIL); + PD_DISC_FAIL); break; } @@ -6012,10 +6059,10 @@ static void pe_init_vdm_modes_request_exit(int port) { if (pd_get_modes_discovery(port, pe[port].tx_type) != PD_DISC_NEEDED) /* Mode discovery done, notify the AP */ - pd_notify_event(port, pe[port].tx_type == TCPCI_MSG_SOP ? - PD_STATUS_EVENT_SOP_DISC_DONE : - PD_STATUS_EVENT_SOP_PRIME_DISC_DONE); - + pd_notify_event(port, + pe[port].tx_type == TCPCI_MSG_SOP ? + PD_STATUS_EVENT_SOP_DISC_DONE : + PD_STATUS_EVENT_SOP_PRIME_DISC_DONE); } /** @@ -6030,7 +6077,7 @@ static void pe_vdm_request_dpm_entry(int port) if ((pe[port].tx_type == TCPCI_MSG_SOP_PRIME || pe[port].tx_type == TCPCI_MSG_SOP_PRIME_PRIME) && - !pe_can_send_sop_prime(port)) { + !pe_can_send_sop_prime(port)) { /* * The parent state already tried to enable SOP' traffic. If it * is still disabled, there's nothing left to try. @@ -6045,9 +6092,8 @@ static void pe_vdm_request_dpm_entry(int port) /* Copy Vendor Data Objects (VDOs) into message buffer */ if (pe[port].vdm_cnt > 0) { /* Copy data after header */ - memcpy(&tx_emsg[port].buf, - (uint8_t *)pe[port].vdm_data, - pe[port].vdm_cnt * 4); + memcpy(&tx_emsg[port].buf, (uint8_t *)pe[port].vdm_data, + pe[port].vdm_cnt * 4); /* Update len with the number of VDO bytes */ tx_emsg[port].len = pe[port].vdm_cnt * 4; } @@ -6085,8 +6131,8 @@ static void pe_vdm_request_dpm_run(int port) * transmit is complete. */ vdm_hdr = pe[port].vdm_data[0]; - if(PD_VDO_SVDM(vdm_hdr) && - (PD_VDO_CMD(vdm_hdr) == CMD_ATTENTION)) { + if (PD_VDO_SVDM(vdm_hdr) && + (PD_VDO_CMD(vdm_hdr) == CMD_ATTENTION)) { if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE)) { PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE); break; @@ -6108,7 +6154,7 @@ static void pe_vdm_request_dpm_run(int port) break; case VDM_RESULT_ACK: { /* Retrieve the message information. */ - uint32_t *payload = (uint32_t *) rx_emsg[port].buf; + uint32_t *payload = (uint32_t *)rx_emsg[port].buf; int sop = PD_HEADER_GET_SOP(rx_emsg[port].header); uint8_t cnt = PD_HEADER_CNT(rx_emsg[port].header); uint16_t svid = PD_VDO_VID(payload[0]); @@ -6121,11 +6167,11 @@ static void pe_vdm_request_dpm_run(int port) dpm_vdm_acked(port, sop, cnt, payload); if (sop == TCPCI_MSG_SOP && svid == USB_SID_DISPLAYPORT && - vdm_cmd == CMD_DP_CONFIG) { + vdm_cmd == CMD_DP_CONFIG) { PE_SET_FLAG(port, PE_FLAGS_VDM_SETUP_DONE); } break; - } + } case VDM_RESULT_NAK: /* * PE initiator VDM-NAKed state for requested VDM, like @@ -6139,8 +6185,8 @@ static void pe_vdm_request_dpm_run(int port) * Extract the needed information from the sent VDM. */ dpm_vdm_naked(port, pe[port].tx_type, - PD_VDO_VID(pe[port].vdm_data[0]), - PD_VDO_CMD(pe[port].vdm_data[0])); + PD_VDO_VID(pe[port].vdm_data[0]), + PD_VDO_CMD(pe[port].vdm_data[0])); break; } @@ -6150,6 +6196,24 @@ static void pe_vdm_request_dpm_run(int port) static void pe_vdm_request_dpm_exit(int port) { + if (PE_CHK_FLAG(port, PE_FLAGS_VDM_REQUEST_TIMEOUT)) { + PE_CLR_FLAG(port, PE_FLAGS_VDM_REQUEST_TIMEOUT); + PE_SET_FLAG(port, PE_FLAGS_VDM_SETUP_DONE); + + /* + * Mark failure to respond as discovery failure. + * + * For PD 2.0 partners (6.10.3 Applicability of Structured VDM + * Commands Note 3): + * + * If Structured VDMs are not supported, a Structured VDM + * Command received by a DFP or UFP Shall be Ignored. + */ + dpm_vdm_naked(port, pe[port].tx_type, + PD_VDO_VID(pe[port].vdm_data[0]), + PD_VDO_CMD(pe[port].vdm_data[0])); + } + /* * Force Tx type to be reset before reentering a VDM state, unless the * current VDM request will be resumed. @@ -6323,11 +6387,9 @@ static void pe_vdm_response_run(int port) if (PE_CHK_FLAG(port, PE_FLAGS_TX_COMPLETE) || PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR) || PE_CHK_FLAG(port, PE_FLAGS_MSG_DISCARDED)) { - - PE_CLR_MASK(port, - BIT(PE_FLAGS_TX_COMPLETE_FN) | - BIT(PE_FLAGS_PROTOCOL_ERROR_FN) | - BIT(PE_FLAGS_MSG_DISCARDED_FN)); + PE_CLR_MASK(port, BIT(PE_FLAGS_TX_COMPLETE_FN) | + BIT(PE_FLAGS_PROTOCOL_ERROR_FN) | + BIT(PE_FLAGS_MSG_DISCARDED_FN)); pe_set_ready_state(port); } @@ -6360,7 +6422,7 @@ static void pe_enter_usb_entry(int port) if ((pe[port].tx_type == TCPCI_MSG_SOP_PRIME || pe[port].tx_type == TCPCI_MSG_SOP_PRIME_PRIME) && - !tc_is_vconn_src(port)) { + !tc_is_vconn_src(port)) { if (port_try_vconn_swap(port)) return; } @@ -6566,11 +6628,12 @@ static void pe_vcs_send_swap_run(int port) */ if (type == PD_CTRL_ACCEPT) { if (tc_is_vconn_src(port)) { - set_state_pe(port, + set_state_pe( + port, PE_VCS_WAIT_FOR_VCONN_SWAP); } else { set_state_pe(port, - PE_VCS_TURN_ON_VCONN_SWAP); + PE_VCS_TURN_ON_VCONN_SWAP); } return; } @@ -6593,7 +6656,7 @@ static void pe_vcs_send_swap_run(int port) */ if (type == PD_CTRL_NOT_SUPPORTED) { if (IS_ENABLED(CONFIG_USB_PD_REV30) && - !tc_is_vconn_src(port)) + !tc_is_vconn_src(port)) set_state_pe(port, PE_VCS_FORCE_VCONN); else pe_set_ready_state(port); @@ -6675,8 +6738,8 @@ static void pe_vcs_wait_for_vconn_swap_run(int port) * the incoming message. */ PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); - pe_send_soft_reset(port, - PD_HEADER_GET_SOP(rx_emsg[port].header)); + pe_send_soft_reset( + port, PD_HEADER_GET_SOP(rx_emsg[port].header)); return; } } @@ -6718,7 +6781,6 @@ static void pe_vcs_turn_on_vconn_swap_entry(int port) static void pe_vcs_turn_on_vconn_swap_run(int port) { - /* * Transition to the PE_VCS_Send_Ps_Rdy state when: * 1) The Port’s VCONN is on. @@ -6778,7 +6840,7 @@ static void pe_vcs_send_ps_rdy_swap_entry(int port) /* Check for any interruptions to this non-interruptible AMS */ if (PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { enum tcpci_msg_type sop = - PD_HEADER_GET_SOP(rx_emsg[port].header); + PD_HEADER_GET_SOP(rx_emsg[port].header); PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); @@ -6906,7 +6968,7 @@ static void pe_vcs_cbl_send_soft_reset_run(int port) /* Got ACCEPT or REJECT from Cable Plug */ if ((msg_check & PE_MSG_SENT) && - PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { + PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); cable_soft_reset_complete = true; @@ -7003,16 +7065,17 @@ static void pe_dr_get_sink_cap_run(int port) if ((cnt > 0) && (type == PD_DATA_SINK_CAP)) { uint32_t *payload = (uint32_t *)rx_emsg[port].buf; - uint8_t cap_cnt = rx_emsg[port].len / - sizeof(uint32_t); + uint8_t cap_cnt = + rx_emsg[port].len / sizeof(uint32_t); pe_set_snk_caps(port, cap_cnt, payload); dpm_evaluate_sink_fixed_pdo(port, payload[0]); pe_set_ready_state(port); return; - } else if (cnt == 0 && (type == PD_CTRL_REJECT || - type == PD_CTRL_NOT_SUPPORTED)) { + } else if (cnt == 0 && + (type == PD_CTRL_REJECT || + type == PD_CTRL_NOT_SUPPORTED)) { pe_set_ready_state(port); return; } @@ -7126,12 +7189,13 @@ static void pe_dr_src_get_source_cap_run(int port) */ if (IS_ENABLED(CONFIG_CHARGE_MANAGER) && pd_get_partner_dual_role_power(port)) - charge_manager_update_dualrole(port, - CAP_DUALROLE); + charge_manager_update_dualrole( + port, CAP_DUALROLE); set_state_pe(port, PE_SRC_READY); - } else if ((cnt == 0) && (type == PD_CTRL_REJECT || - type == PD_CTRL_NOT_SUPPORTED)) { + } else if ((cnt == 0) && + (type == PD_CTRL_REJECT || + type == PD_CTRL_NOT_SUPPORTED)) { pd_set_src_caps(port, -1, NULL); set_state_pe(port, PE_SRC_READY); } else { @@ -7172,15 +7236,6 @@ __maybe_unused static void pe_get_revision_entry(int port) { print_current_state(port); - /* - * Only USB PD partners with major revision 3.0 could potentially - * respond to Get_Revision. - */ - if (prl_get_rev(port, TCPCI_MSG_SOP) != PD_REV30) { - pe_set_ready_state(port); - return; - } - /* Send a Get_Revision message */ send_ctrl_msg(port, TCPCI_MSG_SOP, PD_CTRL_GET_REVISION); pe_sender_response_msg_entry(port); @@ -7193,14 +7248,11 @@ __maybe_unused static void pe_get_revision_run(int port) int ext; enum pe_msg_check msg_check; - if (prl_get_rev(port, TCPCI_MSG_SOP) != PD_REV30) - return; - /* Check the state of the message sent */ msg_check = pe_sender_response_msg_run(port); if ((msg_check & PE_MSG_SENT) && - PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { + PE_CHK_FLAG(port, PE_FLAGS_MSG_RECEIVED)) { PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); type = PD_HEADER_TYPE(rx_emsg[port].header); @@ -7210,7 +7262,7 @@ __maybe_unused static void pe_get_revision_run(int port) if (ext == 0 && cnt == 1 && type == PD_DATA_REVISION) { /* Revision returned by partner */ pe[port].partner_rmdo = - *((struct rmdo *) rx_emsg[port].buf); + *((struct rmdo *)rx_emsg[port].buf); } else if (type != PD_CTRL_NOT_SUPPORTED) { /* * If the partner response with a message other than @@ -7235,14 +7287,10 @@ __maybe_unused static void pe_get_revision_run(int port) if ((msg_check & PE_MSG_DISCARDED) || pd_timer_is_expired(port, PE_TIMER_SENDER_RESPONSE)) pe_set_ready_state(port); - } __maybe_unused static void pe_get_revision_exit(int port) { - if (prl_get_rev(port, TCPCI_MSG_SOP) != PD_REV30) - return; - pe_sender_response_msg_exit(port); } @@ -7284,17 +7332,17 @@ static void pe_udr_send_data_reset_run(int port) PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); if (PD_HEADER_GET_SOP(hdr) == TCPCI_MSG_SOP && - PD_HEADER_CNT(hdr) == 0 && - !PD_HEADER_EXT(hdr) && - PD_HEADER_TYPE(hdr) == PD_CTRL_ACCEPT) { - set_state_pe(port, tc_is_vconn_src(port) ? + PD_HEADER_CNT(hdr) == 0 && !PD_HEADER_EXT(hdr) && + PD_HEADER_TYPE(hdr) == PD_CTRL_ACCEPT) { + set_state_pe( + port, + tc_is_vconn_src(port) ? PE_UDR_TURN_OFF_VCONN : PE_UDR_WAIT_FOR_DATA_RESET_COMPLETE); return; } else if (PD_HEADER_GET_SOP(hdr) == TCPCI_MSG_SOP && - PD_HEADER_CNT(hdr) == 0 && - !PD_HEADER_EXT(hdr) && - PD_HEADER_TYPE(hdr) == PD_CTRL_NOT_SUPPORTED) { + PD_HEADER_CNT(hdr) == 0 && !PD_HEADER_EXT(hdr) && + PD_HEADER_TYPE(hdr) == PD_CTRL_NOT_SUPPORTED) { /* Just pretend it worked. */ dpm_data_reset_complete(port); pe_set_ready_state(port); @@ -7306,7 +7354,7 @@ static void pe_udr_send_data_reset_run(int port) } if (pd_timer_is_expired(port, PE_TIMER_SENDER_RESPONSE) || - PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) { + 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); return; @@ -7333,10 +7381,9 @@ static void pe_udr_data_reset_received_run(int port) if (tc_is_vconn_src(port)) set_state_pe(port, PE_UDR_TURN_OFF_VCONN); else - set_state_pe(port, - PE_UDR_WAIT_FOR_DATA_RESET_COMPLETE); + set_state_pe(port, PE_UDR_WAIT_FOR_DATA_RESET_COMPLETE); } else if (PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR) || - PE_CHK_FLAG(port, PE_FLAGS_MSG_DISCARDED)) { + PE_CHK_FLAG(port, PE_FLAGS_MSG_DISCARDED)) { PE_CLR_FLAG(port, PE_FLAGS_PROTOCOL_ERROR); PE_CLR_FLAG(port, PE_FLAGS_MSG_DISCARDED); set_state_pe(port, PE_WAIT_FOR_ERROR_RECOVERY); @@ -7355,7 +7402,7 @@ static void pe_udr_turn_off_vconn_run(int port) { /* Wait until VCONN is fully discharged */ if (pd_timer_is_disabled(port, PE_TIMER_TIMEOUT) && - PE_CHK_FLAG(port, PE_FLAGS_VCONN_SWAP_COMPLETE)) { + PE_CHK_FLAG(port, PE_FLAGS_VCONN_SWAP_COMPLETE)) { PE_CLR_FLAG(port, PE_FLAGS_VCONN_SWAP_COMPLETE); pd_timer_enable(port, PE_TIMER_TIMEOUT, CONFIG_USBC_VCONN_SWAP_DELAY_US); @@ -7379,7 +7426,7 @@ static void pe_udr_send_ps_rdy_run(int port) PE_CLR_FLAG(port, PE_FLAGS_TX_COMPLETE); set_state_pe(port, PE_UDR_WAIT_FOR_DATA_RESET_COMPLETE); } else if (PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR) || - PE_CHK_FLAG(port, PE_FLAGS_MSG_DISCARDED)) { + PE_CHK_FLAG(port, PE_FLAGS_MSG_DISCARDED)) { PE_CLR_FLAG(port, PE_FLAGS_PROTOCOL_ERROR); PE_CLR_FLAG(port, PE_FLAGS_MSG_DISCARDED); set_state_pe(port, PE_WAIT_FOR_ERROR_RECOVERY); @@ -7461,9 +7508,8 @@ static void pe_ddr_send_data_reset_run(int port) PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); if (PD_HEADER_GET_SOP(hdr) == TCPCI_MSG_SOP && - PD_HEADER_CNT(hdr) == 0 && - !PD_HEADER_EXT(hdr) && - PD_HEADER_TYPE(hdr) == PD_CTRL_ACCEPT) { + PD_HEADER_CNT(hdr) == 0 && !PD_HEADER_EXT(hdr) && + PD_HEADER_TYPE(hdr) == PD_CTRL_ACCEPT) { /* * Start DataResetFailTimer NOTE: This timer continues * to run in every state until it is stopped or it times @@ -7472,13 +7518,12 @@ static void pe_ddr_send_data_reset_run(int port) pd_timer_enable(port, PE_TIMER_DATA_RESET_FAIL, PD_T_DATA_RESET_FAIL); set_state_pe(port, tc_is_vconn_src(port) ? - PE_DDR_PERFORM_DATA_RESET : - PE_DDR_WAIT_FOR_VCONN_OFF); + PE_DDR_PERFORM_DATA_RESET : + PE_DDR_WAIT_FOR_VCONN_OFF); return; } else if (PD_HEADER_GET_SOP(hdr) == TCPCI_MSG_SOP && - PD_HEADER_CNT(hdr) == 0 && - !PD_HEADER_EXT(hdr) && - PD_HEADER_TYPE(hdr) == PD_CTRL_NOT_SUPPORTED) { + PD_HEADER_CNT(hdr) == 0 && !PD_HEADER_EXT(hdr) && + PD_HEADER_TYPE(hdr) == PD_CTRL_NOT_SUPPORTED) { /* Just pretend it worked. */ dpm_data_reset_complete(port); pe_set_ready_state(port); @@ -7490,7 +7535,7 @@ static void pe_ddr_send_data_reset_run(int port) } if (pd_timer_is_expired(port, PE_TIMER_SENDER_RESPONSE) || - PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) { + 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); return; @@ -7554,9 +7599,8 @@ static void pe_ddr_wait_for_vconn_off_run(int port) PE_CLR_FLAG(port, PE_FLAGS_MSG_RECEIVED); if (PD_HEADER_GET_SOP(hdr) == TCPCI_MSG_SOP && - PD_HEADER_CNT(hdr) == 0 && - !PD_HEADER_EXT(hdr) && - PD_HEADER_TYPE(hdr) == PD_CTRL_PS_RDY) { + PD_HEADER_CNT(hdr) == 0 && !PD_HEADER_EXT(hdr) && + PD_HEADER_TYPE(hdr) == PD_CTRL_PS_RDY) { /* PS_RDY message received */ pd_timer_enable(port, PE_TIMER_VCONN_REAPPLIED, PD_T_VCONN_REAPPLIED); @@ -7569,7 +7613,7 @@ static void pe_ddr_wait_for_vconn_off_run(int port) } if (pd_timer_is_expired(port, PE_TIMER_VCONN_DISCHARGE) || - PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) { + 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); return; @@ -7596,7 +7640,7 @@ static void pe_ddr_perform_data_reset_entry(int port) * c) If operating in [USB4] drive the port’s SBTX to a logic low. */ usb_mux_set(port, USB_PD_MUX_NONE, USB_SWITCH_DISCONNECT, - polarity_rm_dts(pd_get_polarity(port))); + polarity_rm_dts(pd_get_polarity(port))); /* 2) Both the DFP and UFP Shall exit all Alternate Modes if any. */ if (IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { @@ -7635,18 +7679,18 @@ static void pe_ddr_perform_data_reset_run(int port) * expires. At this point, the Data Reset process is complete. */ if (IS_ENABLED(CONFIG_USBC_VCONN) && !tc_is_vconn_src(port) && - PE_CHK_FLAG(port, PE_FLAGS_VCONN_SWAP_COMPLETE)) { + PE_CHK_FLAG(port, PE_FLAGS_VCONN_SWAP_COMPLETE)) { PE_CLR_FLAG(port, PE_FLAGS_VCONN_SWAP_COMPLETE); /* Wait until VCONN has discharged to start tVconnReapplied. */ pd_timer_enable(port, PE_TIMER_TIMEOUT, - CONFIG_USBC_VCONN_SWAP_DELAY_US); + CONFIG_USBC_VCONN_SWAP_DELAY_US); } else if (IS_ENABLED(CONFIG_USBC_VCONN) && - pd_timer_is_expired(port, PE_TIMER_TIMEOUT)) { + pd_timer_is_expired(port, PE_TIMER_TIMEOUT)) { pd_timer_disable(port, PE_TIMER_TIMEOUT); pd_timer_enable(port, PE_TIMER_VCONN_REAPPLIED, PD_T_VCONN_REAPPLIED); } else if (IS_ENABLED(CONFIG_USBC_VCONN) && - pd_timer_is_expired(port, PE_TIMER_VCONN_REAPPLIED)) { + pd_timer_is_expired(port, PE_TIMER_VCONN_REAPPLIED)) { pd_request_vconn_swap_on(port); pd_timer_disable(port, PE_TIMER_VCONN_REAPPLIED); @@ -7664,15 +7708,21 @@ static void pe_ddr_perform_data_reset_run(int port) * ambiguity and update this implementation. */ usb_mux_set(port, USB_PD_MUX_NONE, USB_SWITCH_DISCONNECT, - polarity_rm_dts(pd_get_polarity(port))); + polarity_rm_dts(pd_get_polarity(port))); } else if (IS_ENABLED(CONFIG_USBC_VCONN) && - PE_CHK_FLAG(port, PE_FLAGS_VCONN_SWAP_COMPLETE) && - tc_is_vconn_src(port)) { + PE_CHK_FLAG(port, PE_FLAGS_VCONN_SWAP_COMPLETE) && + tc_is_vconn_src(port)) { PE_CLR_FLAG(port, PE_FLAGS_VCONN_SWAP_COMPLETE); PE_SET_FLAG(port, PE_FLAGS_DATA_RESET_COMPLETE); } else if (PE_CHK_FLAG(port, PE_FLAGS_DATA_RESET_COMPLETE) && - !pd_timer_is_disabled(port, PE_TIMER_DATA_RESET_FAIL)) { + !pd_timer_is_disabled(port, PE_TIMER_DATA_RESET_FAIL)) { pd_timer_disable(port, PE_TIMER_DATA_RESET_FAIL); + /* + * Because the cable power-cycled, reset the Tx (optional) and + * cached Rx (mandatory) message IDs. + */ + prl_reset_msg_ids(port, TCPCI_MSG_SOP_PRIME); + prl_reset_msg_ids(port, TCPCI_MSG_SOP_PRIME_PRIME); send_ctrl_msg(port, TCPCI_MSG_SOP, PD_CTRL_DATA_RESET_COMPLETE); } else if (PE_CHK_FLAG(port, PE_FLAGS_DATA_RESET_COMPLETE)) { /* @@ -7689,7 +7739,7 @@ static void pe_ddr_perform_data_reset_run(int port) } return; } else if (pd_timer_is_expired(port, PE_TIMER_DATA_RESET_FAIL) || - PE_CHK_FLAG(port, PE_FLAGS_PROTOCOL_ERROR)) { + 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); return; @@ -7709,11 +7759,12 @@ static void pe_ddr_perform_data_reset_exit(int port) pd_timer_disable(port, PE_TIMER_VCONN_REAPPLIED); pd_timer_disable(port, PE_TIMER_DATA_RESET_FAIL); PE_CLR_FLAG(port, PE_FLAGS_DATA_RESET_COMPLETE); + pd_dpm_request(port, DPM_REQUEST_PORT_DISCOVERY); dpm_data_reset_complete(port); } #endif /* CONFIG_USB_PD_DATA_RESET_MSG */ -const uint32_t * const pd_get_src_caps(int port) +const uint32_t *const pd_get_src_caps(int port) { return pe[port].src_caps; } @@ -7746,7 +7797,6 @@ void pd_dfp_discovery_init(int port) BIT(task_get_current())); memset(pe[port].discovery, 0, sizeof(pe[port].discovery)); - } void pd_dfp_mode_init(int port) @@ -7755,9 +7805,8 @@ void pd_dfp_mode_init(int port) * Clear the VDM Setup Done and Modal Operation flags so we will * have a fresh discovery */ - PE_CLR_MASK(port, - BIT(PE_FLAGS_VDM_SETUP_DONE_FN) | - BIT(PE_FLAGS_MODAL_OPERATION_FN)); + PE_CLR_MASK(port, BIT(PE_FLAGS_VDM_SETUP_DONE_FN) | + BIT(PE_FLAGS_MODAL_OPERATION_FN)); memset(pe[port].partner_amodes, 0, sizeof(pe[port].partner_amodes)); @@ -7776,7 +7825,7 @@ void pd_dfp_mode_init(int port) } __maybe_unused void pd_discovery_access_clear(int port, - enum tcpci_msg_type type) + enum tcpci_msg_type type) { if (!IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) assert(0); @@ -7785,7 +7834,7 @@ __maybe_unused void pd_discovery_access_clear(int port, } __maybe_unused bool pd_discovery_access_validate(int port, - enum tcpci_msg_type type) + enum tcpci_msg_type type) { if (!IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) assert(0); @@ -7793,15 +7842,15 @@ __maybe_unused bool pd_discovery_access_validate(int port, return !(task_access[port][type] & ~BIT(task_get_current())); } -__maybe_unused struct pd_discovery *pd_get_am_discovery_and_notify_access( - int port, enum tcpci_msg_type type) +__maybe_unused struct pd_discovery * +pd_get_am_discovery_and_notify_access(int port, enum tcpci_msg_type type) { atomic_or(&task_access[port][type], BIT(task_get_current())); return (struct pd_discovery *)pd_get_am_discovery(port, type); } -__maybe_unused const struct pd_discovery *pd_get_am_discovery(int port, - enum tcpci_msg_type type) +__maybe_unused const struct pd_discovery * +pd_get_am_discovery(int port, enum tcpci_msg_type type) { if (!IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) assert(0); @@ -7810,8 +7859,8 @@ __maybe_unused const struct pd_discovery *pd_get_am_discovery(int port, return &pe[port].discovery[type]; } -__maybe_unused struct partner_active_modes *pd_get_partner_active_modes( - int port, enum tcpci_msg_type type) +__maybe_unused struct partner_active_modes * +pd_get_partner_active_modes(int port, enum tcpci_msg_type type) { if (!IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) assert(0); @@ -7847,7 +7896,7 @@ uint32_t pe_get_flags(int port) } static __const_data const struct usb_state pe_states[] = { - /* Super States */ +/* Super States */ #ifdef CONFIG_USB_PD_REV30 [PE_PRS_FRS_SHARED] = { .entry = pe_prs_frs_shared_entry, @@ -8179,6 +8228,9 @@ static __const_data const struct usb_state pe_states[] = { .entry = pe_send_alert_entry, .run = pe_send_alert_run, }, + [PE_ALERT_RECEIVED] = { + .entry = pe_alert_received_entry, + }, #else [PE_SRC_CHUNK_RECEIVED] = { .entry = pe_chunk_received_entry, diff --git a/common/usbc/usb_pe_private.h b/common/usbc/usb_pe_private.h index e68c4c2fcd..bfe534dcca 100644 --- a/common/usbc/usb_pe_private.h +++ b/common/usbc/usb_pe_private.h @@ -1,4 +1,4 @@ -/* Copyright 2022 The Chromium OS Authors. All rights reserved. +/* Copyright 2022 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -13,76 +13,84 @@ */ enum { -/* At least one successful PD communication packet received from port partner */ + /* At least one successful PD communication packet received from port + partner */ PE_FLAGS_PD_CONNECTION_FN = 0, -/* Accept message received from port partner */ + /* Accept message received from port partner */ PE_FLAGS_ACCEPT_FN, -/* Power Supply Ready message received from port partner */ + /* Power Supply Ready message received from port partner */ PE_FLAGS_PS_READY_FN, -/* Protocol Error was determined based on error recovery current state */ + /* Protocol Error was determined based on error recovery current state + */ PE_FLAGS_PROTOCOL_ERROR_FN, -/* Set if we are in Modal Operation */ + /* Set if we are in Modal Operation */ PE_FLAGS_MODAL_OPERATION_FN, -/* A message we requested to be sent has been transmitted */ + /* A message we requested to be sent has been transmitted */ PE_FLAGS_TX_COMPLETE_FN, -/* A message sent by a port partner has been received */ + /* A message sent by a port partner has been received */ PE_FLAGS_MSG_RECEIVED_FN, -/* A hard reset has been requested but has not been sent, not currently used */ + /* A hard reset has been requested but has not been sent, not currently + used */ PE_FLAGS_HARD_RESET_PENDING_FN, -/* Port partner sent a Wait message. Wait before we resend our message */ + /* Port partner sent a Wait message. Wait before we resend our message + */ PE_FLAGS_WAIT_FN, -/* An explicit contract is in place with our port partner */ + /* An explicit contract is in place with our port partner */ PE_FLAGS_EXPLICIT_CONTRACT_FN, -/* Waiting for Sink Capabailities timed out. Used for retry error handling */ + /* Waiting for Sink Capabailities timed out. Used for retry error + handling */ PE_FLAGS_SNK_WAIT_CAP_TIMEOUT_FN, -/* Power Supply voltage/current transition timed out */ + /* Power Supply voltage/current transition timed out */ PE_FLAGS_PS_TRANSITION_TIMEOUT_FN, -/* Flag to note current Atomic Message Sequence is interruptible */ + /* Flag to note current Atomic Message Sequence is interruptible */ PE_FLAGS_INTERRUPTIBLE_AMS_FN, -/* Flag to note Power Supply reset has completed */ + /* Flag to note Power Supply reset has completed */ PE_FLAGS_PS_RESET_COMPLETE_FN, -/* VCONN swap operation has completed */ + /* VCONN swap operation has completed */ PE_FLAGS_VCONN_SWAP_COMPLETE_FN, -/* Flag to note no more setup VDMs (discovery, etc.) should be sent */ + /* Flag to note no more setup VDMs (discovery, etc.) should be sent */ PE_FLAGS_VDM_SETUP_DONE_FN, -/* Flag to note PR Swap just completed for Startup entry */ + /* Flag to note PR Swap just completed for Startup entry */ PE_FLAGS_PR_SWAP_COMPLETE_FN, -/* Flag to note Port Discovery port partner replied with BUSY */ + /* Flag to note Port Discovery port partner replied with BUSY */ PE_FLAGS_VDM_REQUEST_BUSY_FN, -/* Flag to note Port Discovery port partner replied with NAK */ + /* Flag to note Port Discovery port partner replied with NAK */ PE_FLAGS_VDM_REQUEST_NAKED_FN, -/* Flag to note FRS/PRS context in shared state machine path */ + /* Flag to note FRS/PRS context in shared state machine path */ PE_FLAGS_FAST_ROLE_SWAP_PATH_FN, -/* Flag to note if FRS listening is enabled */ + /* Flag to note if FRS listening is enabled */ PE_FLAGS_FAST_ROLE_SWAP_ENABLED_FN, -/* Flag to note TCPC passed on FRS signal from port partner */ + /* Flag to note TCPC passed on FRS signal from port partner */ PE_FLAGS_FAST_ROLE_SWAP_SIGNALED_FN, -/* TODO: POLICY decision: Triggers a DR SWAP attempt from UFP to DFP */ + /* TODO: POLICY decision: Triggers a DR SWAP attempt from UFP to DFP */ PE_FLAGS_DR_SWAP_TO_DFP_FN, -/* - * TODO: POLICY decision - * Flag to trigger a message resend after receiving a WAIT from port partner - */ + /* + * TODO: POLICY decision + * Flag to trigger a message resend after receiving a WAIT from port + * partner + */ PE_FLAGS_WAITING_PR_SWAP_FN, -/* FLAG is set when an AMS is initiated locally. ie. AP requested a PR_SWAP */ + /* FLAG is set when an AMS is initiated locally. ie. AP requested a + PR_SWAP */ PE_FLAGS_LOCALLY_INITIATED_AMS_FN, -/* Flag to note the first message sent in PE_SRC_READY and PE_SNK_READY */ + /* Flag to note the first message sent in PE_SRC_READY and PE_SNK_READY + */ PE_FLAGS_FIRST_MSG_FN, -/* Flag to continue a VDM request if it was interrupted */ + /* Flag to continue a VDM request if it was interrupted */ PE_FLAGS_VDM_REQUEST_CONTINUE_FN, -/* TODO: POLICY decision: Triggers a Vconn SWAP attempt to on */ + /* TODO: POLICY decision: Triggers a Vconn SWAP attempt to on */ PE_FLAGS_VCONN_SWAP_TO_ON_FN, -/* FLAG to track that VDM request to port partner timed out */ + /* FLAG to track that VDM request to port partner timed out */ PE_FLAGS_VDM_REQUEST_TIMEOUT_FN, -/* FLAG to note message was discarded due to incoming message */ + /* FLAG to note message was discarded due to incoming message */ PE_FLAGS_MSG_DISCARDED_FN, -/* FLAG to note that hard reset can't be performed due to battery low */ + /* FLAG to note that hard reset can't be performed due to battery low */ PE_FLAGS_SNK_WAITING_BATT_FN, -/* FLAG to note that a data reset is complete */ + /* FLAG to note that a data reset is complete */ PE_FLAGS_DATA_RESET_COMPLETE_FN, -/* Waiting for SRC to SNK settle time */ + /* Waiting for SRC to SNK settle time */ PE_FLAGS_SRC_SNK_SETTLE_FN, -/* Last element */ + /* Last element */ PE_FLAGS_COUNT }; diff --git a/common/usbc/usb_prl_sm.c b/common/usbc/usb_prl_sm.c index 805e6dfcd8..b1843da6eb 100644 --- a/common/usbc/usb_prl_sm.c +++ b/common/usbc/usb_prl_sm.c @@ -1,4 +1,4 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. +/* Copyright 2019 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -6,6 +6,7 @@ #include "battery.h" #include "battery_smart.h" #include "board.h" +#include "builtin/assert.h" #include "charge_manager.h" #include "charge_state.h" #include "chipset.h" @@ -33,8 +34,8 @@ #include "vpd_api.h" #ifdef CONFIG_COMMON_RUNTIME -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) #else #define CPRINTF(format, args...) #define CPRINTS(format, args...) @@ -46,27 +47,25 @@ #undef DEBUG_PRINT_FLAG_NAMES #ifdef DEBUG_PRINT_FLAG_NAMES -__maybe_unused static void print_flag(const char *group, - int set_or_clear, +__maybe_unused static void print_flag(const char *group, int set_or_clear, int flag); -#define SET_FLAG(group, flags, flag) \ - do { \ - print_flag(group, 1, flag); \ - atomic_or(flags, (flag)); \ +#define SET_FLAG(group, flags, flag) \ + do { \ + print_flag(group, 1, flag); \ + atomic_or(flags, (flag)); \ } while (0) -#define CLR_FLAG(group, flags, flag) \ - do { \ - int before = *flags; \ - atomic_clear_bits(flags, (flag)); \ - if (*flags != before) \ - print_flag(group, 0, flag); \ +#define CLR_FLAG(group, flags, flag) \ + do { \ + int before = *flags; \ + atomic_clear_bits(flags, (flag)); \ + if (*flags != before) \ + print_flag(group, 0, flag); \ } while (0) #else #define SET_FLAG(group, flags, flag) atomic_or(flags, (flag)) #define CLR_FLAG(group, flags, flag) atomic_clear_bits(flags, (flag)) #endif - #define RCH_SET_FLAG(port, flag) SET_FLAG("RCH", &rch[port].flags, (flag)) #define RCH_CLR_FLAG(port, flag) CLR_FLAG("RCH", &rch[port].flags, (flag)) #define RCH_CHK_FLAG(port, flag) (rch[port].flags & (flag)) @@ -98,34 +97,34 @@ __maybe_unused static void print_flag(const char *group, * different meanings in each state machine. */ /* Flag to note message transmission completed */ -#define PRL_FLAGS_TX_COMPLETE BIT(0) +#define PRL_FLAGS_TX_COMPLETE BIT(0) /* Flag to note that PRL requested to set SINK_NG CC state */ -#define PRL_FLAGS_SINK_NG BIT(1) +#define PRL_FLAGS_SINK_NG BIT(1) /* Flag to note PRL waited for SINK_OK CC state before transmitting */ -#define PRL_FLAGS_WAIT_SINK_OK BIT(2) +#define PRL_FLAGS_WAIT_SINK_OK BIT(2) /* Flag to note transmission error occurred */ -#define PRL_FLAGS_TX_ERROR BIT(3) +#define PRL_FLAGS_TX_ERROR BIT(3) /* Flag to note PE triggered a hard reset */ -#define PRL_FLAGS_PE_HARD_RESET BIT(4) +#define PRL_FLAGS_PE_HARD_RESET BIT(4) /* Flag to note hard reset has completed */ -#define PRL_FLAGS_HARD_RESET_COMPLETE BIT(5) +#define PRL_FLAGS_HARD_RESET_COMPLETE BIT(5) /* Flag to note port partner sent a hard reset */ #define PRL_FLAGS_PORT_PARTNER_HARD_RESET BIT(6) /* * Flag to note a message transmission has been requested. It is only cleared * when we send the message to the TCPC layer. */ -#define PRL_FLAGS_MSG_XMIT BIT(7) +#define PRL_FLAGS_MSG_XMIT BIT(7) /* Flag to note a message was received */ -#define PRL_FLAGS_MSG_RECEIVED BIT(8) +#define PRL_FLAGS_MSG_RECEIVED BIT(8) /* Flag to note aborting current TX message, not currently set */ -#define PRL_FLAGS_ABORT BIT(9) +#define PRL_FLAGS_ABORT BIT(9) /* Flag to note current TX message uses chunking */ -#define PRL_FLAGS_CHUNKING BIT(10) +#define PRL_FLAGS_CHUNKING BIT(10) struct bit_name { - int value; - const char *name; + int value; + const char *name; }; static __const_data const struct bit_name flag_bit_names[] = { @@ -136,17 +135,15 @@ static __const_data const struct bit_name flag_bit_names[] = { { PRL_FLAGS_PE_HARD_RESET, "PRL_FLAGS_PE_HARD_RESET" }, { PRL_FLAGS_HARD_RESET_COMPLETE, "PRL_FLAGS_HARD_RESET_COMPLETE" }, { PRL_FLAGS_PORT_PARTNER_HARD_RESET, - "PRL_FLAGS_PORT_PARTNER_HARD_RESET" }, + "PRL_FLAGS_PORT_PARTNER_HARD_RESET" }, { PRL_FLAGS_MSG_XMIT, "PRL_FLAGS_MSG_XMIT" }, { PRL_FLAGS_MSG_RECEIVED, "PRL_FLAGS_MSG_RECEIVED" }, { PRL_FLAGS_ABORT, "PRL_FLAGS_ABORT" }, { PRL_FLAGS_CHUNKING, "PRL_FLAGS_CHUNKING" }, }; -__maybe_unused static void print_bits(const char *group, - const char *desc, - int value, - const struct bit_name *names, +__maybe_unused static void print_bits(const char *group, const char *desc, + int value, const struct bit_name *names, int names_size) { int i; @@ -162,8 +159,7 @@ __maybe_unused static void print_bits(const char *group, CPRINTF("\n"); } -__maybe_unused static void print_flag(const char *group, - int set_or_clear, +__maybe_unused static void print_flag(const char *group, int set_or_clear, int flag) { print_bits(group, set_or_clear ? "Set" : "Clr", flag, flag_bit_names, @@ -189,6 +185,8 @@ __maybe_unused static void print_flag(const char *group, */ #ifdef CONFIG_USB_PD_DEBUG_LEVEL static const enum debug_level prl_debug_level = CONFIG_USB_PD_DEBUG_LEVEL; +#elif defined(CONFIG_USB_PD_INITIAL_DEBUG_LEVEL) +static enum debug_level prl_debug_level = CONFIG_USB_PD_INITIAL_DEBUG_LEVEL; #else static enum debug_level prl_debug_level = DEBUG_LEVEL_1; #endif @@ -238,7 +236,7 @@ enum usb_tch_state { TCH_REPORT_ERROR, }; -static const char * const prl_tx_state_names[] = { +static const char *const prl_tx_state_names[] = { [PRL_TX_PHY_LAYER_RESET] = "PRL_TX_PHY_LAYER_RESET", [PRL_TX_WAIT_FOR_MESSAGE_REQUEST] = "PRL_TX_WAIT_FOR_MESSAGE_REQUEST", [PRL_TX_LAYER_RESET_FOR_TRANSMIT] = "PRL_TX_LAYER_RESET_FOR_TRANSMIT", @@ -250,18 +248,18 @@ static const char * const prl_tx_state_names[] = { [PRL_TX_DISCARD_MESSAGE] = "PRL_TX_DISCARD_MESSAGE", }; -static const char * const prl_hr_state_names[] = { +static const char *const prl_hr_state_names[] = { [PRL_HR_WAIT_FOR_REQUEST] = "PRL_HR_WAIT_FOR_REQUEST", [PRL_HR_RESET_LAYER] = "PRL_HR_RESET_LAYER", - [PRL_HR_WAIT_FOR_PHY_HARD_RESET_COMPLETE] - = "PRL_HR_WAIT_FOR_PHY_HARD_RESET_COMPLETE", - [PRL_HR_WAIT_FOR_PE_HARD_RESET_COMPLETE] - = "PRL_HR_WAIT_FOR_PE_HARD_RESET_COMPLETE", + [PRL_HR_WAIT_FOR_PHY_HARD_RESET_COMPLETE] = + "PRL_HR_WAIT_FOR_PHY_HARD_RESET_COMPLETE", + [PRL_HR_WAIT_FOR_PE_HARD_RESET_COMPLETE] = + "PRL_HR_WAIT_FOR_PE_HARD_RESET_COMPLETE", }; -__maybe_unused static const char * const rch_state_names[] = { - [RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER] - = "RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER", +__maybe_unused static const char *const rch_state_names[] = { + [RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER] = + "RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER", [RCH_PASS_UP_MESSAGE] = "RCH_PASS_UP_MESSAGE", [RCH_PROCESSING_EXTENDED_MESSAGE] = "RCH_PROCESSING_EXTENDED_MESSAGE", [RCH_REQUESTING_CHUNK] = "RCH_REQUESTING_CHUNK", @@ -269,11 +267,11 @@ __maybe_unused static const char * const rch_state_names[] = { [RCH_REPORT_ERROR] = "RCH_REPORT_ERROR", }; -__maybe_unused static const char * const tch_state_names[] = { - [TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE] - = "TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE", - [TCH_WAIT_FOR_TRANSMISSION_COMPLETE] - = "TCH_WAIT_FOR_TRANSMISSION_COMPLETE", +__maybe_unused static const char *const tch_state_names[] = { + [TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE] = + "TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE", + [TCH_WAIT_FOR_TRANSMISSION_COMPLETE] = + "TCH_WAIT_FOR_TRANSMISSION_COMPLETE", [TCH_CONSTRUCT_CHUNKED_MESSAGE] = "TCH_CONSTRUCT_CHUNKED_MESSAGE", [TCH_SENDING_CHUNKED_MESSAGE] = "TCH_SENDING_CHUNKED_MESSAGE", [TCH_WAIT_CHUNK_REQUEST] = "TCH_WAIT_CHUNK_REQUEST", @@ -380,12 +378,12 @@ GEN_NOT_SUPPORTED(PRL_TX_SNK_START_AMS); GEN_NOT_SUPPORTED(RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER); #define RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER \ - RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER_NOT_SUPPORTED + RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER_NOT_SUPPORTED GEN_NOT_SUPPORTED(RCH_PASS_UP_MESSAGE); #define RCH_PASS_UP_MESSAGE RCH_PASS_UP_MESSAGE_NOT_SUPPORTED GEN_NOT_SUPPORTED(RCH_PROCESSING_EXTENDED_MESSAGE); #define RCH_PROCESSING_EXTENDED_MESSAGE \ - RCH_PROCESSING_EXTENDED_MESSAGE_NOT_SUPPORTED + RCH_PROCESSING_EXTENDED_MESSAGE_NOT_SUPPORTED GEN_NOT_SUPPORTED(RCH_REQUESTING_CHUNK); #define RCH_REQUESTING_CHUNK RCH_REQUESTING_CHUNK_NOT_SUPPORTED GEN_NOT_SUPPORTED(RCH_WAITING_CHUNK); @@ -395,13 +393,13 @@ GEN_NOT_SUPPORTED(RCH_REPORT_ERROR); GEN_NOT_SUPPORTED(TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); #define TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE \ - TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE_NOT_SUPPORTED + TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE_NOT_SUPPORTED GEN_NOT_SUPPORTED(TCH_WAIT_FOR_TRANSMISSION_COMPLETE); #define TCH_WAIT_FOR_TRANSMISSION_COMPLETE \ - TCH_WAIT_FOR_TRANSMISSION_COMPLETE_NOT_SUPPORTED + TCH_WAIT_FOR_TRANSMISSION_COMPLETE_NOT_SUPPORTED GEN_NOT_SUPPORTED(TCH_CONSTRUCT_CHUNKED_MESSAGE); #define TCH_CONSTRUCT_CHUNKED_MESSAGE \ - TCH_CONSTRUCT_CHUNKED_MESSAGE_NOT_SUPPORTED + TCH_CONSTRUCT_CHUNKED_MESSAGE_NOT_SUPPORTED GEN_NOT_SUPPORTED(TCH_SENDING_CHUNKED_MESSAGE); #define TCH_SENDING_CHUNKED_MESSAGE TCH_SENDING_CHUNKED_MESSAGE_NOT_SUPPORTED GEN_NOT_SUPPORTED(TCH_WAIT_CHUNK_REQUEST); @@ -435,7 +433,7 @@ static void print_current_prl_tx_state(const int port) { if (prl_debug_level >= DEBUG_LEVEL_3) CPRINTS("C%d: %s", port, - prl_tx_state_names[prl_tx_get_state(port)]); + prl_tx_state_names[prl_tx_get_state(port)]); } /* Set the hard reset statemachine to a new state. */ @@ -456,7 +454,7 @@ static void print_current_prl_hr_state(const int port) { if (prl_debug_level >= DEBUG_LEVEL_3) CPRINTS("C%d: %s", port, - prl_hr_state_names[prl_hr_get_state(port)]); + prl_hr_state_names[prl_hr_get_state(port)]); } /* Set the chunked Rx statemachine to a new state. */ @@ -477,8 +475,7 @@ test_export_static enum usb_rch_state rch_get_state(const int port) static void print_current_rch_state(const int port) { if (prl_debug_level >= DEBUG_LEVEL_3) - CPRINTS("C%d: %s", port, - rch_state_names[rch_get_state(port)]); + CPRINTS("C%d: %s", port, rch_state_names[rch_get_state(port)]); } #endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ @@ -503,12 +500,10 @@ test_export_static enum usb_tch_state tch_get_state(const int port) static void print_current_tch_state(const int port) { if (prl_debug_level >= DEBUG_LEVEL_3) - CPRINTS("C%d: %s", port, - tch_state_names[tch_get_state(port)]); + CPRINTS("C%d: %s", port, tch_state_names[tch_get_state(port)]); } #endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ - timestamp_t prl_get_tcpc_tx_success_ts(int port) { return tcpc_tx_success_ts[port]; @@ -578,10 +573,8 @@ static void prl_init(int port) prl_hr[port].flags = 0; - for (i = 0; i < NUM_SOP_STAR_TYPES; i++) { - prl_rx[port].msg_id[i] = -1; - prl_tx[port].msg_id_counter[i] = 0; - } + for (i = 0; i < NUM_SOP_STAR_TYPES; i++) + prl_reset_msg_ids(port, i); pd_timer_disable_range(port, PR_TIMER_RANGE); @@ -605,9 +598,8 @@ bool prl_is_busy(int port) { #ifdef CONFIG_USB_PD_EXTENDED_MESSAGES return rch_get_state(port) != - RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER || - tch_get_state(port) != - TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE; + RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER || + tch_get_state(port) != TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE; #else return false; #endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ @@ -626,9 +618,8 @@ void prl_hard_reset_complete(int port) task_wake(PD_PORT_TO_TASK_ID(port)); } -void prl_send_ctrl_msg(int port, - enum tcpci_msg_type type, - enum pd_ctrl_msg_type msg) +void prl_send_ctrl_msg(int port, enum tcpci_msg_type type, + enum pd_ctrl_msg_type msg) { pdmsg[port].xmit_type = type; pdmsg[port].msg_type = msg; @@ -646,9 +637,8 @@ void prl_send_ctrl_msg(int port, task_wake(PD_PORT_TO_TASK_ID(port)); } -void prl_send_data_msg(int port, - enum tcpci_msg_type type, - enum pd_data_msg_type msg) +void prl_send_data_msg(int port, enum tcpci_msg_type type, + enum pd_data_msg_type msg) { pdmsg[port].xmit_type = type; pdmsg[port].msg_type = msg; @@ -666,9 +656,8 @@ void prl_send_data_msg(int port, } #ifdef CONFIG_USB_PD_EXTENDED_MESSAGES -void prl_send_ext_data_msg(int port, - enum tcpci_msg_type type, - enum pd_ext_msg_type msg) +void prl_send_ext_data_msg(int port, enum tcpci_msg_type type, + enum pd_ext_msg_type msg) { pdmsg[port].xmit_type = type; pdmsg[port].msg_type = msg; @@ -736,11 +725,9 @@ void prl_run(int port, int evt, int en) * reset. */ if (prl_hr_get_state(port) == PRL_HR_WAIT_FOR_REQUEST) { - /* Run Protocol Layer Message Reception */ prl_rx_wait_for_phy_message(port, evt); - if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES)) { /* * Run RX Chunked state machine after prl_rx. @@ -772,8 +759,7 @@ void prl_run(int port, int evt, int en) } } -void prl_set_rev(int port, enum tcpci_msg_type type, - enum pd_rev_type rev) +void prl_set_rev(int port, enum tcpci_msg_type type, enum pd_rev_type rev) { /* We only store revisions for SOP* types. */ ASSERT(type < NUM_SOP_STAR_TYPES); @@ -789,6 +775,12 @@ enum pd_rev_type prl_get_rev(int port, enum tcpci_msg_type type) return pdmsg[port].rev[type]; } +void prl_reset_msg_ids(int port, enum tcpci_msg_type type) +{ + prl_tx[port].msg_id_counter[type] = 0; + prl_rx[port].msg_id[type] = -1; +} + static void prl_copy_msg_to_buffer(int port) { /* @@ -814,7 +806,7 @@ static void prl_copy_msg_to_buffer(int port) /* Copy message to chunked buffer */ memset((uint8_t *)pdmsg[port].tx_chk_buf, 0, CHK_BUF_SIZE_BYTES); memcpy((uint8_t *)pdmsg[port].tx_chk_buf, (uint8_t *)tx_emsg[port].buf, - tx_emsg[port].len); + tx_emsg[port].len); /* * Pad length to 4-byte boundary and * convert to number of 32-bit objects. @@ -828,8 +820,8 @@ static void prl_copy_msg_to_buffer(int port) static __maybe_unused int pdmsg_xmit_type_is_rev30(const int port) { if (IS_ENABLED(CONFIG_USB_PD_REV30)) - return ((pdmsg[port].xmit_type < NUM_SOP_STAR_TYPES) - && (prl_get_rev(port, pdmsg[port].xmit_type) == PD_REV30)); + return ((pdmsg[port].xmit_type < NUM_SOP_STAR_TYPES) && + (prl_get_rev(port, pdmsg[port].xmit_type) == PD_REV30)); else return 0; } @@ -846,8 +838,7 @@ static void prl_tx_phy_layer_reset_entry(const int port) { print_current_prl_tx_state(port); - if (IS_ENABLED(CONFIG_USB_CTVPD) - || IS_ENABLED(CONFIG_USB_VPD)) { + if (IS_ENABLED(CONFIG_USB_CTVPD) || IS_ENABLED(CONFIG_USB_VPD)) { vpd_rx_enable(pd_is_connected(port)); } else { /* Note: can't clear PHY messages due to TCPC architecture */ @@ -884,7 +875,7 @@ static void prl_tx_wait_for_message_request_run(const int port) if (IS_ENABLED(CONFIG_USB_PD_REV30) && is_sop_rev30(port) && pe_in_local_ams(port)) { if (PRL_TX_CHK_FLAG(port, PRL_FLAGS_SINK_NG | - PRL_FLAGS_WAIT_SINK_OK)) { + PRL_FLAGS_WAIT_SINK_OK)) { /* * If we are already in an AMS then allow the * multi-message AMS to continue, even if we @@ -915,7 +906,7 @@ static void prl_tx_wait_for_message_request_run(const int port) * Soft Reset Message Message pending */ if ((pdmsg[port].msg_type == PD_CTRL_SOFT_RESET) && - (tx_emsg[port].len == 0)) { + (tx_emsg[port].len == 0)) { set_state_prl_tx(port, PRL_TX_LAYER_RESET_FOR_TRANSMIT); } /* @@ -1031,16 +1022,14 @@ static void prl_tx_layer_reset_for_transmit_entry(const int port) * From section 6.3.13 Soft Reset Message in the USB PD 3.0 * v2.0 spec, Soft_Reset Message Shall be targeted at a * specific entity depending on the type of SOP* Packet used. - */ - prl_tx[port].msg_id_counter[pdmsg[port].xmit_type] = 0; - - /* + * + * * From section 6.11.2.3.2, the MessageID should be cleared * from the PRL_Rx_Layer_Reset_for_Receive state. However, we * don't implement a full state machine for PRL RX states so * clear the MessageID here. */ - prl_rx[port].msg_id[pdmsg[port].xmit_type] = -1; + prl_reset_msg_ids(port, pdmsg[port].xmit_type); } } @@ -1063,23 +1052,21 @@ static uint32_t get_sop_star_header(const int port) #endif /* SOP vs SOP'/SOP" headers are different. Replace fields as needed */ - return PD_HEADER( - pdmsg[port].msg_type, - is_sop_packet ? - pd_get_power_role(port) : tc_get_cable_plug(port), - is_sop_packet ? - pd_get_data_role(port) : 0, - prl_tx[port].msg_id_counter[pdmsg[port].xmit_type], - pdmsg[port].data_objs, - pdmsg[port].rev[pdmsg[port].xmit_type], - ext); + return PD_HEADER(pdmsg[port].msg_type, + is_sop_packet ? pd_get_power_role(port) : + tc_get_cable_plug(port), + is_sop_packet ? pd_get_data_role(port) : 0, + prl_tx[port].msg_id_counter[pdmsg[port].xmit_type], + pdmsg[port].data_objs, + pdmsg[port].rev[pdmsg[port].xmit_type], ext); } static void prl_tx_construct_message(const int port) { /* The header is unused for hard reset, etc. */ const uint32_t header = pdmsg[port].xmit_type < NUM_SOP_STAR_TYPES ? - get_sop_star_header(port) : 0; + get_sop_star_header(port) : + 0; /* Save SOP* so the correct msg_id_counter can be incremented */ prl_tx[port].last_xmit_type = pdmsg[port].xmit_type; @@ -1199,7 +1186,7 @@ static void prl_tx_src_pending_run(const int port) * SinkTxTimer timeout */ if ((tx_emsg[port].len == 0) && - (pdmsg[port].msg_type == PD_CTRL_SOFT_RESET)) { + (pdmsg[port].msg_type == PD_CTRL_SOFT_RESET)) { set_state_prl_tx(port, PRL_TX_LAYER_RESET_FOR_TRANSMIT); } /* Message pending (except Soft Reset) & @@ -1259,7 +1246,7 @@ static void prl_tx_snk_pending_run(const int port) * Rp = SinkTxOk */ if ((pdmsg[port].msg_type == PD_CTRL_SOFT_RESET) && - (tx_emsg[port].len == 0)) { + (tx_emsg[port].len == 0)) { set_state_prl_tx(port, PRL_TX_LAYER_RESET_FOR_TRANSMIT); } /* @@ -1305,7 +1292,7 @@ static void prl_hr_wait_for_request_entry(const int port) static void prl_hr_wait_for_request_run(const int port) { if (PRL_HR_CHK_FLAG(port, PRL_FLAGS_PE_HARD_RESET | - PRL_FLAGS_PORT_PARTNER_HARD_RESET)) + PRL_FLAGS_PORT_PARTNER_HARD_RESET)) set_state_prl_hr(port, PRL_HR_RESET_LAYER); } @@ -1327,13 +1314,11 @@ static void prl_hr_reset_layer_entry(const int port) /* Hard reset resets messageIDCounters for all TX types */ for (i = 0; i < NUM_SOP_STAR_TYPES; i++) { - prl_rx[port].msg_id[i] = -1; - prl_tx[port].msg_id_counter[i] = 0; + prl_reset_msg_ids(port, i); } /* Disable RX */ - if (IS_ENABLED(CONFIG_USB_CTVPD) || - IS_ENABLED(CONFIG_USB_VPD)) + if (IS_ENABLED(CONFIG_USB_CTVPD) || IS_ENABLED(CONFIG_USB_VPD)) vpd_rx_enable(0); else tcpm_set_rx_enable(port, 0); @@ -1396,8 +1381,7 @@ static void prl_hr_wait_for_phy_hard_reset_complete_entry(const int port) print_current_prl_hr_state(port); /* Start HardResetCompleteTimer */ - pd_timer_enable(port, PR_TIMER_HARD_RESET_COMPLETE, - PD_T_PS_HARD_RESET); + pd_timer_enable(port, PR_TIMER_HARD_RESET_COMPLETE, PD_T_PS_HARD_RESET); } static void prl_hr_wait_for_phy_hard_reset_complete_run(const int port) @@ -1455,11 +1439,11 @@ static void copy_chunk_to_ext(int port) { /* Calculate number of bytes */ pdmsg[port].num_bytes_received = - (PD_HEADER_CNT(rx_emsg[port].header) * 4); + (PD_HEADER_CNT(rx_emsg[port].header) * 4); /* Copy chunk into extended message */ memcpy((uint8_t *)rx_emsg[port].buf, (uint8_t *)pdmsg[port].rx_chk_buf, - pdmsg[port].num_bytes_received); + pdmsg[port].num_bytes_received); /* Set extended message length */ rx_emsg[port].len = pdmsg[port].num_bytes_received; @@ -1491,10 +1475,10 @@ static void rch_wait_for_message_from_protocol_layer_run(const int port) * Are we communicating with a PD3.0 device and is * this an extended message? */ - if (pdmsg_xmit_type_is_rev30(port) - && PD_HEADER_EXT(rx_emsg[port].header)) { + if (pdmsg_xmit_type_is_rev30(port) && + PD_HEADER_EXT(rx_emsg[port].header)) { uint16_t exhdr = - GET_EXT_HEADER(*pdmsg[port].rx_chk_buf); + GET_EXT_HEADER(*pdmsg[port].rx_chk_buf); uint8_t chunked = PD_EXT_HEADER_CHUNKED(exhdr); /* @@ -1502,7 +1486,7 @@ static void rch_wait_for_message_from_protocol_layer_run(const int port) * (Chunking = 1 & Chunked = 1) */ if ((RCH_CHK_FLAG(port, PRL_FLAGS_CHUNKING)) && - chunked) { + chunked) { /* * RCH_Processing_Extended_Message first chunk * entry processing embedded here @@ -1524,7 +1508,7 @@ static void rch_wait_for_message_from_protocol_layer_run(const int port) * (Chunking = 0 & Chunked = 0)) */ else if (!RCH_CHK_FLAG(port, PRL_FLAGS_CHUNKING) && - !chunked) { + !chunked) { /* Copy chunk to extended buffer */ copy_chunk_to_ext(port); set_state_rch(port, RCH_PASS_UP_MESSAGE); @@ -1602,8 +1586,8 @@ static void rch_processing_extended_message_run(const int port) byte_num = PD_MAX_EXTENDED_MSG_CHUNK_LEN; /* Make sure extended message buffer does not overflow */ - if (pdmsg[port].num_bytes_received + - byte_num > EXTENDED_BUFFER_SIZE) { + if (pdmsg[port].num_bytes_received + byte_num > + EXTENDED_BUFFER_SIZE) { rch[port].error = ERR_RCH_CHUNKED; set_state_rch(port, RCH_REPORT_ERROR); return; @@ -1612,9 +1596,8 @@ static void rch_processing_extended_message_run(const int port) /* Append data */ /* Add 2 to chk_buf to skip over extended message header */ memcpy(((uint8_t *)rx_emsg[port].buf + - pdmsg[port].num_bytes_received), - (uint8_t *)pdmsg[port].rx_chk_buf + 2, - byte_num); + pdmsg[port].num_bytes_received), + (uint8_t *)pdmsg[port].rx_chk_buf + 2, byte_num); /* increment chunk number expected */ pdmsg[port].chunk_number_expected++; /* adjust num bytes received */ @@ -1623,7 +1606,7 @@ static void rch_processing_extended_message_run(const int port) /* Was that the last chunk? */ if (pdmsg[port].num_bytes_received >= data_size) { rx_emsg[port].len = pdmsg[port].num_bytes_received; - /* Pass Message to Policy Engine */ + /* Pass Message to Policy Engine */ set_state_rch(port, RCH_PASS_UP_MESSAGE); } /* @@ -1652,11 +1635,11 @@ static void rch_requesting_chunk_entry(const int port) * Send Chunk Request to Protocol Layer * with chunk number = Chunk_Number_Expected */ - pdmsg[port].tx_chk_buf[0] = PD_EXT_HEADER( - pdmsg[port].chunk_number_expected, - 1, /* Request Chunk */ - 0 /* Data Size */ - ); + pdmsg[port].tx_chk_buf[0] = + PD_EXT_HEADER(pdmsg[port].chunk_number_expected, 1, /* Request + Chunk */ + 0 /* Data Size */ + ); pdmsg[port].data_objs = 1; pdmsg[port].ext = 1; @@ -1827,16 +1810,15 @@ static void tch_wait_for_message_request_from_pe_run(const int port) * Discard the Message */ if (rch_get_state(port) != - RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER) { + RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER) { tch[port].error = ERR_TCH_XMIT; set_state_tch(port, TCH_REPORT_ERROR); } else { /* * Extended Message Request & Chunking */ - if (pdmsg_xmit_type_is_rev30(port) - && pdmsg[port].ext - && TCH_CHK_FLAG(port, PRL_FLAGS_CHUNKING)) { + if (pdmsg_xmit_type_is_rev30(port) && pdmsg[port].ext && + TCH_CHK_FLAG(port, PRL_FLAGS_CHUNKING)) { /* * NOTE: TCH_Prepare_To_Send_Chunked_Message * embedded here. @@ -1855,7 +1837,8 @@ static void tch_wait_for_message_request_from_pe_run(const int port) /* Pass Message to Protocol Layer */ PRL_TX_SET_FLAG(port, PRL_FLAGS_MSG_XMIT); - set_state_tch(port, + set_state_tch( + port, TCH_WAIT_FOR_TRANSMISSION_COMPLETE); } } @@ -1900,7 +1883,7 @@ static void tch_wait_for_transmission_complete_run(const int port) * the tx message was sent successfully. */ if (TCH_CHK_FLAG(port, PRL_FLAGS_MSG_RECEIVED) && - prl_tx[port].xmit_status != TCPC_TX_COMPLETE_SUCCESS) { + prl_tx[port].xmit_status != TCPC_TX_COMPLETE_SUCCESS) { TCH_CLR_FLAG(port, PRL_FLAGS_MSG_RECEIVED); set_state_tch(port, TCH_MESSAGE_RECEIVED); return; @@ -1937,8 +1920,9 @@ static void tch_construct_chunked_message_entry(const int port) num = PD_MAX_EXTENDED_MSG_CHUNK_LEN; /* Set the chunks extended header */ - *ext_hdr = PD_EXT_HEADER(pdmsg[port].chunk_number_to_send, - 0, /* Chunk Request */ + *ext_hdr = PD_EXT_HEADER(pdmsg[port].chunk_number_to_send, 0, /* Chunk + Request + */ tx_emsg[port].len); /* Copy the message chunk into chk_buf */ @@ -2036,7 +2020,8 @@ static void tch_wait_chunk_request_run(const int port) */ if (PD_EXT_HEADER_CHUNK_NUM(exthdr) == pdmsg[port].chunk_number_to_send) { - set_state_tch(port, + set_state_tch( + port, TCH_CONSTRUCT_CHUNKED_MESSAGE); } /* @@ -2111,8 +2096,6 @@ static void tch_message_sent_entry(const int port) return; } - - set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); } @@ -2136,7 +2119,6 @@ static void tch_report_error_entry(const int port) return; } - set_state_tch(port, TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); } #endif /* CONFIG_USB_PD_EXTENDED_MESSAGES */ @@ -2176,7 +2158,7 @@ static void prl_rx_wait_for_phy_message(const int port, int evt) /* dump received packet content (only dump ping at debug level MAX) */ if ((prl_debug_level >= DEBUG_LEVEL_2 && type != PD_CTRL_PING) || - prl_debug_level >= DEBUG_LEVEL_3) { + prl_debug_level >= DEBUG_LEVEL_3) { int p; ccprintf("C%d: RECV %04x/%d ", port, header, cnt); @@ -2189,8 +2171,7 @@ static void prl_rx_wait_for_phy_message(const int port, int evt) * Ignore messages sent to the cable from our * port partner if we aren't Vconn powered device. */ - if (!IS_ENABLED(CONFIG_USB_CTVPD) && - !IS_ENABLED(CONFIG_USB_VPD) && + if (!IS_ENABLED(CONFIG_USB_CTVPD) && !IS_ENABLED(CONFIG_USB_VPD) && PD_HEADER_GET_SOP(header) != TCPCI_MSG_SOP && PD_HEADER_PROLE(header) == PD_PLUG_FROM_DFP_UFP) return; @@ -2214,19 +2195,17 @@ static void prl_rx_wait_for_phy_message(const int port, int evt) /* Handle incoming soft reset as special case */ if (cnt == 0 && type == PD_CTRL_SOFT_RESET) { - /* Clear MessageIdCounter */ - prl_tx[port].msg_id_counter[prl_rx[port].sop] = 0; - /* Clear stored MessageID value */ - prl_rx[port].msg_id[prl_rx[port].sop] = -1; + /* Clear MessageIdCounter and stored MessageID value. */ + prl_reset_msg_ids(port, prl_rx[port].sop); /* Soft Reset occurred */ set_state_prl_tx(port, PRL_TX_PHY_LAYER_RESET); if (IS_ENABLED(CONFIG_USB_PD_EXTENDED_MESSAGES)) { set_state_rch(port, - RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER); + RCH_WAIT_FOR_MESSAGE_FROM_PROTOCOL_LAYER); set_state_tch(port, - TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); + TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE); } /* @@ -2286,7 +2265,7 @@ static void prl_rx_wait_for_phy_message(const int port, int evt) * tch_wait_for_message_request_from_pe has been run */ else if (tch_get_state(port) != - TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE || + TCH_WAIT_FOR_MESSAGE_REQUEST_FROM_PE || TCH_CHK_FLAG(port, PRL_FLAGS_MSG_XMIT)) { /* NOTE: RTR_TX_CHUNKS State embedded here. */ /* diff --git a/common/usbc/usb_retimer_fw_update.c b/common/usbc/usb_retimer_fw_update.c index 1c3023db9b..3f9b1b4c72 100644 --- a/common/usbc/usb_retimer_fw_update.c +++ b/common/usbc/usb_retimer_fw_update.c @@ -1,10 +1,12 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. +/* Copyright 2021 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include <stdbool.h> #include <stdint.h> + +#include "builtin/assert.h" #include "compile_time_macros.h" #include "console.h" #include "hooks.h" @@ -14,14 +16,20 @@ #include "usb_tc_sm.h" #ifdef CONFIG_COMMON_RUNTIME -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) #else #define CPRINTS(format, args...) #define CPRINTF(format, args...) #endif /* + * Update retimer firmware of no device attached (NDA) ports + * + * https://docs.kernel.org/admin-guide/thunderbolt.html# + * upgrading-on-board-retimer-nvm-when-there-is-no-cable-connected + * + * On EC side: * Retimer firmware update is initiated by AP. * The operations requested by AP are: * 0 - USB_RETIMER_FW_UPDATE_QUERY_PORT @@ -43,10 +51,52 @@ * If 4/5/6/7 is received, TC_FLAGS_USB_RETIMER_FW_UPDATE_LTD_RUN is * set, PD task should be in suspended mode and process it. * + * On host side: + * 1. Put NDA ports into offline mode. + * This forces retimer to power on, and requests EC to suspend + * PD port, set USB mux to USB, Safe then TBT. + * 2. Scan for retimers + * 3. Update retimer NVM firmware. + * 4. Authenticate. + * 5. Wait 5 or more seconds for retimer to come back. + * 6. Put NDA ports into online mode -- the functional state. + * This requestes EC to disconnect(set USB mux to 0), resume PD port. + * + * Error recovery: + * As mentioned above, to put port online, host sends two requests to EC + * 1. Disconnect USB MUX: USB_RETIMER_FW_UPDATE_DISCONNECT + * if step 1 is successful, then + * 2. Resume PD port: USB_RETIMER_FW_UPDATE_RESUME_PD + * + * If step 1 fails, host will not send step 2. This means no + * resume request from host. PD port stays in suspended state. + * EC needs an error recovery to resume PD port by itself. + * + * Below is how error recovery works: + * PD port state is set to RETIMER_ONLINE_REQUESTED when receives + * "Disconnect USB MUX"; a deferred call is set up too. When EC resumes + * port upon host's request, port state will be set to RETIMER_ONLINE; + * or port state stays RETIMER_ONLINE_REQUESTED if host doesn't request. + * By the time the deferrred call is fired, it will check if any port is + * still in RETIMER_ONLINE_REQUESTED state. If true, EC will put the + * port online by itself. That is, retry disconnect and unconditionally + * resume the port. */ #define SUSPEND 1 -#define RESUME 0 +#define RESUME 0 + +enum retimer_port_state { + RETIMER_ONLINE, + RETIMER_OFFLINE, + RETIMER_ONLINE_REQUESTED +}; + +/* + * Two seconds buffer is added on top of required 5 seconds; + * to cover the time to disconnect and resume. + */ +#define RETIMTER_ONLINE_DELAY (7 * SECOND) /* Track current port AP requested to update retimer firmware */ static int cur_port; @@ -54,7 +104,7 @@ static int last_op; /* Operation received from AP via ACPI_WRITE */ /* Operation result returned to ACPI_READ */ static int last_result; /* Track port state: SUSPEND or RESUME */ -static int port_state[CONFIG_USB_PD_PORT_MAX_COUNT]; +static enum retimer_port_state port_state[CONFIG_USB_PD_PORT_MAX_COUNT]; int usb_retimer_fw_update_get_result(void) { @@ -87,12 +137,13 @@ int usb_retimer_fw_update_get_result(void) return result; } -static void retimer_fw_update_set_port_state(int port, int state) +static void retimer_fw_update_set_port_state(int port, + enum retimer_port_state state) { port_state[port] = state; } -static int retimer_fw_update_get_port_state(int port) +static enum retimer_port_state retimer_fw_update_get_port_state(int port) { return port_state[port]; } @@ -101,16 +152,16 @@ static int retimer_fw_update_get_port_state(int port) * @brief Suspend or resume PD task and update the state of the port. * * @param port PD port - * @param state - * SUSPEND: suspend PD task for firmware update; and set state to SUSPEND - * RESUME: resume PD task after firmware update is done; and set state - * to RESUME. + * @param suspend + * SUSPEND: suspend PD task; set state to RETIMER_OFFLINE + * RESUME: resume PD task; set state to RETIMER_ONLINE. * */ -static void retimer_fw_update_port_handler(int port, int state) +static void retimer_fw_update_port_handler(int port, bool suspend) { - pd_set_suspend(port, state); - retimer_fw_update_set_port_state(port, state); + pd_set_suspend(port, suspend); + retimer_fw_update_set_port_state( + port, suspend == SUSPEND ? RETIMER_OFFLINE : RETIMER_ONLINE); } static void deferred_pd_suspend(void) @@ -124,14 +175,74 @@ static inline mux_state_t retimer_fw_update_usb_mux_get(int port) return usb_mux_get(port) & USB_RETIMER_FW_UPDATE_MUX_MASK; } +/* + * Host will wait maximum 300ms for result; otherwise it's error. + * so the polling takes 300ms too. + */ +#define POLLING_CYCLE 15 +#define POLLING_TIME_MS 20 + +static bool query_usb_mux_set_completed_timeout(int port) +{ + int i; + + for (i = 0; i < POLLING_CYCLE; i++) { + if (!usb_mux_set_completed(port)) + msleep(POLLING_TIME_MS); + else + return false; + } + + return true; +} + +static void retry_online(int port) +{ + usb_mux_set(port, USB_PD_MUX_NONE, USB_SWITCH_DISCONNECT, + pd_get_polarity(port)); + /* Wait maximum 300 ms for USB mux to be set */ + query_usb_mux_set_completed_timeout(port); + /* Resume the port unconditionally */ + retimer_fw_update_port_handler(port, RESUME); +} + +/* + * After NVM update, if AP skips step 5, not wait 5+ seconds for retimer + * to come back; then do step 6 immediately, requesting EC to put + * retimer online. Step 6 will fail; port is still offline afterwards. + * + * This deferred function monitors if any port has this problem and retry + * online one more time. + */ +static void retimer_check_online(void) +{ + int i; + + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { + if (retimer_fw_update_get_port_state(i) == + RETIMER_ONLINE_REQUESTED) { + /* + * Now the time has passed RETIMTER_ONLINE_DELAY; + * retry online. + * The port is suspended; if the port is not + * suspended, DISCONNECT request won't go through, + * we couldn't be here. + */ + retry_online(i); + /* PD port is resumed */ + } + } +} +DECLARE_DEFERRED(retimer_check_online); + /* Allow mux results to be filled in during HOOKS if needed */ static void last_result_mux_get(void); DECLARE_DEFERRED(last_result_mux_get); static void last_result_mux_get(void) { - if (!usb_mux_set_completed(cur_port)) { - hook_call_deferred(&last_result_mux_get_data, 20 * MSEC); + if (query_usb_mux_set_completed_timeout(cur_port)) { + last_result = USB_RETIMER_FW_UPDATE_ERR; return; } @@ -175,8 +286,8 @@ void usb_retimer_fw_update_process_op_cb(int port) result_mux_get = true; break; case USB_RETIMER_FW_UPDATE_SET_USB: - usb_mux_set(port, USB_PD_MUX_USB_ENABLED, - USB_SWITCH_CONNECT, pd_get_polarity(port)); + usb_mux_set(port, USB_PD_MUX_USB_ENABLED, USB_SWITCH_CONNECT, + pd_get_polarity(port)); result_mux_get = true; break; case USB_RETIMER_FW_UPDATE_SET_SAFE: @@ -185,13 +296,21 @@ void usb_retimer_fw_update_process_op_cb(int port) break; case USB_RETIMER_FW_UPDATE_SET_TBT: usb_mux_set(port, USB_PD_MUX_TBT_COMPAT_ENABLED, - USB_SWITCH_CONNECT, pd_get_polarity(port)); + USB_SWITCH_CONNECT, pd_get_polarity(port)); result_mux_get = true; break; case USB_RETIMER_FW_UPDATE_DISCONNECT: - usb_mux_set(port, USB_PD_MUX_NONE, - USB_SWITCH_DISCONNECT, pd_get_polarity(port)); + usb_mux_set(port, USB_PD_MUX_NONE, USB_SWITCH_DISCONNECT, + pd_get_polarity(port)); result_mux_get = true; + /* + * Host decides to put retimer online; now disconnects USB MUX + * and sets port state to "RETIMER_ONLINE_REQUESTED". + */ + retimer_fw_update_set_port_state(port, + RETIMER_ONLINE_REQUESTED); + hook_call_deferred(&retimer_check_online_data, + RETIMTER_ONLINE_DELAY); break; default: break; @@ -210,12 +329,32 @@ void usb_retimer_fw_update_process_op(int port, int op) ASSERT(port >= 0 && port < CONFIG_USB_PD_PORT_MAX_COUNT); /* - * TODO(b/179220036): check not overlapping requests; - * not change cur_port if retimer scan is in progress + * The order of requests from host are: + * + * Port 0 offline + * Port 0 rescan retimers + * Port 1 offline + * Port 1 rescan retimers + * ... + * Port 0 online + * Port 1 online + * ... */ last_op = op; cur_port = port; + /* + * Host has requested to put this port back online, and haven't + * finished online process. During this period, don't accept any + * requests, except USB_RETIMER_FW_UPDATE_RESUME_PD. + */ + if (port_state[port] == RETIMER_ONLINE_REQUESTED) { + if (op != USB_RETIMER_FW_UPDATE_RESUME_PD) { + last_result = USB_RETIMER_FW_UPDATE_ERR; + return; + } + } + switch (op) { case USB_RETIMER_FW_UPDATE_QUERY_PORT: break; @@ -253,9 +392,10 @@ static void restore_port(void) { int port; - for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) { + for (port = 0; port < CONFIG_USB_PD_PORT_MAX_COUNT; port++) { if (retimer_fw_update_get_port_state(port)) retimer_fw_update_port_handler(port, RESUME); } } DECLARE_HOOK(HOOK_CHIPSET_SHUTDOWN, restore_port, HOOK_PRIO_DEFAULT); +DECLARE_HOOK(HOOK_CHIPSET_RESET, restore_port, HOOK_PRIO_DEFAULT); diff --git a/common/usbc/usb_sm.c b/common/usbc/usb_sm.c index 04b7193c0f..96b0b81e33 100644 --- a/common/usbc/usb_sm.c +++ b/common/usbc/usb_sm.c @@ -1,4 +1,4 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. +/* Copyright 2019 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -12,8 +12,8 @@ #include "util.h" #ifdef CONFIG_COMMON_RUNTIME -#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USB, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USB, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USB, format, ##args) #else /* CONFIG_COMMON_RUNTIME */ #define CPRINTF(format, args...) #define CPRINTS(format, args...) @@ -23,8 +23,8 @@ struct internal_ctx { usb_state_ptr last_entered; uint32_t running : 1; - uint32_t enter : 1; - uint32_t exit : 1; + uint32_t enter : 1; + uint32_t exit : 1; }; BUILD_ASSERT(sizeof(struct internal_ctx) == member_size(struct sm_ctx, internal)); @@ -65,9 +65,9 @@ static usb_state_ptr shared_parent_state(usb_state_ptr a, usb_state_ptr b) * functions. */ static void call_entry_functions(const int port, - struct internal_ctx *const internal, - const usb_state_ptr stop, - const usb_state_ptr current) + struct internal_ctx *const internal, + const usb_state_ptr stop, + const usb_state_ptr current) { if (current == stop) return; @@ -92,7 +92,7 @@ static void call_entry_functions(const int port, * during an exit function. */ static void call_exit_functions(const int port, const usb_state_ptr stop, - const usb_state_ptr current) + const usb_state_ptr current) { if (current == stop) return; @@ -106,7 +106,7 @@ static void call_exit_functions(const int port, const usb_state_ptr stop, void set_state(const int port, struct sm_ctx *const ctx, const usb_state_ptr new_state) { - struct internal_ctx * const internal = (void *) ctx->internal; + struct internal_ctx *const internal = (void *)ctx->internal; usb_state_ptr last_state; usb_state_ptr shared_parent; @@ -116,8 +116,8 @@ void set_state(const int port, struct sm_ctx *const ctx, * intended state to transition into. */ if (internal->exit) { - CPRINTF("C%d: Ignoring set state to 0x%pP within 0x%pP", - port, new_state, ctx->current); + CPRINTF("C%d: Ignoring set state to 0x%p within 0x%p", port, + new_state, ctx->current); return; } @@ -176,8 +176,8 @@ void set_state(const int port, struct sm_ctx *const ctx, * functions. */ static void call_run_functions(const int port, - const struct internal_ctx *const internal, - const usb_state_ptr current) + const struct internal_ctx *const internal, + const usb_state_ptr current) { if (!current) return; @@ -194,7 +194,7 @@ static void call_run_functions(const int port, void run_state(const int port, struct sm_ctx *const ctx) { - struct internal_ctx * const internal = (void *) ctx->internal; + struct internal_ctx *const internal = (void *)ctx->internal; internal->running = true; call_run_functions(port, internal, ctx->current); diff --git a/common/usbc/usb_tc_ctvpd_sm.c b/common/usbc/usb_tc_ctvpd_sm.c index 46550978ed..045cca55c4 100644 --- a/common/usbc/usb_tc_ctvpd_sm.c +++ b/common/usbc/usb_tc_ctvpd_sm.c @@ -1,8 +1,9 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. +/* Copyright 2019 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +#include "builtin/assert.h" #include "common.h" #include "console.h" #include "system.h" @@ -16,18 +17,18 @@ /* USB Type-C CTVPD module */ #ifdef CONFIG_COMMON_RUNTIME -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) #else /* CONFIG_COMMON_RUNTIME */ #define CPRINTF(format, args...) #define CPRINTS(format, args...) #endif /* Type-C Layer Flags */ -#define TC_FLAGS_VCONN_ON BIT(0) +#define TC_FLAGS_VCONN_ON BIT(0) -#define SUPPORT_TIMER_RESET_INIT 0 -#define SUPPORT_TIMER_RESET_REQUEST 1 +#define SUPPORT_TIMER_RESET_INIT 0 +#define SUPPORT_TIMER_RESET_REQUEST 1 #define SUPPORT_TIMER_RESET_COMPLETE 2 /** @@ -105,9 +106,8 @@ enum usb_tc_state { /* Forward declare the full list of states. This is indexed by usb_tc_state */ static const struct usb_state tc_states[]; - /* List of human readable state names for console debugging */ -__maybe_unused const char * const tc_state_names[] = { +__maybe_unused const char *const tc_state_names[] = { #ifdef CONFIG_COMMON_RUNTIME [TC_DISABLED] = "Disabled", [TC_UNATTACHED_SNK] = "Unattached.SNK", @@ -257,9 +257,9 @@ test_mockable_static void print_current_state(const int port) int pd_is_connected(int port) { return (get_state_tc(port) == TC_ATTACHED_SNK) || - (get_state_tc(port) == TC_ATTACHED_SRC) || - (get_state_tc(port) == TC_CT_ATTACHED_UNSUPPORTED) || - (get_state_tc(port) == TC_CT_ATTACHED_VPD); + (get_state_tc(port) == TC_ATTACHED_SRC) || + (get_state_tc(port) == TC_CT_ATTACHED_UNSUPPORTED) || + (get_state_tc(port) == TC_CT_ATTACHED_VPD); } bool pd_is_disconnected(int port) @@ -398,7 +398,7 @@ static void tc_unattached_snk_run(const int port) * 2) VBUS is detected */ if (vpd_is_ct_vbus_present() && - tc[port].cc_state == PD_CC_DFP_ATTACHED) { + tc[port].cc_state == PD_CC_DFP_ATTACHED) { set_state_tc(port, TC_UNATTACHED_SRC); return; } @@ -436,11 +436,11 @@ static void tc_attach_wait_snk_run(const int port) if (tc[port].host_cc_state != host_new_cc_state) { tc[port].host_cc_state = host_new_cc_state; if (host_new_cc_state == PD_CC_DFP_ATTACHED) - tc[port].host_cc_debounce = get_time().val + - PD_T_CC_DEBOUNCE; + tc[port].host_cc_debounce = + get_time().val + PD_T_CC_DEBOUNCE; else - tc[port].host_cc_debounce = get_time().val + - PD_T_PD_DEBOUNCE; + tc[port].host_cc_debounce = + get_time().val + PD_T_PD_DEBOUNCE; return; } @@ -458,7 +458,7 @@ static void tc_attach_wait_snk_run(const int port) * CC2 pins is SNK.Open for at least tPDDebounce. */ if (tc[port].host_cc_state == PD_CC_DFP_ATTACHED && - (vpd_is_vconn_present() || vpd_is_host_vbus_present())) + (vpd_is_vconn_present() || vpd_is_host_vbus_present())) set_state_tc(port, TC_ATTACHED_SNK); else if (tc[port].host_cc_state == PD_CC_NONE) set_state_tc(port, TC_UNATTACHED_SNK); @@ -551,7 +551,7 @@ static void tc_attached_snk_run(const int port) /* Check the Support Timer */ if (get_time().val > tc[port].support_timer && - !tc[port].billboard_presented) { + !tc[port].billboard_presented) { /* * Present USB Billboard Device Class interface * indicating that Charge-Through is not supported @@ -654,7 +654,7 @@ static void tc_unattached_src_run(const int port) * if Charge-Through VBUS is removed. */ if (!vpd_is_ct_vbus_present() || - get_time().val > tc[port].next_role_swap) { + get_time().val > tc[port].next_role_swap) { set_state_tc(port, TC_UNATTACHED_SNK); return; } @@ -719,7 +719,7 @@ static void tc_attach_wait_src_run(const int port) * state is on the Host-side port’s CC pin for at least tCCDebounce. */ if (tc[port].host_cc_state == PD_CC_UFP_ATTACHED && - !vpd_is_host_vbus_present()) { + !vpd_is_host_vbus_present()) { set_state_tc(port, TC_TRY_SNK); return; } @@ -847,7 +847,7 @@ static void tc_try_snk_run(const int port) * for tTryCCDebounce. */ if (tc[port].host_cc_state == PD_CC_DFP_ATTACHED && - (vpd_is_host_vbus_present() || vpd_is_vconn_present())) + (vpd_is_host_vbus_present() || vpd_is_vconn_present())) set_state_tc(port, TC_ATTACHED_SNK); else if (tc[port].host_cc_state == PD_CC_NONE) set_state_tc(port, TC_TRY_WAIT_SRC); @@ -887,7 +887,7 @@ static void tc_try_wait_src_run(const int port) if (tc[port].host_cc_state != host_new_cc_state) { tc[port].host_cc_state = host_new_cc_state; tc[port].host_cc_debounce = - get_time().val + PD_T_TRY_CC_DEBOUNCE; + get_time().val + PD_T_TRY_CC_DEBOUNCE; return; } @@ -899,7 +899,7 @@ static void tc_try_wait_src_run(const int port) * at least tTryCCDebounce. */ if (tc[port].host_cc_state == PD_CC_UFP_ATTACHED && - !vpd_is_host_vbus_present()) { + !vpd_is_host_vbus_present()) { set_state_tc(port, TC_ATTACHED_SRC); return; } @@ -988,7 +988,7 @@ static void tc_ct_try_snk_run(const int port) * Charge-Through port. */ if (tc[port].cc_state == PD_CC_DFP_ATTACHED && - vpd_is_ct_vbus_present()) { + vpd_is_ct_vbus_present()) { set_state_tc(port, TC_CT_ATTACHED_VPD); return; } @@ -1001,8 +1001,7 @@ static void tc_ct_try_snk_run(const int port) * for tDRPTryWait. */ if (tc[port].cc_state == PD_CC_NONE) { - set_state_tc(port, - TC_CT_ATTACHED_UNSUPPORTED); + set_state_tc(port, TC_CT_ATTACHED_UNSUPPORTED); return; } } @@ -1181,8 +1180,7 @@ static void tc_ct_unattached_unsupported_run(const int port) * on both the CC1 and CC2 pins. */ if (cc_is_at_least_one_rd(cc1, cc2) || cc_is_audio_acc(cc1, cc2)) { - set_state_tc(port, - TC_CT_ATTACH_WAIT_UNSUPPORTED); + set_state_tc(port, TC_CT_ATTACH_WAIT_UNSUPPORTED); return; } @@ -1343,7 +1341,7 @@ static void tc_ct_attached_vpd_entry(const int port) * pins is connected through the cable */ vpd_ct_get_cc(&cc1, &cc2); - tc[port].ct_cc = cc_is_rp(cc2) ? CT_CC2 : CT_CC1; + tc[port].ct_cc = cc_is_rp(cc2) ? CT_CC2 : CT_CC1; /* * 1. Remove or reduce any additional capacitance on the @@ -1468,10 +1466,8 @@ static void tc_ct_attach_wait_vpd_run(const int port) /* Debounce the cc state */ if (new_cc_state != tc[port].cc_state) { tc[port].cc_state = new_cc_state; - tc[port].cc_debounce = get_time().val + - PD_T_CC_DEBOUNCE; - tc[port].pd_debounce = get_time().val + - PD_T_PD_DEBOUNCE; + tc[port].cc_debounce = get_time().val + PD_T_CC_DEBOUNCE; + tc[port].pd_debounce = get_time().val + PD_T_PD_DEBOUNCE; return; } @@ -1482,7 +1478,7 @@ static void tc_ct_attach_wait_vpd_run(const int port) * port’s CC1 and CC2 pins are SNK.Open for at least * tPDDebounce. */ - if (tc[port].cc_state == PD_CC_NONE) { + if (tc[port].cc_state == PD_CC_NONE) { set_state_tc(port, TC_CT_UNATTACHED_VPD); return; } @@ -1496,8 +1492,8 @@ static void tc_ct_attach_wait_vpd_run(const int port) * least tCCDebounce and VBUS on the Charge-Through port is * detected. */ - if (tc[port].cc_state == PD_CC_DFP_ATTACHED && - vpd_is_ct_vbus_present()) { + if (tc[port].cc_state == PD_CC_DFP_ATTACHED && + vpd_is_ct_vbus_present()) { set_state_tc(port, TC_CT_ATTACHED_VPD); return; } diff --git a/common/usbc/usb_tc_drp_acc_trysrc_sm.c b/common/usbc/usb_tc_drp_acc_trysrc_sm.c index 2da6b59f0a..e68b0139db 100644 --- a/common/usbc/usb_tc_drp_acc_trysrc_sm.c +++ b/common/usbc/usb_tc_drp_acc_trysrc_sm.c @@ -1,8 +1,9 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. +/* Copyright 2019 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +#include "builtin/assert.h" #include "charge_manager.h" #include "charge_state.h" #include "common.h" @@ -32,30 +33,30 @@ * See Figure 4-16 in Release 1.4 of USB Type-C Spec. */ #ifdef CONFIG_COMMON_RUNTIME -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) #else /* CONFIG_COMMON_RUNTIME */ #define CPRINTF(format, args...) #define CPRINTS(format, args...) #endif -#define CPRINTF_LX(x, format, args...) \ - do { \ - if (tc_debug_level >= x) \ - CPRINTF(format, ## args); \ +#define CPRINTF_LX(x, format, args...) \ + do { \ + if (tc_debug_level >= x) \ + CPRINTF(format, ##args); \ } while (0) -#define CPRINTF_L1(format, args...) CPRINTF_LX(1, format, ## args) -#define CPRINTF_L2(format, args...) CPRINTF_LX(2, format, ## args) -#define CPRINTF_L3(format, args...) CPRINTF_LX(3, format, ## args) - -#define CPRINTS_LX(x, format, args...) \ - do { \ - if (tc_debug_level >= x) \ - CPRINTS(format, ## args); \ +#define CPRINTF_L1(format, args...) CPRINTF_LX(1, format, ##args) +#define CPRINTF_L2(format, args...) CPRINTF_LX(2, format, ##args) +#define CPRINTF_L3(format, args...) CPRINTF_LX(3, format, ##args) + +#define CPRINTS_LX(x, format, args...) \ + do { \ + if (tc_debug_level >= x) \ + CPRINTS(format, ##args); \ } while (0) -#define CPRINTS_L1(format, args...) CPRINTS_LX(1, format, ## args) -#define CPRINTS_L2(format, args...) CPRINTS_LX(2, format, ## args) -#define CPRINTS_L3(format, args...) CPRINTS_LX(3, format, ## args) +#define CPRINTS_L1(format, args...) CPRINTS_LX(1, format, ##args) +#define CPRINTS_L2(format, args...) CPRINTS_LX(2, format, ##args) +#define CPRINTS_L3(format, args...) CPRINTS_LX(3, format, ##args) /* * Define DEBUG_PRINT_FLAG_AND_EVENT_NAMES to print flag names when set and @@ -83,57 +84,58 @@ void print_flag(int port, int set_or_clear, int flag); /* Type-C Layer Flags */ /* Flag to note we are sourcing VCONN */ -#define TC_FLAGS_VCONN_ON BIT(0) +#define TC_FLAGS_VCONN_ON BIT(0) /* Flag to note port partner has Rp/Rp or Rd/Rd */ -#define TC_FLAGS_TS_DTS_PARTNER BIT(1) +#define TC_FLAGS_TS_DTS_PARTNER BIT(1) /* Flag to note VBus input has never been low */ -#define TC_FLAGS_VBUS_NEVER_LOW BIT(2) +#define TC_FLAGS_VBUS_NEVER_LOW BIT(2) /* Flag to note Low Power Mode transition is currently happening */ -#define TC_FLAGS_LPM_TRANSITION BIT(3) +#define TC_FLAGS_LPM_TRANSITION BIT(3) /* Flag to note Low Power Mode is currently on */ -#define TC_FLAGS_LPM_ENGAGED BIT(4) +#define TC_FLAGS_LPM_ENGAGED BIT(4) /* Flag to note CVTPD has been detected */ -#define TC_FLAGS_CTVPD_DETECTED BIT(5) +#define TC_FLAGS_CTVPD_DETECTED BIT(5) /* Flag to note request to swap to VCONN on */ -#define TC_FLAGS_REQUEST_VC_SWAP_ON BIT(6) +#define TC_FLAGS_REQUEST_VC_SWAP_ON BIT(6) /* Flag to note request to swap to VCONN off */ -#define TC_FLAGS_REQUEST_VC_SWAP_OFF BIT(7) +#define TC_FLAGS_REQUEST_VC_SWAP_OFF BIT(7) /* Flag to note request to swap VCONN is being rejected */ -#define TC_FLAGS_REJECT_VCONN_SWAP BIT(8) +#define TC_FLAGS_REJECT_VCONN_SWAP BIT(8) /* Flag to note request to power role swap */ -#define TC_FLAGS_REQUEST_PR_SWAP BIT(9) +#define TC_FLAGS_REQUEST_PR_SWAP BIT(9) /* Flag to note request to data role swap */ -#define TC_FLAGS_REQUEST_DR_SWAP BIT(10) +#define TC_FLAGS_REQUEST_DR_SWAP BIT(10) /* Flag to note request to power off sink */ -#define TC_FLAGS_POWER_OFF_SNK BIT(11) +#define TC_FLAGS_POWER_OFF_SNK BIT(11) /* Flag to note port partner is Power Delivery capable */ -#define TC_FLAGS_PARTNER_PD_CAPABLE BIT(12) +#define TC_FLAGS_PARTNER_PD_CAPABLE BIT(12) /* Flag to note hard reset has been requested */ -#define TC_FLAGS_HARD_RESET_REQUESTED BIT(13) +#define TC_FLAGS_HARD_RESET_REQUESTED BIT(13) /* Flag to note we are currently performing PR Swap */ -#define TC_FLAGS_PR_SWAP_IN_PROGRESS BIT(14) +#define TC_FLAGS_PR_SWAP_IN_PROGRESS BIT(14) /* Flag to note we should check for connection */ -#define TC_FLAGS_CHECK_CONNECTION BIT(15) +#define TC_FLAGS_CHECK_CONNECTION BIT(15) /* Flag to note request from pd_set_suspend to enter TC_DISABLED state */ -#define TC_FLAGS_REQUEST_SUSPEND BIT(16) +#define TC_FLAGS_REQUEST_SUSPEND BIT(16) /* Flag to note we are in TC_DISABLED state */ -#define TC_FLAGS_SUSPENDED BIT(17) +#define TC_FLAGS_SUSPENDED BIT(17) /* Flag to indicate the port current limit has changed */ -#define TC_FLAGS_UPDATE_CURRENT BIT(18) +#define TC_FLAGS_UPDATE_CURRENT BIT(18) /* Flag to indicate USB mux should be updated */ -#define TC_FLAGS_UPDATE_USB_MUX BIT(19) +#define TC_FLAGS_UPDATE_USB_MUX BIT(19) /* Flag for retimer firmware update */ -#define TC_FLAGS_USB_RETIMER_FW_UPDATE_RUN BIT(20) +#define TC_FLAGS_USB_RETIMER_FW_UPDATE_RUN BIT(20) #define TC_FLAGS_USB_RETIMER_FW_UPDATE_LTD_RUN BIT(21) /* Flag for asynchronous call to request Error Recovery */ -#define TC_FLAGS_REQUEST_ERROR_RECOVERY BIT(22) +#define TC_FLAGS_REQUEST_ERROR_RECOVERY BIT(22) /* For checking flag_bit_names[] array */ -#define TC_FLAGS_COUNT 23 +#define TC_FLAGS_COUNT 23 /* On disconnect, clear most of the flags. */ -#define CLR_FLAGS_ON_DISCONNECT(port) TC_CLR_FLAG(port, \ - ~(TC_FLAGS_LPM_ENGAGED | TC_FLAGS_REQUEST_SUSPEND | TC_FLAGS_SUSPENDED)) +#define CLR_FLAGS_ON_DISCONNECT(port) \ + TC_CLR_FLAG(port, ~(TC_FLAGS_LPM_ENGAGED | TC_FLAGS_REQUEST_SUSPEND | \ + TC_FLAGS_SUSPENDED)) /* * 10 ms is enough time for any TCPC transaction to complete @@ -166,14 +168,14 @@ void print_flag(int port, int set_or_clear, int flag); * The TypeC state machine uses this bit to disable/enable PD * This bit corresponds to bit-0 of pd_disabled_mask */ -#define PD_DISABLED_NO_CONNECTION BIT(0) +#define PD_DISABLED_NO_CONNECTION BIT(0) /* * Console and Host commands use this bit to override the * PD_DISABLED_NO_CONNECTION bit that was set by the TypeC * state machine. * This bit corresponds to bit-1 of pd_disabled_mask */ -#define PD_DISABLED_BY_POLICY BIT(1) +#define PD_DISABLED_BY_POLICY BIT(1) /* Unreachable time in future */ #define TIMER_DISABLED 0xffffffffffffffff @@ -250,9 +252,8 @@ extern int _GPIO_CCD_MODE_ODL; * If we can't print or the CONFIG_USB_PD_DEBUG_LEVEL is defined to be 0 * then the DEBUG LABELS will be removed from the build. */ -#if defined(CONFIG_COMMON_RUNTIME) && \ - (!defined(CONFIG_USB_PD_DEBUG_LEVEL) || \ - (CONFIG_USB_PD_DEBUG_LEVEL > 0)) +#if defined(CONFIG_COMMON_RUNTIME) && (!defined(CONFIG_USB_PD_DEBUG_LEVEL) || \ + (CONFIG_USB_PD_DEBUG_LEVEL > 0)) #define USB_PD_DEBUG_LABELS #endif @@ -268,9 +269,8 @@ extern int _GPIO_CCD_MODE_ODL; */ #define IS_ATTACHED_SNK(port) (get_state_tc(port) == TC_ATTACHED_SNK) - /* List of human readable state names for console debugging */ -__maybe_unused static __const_data const char * const tc_state_names[] = { +__maybe_unused static __const_data const char *const tc_state_names[] = { #ifdef USB_PD_DEBUG_LABELS [TC_DISABLED] = "Disabled", [TC_ERROR_RECOVERY] = "ErrorRecovery", @@ -289,7 +289,7 @@ __maybe_unused static __const_data const char * const tc_state_names[] = { [TC_LOW_POWER_MODE] = "LowPowerMode", #endif #ifdef CONFIG_USB_PE_SM - [TC_CT_UNATTACHED_SNK] = "CTUnattached.SNK", + [TC_CT_UNATTACHED_SNK] = "CTUnattached.SNK", [TC_CT_ATTACHED_SNK] = "CTAttached.SNK", #endif /* Super States */ @@ -304,14 +304,16 @@ __maybe_unused static __const_data const char * const tc_state_names[] = { /* Debug log level - higher number == more log */ #ifdef CONFIG_USB_PD_DEBUG_LEVEL static const enum debug_level tc_debug_level = CONFIG_USB_PD_DEBUG_LEVEL; +#elif defined(CONFIG_USB_PD_INITIAL_DEBUG_LEVEL) +static enum debug_level tc_debug_level = CONFIG_USB_PD_INITIAL_DEBUG_LEVEL; #else static enum debug_level tc_debug_level = DEBUG_LEVEL_1; #endif #ifdef DEBUG_PRINT_FLAG_AND_EVENT_NAMES struct bit_name { - int value; - const char *name; + int value; + const char *name; }; static struct bit_name flag_bit_names[] = { @@ -335,11 +337,10 @@ static struct bit_name flag_bit_names[] = { { TC_FLAGS_SUSPENDED, "SUSPENDED" }, { TC_FLAGS_UPDATE_CURRENT, "UPDATE_CURRENT" }, { TC_FLAGS_UPDATE_USB_MUX, "UPDATE_USB_MUX" }, - { TC_FLAGS_USB_RETIMER_FW_UPDATE_RUN, - "USB_RETIMER_FW_UPDATE_RUN" }, + { TC_FLAGS_USB_RETIMER_FW_UPDATE_RUN, "USB_RETIMER_FW_UPDATE_RUN" }, { TC_FLAGS_USB_RETIMER_FW_UPDATE_LTD_RUN, - "USB_RETIMER_FW_UPDATE_LTD_RUN" }, - { TC_FLAGS_REQUEST_ERROR_RECOVERY, "REQUEST_ERROR_RECOCVERY"}, + "USB_RETIMER_FW_UPDATE_LTD_RUN" }, + { TC_FLAGS_REQUEST_ERROR_RECOVERY, "REQUEST_ERROR_RECOCVERY" }, }; BUILD_ASSERT(ARRAY_SIZE(flag_bit_names) == TC_FLAGS_COUNT); @@ -394,8 +395,8 @@ void print_flag(int port, int set_or_clear, int flag) #ifndef CONFIG_USB_PD_TRY_SRC extern int TC_TRY_SRC_UNDEFINED; extern int TC_TRY_WAIT_SNK_UNDEFINED; -#define TC_TRY_SRC TC_TRY_SRC_UNDEFINED -#define TC_TRY_WAIT_SNK TC_TRY_WAIT_SNK_UNDEFINED +#define TC_TRY_SRC TC_TRY_SRC_UNDEFINED +#define TC_TRY_WAIT_SNK TC_TRY_WAIT_SNK_UNDEFINED #endif static struct type_c { @@ -444,10 +445,11 @@ static struct type_c { } tc[CONFIG_USB_PD_PORT_MAX_COUNT]; /* Port dual-role state */ -static volatile __maybe_unused -enum pd_dual_role_states drp_state[CONFIG_USB_PD_PORT_MAX_COUNT] = { - [0 ... (CONFIG_USB_PD_PORT_MAX_COUNT - 1)] = - CONFIG_USB_PD_INITIAL_DRP_STATE}; +static volatile __maybe_unused enum pd_dual_role_states + drp_state[CONFIG_USB_PD_PORT_MAX_COUNT] = { + [0 ...(CONFIG_USB_PD_PORT_MAX_COUNT - 1)] = + CONFIG_USB_PD_INITIAL_DRP_STATE + }; static void set_vconn(int port, int enable); @@ -516,7 +518,7 @@ __overridable void pd_set_vbus_discharge(int port, int enable) /* * These pd_ functions are implemented in the PE layer */ -const uint32_t * const pd_get_src_caps(int port) +const uint32_t *const pd_get_src_caps(int port) { return NULL; } @@ -526,7 +528,7 @@ uint8_t pd_get_src_cap_cnt(int port) return 0; } -const uint32_t * const pd_get_snk_caps(int port) +const uint32_t *const pd_get_snk_caps(int port) { return NULL; } @@ -718,7 +720,7 @@ __maybe_unused static void tc_enable_try_src(int en) static void tc_set_modes_exit(int port) { if (IS_ENABLED(CONFIG_USB_PE_SM) && - IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { + IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { pd_dfp_exit_mode(port, TCPCI_MSG_SOP, 0, 0); pd_dfp_exit_mode(port, TCPCI_MSG_SOP_PRIME, 0, 0); pd_dfp_exit_mode(port, TCPCI_MSG_SOP_PRIME_PRIME, 0, 0); @@ -738,12 +740,13 @@ static void tc_detached(int port) /* Clear any mux connection on detach */ if (IS_ENABLED(CONFIG_USBC_SS_MUX)) - usb_mux_set(port, USB_PD_MUX_NONE, - USB_SWITCH_DISCONNECT, tc[port].polarity); + usb_mux_set(port, USB_PD_MUX_NONE, USB_SWITCH_DISCONNECT, + tc[port].polarity); } static inline void pd_set_dual_role_and_event(int port, - enum pd_dual_role_states state, uint32_t event) + enum pd_dual_role_states state, + uint32_t event) { drp_state[port] = state; @@ -1072,8 +1075,8 @@ static void tc_set_partner_role(int port, enum ppc_device_role role, * to run. So build in 1ms delays, for up to 300ms, to wait for * the suspend to actually happen. */ -#define SUSPEND_SLEEP_DELAY 1 -#define SUSPEND_SLEEP_RETRIES 300 +#define SUSPEND_SLEEP_DELAY 1 +#define SUSPEND_SLEEP_RETRIES 300 void pd_set_suspend(int port, int suspend) { @@ -1098,8 +1101,8 @@ void pd_set_suspend(int port, int suspend) /* Sleep this task if we are not suspended */ while (pd_is_port_enabled(port)) { if (++wait > SUSPEND_SLEEP_RETRIES) { - CPRINTS("C%d: NOT SUSPENDED after %dms", - port, wait * SUSPEND_SLEEP_DELAY); + CPRINTS("C%d: NOT SUSPENDED after %dms", port, + wait * SUSPEND_SLEEP_DELAY); return; } msleep(SUSPEND_SLEEP_DELAY); @@ -1177,8 +1180,8 @@ int pd_is_connected(int port) { return (IS_ATTACHED_SRC(port) || (IS_ENABLED(CONFIG_USB_PE_SM) && - ((get_state_tc(port) == TC_CT_UNATTACHED_SNK) || - (get_state_tc(port) == TC_CT_ATTACHED_SNK))) || + ((get_state_tc(port) == TC_CT_UNATTACHED_SNK) || + (get_state_tc(port) == TC_CT_ATTACHED_SNK))) || IS_ATTACHED_SNK(port)); } @@ -1235,7 +1238,7 @@ bool pd_get_partner_unconstr_power(int port) } static void bc12_role_change_handler(int port, enum pd_data_role prev_data_role, - enum pd_data_role data_role) + enum pd_data_role data_role) { int event = 0; bool role_changed = (data_role != prev_data_role); @@ -1290,8 +1293,7 @@ void typec_select_src_collision_rp(int port, enum tcpc_rp_value rp) static enum tcpc_rp_value typec_get_active_select_rp(int port) { /* Explicit contract will use the collision Rp */ - if (IS_ENABLED(CONFIG_USB_PD_REV30) && - pe_is_explicit_contract(port)) + if (IS_ENABLED(CONFIG_USB_PD_REV30) && pe_is_explicit_contract(port)) return tc[port].select_collision_rp; return tc[port].select_current_limit_rp; } @@ -1412,7 +1414,7 @@ static bool tc_perform_snk_hard_reset(int port) tc[port].ps_reset_state = PS_STATE2; pd_timer_enable(port, TC_TIMER_TIMEOUT, PD_T_SRC_RECOVER_MAX + - PD_T_SRC_TURN_ON); + PD_T_SRC_TURN_ON); } if (pd_timer_is_expired(port, TC_TIMER_TIMEOUT)) { @@ -1423,7 +1425,7 @@ static bool tc_perform_snk_hard_reset(int port) tc[port].ps_reset_state = PS_STATE2; pd_timer_enable(port, TC_TIMER_TIMEOUT, PD_T_SRC_RECOVER_MAX + - PD_T_SRC_TURN_ON); + PD_T_SRC_TURN_ON); } return false; case PS_STATE2: @@ -1497,8 +1499,8 @@ static void restart_tc_sm(int port, enum usb_tc_state start_state) * Update the Rp Value. We don't need to update CC lines though as that * happens in below set_state transition. */ - typec_select_src_current_limit_rp(port, - typec_get_default_current_limit_rp(port)); + typec_select_src_current_limit_rp( + port, typec_get_default_current_limit_rp(port)); /* Disable if restart failed, otherwise start in default state. */ set_state_tc(port, res ? TC_DISABLED : start_state); @@ -1567,7 +1569,6 @@ void tc_state_init(int port) return; } - /* Allow system to set try src enable */ if (IS_ENABLED(CONFIG_USB_PD_TRY_SRC)) tc_try_src_override(TRY_SRC_NO_OVERRIDE); @@ -1582,11 +1583,13 @@ void tc_state_init(int port) if (chipset_in_state(CHIPSET_STATE_ANY_OFF)) pd_set_dual_role_and_event(port, PD_DRP_FORCE_SINK, 0); else if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND)) - pd_set_dual_role_and_event(port, pd_get_drp_state_in_suspend(), 0); + pd_set_dual_role_and_event(port, pd_get_drp_state_in_suspend(), + 0); else /* CHIPSET_STATE_ON */ pd_set_dual_role_and_event(port, pd_get_drp_state_in_s0(), 0); #else - pd_set_dual_role_and_event(port, board_tc_get_initial_drp_mode(port), 0); + pd_set_dual_role_and_event(port, board_tc_get_initial_drp_mode(port), + 0); #endif /* @@ -1771,8 +1774,7 @@ void tc_event_check(int port, int evt) * Notify all ports of sysjump */ if (evt & PD_EVENT_SYSJUMP) { - for (i = 0; i < - CONFIG_USB_PD_PORT_MAX_COUNT; i++) + for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) dpm_set_mode_exit_request(i); notify_sysjump_ready(); } @@ -1834,8 +1836,8 @@ static void sink_stop_drawing_current(int port) if (IS_ENABLED(CONFIG_CHARGE_MANAGER)) { typec_set_input_current_limit(port, 0, 0); - charge_manager_set_ceil(port, - CEIL_REQUESTOR_PD, CHARGE_CEIL_NONE); + charge_manager_set_ceil(port, CEIL_REQUESTOR_PD, + CHARGE_CEIL_NONE); } } @@ -1861,9 +1863,9 @@ static void set_vconn(int port, int enable) static void pd_update_dual_role_config(int port) { if (tc[port].power_role == PD_ROLE_SOURCE && - (drp_state[port] == PD_DRP_FORCE_SINK || - (drp_state[port] == PD_DRP_TOGGLE_OFF && - get_state_tc(port) == TC_UNATTACHED_SRC))) { + (drp_state[port] == PD_DRP_FORCE_SINK || + (drp_state[port] == PD_DRP_TOGGLE_OFF && + get_state_tc(port) == TC_UNATTACHED_SRC))) { /* * Change to sink if port is currently a source AND (new DRP * state is force sink OR new DRP state is toggle off and we are @@ -1871,7 +1873,7 @@ static void pd_update_dual_role_config(int port) */ set_state_tc(port, TC_UNATTACHED_SNK); } else if (tc[port].power_role == PD_ROLE_SINK && - drp_state[port] == PD_DRP_FORCE_SOURCE) { + drp_state[port] == PD_DRP_FORCE_SOURCE) { /* * Change to source if port is currently a sink and the * new DRP state is force source. @@ -1885,10 +1887,9 @@ __maybe_unused static void handle_new_power_state(int port) if (!IS_ENABLED(CONFIG_POWER_COMMON)) assert(0); - if (IS_ENABLED(CONFIG_POWER_COMMON) && - IS_ENABLED(CONFIG_USB_PE_SM)) { + if (IS_ENABLED(CONFIG_POWER_COMMON) && IS_ENABLED(CONFIG_USB_PE_SM)) { if (chipset_in_or_transitioning_to_state( - CHIPSET_STATE_ANY_OFF)) { + CHIPSET_STATE_ANY_OFF)) { /* * The SoC will negotiate alternate mode again when it * boots up @@ -1905,8 +1906,7 @@ __maybe_unused static void handle_new_power_state(int port) */ if (IS_ENABLED(CONFIG_USB_PE_SM)) { if (tc_is_vconn_src(port) && tc_is_attached_snk(port) && - !pd_check_vconn_swap(port) && - pd_is_battery_capable()) + !pd_check_vconn_swap(port) && pd_is_battery_capable()) pd_dpm_request(port, DPM_REQUEST_HARD_RESET_SEND); } @@ -1928,7 +1928,7 @@ __maybe_unused static void handle_new_power_state(int port) void pd_request_vconn_swap_off(int port) { if (get_state_tc(port) == TC_ATTACHED_SRC || - get_state_tc(port) == TC_ATTACHED_SNK) { + get_state_tc(port) == TC_ATTACHED_SNK) { TC_SET_FLAG(port, TC_FLAGS_REQUEST_VC_SWAP_OFF); task_wake(PD_PORT_TO_TASK_ID(port)); } @@ -1937,7 +1937,7 @@ void pd_request_vconn_swap_off(int port) void pd_request_vconn_swap_on(int port) { if (get_state_tc(port) == TC_ATTACHED_SRC || - get_state_tc(port) == TC_ATTACHED_SNK) { + get_state_tc(port) == TC_ATTACHED_SNK) { TC_SET_FLAG(port, TC_FLAGS_REQUEST_VC_SWAP_ON); task_wake(PD_PORT_TO_TASK_ID(port)); } @@ -2090,14 +2090,13 @@ static void sink_power_sub_states(int port) tc[port].typec_curr = usb_get_typec_current_limit( tc[port].polarity, cc1, cc2); - typec_set_input_current_limit(port, - tc[port].typec_curr, TYPE_C_VOLTAGE); + typec_set_input_current_limit(port, tc[port].typec_curr, + TYPE_C_VOLTAGE); charge_manager_update_dualrole(port, CAP_DEDICATED); } } } - /* * TYPE-C State Implementations */ @@ -2117,6 +2116,7 @@ static void tc_disabled_entry(const int port) * to indicate to pd_is_port_enabled that we are now suspended. */ TC_SET_FLAG(port, TC_FLAGS_SUSPENDED); + tcpm_release(port); } static void tc_disabled_run(const int port) @@ -2124,13 +2124,16 @@ static void tc_disabled_run(const int port) /* If pd_set_suspend clears the request, go to TC_UNATTACHED_SNK/SRC. */ if (!TC_CHK_FLAG(port, TC_FLAGS_REQUEST_SUSPEND)) { set_state_tc(port, drp_state[port] == PD_DRP_FORCE_SOURCE ? - TC_UNATTACHED_SRC : TC_UNATTACHED_SNK); + TC_UNATTACHED_SRC : + TC_UNATTACHED_SNK); } else { if (IS_ENABLED(CONFIG_USBC_RETIMER_FW_UPDATE)) { - if (TC_CHK_FLAG(port, - TC_FLAGS_USB_RETIMER_FW_UPDATE_LTD_RUN)) { - TC_CLR_FLAG(port, - TC_FLAGS_USB_RETIMER_FW_UPDATE_LTD_RUN); + if (TC_CHK_FLAG( + port, + TC_FLAGS_USB_RETIMER_FW_UPDATE_LTD_RUN)) { + TC_CLR_FLAG( + port, + TC_FLAGS_USB_RETIMER_FW_UPDATE_LTD_RUN); usb_retimer_fw_update_process_op_cb(port); } } @@ -2179,7 +2182,8 @@ static void tc_error_recovery_run(const int port) */ if (tc[port].ctx.previous == NULL) { set_state_tc(port, drp_state[port] == PD_DRP_FORCE_SOURCE ? - TC_UNATTACHED_SRC : TC_UNATTACHED_SNK); + TC_UNATTACHED_SRC : + TC_UNATTACHED_SNK); return; } @@ -2230,11 +2234,10 @@ static void tc_unattached_snk_entry(const int port) */ tcpm_debug_detach(port); typec_select_pull(port, TYPEC_CC_RD); - typec_select_src_current_limit_rp(port, - typec_get_default_current_limit_rp(port)); + typec_select_src_current_limit_rp( + port, typec_get_default_current_limit_rp(port)); typec_update_cc(port); - prev_data_role = tc[port].data_role; tc[port].data_role = PD_ROLE_DISCONNECTED; /* @@ -2256,10 +2259,11 @@ static void tc_unattached_snk_entry(const int port) pd_execute_data_swap(port, PD_ROLE_DISCONNECTED); pd_timer_enable(port, TC_TIMER_NEXT_ROLE_SWAP, PD_T_DRP_SNK); - if (IS_ENABLED(CONFIG_USB_PE_SM)) { - CLR_FLAGS_ON_DISCONNECT(port); - tc_enable_pd(port, 0); - } +#ifdef CONFIG_USB_PE_SM + CLR_FLAGS_ON_DISCONNECT(port); + tc_enable_pd(port, 0); + tc[port].ps_reset_state = PS_STATE0; +#endif } static void tc_unattached_snk_run(const int port) @@ -2383,9 +2387,9 @@ static void tc_attach_wait_snk_run(const int port) if (new_cc_state == PD_CC_NONE && pd_timer_is_expired(port, TC_TIMER_PD_DEBOUNCE)) { /* We are detached */ - if (drp_state[port] == PD_DRP_TOGGLE_OFF - || drp_state[port] == PD_DRP_FREEZE - || drp_state[port] == PD_DRP_FORCE_SINK) + if (drp_state[port] == PD_DRP_TOGGLE_OFF || + drp_state[port] == PD_DRP_FREEZE || + drp_state[port] == PD_DRP_FORCE_SINK) set_state_tc(port, TC_UNATTACHED_SNK); else set_state_tc(port, TC_UNATTACHED_SRC); @@ -2425,9 +2429,9 @@ static void tc_attach_wait_snk_run(const int port) } if (IS_ENABLED(CONFIG_USB_PE_SM) && - IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { + IS_ENABLED(CONFIG_USB_PD_ALT_MODE_DFP)) { hook_call_deferred(&pd_usb_billboard_deferred_data, - PD_T_AME); + PD_T_AME); } } } @@ -2471,7 +2475,7 @@ static void tc_attached_snk_entry(const int port) /* Change role to sink */ tc_set_power_role(port, PD_ROLE_SINK); tcpm_set_msg_header(port, tc[port].power_role, - tc[port].data_role); + tc[port].data_role); /* * Maintain VCONN supply state, whether ON or OFF, and its @@ -2490,11 +2494,10 @@ static void tc_attached_snk_entry(const int port) hook_notify(HOOK_USB_PD_CONNECT); if (IS_ENABLED(CONFIG_CHARGE_MANAGER)) { - tc[port].typec_curr = - usb_get_typec_current_limit(tc[port].polarity, - cc1, cc2); - typec_set_input_current_limit(port, - tc[port].typec_curr, TYPE_C_VOLTAGE); + tc[port].typec_curr = usb_get_typec_current_limit( + tc[port].polarity, cc1, cc2); + typec_set_input_current_limit(port, tc[port].typec_curr, + TYPE_C_VOLTAGE); /* * Start new connections as dedicated until source caps * are received, at which point the PE will update the @@ -2550,8 +2553,8 @@ static bool tc_snk_check_vbus_removed(const int port) TC_TIMER_VBUS_DEBOUNCE)) { pd_timer_enable(port, TC_TIMER_VBUS_DEBOUNCE, PD_T_FRS_VBUS_DEBOUNCE); - } else if (pd_timer_is_expired(port, - TC_TIMER_VBUS_DEBOUNCE)) { + } else if (pd_timer_is_expired( + port, TC_TIMER_VBUS_DEBOUNCE)) { set_state_tc(port, TC_UNATTACHED_SNK); return true; } @@ -2658,8 +2661,9 @@ static void tc_attached_snk_run(const int port) /* Perform Data Role Swap */ tc_set_data_role(port, - tc[port].data_role == PD_ROLE_UFP ? - PD_ROLE_DFP : PD_ROLE_UFP); + tc[port].data_role == PD_ROLE_UFP ? + PD_ROLE_DFP : + PD_ROLE_UFP); } /* @@ -2787,8 +2791,8 @@ static void tc_unattached_src_entry(const int port) */ tcpm_debug_detach(port); typec_select_pull(port, TYPEC_CC_RP); - typec_select_src_current_limit_rp(port, - typec_get_default_current_limit_rp(port)); + typec_select_src_current_limit_rp( + port, typec_get_default_current_limit_rp(port)); typec_update_cc(port); prev_data_role = tc[port].data_role; @@ -2806,10 +2810,11 @@ static void tc_unattached_src_entry(const int port) if (IS_ENABLED(CONFIG_CHARGE_MANAGER)) charge_manager_update_dualrole(port, CAP_UNKNOWN); - if (IS_ENABLED(CONFIG_USB_PE_SM)) { - CLR_FLAGS_ON_DISCONNECT(port); - tc_enable_pd(port, 0); - } +#ifdef CONFIG_USB_PE_SM + CLR_FLAGS_ON_DISCONNECT(port); + tc_enable_pd(port, 0); + tc[port].ps_reset_state = PS_STATE0; +#endif pd_timer_enable(port, TC_TIMER_NEXT_ROLE_SWAP, PD_T_DRP_SRC); } @@ -2983,9 +2988,8 @@ static void tc_attached_src_entry(const int port) if (TC_CHK_FLAG(port, TC_FLAGS_PR_SWAP_IN_PROGRESS)) { /* Change role to source */ tc_set_power_role(port, PD_ROLE_SOURCE); - tcpm_set_msg_header(port, - tc[port].power_role, - tc[port].data_role); + tcpm_set_msg_header(port, tc[port].power_role, + tc[port].data_role); /* Enable VBUS */ tc_src_power_on(port); @@ -3040,10 +3044,9 @@ static void tc_attached_src_entry(const int port) set_vconn(port, 0); if (IS_ENABLED(CONFIG_USBC_SS_MUX)) - usb_mux_set(port, - USB_PD_MUX_NONE, - USB_SWITCH_DISCONNECT, - tc[port].polarity); + usb_mux_set(port, USB_PD_MUX_NONE, + USB_SWITCH_DISCONNECT, + tc[port].polarity); } tc_enable_pd(port, 0); @@ -3093,7 +3096,8 @@ static void tc_attached_src_entry(const int port) if (IS_ENABLED(CONFIG_USBC_SS_MUX)) usb_mux_set(port, USB_PD_MUX_NONE, - USB_SWITCH_DISCONNECT, tc[port].polarity); + USB_SWITCH_DISCONNECT, + tc[port].polarity); } } @@ -3161,13 +3165,13 @@ static void tc_attached_src_run(const int port) if (IS_ENABLED(CONFIG_USB_PD_TRY_SRC)) tryWait = is_try_src_enabled(port) && - !TC_CHK_FLAG(port, TC_FLAGS_TS_DTS_PARTNER); + !TC_CHK_FLAG(port, TC_FLAGS_TS_DTS_PARTNER); if (drp_state[port] == PD_DRP_FORCE_SOURCE) new_tc_state = TC_UNATTACHED_SRC; - else if(IS_ENABLED(CONFIG_USB_PD_TRY_SRC)) - new_tc_state = tryWait ? - TC_TRY_WAIT_SNK : TC_UNATTACHED_SNK; + else if (IS_ENABLED(CONFIG_USB_PD_TRY_SRC)) + new_tc_state = tryWait ? TC_TRY_WAIT_SNK : + TC_UNATTACHED_SNK; set_state_tc(port, new_tc_state); return; @@ -3221,8 +3225,9 @@ static void tc_attached_src_run(const int port) /* Perform Data Role Swap */ tc_set_data_role(port, - tc[port].data_role == PD_ROLE_DFP ? - PD_ROLE_UFP : PD_ROLE_DFP); + tc[port].data_role == PD_ROLE_DFP ? + PD_ROLE_UFP : + PD_ROLE_DFP); } /* @@ -3230,7 +3235,7 @@ static void tc_attached_src_run(const int port) * UnorientedDebugAccessory.SRC shall not drive Vconn */ if (IS_ENABLED(CONFIG_USBC_VCONN) && - !TC_CHK_FLAG(port, TC_FLAGS_TS_DTS_PARTNER)) { + !TC_CHK_FLAG(port, TC_FLAGS_TS_DTS_PARTNER)) { /* * VCONN Swap Request */ @@ -3239,7 +3244,7 @@ static void tc_attached_src_run(const int port) set_vconn(port, 1); pe_vconn_swap_complete(port); } else if (TC_CHK_FLAG(port, - TC_FLAGS_REQUEST_VC_SWAP_OFF)) { + TC_FLAGS_REQUEST_VC_SWAP_OFF)) { TC_CLR_FLAG(port, TC_FLAGS_REQUEST_VC_SWAP_OFF); set_vconn(port, 0); pe_vconn_swap_complete(port); @@ -3265,8 +3270,7 @@ static void tc_attached_src_run(const int port) * applied. */ if (!TC_CHK_FLAG(port, TC_FLAGS_TS_DTS_PARTNER) && - TC_CHK_FLAG(port, TC_FLAGS_CTVPD_DETECTED)) { - + TC_CHK_FLAG(port, TC_FLAGS_CTVPD_DETECTED)) { set_state_tc(port, TC_CT_UNATTACHED_SNK); } } @@ -3274,13 +3278,13 @@ static void tc_attached_src_run(const int port) if (TC_CHK_FLAG(port, TC_FLAGS_UPDATE_CURRENT)) { TC_CLR_FLAG(port, TC_FLAGS_UPDATE_CURRENT); - typec_set_source_current_limit(port, - tc[port].select_current_limit_rp); + typec_set_source_current_limit( + port, tc[port].select_current_limit_rp); pd_update_contract(port); /* Update Rp if no contract is present */ if (!IS_ENABLED(CONFIG_USB_PE_SM) || - !pe_is_explicit_contract(port)) + !pe_is_explicit_contract(port)) typec_update_cc(port); } } @@ -3302,7 +3306,7 @@ static void tc_attached_src_exit(const int port) * a CTVPD was not detected */ if (TC_CHK_FLAG(port, TC_FLAGS_VCONN_ON) && - !TC_CHK_FLAG(port, TC_FLAGS_CTVPD_DETECTED)) + !TC_CHK_FLAG(port, TC_FLAGS_CTVPD_DETECTED)) set_vconn(port, 0); } @@ -3332,14 +3336,14 @@ static __maybe_unused void check_drp_connection(const int port) tc[port].drp_sink_time = get_time().val; /* Get the next toggle state */ - next_state = drp_auto_toggle_next_state(&tc[port].drp_sink_time, - tc[port].power_role, drp_state[port], cc1, cc2, - tcpm_auto_toggle_supported(port)); + next_state = drp_auto_toggle_next_state( + &tc[port].drp_sink_time, tc[port].power_role, drp_state[port], + cc1, cc2, tcpm_auto_toggle_supported(port)); if (next_state == DRP_TC_DEFAULT) - next_state = (PD_ROLE_DEFAULT(port) == PD_ROLE_SOURCE) - ? DRP_TC_UNATTACHED_SRC - : DRP_TC_UNATTACHED_SNK; + next_state = (PD_ROLE_DEFAULT(port) == PD_ROLE_SOURCE) ? + DRP_TC_UNATTACHED_SRC : + DRP_TC_UNATTACHED_SNK; switch (next_state) { case DRP_TC_UNATTACHED_SNK: @@ -3491,8 +3495,8 @@ static void tc_try_src_entry(const int port) */ typec_select_pull(port, TYPEC_CC_RP); - typec_select_src_current_limit_rp(port, - typec_get_default_current_limit_rp(port)); + typec_select_src_current_limit_rp( + port, typec_get_default_current_limit_rp(port)); /* Apply Rp */ typec_update_cc(port); @@ -3507,7 +3511,7 @@ static void tc_try_src_run(const int port) tcpm_get_cc(port, &cc1, &cc2); if ((cc1 == TYPEC_CC_VOLT_RD && cc2 != TYPEC_CC_VOLT_RD) || - (cc1 != TYPEC_CC_VOLT_RD && cc2 == TYPEC_CC_VOLT_RD)) + (cc1 != TYPEC_CC_VOLT_RD && cc2 == TYPEC_CC_VOLT_RD)) new_cc_state = PD_CC_UFP_ATTACHED; else new_cc_state = PD_CC_NONE; @@ -3801,7 +3805,6 @@ static void tc_cc_rd_entry(const int port) tcpm_set_msg_header(port, tc[port].power_role, tc[port].data_role); } - /** * Super State CC_RP */ @@ -3887,8 +3890,8 @@ void tc_run(const int port) * If pd_set_suspend set TC_FLAGS_REQUEST_SUSPEND, go directly to * TC_DISABLED. */ - if (get_state_tc(port) != TC_DISABLED - && TC_CHK_FLAG(port, TC_FLAGS_REQUEST_SUSPEND)) { + if (get_state_tc(port) != TC_DISABLED && + TC_CHK_FLAG(port, TC_FLAGS_REQUEST_SUSPEND)) { /* Invalidate a contract, if there is one */ if (IS_ENABLED(CONFIG_USB_PE_SM)) pe_invalidate_explicit_contract(port); @@ -3918,17 +3921,16 @@ static void pd_chipset_resume(void) int i; for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { - if(IS_ENABLED(CONFIG_USB_PE_SM)) + if (IS_ENABLED(CONFIG_USB_PE_SM)) pd_resume_check_pr_swap_needed(i); - pd_set_dual_role_and_event(i, - pd_get_drp_state_in_s0(), - PD_EVENT_UPDATE_DUAL_ROLE - | PD_EVENT_POWER_STATE_CHANGE); + pd_set_dual_role_and_event(i, pd_get_drp_state_in_s0(), + PD_EVENT_UPDATE_DUAL_ROLE | + PD_EVENT_POWER_STATE_CHANGE); if (tc[i].data_role == PD_ROLE_DFP) { pd_send_alert_msg(i, ADO_EXTENDED_ALERT_EVENT | - ADO_POWER_STATE_CHANGE); + ADO_POWER_STATE_CHANGE); } } @@ -3941,14 +3943,13 @@ static void pd_chipset_suspend(void) int i; for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { - pd_set_dual_role_and_event(i, - pd_get_drp_state_in_suspend(), - PD_EVENT_UPDATE_DUAL_ROLE - | PD_EVENT_POWER_STATE_CHANGE); + pd_set_dual_role_and_event(i, pd_get_drp_state_in_suspend(), + PD_EVENT_UPDATE_DUAL_ROLE | + PD_EVENT_POWER_STATE_CHANGE); if (tc[i].data_role == PD_ROLE_DFP) { pd_send_alert_msg(i, ADO_EXTENDED_ALERT_EVENT | - ADO_POWER_STATE_CHANGE); + ADO_POWER_STATE_CHANGE); } } @@ -3974,12 +3975,15 @@ static void pd_chipset_reset(void) * kernel knows to consume discovery information for them. */ for (tx = TCPCI_MSG_SOP; tx <= TCPCI_MSG_SOP_PRIME; tx++) { - if (pd_get_identity_discovery(i, tx) != PD_DISC_NEEDED - && pd_get_svids_discovery(i, tx) != PD_DISC_NEEDED - && pd_get_modes_discovery(i, tx) != PD_DISC_NEEDED) - pd_notify_event(i, tx == TCPCI_MSG_SOP ? - PD_STATUS_EVENT_SOP_DISC_DONE : - PD_STATUS_EVENT_SOP_PRIME_DISC_DONE); + if (pd_get_identity_discovery(i, tx) != + PD_DISC_NEEDED && + pd_get_svids_discovery(i, tx) != PD_DISC_NEEDED && + pd_get_modes_discovery(i, tx) != PD_DISC_NEEDED) + pd_notify_event( + i, + tx == TCPCI_MSG_SOP ? + PD_STATUS_EVENT_SOP_DISC_DONE : + PD_STATUS_EVENT_SOP_PRIME_DISC_DONE); } /* Exit mode so AP can enter mode again after reset */ @@ -3995,10 +3999,9 @@ static void pd_chipset_startup(void) for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { TC_SET_FLAG(i, TC_FLAGS_UPDATE_USB_MUX); - pd_set_dual_role_and_event(i, - pd_get_drp_state_in_suspend(), - PD_EVENT_UPDATE_DUAL_ROLE - | PD_EVENT_POWER_STATE_CHANGE); + pd_set_dual_role_and_event(i, pd_get_drp_state_in_suspend(), + PD_EVENT_UPDATE_DUAL_ROLE | + PD_EVENT_POWER_STATE_CHANGE); /* * Request port discovery to restore any * alt modes. @@ -4010,7 +4013,7 @@ static void pd_chipset_startup(void) if (tc[i].data_role == PD_ROLE_DFP) { pd_send_alert_msg(i, ADO_EXTENDED_ALERT_EVENT | - ADO_POWER_STATE_CHANGE); + ADO_POWER_STATE_CHANGE); } } @@ -4024,14 +4027,13 @@ static void pd_chipset_shutdown(void) for (i = 0; i < CONFIG_USB_PD_PORT_MAX_COUNT; i++) { TC_SET_FLAG(i, TC_FLAGS_UPDATE_USB_MUX); - pd_set_dual_role_and_event(i, - PD_DRP_FORCE_SINK, - PD_EVENT_UPDATE_DUAL_ROLE - | PD_EVENT_POWER_STATE_CHANGE); + pd_set_dual_role_and_event(i, PD_DRP_FORCE_SINK, + PD_EVENT_UPDATE_DUAL_ROLE | + PD_EVENT_POWER_STATE_CHANGE); if (tc[i].data_role == PD_ROLE_DFP) { pd_send_alert_msg(i, ADO_EXTENDED_ALERT_EVENT | - ADO_POWER_STATE_CHANGE); + ADO_POWER_STATE_CHANGE); } } diff --git a/common/usbc/usb_tc_vpd_sm.c b/common/usbc/usb_tc_vpd_sm.c index 70f3ed6327..40b855db9b 100644 --- a/common/usbc/usb_tc_vpd_sm.c +++ b/common/usbc/usb_tc_vpd_sm.c @@ -1,8 +1,9 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. +/* Copyright 2019 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ +#include "builtin/assert.h" #include "common.h" #include "console.h" #include "system.h" @@ -17,15 +18,15 @@ /* USB Type-C VCONN Powered Device module */ #ifdef CONFIG_COMMON_RUNTIME -#define CPRINTF(format, args...) cprintf(CC_USB, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USB, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USB, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USB, format, ##args) #else /* CONFIG_COMMON_RUNTIME */ #define CPRINTF(format, args...) #define CPRINTS(format, args...) #endif /* Type-C Layer Flags */ -#define TC_FLAGS_VCONN_ON BIT(0) +#define TC_FLAGS_VCONN_ON BIT(0) /** * This is the Type-C Port object that contains information needed to @@ -61,7 +62,7 @@ enum usb_tc_state { static const struct usb_state tc_states[]; /* List of human readable state names for console debugging */ -__maybe_unused static const char * const tc_state_names[] = { +__maybe_unused static const char *const tc_state_names[] = { #ifdef CONFIG_COMMON_RUNTIME [TC_DISABLED] = "Disabled", [TC_UNATTACHED_SNK] = "Unattached.SNK", @@ -270,11 +271,11 @@ static void tc_attach_wait_snk_run(const int port) if (tc[port].host_cc_state != host_new_cc_state) { tc[port].host_cc_state = host_new_cc_state; if (host_new_cc_state == PD_CC_DFP_ATTACHED) - tc[port].cc_debounce = get_time().val + - PD_T_CC_DEBOUNCE; + tc[port].cc_debounce = + get_time().val + PD_T_CC_DEBOUNCE; else - tc[port].cc_debounce = get_time().val + - PD_T_PD_DEBOUNCE; + tc[port].cc_debounce = + get_time().val + PD_T_PD_DEBOUNCE; return; } @@ -293,7 +294,7 @@ static void tc_attach_wait_snk_run(const int port) * CC2 pins is SNK.Open for at least tPDDebounce. */ if (tc[port].host_cc_state == PD_CC_DFP_ATTACHED && - (vpd_is_vconn_present() || vpd_is_host_vbus_present())) + (vpd_is_vconn_present() || vpd_is_host_vbus_present())) set_state_tc(port, TC_ATTACHED_SNK); else if (tc[port].host_cc_state == PD_CC_NONE) set_state_tc(port, TC_UNATTACHED_SNK); diff --git a/common/usbc/usbc_pd_policy.c b/common/usbc/usbc_pd_policy.c index 6a06d4014f..6d82ed114c 100644 --- a/common/usbc/usbc_pd_policy.c +++ b/common/usbc/usbc_pd_policy.c @@ -1,4 +1,4 @@ -/* Copyright 2021 The Chromium OS Authors. All rights reserved. +/* Copyright 2021 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -19,8 +19,8 @@ * 1) If dr_swap_to_dfp_flag == true and port data role is UFP, * transition to pe_drs_send_swap */ -__overridable bool port_discovery_dr_swap_policy(int port, - enum pd_data_role dr, bool dr_swap_flag) +__overridable bool port_discovery_dr_swap_policy(int port, enum pd_data_role dr, + bool dr_swap_flag) { if (dr_swap_flag && dr == PD_ROLE_UFP) return true; @@ -37,10 +37,10 @@ __overridable bool port_discovery_dr_swap_policy(int port, * then transition to pe_vcs_send_swap */ __overridable bool port_discovery_vconn_swap_policy(int port, - bool vconn_swap_flag) + bool vconn_swap_flag) { if (IS_ENABLED(CONFIG_USBC_VCONN) && vconn_swap_flag && - !tc_is_vconn_src(port) && tc_check_vconn_swap(port)) + !tc_is_vconn_src(port) && tc_check_vconn_swap(port)) return true; /* Do not perform a VCONN swap */ diff --git a/common/usbc/usbc_task.c b/common/usbc/usbc_task.c index 915827b692..56ea3d4d10 100644 --- a/common/usbc/usbc_task.c +++ b/common/usbc/usbc_task.c @@ -1,4 +1,4 @@ -/* Copyright 2019 The Chromium OS Authors. All rights reserved. +/* Copyright 2019 The ChromiumOS Authors * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ @@ -6,6 +6,7 @@ #include "battery.h" #include "battery_smart.h" #include "board.h" +#include "builtin/assert.h" #include "charge_manager.h" #include "charge_state.h" #include "chipset.h" @@ -36,8 +37,8 @@ #define USBC_EVENT_TIMEOUT (5 * MSEC) #define USBC_MIN_EVENT_TIMEOUT (1 * MSEC) -#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args) -#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args) +#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ##args) +#define CPRINTS(format, args...) cprints(CC_USBPD, format, ##args) /* * If CONFIG_ASSERT_CCD_MODE_ON_DTS_CONNECT is not defined then |