diff options
-rw-r--r-- | baseboard/volteer/usb_pd_policy.c | 137 | ||||
-rw-r--r-- | include/usb_pd.h | 8 | ||||
-rw-r--r-- | include/usb_pd_vdo.h | 107 |
3 files changed, 250 insertions, 2 deletions
diff --git a/baseboard/volteer/usb_pd_policy.c b/baseboard/volteer/usb_pd_policy.c index 39bbd918a5..a18e8c7149 100644 --- a/baseboard/volteer/usb_pd_policy.c +++ b/baseboard/volteer/usb_pd_policy.c @@ -4,9 +4,11 @@ */ /* Shared USB-C policy for Volteer boards */ #include "charge_manager.h" +#include "chipset.h" #include "compile_time_macros.h" #include "console.h" #include "gpio.h" +#include "usb_common.h" #include "usb_mux.h" #include "usbc_ppc.h" #include "usb_pd.h" @@ -79,3 +81,138 @@ int board_vbus_source_enabled(int port) { return ppc_is_sourcing_vbus(port); } + +/* ----------------- Vendor Defined Messages ------------------ */ +/* Responses specifically for the enablement of TBT mode in the role of UFP */ + +#define OPOS_TBT 1 +static union tbt_dev_mode_enter_cmd + ufp_enter_mode[CONFIG_USB_PD_PORT_MAX_COUNT]; + +static const union tbt_mode_resp_device vdo_tbt_modes[1] = { + { + .tbt_alt_mode = 0x0001, + .tbt_adapter = TBT_ADAPTER_TBT3, + .intel_spec_b0 = 0, + .vendor_spec_b0 = 0, + .vendor_spec_b1 = 0, + } +}; + +static const uint32_t vdo_idh = VDO_IDH( + 1, /* Data caps as USB host */ + 1, /* Data caps as USB device */ + IDH_PTYPE_PERIPH, + 1, /* Supports alt modes */ + USB_VID_GOOGLE); + +static const uint32_t vdo_idh_rev30 = VDO_IDH_REV30( + 1, /* Data caps as USB host */ + 1, /* Data caps as USB device */ + IDH_PTYPE_PERIPH, + 1, /* Supports alt modes */ + IDH_PTYPE_DFP_HOST, + USB_TYPEC_RECEPTACLE, + USB_VID_GOOGLE); + +/* TODO(b:157163664): add product version */ +static const uint32_t vdo_product = VDO_PRODUCT(CONFIG_USB_PID, 0); + +/* TODO(b/168890624): add USB4 to capability once USB4 response implemented */ +static const uint32_t vdo_ufp1 = VDO_UFP1( + (VDO_UFP1_CAPABILITY_USB20 + | VDO_UFP1_CAPABILITY_USB32), + USB_TYPEC_RECEPTACLE, + VDO_UFP1_ALT_MODE_TBT3, + USB_R30_SS_U40_GEN3); + +static const uint32_t vdo_dfp = VDO_DFP( + (VDO_DFP_HOST_CAPABILITY_USB20 + | VDO_DFP_HOST_CAPABILITY_USB32 + | VDO_DFP_HOST_CAPABILITY_USB4), + USB_TYPEC_RECEPTACLE, + 1 /* Port 1 */); + +static int svdm_tbt_compat_response_identity(int port, uint32_t *payload) +{ + /* TODO(b/154962766): Get an XID */ + payload[VDO_I(CSTAT)] = VDO_CSTAT(0); + payload[VDO_I(PRODUCT)] = vdo_product; + + if (pd_get_rev(port, TCPC_TX_SOP) == PD_REV30) { + /* PD Revision 3.0 */ + payload[VDO_I(IDH)] = vdo_idh_rev30; + payload[VDO_I(PTYPE_UFP1_VDO)] = vdo_ufp1; + /* TODO(b/156749387): Find power number for USB3/4 */ + payload[VDO_I(PTYPE_UFP2_VDO)] = 0; + payload[VDO_I(PTYPE_DFP_VDO)] = vdo_dfp; + return VDO_I(PTYPE_DFP_VDO) + 1; + } + + /* PD Revision 2.0 */ + payload[VDO_I(IDH)] = vdo_idh; + return VDO_I(PRODUCT) + 1; +} + +static int svdm_tbt_compat_response_svids(int port, uint32_t *payload) +{ + payload[1] = VDO_SVID(USB_VID_INTEL, 0); + return 2; +} + +static int svdm_tbt_compat_response_modes(int port, uint32_t *payload) +{ + if (PD_VDO_VID(payload[0]) == USB_VID_INTEL) { + memcpy(payload + 1, vdo_tbt_modes, sizeof(vdo_tbt_modes)); + return ARRAY_SIZE(vdo_tbt_modes) + 1; + } else { + return 0; /* NAK */ + } +} + +static int svdm_tbt_compat_response_enter_mode( + int port, uint32_t *payload) +{ + mux_state_t mux_state = 0; + + /* Do not enter mode while CPU is off. */ + if (chipset_in_or_transitioning_to_state(CHIPSET_STATE_ANY_OFF)) + return 0; /* NAK */ + + if ((PD_VDO_VID(payload[0]) != USB_VID_INTEL) || + (PD_VDO_OPOS(payload[0]) != OPOS_TBT)) + return 0; /* NAK */ + + mux_state = usb_mux_get(port); + /* + * Ref: USB PD 3.0 Spec figure 6-21 Successful Enter Mode sequence + * UFP (responder) should be in USB mode or safe mode before sending + * Enter Mode Command response. + */ + if ((mux_state & USB_PD_MUX_USB_ENABLED) || + (mux_state & USB_PD_MUX_SAFE_MODE)) { + + /* + * TODO(b:157163664): set retimer config for UFP + * Save TBT3 SOP VDO from request so retimer can use it + */ + ufp_enter_mode[port] = + (union tbt_dev_mode_enter_cmd)payload[1]; + + set_tbt_compat_mode_ready(port); + CPRINTS("UFP Enter TBT mode"); + return 1; /* ACK */ + } + + CPRINTS("UFP failed to enter TBT mode(mux=0x%x)", mux_state); + return 0; +} + +const struct svdm_response svdm_rsp = { + .identity = &svdm_tbt_compat_response_identity, + .svids = &svdm_tbt_compat_response_svids, + .modes = &svdm_tbt_compat_response_modes, + .enter_mode = &svdm_tbt_compat_response_enter_mode, + .amode = NULL, + .exit_mode = NULL, +}; diff --git a/include/usb_pd.h b/include/usb_pd.h index 19ae64b45f..8222a93e4d 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -527,15 +527,21 @@ struct partner_active_modes { #define VDO_INDEX_AMA 4 #define VDO_INDEX_PTYPE_UFP1_VDO 4 #define VDO_INDEX_PTYPE_CABLE1 4 -#define VDO_INDEX_PTYPE_UFP2_VDO 4 +#define VDO_INDEX_PTYPE_UFP2_VDO 5 #define VDO_INDEX_PTYPE_CABLE2 5 #define VDO_INDEX_PTYPE_DFP_VDO 6 #define VDO_I(name) VDO_INDEX_##name +/* PD Rev 2.0 ID Header VDO */ #define VDO_IDH(usbh, usbd, ptype, is_modal, vid) \ ((usbh) << 31 | (usbd) << 30 | ((ptype) & 0x7) << 27 \ | (is_modal) << 26 | ((vid) & 0xffff)) +/* PD Rev 3.0 ID Header VDO */ +#define VDO_IDH_REV30(usbh, usbd, ptype_u, is_modal, ptype_d, ctype, vid) \ + (VDO_IDH(usbh, usbd, ptype_u, is_modal, vid) \ + | ((ptype_d) & 0x7) << 23 | ((ctype) & 0x3) << 21) + #define PD_IDH_PTYPE(vdo) (((vdo) >> 27) & 0x7) #define PD_IDH_IS_MODAL(vdo) (((vdo) >> 26) & 0x1) #define PD_IDH_VID(vdo) ((vdo) & 0xffff) diff --git a/include/usb_pd_vdo.h b/include/usb_pd_vdo.h index 76772ef893..b0773ae7e7 100644 --- a/include/usb_pd_vdo.h +++ b/include/usb_pd_vdo.h @@ -19,12 +19,62 @@ * ############################################################################ * * Reference: USB Power Delivery Specification Revision 3.0, Version 2.0 + * Updated to ECN released on Feb 07, 2020 * * ############################################################################ */ /*****************************************************************************/ /* + * Table 6-29 ID Header VDO + * ------------------------------------------------------------- + * <31> : USB Communications Capable as USB Host + * <30> : USB Communications Capable as a USB Device + * <29:27> : Product Type (UFP): + * 000b = Undefined + * 001b = PDUSB Hub + * 010b = PDUSB Peripheral + * 011b = PSD (PD 3.0) + * 101b = Alternate Mode Adapter (AMA) + * 110b = Vconn-Powered USB Device (VPD, PD 3.0) + * 111b = Reserved, shall NOT be used + * + * Product Type (Cable Plug): + * 000b = Undefined + * 001b...010b = Reserved, Shall NOT be used + * 011b = Passive Cable + * 100b = Active Cable + * 101b...111b = Reserved, Shall NOT be used + * <26> : Modal Operation Supported + * <25:23> : Product Type (DFP): + * 000b = Undefined + * 001b = PDUSB Hub + * 010b = PDUSB Host + * 011b = Power Brick + * 100b = Alternate Mode Controller (AMC) + * 101b...111b = Reserved, Shall NOT be used + * <22:21> : Connector Type + * 00b = Reserved for compatibility with legacy systems + * 01b = Reserved, Shall Not be used + * 10b = USB Type-C Receptacle + * 11b = USB Type-C Captive Plug + * <20:16> : Reserved + * <15:0> : USB Vendor ID + */ +enum connector_type { + USB_TYPEC_RECEPTACLE = 2, + USB_TYPEC_CAPTIVE_PLUG, +}; + +enum idh_ptype_dfp { + IDH_PTYPE_DFP_UNDEFINED, + IDH_PTYPE_DFP_HUB, + IDH_PTYPE_DFP_HOST, + IDH_PTYPE_DFP_POWER_BRICK, + IDH_PTYPE_DFP_AMC, +}; +/*****************************************************************************/ +/* * Table 6-33 Cert Stat VDO (Note: same as Revision 2.0) * ------------------------------------------------------------- * <31:0> : XID assigned by USB-IF @@ -50,13 +100,21 @@ struct product_vdo { * Table 6-35 UFP VDO 1 * ------------------------------------------------------------- * <31:29> : UFP VDO version + * Version 1.0 = 000b + * Version 1.1 = 001b + * Values 010b...111b are Reserved and Shall Not be used * <28> : Reserved * <27:24> : Device Capability * 0001b = USB2.0 Device capable * 0010b = USB2.0 Device capable (Billboard only) * 0100b = USB3.2 Device capable * 1000b = USB4 Device Capable - * <23:6> : Reserved + * <23:22> : Connector Type + * 00b = Reserved, Shall Not be used + * 01b = Reserved, Shall Not be used + * 10b = USB Type-C Receptacle + * 11b = USB Type-C Captive Plug + * <21:6> : Reserved * <5:3> : Alternate Modes * 001b = Supports TBT3 alternate mode * 010b = Supports Alternate Modes that reconfigure @@ -75,6 +133,53 @@ struct product_vdo { #define PD_PRODUCT_IS_USB4(vdo) ((vdo) >> 24 & BIT(3)) #define PD_PRODUCT_IS_TBT3(vdo) ((vdo) >> 3 & BIT(0)) +/* UFP VDO Version 1.1; update the value when UFP VDO version changes */ +#define VDO_UFP1(cap, ctype, alt, speed) \ + ((0x1) << 29 | ((cap) & 0xf) << 24 \ + | ((ctype) & 0x3) << 22 | ((alt) & 0x7) << 3 | ((speed) & 0x7)) + +/* UFP VDO 1 Alternate Modes */ +#define VDO_UFP1_ALT_MODE_TBT3 BIT(0) +#define VDO_UFP1_ALT_MODE_RECONFIGURE BIT(1) +#define VDO_UFP1_ALT_MODE_NO_RECONFIGURE BIT(2) + +/* UFP VDO 1 Device Capability */ +#define VDO_UFP1_CAPABILITY_USB20 BIT(0) +#define VDO_UFP1_CAPABILITY_USB20_BILLBOARD BIT(1) +#define VDO_UFP1_CAPABILITY_USB32 BIT(2) +#define VDO_UFP1_CAPABILITY_USB4 BIT(3) +/*****************************************************************************/ +/* + * Table 6-37 DFP VDO + * ------------------------------------------------------------- + * <31:29> : DFP VDO version + * Version 1.0 = 000b + * Version 1.1 = 001b + * Values 010b...111b are Reserved and Shall Not be used + * <28:27> : Reserved + * <26:24> : Host Capability + * 001b = USB2.0 host capable + * 010b = USB3.2 host capable + * 100b = USB4 host capable + * <23:22> : Connector Type + * 00b = Reserved, Shall Not be used + * 01b = Reserved, Shall Not be used + * 10b = USB Type-C Receptacle + * 11b = USB Type-C Captive Plug + * <21:5> : Reserved + * <4:0> : Port number + */ +/* DFP VDO Version 1.1; update the value when DFP VDO version changes */ +#define VDO_DFP(cap, ctype, port) \ + ((0x1) << 29 | ((cap) & 0x7) << 24 \ + | ((ctype) & 0x3) << 22 | ((port) & 0x1f)) + +/* DFP VDO Host Capability */ +#define VDO_DFP_HOST_CAPABILITY_USB20 BIT(0) +#define VDO_DFP_HOST_CAPABILITY_USB32 BIT(1) +#define VDO_DFP_HOST_CAPABILITY_USB4 BIT(2) + + /*****************************************************************************/ /* * Table 6-38 Passive Cable VDO |