summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorli feng <li1.feng@intel.com>2020-08-21 15:23:28 -0700
committerCommit Bot <commit-bot@chromium.org>2020-12-21 22:07:31 +0000
commitfe951556a7be3bc68b342dc941be13ff4f82f41b (patch)
tree7af452c46edf37398d1419a7cd5d263a1c70781b
parent774cfcbb675455973bb4d7856633d065f5c674fb (diff)
downloadchrome-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>
-rw-r--r--baseboard/volteer/usb_pd_policy.c137
-rw-r--r--include/usb_pd.h8
-rw-r--r--include/usb_pd_vdo.h107
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