diff options
Diffstat (limited to 'common/usb_pd_alt_mode_dfp.c')
-rw-r--r-- | common/usb_pd_alt_mode_dfp.c | 436 |
1 files changed, 7 insertions, 429 deletions
diff --git a/common/usb_pd_alt_mode_dfp.c b/common/usb_pd_alt_mode_dfp.c index 6df0215274..caba71bb31 100644 --- a/common/usb_pd_alt_mode_dfp.c +++ b/common/usb_pd_alt_mode_dfp.c @@ -163,6 +163,7 @@ void pd_prepare_sysjump(void) #endif /* CONFIG_ZEPHYR */ } +#ifdef CONFIG_USB_PD_DP_MODE /* * This algorithm defaults to choosing higher pin config over lower ones in * order to prefer multi-function if desired. @@ -226,6 +227,7 @@ int pd_dfp_dp_get_pin_mode(int port, uint32_t status) return 1 << get_next_bit(&pin_caps); } +#endif /* CONFIG_USB_PD_DP_MODE */ struct svdm_amode_data *pd_get_amode_data(int port, enum tcpci_msg_type type, uint16_t svid) @@ -324,23 +326,6 @@ int pd_dfp_exit_mode(int port, enum tcpci_msg_type type, uint16_t svid, return 1; } -/* - * Check if the SVID has been recorded previously. Some peripherals provide - * duplicated SVID. - */ -static bool is_svid_duplicated(const struct pd_discovery *disc, uint16_t svid) -{ - int i; - - for (i = 0; i < disc->svid_cnt; ++i) - if (disc->svids[i].svid == svid) { - CPRINTF("ERR:SVIDDUP\n"); - return true; - } - - return false; -} - void dfp_consume_attention(int port, uint32_t *payload) { uint16_t svid = PD_VDO_VID(payload[0]); @@ -355,143 +340,6 @@ void dfp_consume_attention(int port, uint32_t *payload) modep->fx->attention(port, payload); } -void dfp_consume_identity(int port, enum tcpci_msg_type type, int cnt, - uint32_t *payload) -{ - int ptype; - struct pd_discovery *disc; - size_t identity_size; - - if (type == TCPCI_MSG_SOP_PRIME && - !IS_ENABLED(CONFIG_USB_PD_DECODE_SOP)) { - CPRINTF("ERR:Unexpected cable response\n"); - return; - } - - ptype = PD_IDH_PTYPE(payload[VDO_I(IDH)]); - disc = pd_get_am_discovery_and_notify_access(port, type); - identity_size = - MIN(sizeof(union disc_ident_ack), (cnt - 1) * sizeof(uint32_t)); - - /* Note: only store VDOs, not the VDM header */ - memcpy(disc->identity.raw_value, payload + 1, identity_size); - disc->identity_cnt = identity_size / sizeof(uint32_t); - - switch (ptype) { - case IDH_PTYPE_AMA: - /* Leave vbus ON if the following macro is false */ - if (IS_ENABLED(CONFIG_USB_PD_DUAL_ROLE) && - IS_ENABLED(CONFIG_USBC_VCONN_SWAP)) { - /* Adapter is requesting vconn, try to supply it */ - if (PD_VDO_AMA_VCONN_REQ(payload[VDO_I(AMA)])) - pd_try_vconn_src(port); - - /* Only disable vbus if vconn was requested */ - if (PD_VDO_AMA_VCONN_REQ(payload[VDO_I(AMA)]) && - !PD_VDO_AMA_VBUS_REQ(payload[VDO_I(AMA)])) - pd_power_supply_reset(port); - } - break; - default: - break; - } - pd_set_identity_discovery(port, type, PD_DISC_COMPLETE); -} - -void dfp_consume_svids(int port, enum tcpci_msg_type type, int cnt, - uint32_t *payload) -{ - int i; - uint32_t *ptr = payload + 1; - int vdo = 1; - uint16_t svid0, svid1; - struct pd_discovery *disc = - pd_get_am_discovery_and_notify_access(port, type); - - for (i = disc->svid_cnt; i < disc->svid_cnt + 12; i += 2) { - if (i >= SVID_DISCOVERY_MAX) { - CPRINTF("ERR:SVIDCNT\n"); - break; - } - /* - * Verify we're still within the valid packet (count will be one - * for the VDM header + xVDOs) - */ - if (vdo >= cnt) - break; - - svid0 = PD_VDO_SVID_SVID0(*ptr); - if (!svid0) - break; - - if (!is_svid_duplicated(disc, svid0)) - disc->svids[disc->svid_cnt++].svid = svid0; - - svid1 = PD_VDO_SVID_SVID1(*ptr); - if (!svid1) - break; - - if (!is_svid_duplicated(disc, svid1)) - disc->svids[disc->svid_cnt++].svid = svid1; - - ptr++; - vdo++; - } - /* TODO(tbroch) need to re-issue discover svids if > 12 */ - if (i && ((i % 12) == 0)) - CPRINTF("ERR:SVID+12\n"); - - pd_set_svids_discovery(port, type, PD_DISC_COMPLETE); -} - -void dfp_consume_modes(int port, enum tcpci_msg_type type, int cnt, - uint32_t *payload) -{ - int svid_idx; - struct svid_mode_data *mode_discovery = NULL; - struct pd_discovery *disc = - pd_get_am_discovery_and_notify_access(port, type); - uint16_t response_svid = (uint16_t)PD_VDO_VID(payload[0]); - - for (svid_idx = 0; svid_idx < disc->svid_cnt; ++svid_idx) { - uint16_t svid = disc->svids[svid_idx].svid; - - if (svid == response_svid) { - mode_discovery = &disc->svids[svid_idx]; - break; - } - } - if (!mode_discovery) { - const struct svid_mode_data *requested_mode_data = - pd_get_next_mode(port, type); - CPRINTF("C%d: Mode response for undiscovered SVID %x, but TCPM " - "requested SVID %x\n", - port, response_svid, requested_mode_data->svid); - /* - * Although SVIDs discovery seemed like it succeeded before, the - * partner is now responding with undiscovered SVIDs. Discovery - * cannot reasonably continue under these circumstances. - */ - pd_set_modes_discovery(port, type, requested_mode_data->svid, - PD_DISC_FAIL); - return; - } - - mode_discovery->mode_cnt = cnt - 1; - if (mode_discovery->mode_cnt < 1) { - CPRINTF("ERR:NOMODE\n"); - pd_set_modes_discovery(port, type, mode_discovery->svid, - PD_DISC_FAIL); - return; - } - - memcpy(mode_discovery->mode_vdo, &payload[1], - sizeof(uint32_t) * mode_discovery->mode_cnt); - disc->svid_idx++; - pd_set_modes_discovery(port, type, mode_discovery->svid, - PD_DISC_COMPLETE); -} - int pd_alt_mode(int port, enum tcpci_msg_type type, uint16_t svid) { struct svdm_amode_data *modep = pd_get_amode_data(port, type, svid); @@ -499,200 +347,6 @@ int pd_alt_mode(int port, enum tcpci_msg_type type, uint16_t svid) return (modep) ? modep->opos : -1; } -void pd_set_identity_discovery(int port, enum tcpci_msg_type type, - enum pd_discovery_state disc) -{ - struct pd_discovery *pd = - pd_get_am_discovery_and_notify_access(port, type); - - pd->identity_discovery = disc; -} - -enum pd_discovery_state pd_get_identity_discovery(int port, - enum tcpci_msg_type type) -{ - const struct pd_discovery *disc = pd_get_am_discovery(port, type); - - return disc->identity_discovery; -} - -const union disc_ident_ack *pd_get_identity_response(int port, - enum tcpci_msg_type type) -{ - if (type >= DISCOVERY_TYPE_COUNT) - return NULL; - - return &pd_get_am_discovery(port, type)->identity; -} - -uint16_t pd_get_identity_vid(int port) -{ - const union disc_ident_ack *resp = - pd_get_identity_response(port, TCPCI_MSG_SOP); - - return resp->idh.usb_vendor_id; -} - -uint16_t pd_get_identity_pid(int port) -{ - const union disc_ident_ack *resp = - pd_get_identity_response(port, TCPCI_MSG_SOP); - - return resp->product.product_id; -} - -uint8_t pd_get_product_type(int port) -{ - const union disc_ident_ack *resp = - pd_get_identity_response(port, TCPCI_MSG_SOP); - - return resp->idh.product_type; -} - -void pd_set_svids_discovery(int port, enum tcpci_msg_type type, - enum pd_discovery_state disc) -{ - struct pd_discovery *pd = - pd_get_am_discovery_and_notify_access(port, type); - - pd->svids_discovery = disc; -} - -enum pd_discovery_state pd_get_svids_discovery(int port, - enum tcpci_msg_type type) -{ - const struct pd_discovery *disc = pd_get_am_discovery(port, type); - - return disc->svids_discovery; -} - -int pd_get_svid_count(int port, enum tcpci_msg_type type) -{ - const struct pd_discovery *disc = pd_get_am_discovery(port, type); - - return disc->svid_cnt; -} - -uint16_t pd_get_svid(int port, uint16_t svid_idx, enum tcpci_msg_type type) -{ - const struct pd_discovery *disc = pd_get_am_discovery(port, type); - - return disc->svids[svid_idx].svid; -} - -void pd_set_modes_discovery(int port, enum tcpci_msg_type type, uint16_t svid, - enum pd_discovery_state disc) -{ - struct pd_discovery *pd = - pd_get_am_discovery_and_notify_access(port, type); - int svid_idx; - - for (svid_idx = 0; svid_idx < pd->svid_cnt; ++svid_idx) { - struct svid_mode_data *mode_data = &pd->svids[svid_idx]; - - if (mode_data->svid != svid) - continue; - - mode_data->discovery = disc; - return; - } -} - -enum pd_discovery_state pd_get_modes_discovery(int port, - enum tcpci_msg_type type) -{ - const struct svid_mode_data *mode_data = pd_get_next_mode(port, type); - - /* - * If there are no SVIDs for which to discover modes, mode discovery is - * trivially complete. - */ - if (!mode_data) - return PD_DISC_COMPLETE; - - return mode_data->discovery; -} - -int pd_get_mode_vdo_for_svid(int port, enum tcpci_msg_type type, uint16_t svid, - uint32_t *vdo_out) -{ - int idx; - const struct pd_discovery *disc; - - if (type >= DISCOVERY_TYPE_COUNT) - return 0; - - disc = pd_get_am_discovery(port, type); - - for (idx = 0; idx < disc->svid_cnt; ++idx) { - if (pd_get_svid(port, idx, type) == svid) { - memcpy(vdo_out, disc->svids[idx].mode_vdo, - sizeof(uint32_t) * disc->svids[idx].mode_cnt); - return disc->svids[idx].mode_cnt; - } - } - return 0; -} - -const struct svid_mode_data *pd_get_next_mode(int port, - enum tcpci_msg_type type) -{ - const struct pd_discovery *disc = pd_get_am_discovery(port, type); - const struct svid_mode_data *failed_mode_data = NULL; - bool svid_good_discovery = false; - int svid_idx; - - /* Walk through all of the discovery mode entries */ - for (svid_idx = 0; svid_idx < disc->svid_cnt; ++svid_idx) { - const struct svid_mode_data *mode_data = &disc->svids[svid_idx]; - - /* Discovery is needed, so send this one back now */ - if (mode_data->discovery == PD_DISC_NEEDED) - return mode_data; - - /* Discovery already succeeded, save that it was seen */ - if (mode_data->discovery == PD_DISC_COMPLETE) - svid_good_discovery = true; - /* Discovery already failed, save first failure */ - else if (!failed_mode_data) - failed_mode_data = mode_data; - } - - /* If no good entries were located, then return last failed */ - if (!svid_good_discovery) - return failed_mode_data; - - /* - * Mode discovery has been attempted for every discovered SVID (if - * any exist) - */ - return NULL; -} - -const uint32_t *pd_get_mode_vdo(int port, uint16_t svid_idx, - enum tcpci_msg_type type) -{ - const struct pd_discovery *disc = pd_get_am_discovery(port, type); - - return disc->svids[svid_idx].mode_vdo; -} - -bool pd_is_mode_discovered_for_svid(int port, enum tcpci_msg_type type, - uint16_t svid) -{ - const struct pd_discovery *disc = pd_get_am_discovery(port, type); - const struct svid_mode_data *mode_data; - - for (mode_data = disc->svids; mode_data < disc->svids + disc->svid_cnt; - ++mode_data) { - if (mode_data->svid == svid && - mode_data->discovery == PD_DISC_COMPLETE) - return true; - } - - return false; -} - void notify_sysjump_ready(void) { /* @@ -703,86 +357,7 @@ void notify_sysjump_ready(void) task_set_event(sysjump_task_waiting, TASK_EVENT_SYSJUMP_READY); } -static inline bool is_pd_rev3(int port, enum tcpci_msg_type type) -{ - return pd_get_rev(port, type) == PD_REV30; -} - -/* - * ############################################################################ - * - * (Charge Through) Vconn Powered Device functions - * - * ############################################################################ - */ -bool is_vpd_ct_supported(int port) -{ - const struct pd_discovery *disc = - pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME); - union vpd_vdo vpd = disc->identity.product_t1.vpd; - - return vpd.ct_support; -} - -/* - * ############################################################################ - * - * Cable communication functions - * - * ############################################################################ - */ -enum idh_ptype get_usb_pd_cable_type(int port) -{ - const struct pd_discovery *disc = - pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME); - - return disc->identity.idh.product_type; -} - -bool is_usb2_cable_support(int port) -{ - const struct pd_discovery *disc = - pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME); - - return disc->identity.idh.product_type == IDH_PTYPE_PCABLE || - pd_get_vdo_ver(port, TCPCI_MSG_SOP_PRIME) < VDM_VER20 || - disc->identity.product_t2.a2_rev30.usb_20_support == - USB2_SUPPORTED; -} - -bool is_cable_speed_gen2_capable(int port) -{ - const struct pd_discovery *disc = - pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME); - - switch (pd_get_rev(port, TCPCI_MSG_SOP_PRIME)) { - case PD_REV20: - return disc->identity.product_t1.p_rev20.ss == - USB_R20_SS_U31_GEN1_GEN2; - - case PD_REV30: - return 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; - default: - return false; - } -} - -bool is_active_cable_element_retimer(int port) -{ - const struct pd_discovery *disc = - pd_get_am_discovery(port, TCPCI_MSG_SOP_PRIME); - - /* Ref: USB PD Spec 2.0 Table 6-29 Active Cable VDO - * Revision 2 Active cables do not have Active element support. - */ - return is_pd_rev3(port, TCPCI_MSG_SOP_PRIME) && - disc->identity.idh.product_type == IDH_PTYPE_ACABLE && - disc->identity.product_t2.a2_rev30.active_elem == ACTIVE_RETIMER; -} - +#ifdef CONFIG_USB_PD_DP_MODE __overridable void svdm_safe_dp_mode(int port) { /* make DP interface safe until configure */ @@ -1040,6 +615,7 @@ __overridable void svdm_exit_dp_mode(int port) baseboard_mst_enable_control(port, 0); #endif } +#endif /* CONFIG_USB_PD_DP_MODE */ #ifdef CONFIG_USB_PD_TCPMV1 __overridable int svdm_enter_gfu_mode(int port, uint32_t mode_caps) @@ -1104,6 +680,7 @@ __overridable int svdm_tbt_compat_attention(int port, uint32_t *payload) * configuration to Device Policy Manager. */ const struct svdm_amode_fx supported_modes[] = { +#ifdef CONFIG_USB_PD_DP_MODE { .svid = USB_SID_DISPLAYPORT, .enter = &svdm_enter_dp_mode, @@ -1113,6 +690,7 @@ const struct svdm_amode_fx supported_modes[] = { .attention = &svdm_dp_attention, .exit = &svdm_exit_dp_mode, }, +#endif /* CONFIG_USB_PD_DP_MODE */ #ifdef CONFIG_USB_PD_TCPMV1 { .svid = USB_VID_GOOGLE, @@ -1136,7 +714,7 @@ const struct svdm_amode_fx supported_modes[] = { }; const int supported_modes_cnt = ARRAY_SIZE(supported_modes); -#ifdef CONFIG_CMD_MFALLOW +#if defined(CONFIG_CMD_MFALLOW) static int command_mfallow(int argc, const char **argv) { char *e; |