summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVijay Hiremath <vijay.p.hiremath@intel.com>2019-11-15 12:38:54 -0800
committerCommit Bot <commit-bot@chromium.org>2019-11-21 17:40:25 +0000
commit1809c272d0cd9db68990926a7f0b0168a0bda418 (patch)
treee9d9ce6d21b5011e70e8b747ee59b0a6b21ea2d9
parenta335be1cc1041dcb01bb0f9e523fe2bea39f1819 (diff)
downloadchrome-ec-1809c272d0cd9db68990926a7f0b0168a0bda418.tar.gz
volteer: Add USB-C policy
BUG=b:140578872 BRANCH=none TEST=USB2.0 & USB3.0 device detected over Type-C port 0 Change-Id: I44790aac3543589c32dcd60f84e4e67d5d76cdab Signed-off-by: Vijay Hiremath <vijay.p.hiremath@intel.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1922752 Reviewed-by: Keith Short <keithshort@chromium.org> Signed-off-by: Keith Short <keithshort@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1929379
-rw-r--r--baseboard/volteer/baseboard.c2
-rw-r--r--baseboard/volteer/baseboard.h3
-rw-r--r--baseboard/volteer/usb_pd_policy.c189
-rw-r--r--board/volteer/board.h8
-rw-r--r--board/volteer/gpio.inc4
5 files changed, 194 insertions, 12 deletions
diff --git a/baseboard/volteer/baseboard.c b/baseboard/volteer/baseboard.c
index 04451dff5a..a5057c4396 100644
--- a/baseboard/volteer/baseboard.c
+++ b/baseboard/volteer/baseboard.c
@@ -184,6 +184,7 @@ const struct tcpc_config_t tcpc_config[] = {
.addr_flags = TUSB422_I2C_ADDR_FLAGS,
},
.drv = &tusb422_tcpm_drv,
+ .usb23 = USBC_PORT_0_USB2_NUM | (USBC_PORT_0_USB3_NUM << 4),
},
};
BUILD_ASSERT(ARRAY_SIZE(tcpc_config) == USBC_PORT_COUNT);
@@ -206,6 +207,7 @@ unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
struct usb_mux usb_muxes[] = {
[USBC_PORT_C0] = {
.driver = &virtual_usb_mux_driver,
+ .hpd_update = &virtual_hpd_update,
},
};
BUILD_ASSERT(ARRAY_SIZE(usb_muxes) == USBC_PORT_COUNT);
diff --git a/baseboard/volteer/baseboard.h b/baseboard/volteer/baseboard.h
index 4d3936b6cd..0b51affc7b 100644
--- a/baseboard/volteer/baseboard.h
+++ b/baseboard/volteer/baseboard.h
@@ -88,6 +88,8 @@
#define CONFIG_USB_TYPEC_DRP_ACC_TRYSRC
#define CONFIG_USB_POWER_DELIVERY
+#define CONFIG_USB_PD_ALT_MODE
+#define CONFIG_USB_PD_ALT_MODE_DFP
#define CONFIG_USB_PD_DISCHARGE_PPC
#define CONFIG_USB_PD_DUAL_ROLE
#define CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT TYPEC_RP_3A0
@@ -108,6 +110,7 @@
*/
#define CONFIG_USBC_PPC_SN5S330 /* USBC port C0 */
+#define CONFIG_INTEL_VIRTUAL_MUX
#define CONFIG_USBC_SS_MUX
#define CONFIG_USB_MUX_VIRTUAL
diff --git a/baseboard/volteer/usb_pd_policy.c b/baseboard/volteer/usb_pd_policy.c
index ac424984e4..3d01f37e4e 100644
--- a/baseboard/volteer/usb_pd_policy.c
+++ b/baseboard/volteer/usb_pd_policy.c
@@ -24,18 +24,20 @@
const uint32_t pd_src_pdo[] = {
PDO_FIXED(5000, 1500, PDO_FIXED_FLAGS),
};
+const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
+
const uint32_t pd_src_pdo_max[] = {
PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS),
};
const int pd_src_pdo_max_cnt = ARRAY_SIZE(pd_src_pdo_max);
-const int pd_src_pdo_cnt = ARRAY_SIZE(pd_src_pdo);
const uint32_t pd_snk_pdo[] = {
PDO_FIXED(5000, 500, PDO_FIXED_FLAGS),
PDO_BATT(4750, 21000, 15000),
PDO_VAR(4750, 21000, 3000),
};
const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
+
int pd_check_data_swap(int port, int data_role)
{
/* Allow data swap if we are a UFP, otherwise don't allow. */
@@ -44,30 +46,41 @@ int pd_check_data_swap(int port, int data_role)
int pd_check_power_swap(int port)
{
- /* TODO - check correct operation for Volteer */
-
/*
* Allow power swap if we are acting as a dual role device. If we are
* not acting as dual role (ex. suspended), then only allow power swap
* if we are sourcing when we could be sinking.
*/
- if (pd_get_dual_role(port) == PD_DRP_TOGGLE_ON)
- return 1;
- else if (pd_get_role(port) == PD_ROLE_SOURCE)
- return 1;
- else
- return 0;
+ return (pd_get_dual_role(port) == PD_DRP_TOGGLE_ON ||
+ pd_get_role(port) == PD_ROLE_SOURCE);
}
int pd_check_vconn_swap(int port)
{
- /* TODO - check correct operation for Volteer */
- return 0;
+ /* Only allow vconn swap if pp5000_A rail is enabled */
+ return gpio_get_level(GPIO_EN_PP5000_A);
}
void pd_power_supply_reset(int port)
{
- /* TODO - check correct operation for Volteer */
+ int prev_en;
+
+ prev_en = ppc_is_sourcing_vbus(port);
+
+ /* Disable VBUS. */
+ ppc_vbus_source_enable(port, 0);
+
+ /* Enable discharge if we were previously sourcing 5V */
+ if (prev_en)
+ pd_set_vbus_discharge(port, 1);
+
+#ifdef CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT
+ /* Give back the current quota we are no longer using */
+ charge_manager_source_port(port, 0);
+#endif /* defined(CONFIG_USB_PD_MAX_SINGLE_SOURCE_CURRENT) */
+
+ /* Notify host of power info change. */
+ pd_send_host_event(PD_EVENT_POWER_CHANGE);
}
void pd_execute_data_swap(int port, int data_role)
@@ -207,4 +220,156 @@ int pd_custom_vdm(int port, int cnt, uint32_t *payload,
return 0;
}
+/* CONFIG_USB_PD_ALT_MODE_DFP */
+static int dp_flags[CONFIG_USB_PD_PORT_MAX_COUNT];
+static uint32_t dp_status[CONFIG_USB_PD_PORT_MAX_COUNT];
+
+static void svdm_safe_dp_mode(int port)
+{
+ /* make DP interface safe until configure */
+ dp_flags[port] = 0;
+ dp_status[port] = 0;
+
+ usb_mux_set(port, TYPEC_MUX_SAFE,
+ USB_SWITCH_CONNECT, pd_get_polarity(port));
+}
+
+static int svdm_enter_dp_mode(int port, uint32_t mode_caps)
+{
+ /* Only enter mode if device is DFP_D capable */
+ if (mode_caps & MODE_DP_SNK) {
+ svdm_safe_dp_mode(port);
+ return 0;
+ }
+
+ return -1;
+}
+
+static int svdm_dp_status(int port, uint32_t *payload)
+{
+ int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT);
+
+ payload[0] = VDO(USB_SID_DISPLAYPORT, 1,
+ CMD_DP_STATUS | VDO_OPOS(opos));
+ payload[1] = VDO_DP_STATUS(0, /* HPD IRQ ... not applicable */
+ 0, /* HPD level ... not applicable */
+ 0, /* exit DP? ... no */
+ 0, /* usb mode? ... no */
+ 0, /* multi-function ... no */
+ (!!(dp_flags[port] & DP_FLAGS_DP_ON)),
+ 0, /* power low? ... no */
+ (!!(dp_flags[port] & DP_FLAGS_DP_ON)));
+ return 2;
+};
+
+uint8_t board_get_dp_pin_mode(int port)
+{
+ return (uint8_t) pd_dfp_dp_get_pin_mode(port, dp_status[port]);
+}
+
+static int svdm_dp_config(int port, uint32_t *payload)
+{
+ int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT);
+ int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status[port]);
+ uint8_t pin_mode = board_get_dp_pin_mode(port);
+
+ if (!pin_mode)
+ return 0;
+
+ usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP,
+ USB_SWITCH_CONNECT, pd_get_polarity(port));
+
+ payload[0] = VDO(USB_SID_DISPLAYPORT, 1,
+ CMD_DP_CONFIG | VDO_OPOS(opos));
+ payload[1] = VDO_DP_CFG(pin_mode, /* pin mode */
+ 1, /* DPv1.3 signaling */
+ 2); /* UFP connected */
+ return 2;
+};
+
+static void svdm_dp_post_config(int port)
+{
+ const struct usb_mux *mux = &usb_muxes[port];
+
+ dp_flags[port] |= DP_FLAGS_DP_ON;
+ if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING))
+ return;
+ mux->hpd_update(port, 1, 0);
+}
+
+static int svdm_dp_attention(int port, uint32_t *payload)
+{
+ int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
+ int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
+ const struct usb_mux *mux = &usb_muxes[port];
+
+ dp_status[port] = payload[1];
+ if (!(dp_flags[port] & DP_FLAGS_DP_ON)) {
+ if (lvl)
+ dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING;
+ return 1;
+ }
+ mux->hpd_update(port, lvl, irq);
+
+ /* ack */
+ return 1;
+}
+
+static void svdm_exit_dp_mode(int port)
+{
+ const struct usb_mux *mux = &usb_muxes[port];
+
+ svdm_safe_dp_mode(port);
+ mux->hpd_update(port, 0, 0);
+}
+
+static int svdm_enter_gfu_mode(int port, uint32_t mode_caps)
+{
+ /* Always enter GFU mode */
+ return 0;
+}
+
+static void svdm_exit_gfu_mode(int port)
+{
+}
+
+static int svdm_gfu_status(int port, uint32_t *payload)
+{
+ /*
+ * This is called after enter mode is successful, send unstructured
+ * VDM to read info.
+ */
+ pd_send_vdm(port, USB_VID_GOOGLE, VDO_CMD_READ_INFO, NULL, 0);
+ return 0;
+}
+
+static int svdm_gfu_config(int port, uint32_t *payload)
+{
+ return 0;
+}
+
+static int svdm_gfu_attention(int port, uint32_t *payload)
+{
+ return 0;
+}
+const struct svdm_amode_fx supported_modes[] = {
+ {
+ .svid = USB_SID_DISPLAYPORT,
+ .enter = &svdm_enter_dp_mode,
+ .status = &svdm_dp_status,
+ .config = &svdm_dp_config,
+ .post_config = &svdm_dp_post_config,
+ .attention = &svdm_dp_attention,
+ .exit = &svdm_exit_dp_mode,
+ },
+ {
+ .svid = USB_VID_GOOGLE,
+ .enter = &svdm_enter_gfu_mode,
+ .status = &svdm_gfu_status,
+ .config = &svdm_gfu_config,
+ .attention = &svdm_gfu_attention,
+ .exit = &svdm_exit_gfu_mode,
+ }
+};
+const int supported_modes_cnt = ARRAY_SIZE(supported_modes);
diff --git a/board/volteer/board.h b/board/volteer/board.h
index 06d13e1526..737b0b62ff 100644
--- a/board/volteer/board.h
+++ b/board/volteer/board.h
@@ -38,6 +38,14 @@
/* Sensors */
/* USB Type C and USB PD defines */
+/*
+ * USB-C port's USB2 & USB3 mapping from schematics
+ * USB2 numbering on PCH - 1 to n
+ * USB3 numbering on AP - 0 to n (PMC's USB3 numbering for MUX
+ * configuration is - 1 to n hence add +1)
+ */
+#define USBC_PORT_0_USB2_NUM 9
+#define USBC_PORT_0_USB3_NUM 1
/* USB Type A Features */
diff --git a/board/volteer/gpio.inc b/board/volteer/gpio.inc
index 359a651d7e..e8327b8e5e 100644
--- a/board/volteer/gpio.inc
+++ b/board/volteer/gpio.inc
@@ -115,6 +115,10 @@ GPIO(EC_I2C7_EEPROM_SDA, PIN(B, 2), GPIO_INPUT)
/* Battery signals */
GPIO(EC_BATT_PRES_ODL, PIN(E, 1), GPIO_INPUT)
+/* Physical HPD pins are not needed on EC as these are configured by PMC */
+GPIO(USB_C0_DP_HPD, PIN(F, 3), GPIO_INPUT)
+GPIO(USB_C1_DP_HPD, PIN(7, 0), GPIO_INPUT)
+
/* Alternate functions GPIO definitions */
ALTERNATE(PIN_MASK(B, BIT(5) | BIT(4)), 0, MODULE_I2C, (GPIO_INPUT | GPIO_SEL_1P8V)) /* I2C0 */
ALTERNATE(PIN_MASK(9, BIT(0) | BIT(2) | BIT(1)), 0, MODULE_I2C, 0) /* I2C1 SCL / I2C2 */