summaryrefslogtreecommitdiff
path: root/baseboard/volteer/usb_pd_policy.c
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 /baseboard/volteer/usb_pd_policy.c
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>
Diffstat (limited to 'baseboard/volteer/usb_pd_policy.c')
-rw-r--r--baseboard/volteer/usb_pd_policy.c137
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,
+};