diff options
author | li feng <li1.feng@intel.com> | 2020-08-21 15:23:28 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2020-12-21 22:07:31 +0000 |
commit | fe951556a7be3bc68b342dc941be13ff4f82f41b (patch) | |
tree | 7af452c46edf37398d1419a7cd5d263a1c70781b /baseboard/volteer | |
parent | 774cfcbb675455973bb4d7856633d065f5c674fb (diff) | |
download | chrome-ec-fe951556a7be3bc68b342dc941be13ff4f82f41b.tar.gz |
TCPMv2: support TBT Alt mode as UFP
Implemented SVDM responders for TBT Alt mode
BUG=b:148528713,b:157163664,b:162986785
BRANCH=none
TEST=1. Build ec with CL:2382634; OS CPFE 13447, CB CPFE 13535
2. Boot up Volteer, run "pd trysrc 0" on EC console;
3. Then connect port 1 to TGL Windows RVP TBT port;
4. Thunderbolt connection is established. Volteer port 1 as UFP,
Windows RVP TBT port as DFP. From host console, thunderbolt0 is
listed as network interface in ifconfig.
Signed-off-by: li feng <li1.feng@intel.com>
Change-Id: If4c80418677f541e9c1c7c8c84446357000aaecb
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2370045
Reviewed-by: Vijay P Hiremath <vijay.p.hiremath@intel.com>
Reviewed-by: Aashay Shringarpure <aashay@google.com>
Diffstat (limited to 'baseboard/volteer')
-rw-r--r-- | baseboard/volteer/usb_pd_policy.c | 137 |
1 files changed, 137 insertions, 0 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, +}; |