summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorScott Collyer <scollyer@google.com>2021-02-16 13:38:33 -0800
committerCommit Bot <commit-bot@chromium.org>2021-03-24 23:33:07 +0000
commit2cee0e2eb293cea2ccc1ae782de85480dc04d808 (patch)
treeaf410ddfd0b033f7029aafadc8de03effbb65e67
parent1403ddcbbdea6a55db88465659af5f0cc79ace82 (diff)
downloadchrome-ec-2cee0e2eb293cea2ccc1ae782de85480dc04d808.tar.gz
honeybuns: Add full usb-pd support for C0
This CL adds config options and board level structs to fully support USB-PD on port C0 for both gingerbread and quiche. This includes all the svdm response functions required for support of DP Alt-mode as a UFP_D. This also includes honeybuns specific version of usb-pd policy functions. BUG=b:175660576 BRANCH=None TEST=Verify that C0 port can establish PD contract, enter ALT-DP mode and extend display over DP/HDMI connectors. Signed-off-by: Scott Collyer <scollyer@google.com> Change-Id: I11edee85e63381f00114e9fbe012a37fd8174279 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/2699455 Tested-by: Scott Collyer <scollyer@chromium.org> Reviewed-by: Diana Z <dzigterman@chromium.org> Commit-Queue: Scott Collyer <scollyer@chromium.org>
-rw-r--r--baseboard/honeybuns/baseboard.c8
-rw-r--r--baseboard/honeybuns/baseboard.h31
-rw-r--r--baseboard/honeybuns/usb_pd_policy.c345
-rw-r--r--board/gingerbread/board.c48
-rw-r--r--board/gingerbread/board.h6
-rw-r--r--board/gingerbread/ec.tasklist1
-rw-r--r--board/gingerbread/gpio.inc4
-rw-r--r--board/quiche/board.c47
-rw-r--r--board/quiche/board.h5
-rw-r--r--board/quiche/gpio.inc2
-rw-r--r--include/usb_pd_vdo.h4
11 files changed, 458 insertions, 43 deletions
diff --git a/baseboard/honeybuns/baseboard.c b/baseboard/honeybuns/baseboard.c
index 4b256b6aa3..3edbc2bf3e 100644
--- a/baseboard/honeybuns/baseboard.c
+++ b/baseboard/honeybuns/baseboard.c
@@ -8,7 +8,10 @@
#include "gpio.h"
#include "hooks.h"
#include "i2c.h"
+#include "usb_pd.h"
+#include "system.h"
#include "timer.h"
+#include "util.h"
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
@@ -42,7 +45,10 @@ static void baseboard_init(void)
CPRINTS("board: Power rails enabled");
#ifdef SECTION_IS_RW
-
+ /* Force TC state machine to start in TC_ERROR_RECOVERY */
+ system_clear_reset_flags(EC_RESET_FLAG_POWER_ON);
+ /* Make certain SN5S330 PPC does full initialization */
+ system_set_reset_flags(EC_RESET_FLAG_EFS);
#else
/* Set up host port usbc to present Rd on CC lines */
if(baseboard_usbc_init(USB_PD_PORT_HOST))
diff --git a/baseboard/honeybuns/baseboard.h b/baseboard/honeybuns/baseboard.h
index 32ecf32d23..1e7a7faba1 100644
--- a/baseboard/honeybuns/baseboard.h
+++ b/baseboard/honeybuns/baseboard.h
@@ -87,6 +87,7 @@
#define CONFIG_CROS_BOARD_INFO
#define CONFIG_BOARD_VERSION_CBI
#define CONFIG_CMD_CBI
+#define CONFIG_CMD_CBI_SET
/* USB Configuration */
#define CONFIG_USB
@@ -127,30 +128,34 @@ enum usb_strings {
#define CONFIG_USB_DRP_ACC_TRYSRC
/* No AP on any honeybuns variants */
#undef CONFIG_USB_PD_HOST_CMD
-
-/* TODO(b/167711550): Temporarily support type-c mode only */
-#undef CONFIG_USB_PRL_SM
-#undef CONFIG_USB_PE_SM
-
-#define CONFIG_USB_PD_DUAL_ROLE
#define CONFIG_USB_PD_PORT_MAX_COUNT 1
+#define CONFIG_USB_PD_ALT_MODE
+#define CONFIG_USB_PD_ALT_MODE_DFP
+#define CONFIG_USB_PD_CUSTOM_PDO
+#define CONFIG_USB_PD_ALT_MODE_UFP_DP
+#define CONFIG_USB_PD_DUAL_ROLE
+#define CONFIG_USB_PD_REV30
#define CONFIG_USB_PD_TCPM_MUX
+#define CONFIG_USB_PD_TCPM_PS8805
#define CONFIG_USB_PD_TCPM_STM32GX
#define CONFIG_USB_PD_TCPM_TCPCI
#define CONFIG_USB_PD_DECODE_SOP
-
#define CONFIG_USB_PD_VBUS_DETECT_PPC
#define CONFIG_USB_PD_DISCHARGE_PPC
#define CONFIG_USBC_PPC_SN5S330
#define CONFIG_USBC_PPC_VCONN
#define CONFIG_USBC_PPC_DEDICATED_INT
-#define CONFIG_CMD_PPC_DUMP
+#define CONFIG_USBC_VCONN
+#define CONFIG_USBC_VCONN_SWAP
+#define CONFIG_USBC_SS_MUX
+#define CONFIG_USBC_SS_MUX_UFP_USB3
+#define CONFIG_HAS_TASK_PD_INT
#define CONFIG_STM32G4_UCPD_DEBUG
+#define CONFIG_CMD_PPC_DUMP
+#define CONFIG_CMD_TCPC_DUMP
-/* TODO(b/167711550): Temporary, will be replaced by correct mux config */
-#define CONFIG_USBC_SS_MUX
-#define CONFIG_USB_MUX_VIRTUAL
+#define CONFIG_MP4245
#else /* RO Specific Config Options */
@@ -179,9 +184,9 @@ enum usb_strings {
#define CONFIG_SHA256
/* Define typical operating power and max power. */
-#define PD_MAX_VOLTAGE_MV 20000
+#define PD_MAX_VOLTAGE_MV 5000
#define PD_MAX_CURRENT_MA 3000
-#define PD_MAX_POWER_MW 45000
+#define PD_MAX_POWER_MW 15000
#define PD_OPERATING_POWER_MW 15000
/* TODO(b:147314141): Verify these timings */
diff --git a/baseboard/honeybuns/usb_pd_policy.c b/baseboard/honeybuns/usb_pd_policy.c
index 0bf90995de..b638b8536d 100644
--- a/baseboard/honeybuns/usb_pd_policy.c
+++ b/baseboard/honeybuns/usb_pd_policy.c
@@ -5,18 +5,60 @@
#include "common.h"
#include "console.h"
+#include "chip/stm32/ucpd-stm32gx.h"
+#include "cros_board_info.h"
+#include "driver/mp4245.h"
#include "driver/tcpm/tcpci.h"
+#include "driver/mp4245.h"
+#include "task.h"
+#include "timer.h"
+#include "usb_common.h"
+#include "usb_mux.h"
#include "usb_pd.h"
+#include "usb_pd_dp_ufp.h"
#include "usbc_ppc.h"
#define CPRINTF(format, args...) cprintf(CC_USBPD, format, ## args)
#define CPRINTS(format, args...) cprints(CC_USBPD, format, ## args)
-/*
- * TODO(b/167711550): These 4 functions need to be implemented for honeybuns
- * and are required to build with TCPMv2 enabled. Currently, they only allow the
- * build to work. They will be implemented in a subsequent CL.
- */
+#define PDO_FIXED_FLAGS (PDO_FIXED_DUAL_ROLE | PDO_FIXED_DATA_SWAP |\
+ PDO_FIXED_COMM_CAP | PDO_FIXED_UNCONSTRAINED)
+
+/* Voltage indexes for the PDOs */
+enum volt_idx {
+ PDO_IDX_5V = 0,
+ PDO_IDX_9V = 1,
+ PDO_IDX_15V = 2,
+ PDO_IDX_20V = 3,
+ PDO_IDX_COUNT
+};
+
+/* PDOs */
+const uint32_t pd_src_host_pdo[] = {
+ [PDO_IDX_5V] = PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS),
+ [PDO_IDX_9V] = PDO_FIXED(9000, 3000, 0),
+ [PDO_IDX_15V] = PDO_FIXED(15000, 3000, 0),
+ [PDO_IDX_20V] = PDO_FIXED(20000, 3000, 0),
+};
+BUILD_ASSERT(ARRAY_SIZE(pd_src_host_pdo) == PDO_IDX_COUNT);
+
+/* PDOs */
+const uint32_t pd_snk_pdo[] = {
+ [PDO_IDX_5V] = PDO_FIXED(5000, 0, PDO_FIXED_FLAGS),
+};
+const int pd_snk_pdo_cnt = ARRAY_SIZE(pd_snk_pdo);
+
+int dpm_get_source_pdo(const uint32_t **src_pdo, const int port)
+{
+ int pdo_cnt = 0;
+
+ if (port == USB_PD_PORT_HOST) {
+ *src_pdo = pd_src_host_pdo;
+ pdo_cnt = ARRAY_SIZE(pd_src_host_pdo);
+ }
+
+ return pdo_cnt;
+}
int pd_check_vconn_swap(int port)
{
@@ -39,12 +81,25 @@ void pd_power_supply_reset(int port)
/* Enable discharge if we were previously sourcing 5V */
if (prev_en)
pd_set_vbus_discharge(port, 1);
+
+ if (port == USB_PD_PORT_HOST) {
+ /* Turn off voltage output from buck-boost */
+ mp4245_votlage_out_enable(0);
+ /* Reset VBUS voltage to default value (fixed 5V SRC_CAP) */
+ pd_transition_voltage(1);
+ }
}
int pd_set_power_supply_ready(int port)
{
int rv;
+ if (port == USB_PD_PORT_HOST) {
+ /* Ensure buck-boost is enabled and Vout is on */
+ mp4245_votlage_out_enable(1);
+ msleep(MP4245_VOUT_5V_DELAY_MS);
+ }
+
/*
* Default operation of buck-boost is 5v/3.6A.
* Turn on the PPC Provide Vbus.
@@ -56,6 +111,43 @@ int pd_set_power_supply_ready(int port)
return EC_SUCCESS;
}
+void pd_transition_voltage(int idx)
+{
+ int port = TASK_ID_TO_PD_PORT(task_get_current());
+
+ if (port == USB_PD_PORT_HOST) {
+ int mv;
+ int ma;
+ int vbus_hi;
+ int vbus_lo;
+ int i;
+
+ /*
+ * Set the VBUS output voltage and current limit to the values specified
+ * by the PDO requested by sink. Note that USB PD uses idx = 1 for 1st
+ * PDO of SRC_CAP which must always be 5V fixed supply.
+ */
+ pd_extract_pdo_power(pd_src_host_pdo[idx - 1], &ma, &mv);
+
+ /* Set VBUS level to value specified in the requested PDO */
+ mp4245_set_voltage_out(mv);
+ /* Wait for vbus to be within ~5% of its target value */
+ vbus_hi = mv + (mv >> 4);
+ vbus_lo = mv - (mv >> 4);
+
+ for (i = 0; i < 20; i++) {
+ int rv;
+
+ rv = mp3245_get_vbus(&mv, &ma);
+ if ((rv == EC_SUCCESS) && (mv >= vbus_lo) &&
+ (mv <= vbus_hi))
+ return;
+
+ msleep(2);
+ }
+ }
+}
+
int pd_snk_is_vbus_provided(int port)
{
return ppc_is_vbus_present(port);
@@ -71,3 +163,246 @@ void pd_set_input_current_limit(int port, uint32_t max_ma,
{
}
+
+int pd_check_data_swap(int port,
+ enum pd_data_role data_role)
+{
+ int swap = 0;
+
+ if (port == 0)
+ swap = (data_role == PD_ROLE_DFP);
+
+ return swap;
+}
+
+int pd_check_power_swap(int port)
+{
+
+ if (pd_get_power_role(port) == PD_ROLE_SINK)
+ return 1;
+
+ return 0;
+}
+
+static int vdm_is_dp_enabled(int port)
+{
+ mux_state_t mux_state = usb_mux_get(port);
+
+ return !!(mux_state & USB_PD_MUX_DP_ENABLED);
+}
+
+/* ----------------- Vendor Defined Messages ------------------ */
+
+const uint32_t vdo_idh = VDO_IDH(0, /* data caps as USB host */
+ 1, /* data caps as USB device */
+ IDH_PTYPE_HUB, /* UFP product type usbpd hub */
+ 1, /* supports alt modes */
+ USB_VID_GOOGLE);
+
+static const uint32_t vdo_idh_rev30 = VDO_IDH_REV30(
+ 0, /* Data caps as USB host */
+ 1, /* Data caps as USB device */
+ IDH_PTYPE_HUB,
+ 1, /* Supports alt modes */
+ IDH_PTYPE_DFP_UNDEFINED,
+ USB_TYPEC_RECEPTACLE,
+ USB_VID_GOOGLE);
+
+const uint32_t vdo_product = VDO_PRODUCT(CONFIG_USB_PID, CONFIG_USB_BCD_DEV);
+
+static const uint32_t vdo_ufp1 = VDO_UFP1(
+ (VDO_UFP1_CAPABILITY_USB20
+ | VDO_UFP1_CAPABILITY_USB32),
+ USB_TYPEC_RECEPTACLE,
+ VDO_UFP1_ALT_MODE_RECONFIGURE,
+ USB_R30_SS_U32_U40_GEN2);
+
+static int svdm_response_identity(int port, uint32_t *payload)
+{
+ int vdo_count;
+
+ /* Verify that SVID is PD SID */
+ if (PD_VDO_VID(payload[0]) != USB_SID_PD) {
+ return 0;
+ }
+
+ /* Cstat and Product VDOs don't depend on spec revision */
+ payload[VDO_INDEX_CSTAT] = VDO_CSTAT(0);
+ payload[VDO_INDEX_PRODUCT] = vdo_product;
+
+ if (pd_get_rev(port, TCPC_TX_SOP) == PD_REV30) {
+ /* PD Revision 3.0 */
+ payload[VDO_INDEX_IDH] = vdo_idh_rev30;
+ payload[VDO_INDEX_PTYPE_UFP1_VDO] = vdo_ufp1;
+ vdo_count = VDO_INDEX_PTYPE_UFP1_VDO;
+ } else {
+ payload[VDO_INDEX_IDH] = vdo_idh;
+ vdo_count = VDO_INDEX_PRODUCT;
+ }
+
+ /* Adjust VDO count for VDM header */
+ return vdo_count + 1;
+}
+
+static int svdm_response_svids(int port, uint32_t *payload)
+{
+ /* Verify that SVID is PD SID */
+ if (PD_VDO_VID(payload[0]) != USB_SID_PD) {
+ return 0;
+ }
+
+ payload[1] = USB_SID_DISPLAYPORT << 16;
+ /* number of data objects VDO header + 1 SVID for DP */
+ return 2;
+}
+
+#define OPOS_DP 1
+
+const uint32_t vdo_dp_modes[1] = {
+ VDO_MODE_DP(/* Must support C and E. D is required for 2 lanes */
+ MODE_DP_PIN_C | MODE_DP_PIN_D | MODE_DP_PIN_D,
+ 0, /* DFP pin cfg supported */
+ 1, /* no usb2.0 signalling in AMode */
+ CABLE_RECEPTACLE, /* its a receptacle */
+ MODE_DP_V13, /* DPv1.3 Support, no Gen2 */
+ MODE_DP_SNK) /* Its a sink only */
+};
+
+static int svdm_response_modes(int port, uint32_t *payload)
+{
+ if (PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT) {
+ memcpy(payload + 1, vdo_dp_modes, sizeof(vdo_dp_modes));
+ return ARRAY_SIZE(vdo_dp_modes) + 1;
+ } else {
+ return 0; /* nak */
+ }
+}
+
+static int amode_dp_status(int port, uint32_t *payload)
+{
+ int opos = PD_VDO_OPOS(payload[0]);
+ int hpd = gpio_get_level(GPIO_DP_HPD);
+ uint32_t fw_config;
+ int mf = 0;
+ int rv;
+
+ /* MF (multi function) preferece is indicated by bit 0 of the fw_config
+ * data field. If this data field does not exist, then default to 4 lane
+ * mode.
+ */
+ rv = cbi_get_fw_config(&fw_config);
+ if (!rv)
+ mf = fw_config & 1;
+
+ if (opos != OPOS_DP)
+ return 0; /* nak */
+
+ payload[1] = VDO_DP_STATUS(0, /* IRQ_HPD */
+ (hpd == 1), /* HPD_HI|LOW */
+ 0, /* request exit DP */
+ 0, /* request exit USB */
+ mf, /* MF pref */
+ vdm_is_dp_enabled(port),
+ 0, /* power low */
+ 0x2);
+ return 2;
+}
+
+static void svdm_configure_demux(int port, int enable, int mf)
+{
+ mux_state_t demux = usb_mux_get(port);
+
+ if (enable) {
+ demux |= USB_PD_MUX_DP_ENABLED;
+ /* 4 lane mode if MF is not preferred */
+ if (!mf)
+ demux &= ~USB_PD_MUX_USB_ENABLED;
+ } else {
+ demux &= ~USB_PD_MUX_DP_ENABLED;
+ demux |= USB_PD_MUX_USB_ENABLED;
+ }
+
+ /* Configure demux for 2/4 lane DP and USB3 configuration */
+ usb_mux_set(port, demux, USB_SWITCH_CONNECT, pd_get_polarity(port));
+}
+
+static int amode_dp_config(int port, uint32_t *payload)
+{
+ uint32_t dp_config = payload[1];
+ int mf;
+
+ /*
+ * Check pin assignment selected by DFP_D to determine if 2 lane or 4
+ * lane DP ALT-MODe is required. (note PIN_C is for 4 lane and PIN_D is
+ * for 2 lane mode).
+ */
+ mf = ((dp_config >> 8) & 0xff) == MODE_DP_PIN_D ? 1 : 0;
+ /* Configure demux for DP mode */
+ svdm_configure_demux(port, 1, mf);
+
+ return 1;
+}
+
+static int svdm_enter_mode(int port, uint32_t *payload)
+{
+ int rv = 0; /* will generate a NAK */
+
+ /* SID & mode request is valid */
+ if ((PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT) &&
+ (PD_VDO_OPOS(payload[0]) == OPOS_DP)) {
+
+ /* Store valid object position to indicate mode is active */
+ pd_ufp_set_dp_opos(port, OPOS_DP);
+
+ /* Entering ALT-DP mode, enable DP connection in demux */
+ usb_pd_hpd_converter_enable(1);
+
+ /* ACK response has 1 VDO */
+ rv = 1;
+ }
+
+ CPRINTS("svdm_enter[%d]: svid = %x, ret = %d", port,
+ PD_VDO_VID(payload[0]), rv);
+
+ return rv;
+}
+
+static int svdm_exit_mode(int port, uint32_t *payload)
+{
+ int opos = pd_ufp_get_dp_opos(port);
+
+ if ((PD_VDO_VID(payload[0]) == USB_SID_DISPLAYPORT) &&
+ (opos == OPOS_DP)) {
+ /* Clear mode active object position */
+ pd_ufp_set_dp_opos(port, 0);
+ /* Configure demux to disable DP mode */
+ svdm_configure_demux(port, 0, 0);
+ usb_pd_hpd_converter_enable(0);
+
+ return 1;
+ } else {
+ CPRINTF("Unknown exit mode req:0x%08x\n", payload[0]);
+ return 0;
+ }
+}
+
+static struct amode_fx dp_fx = {
+ .status = &amode_dp_status,
+ .config = &amode_dp_config,
+};
+
+const struct svdm_response svdm_rsp = {
+ .identity = &svdm_response_identity,
+ .svids = &svdm_response_svids,
+ .modes = &svdm_response_modes,
+ .enter_mode = &svdm_enter_mode,
+ .amode = &dp_fx,
+ .exit_mode = &svdm_exit_mode,
+};
+
+int pd_custom_vdm(int port, int cnt, uint32_t *payload,
+ uint32_t **rpayload)
+{
+ /* We don't support, so ignore this message */
+ return 0;
+}
diff --git a/board/gingerbread/board.c b/board/gingerbread/board.c
index 03d70a69d3..82f02da6d3 100644
--- a/board/gingerbread/board.c
+++ b/board/gingerbread/board.c
@@ -7,24 +7,34 @@
#include "common.h"
#include "driver/ppc/sn5s330.h"
+#include "driver/tcpm/ps8xxx.h"
#include "driver/tcpm/stm32gx.h"
#include "driver/tcpm/tcpci.h"
+#include "driver/usb_mux/tusb1064.h"
#include "ec_version.h"
#include "gpio.h"
#include "hooks.h"
+#include "mp4245.h"
#include "switch.h"
#include "system.h"
#include "task.h"
+#include "timer.h"
#include "uart.h"
#include "usb_descriptor.h"
#include "usb_pd.h"
#include "usbc_ppc.h"
+#include "usb_descriptor.h"
+#include "usb_pd_dp_ufp.h"
+#include "usb_pe_sm.h"
+#include "usb_prl_sm.h"
+#include "usb_tc_sm.h"
#include "util.h"
-
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
+#define QUICHE_PD_DEBUG_LVL 1
+
#ifdef SECTION_IS_RW
#define CROS_EC_SECTION "RW"
#else
@@ -32,6 +42,10 @@
#endif
#ifdef SECTION_IS_RW
+static int pd_dual_role_init[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+ PD_DRP_TOGGLE_ON,
+};
+
static void ppc_interrupt(enum gpio_signal signal)
{
switch (signal) {
@@ -44,6 +58,10 @@ static void ppc_interrupt(enum gpio_signal signal)
}
}
+void hpd_interrupt(enum gpio_signal signal)
+{
+ usb_pd_hpd_edge_event(signal);
+}
#endif /* SECTION_IS_RW */
#include "gpio_list.h" /* Must come after other header files. */
@@ -115,8 +133,9 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_HOST] = {
.usb_port = USB_PD_PORT_HOST,
- .driver = &virtual_usb_mux_driver,
- .hpd_update = &virtual_hpd_update,
+ .i2c_port = I2C_PORT_I2C1,
+ .i2c_addr_flags = TUSB1064_I2C_ADDR0_FLAGS,
+ .driver = &tusb1064_usb_mux_driver,
},
};
@@ -130,14 +149,35 @@ struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = {
};
unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
+const struct hpd_to_pd_config_t hpd_config = {
+ .port = USB_PD_PORT_HOST,
+ .signal = GPIO_DDI_MST_IN_HPD,
+};
+
+void board_reset_pd_mcu(void)
+{
+
+}
+
+
/* Power Delivery and charging functions */
void board_tcpc_init(void)
{
+ board_reset_pd_mcu();
+
/* Enable PPC interrupts. */
gpio_enable_interrupt(GPIO_HOST_USBC_PPC_INT_ODL);
+
+ /* Enable HPD interrupt */
+ gpio_enable_interrupt(GPIO_DDI_MST_IN_HPD);
+
}
-DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 1);
+DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 2);
+enum pd_dual_role_states board_tc_get_initial_drp_mode(int port)
+{
+ return pd_dual_role_init[port];
+}
int ppc_get_alert_status(int port)
{
diff --git a/board/gingerbread/board.h b/board/gingerbread/board.h
index 75780a3fb2..1c5983cf68 100644
--- a/board/gingerbread/board.h
+++ b/board/gingerbread/board.h
@@ -20,7 +20,9 @@
/* USB Type C and USB PD defines */
#define USB_PD_PORT_HOST 0
#define USB_PD_PORT_DP 1
+
#define CONFIG_USB_PD_PORT_MAX_COUNT 1
+#define CONFIG_USB_MUX_TUSB1064
#define CONFIG_USB_PID 0x5049
#define CONFIG_USB_BCD_DEV 0x0001 /* v 0.01 */
@@ -34,7 +36,7 @@
/* Required symbolic I2C port names */
#define I2C_PORT_MP4245 I2C_PORT_I2C3
#define I2C_PORT_EEPROM I2C_PORT_I2C1
-#define MP4245_SLAVE_ADDR MP4245_I2C_ADDR_0_FLAGS
+#define MP4245_I2C_ADDR_FLAGS MP4245_I2C_ADDR_0_FLAGS
/*
* Macros for GPIO signals used in common code that don't match the
@@ -50,6 +52,8 @@
#include "registers.h"
+#define GPIO_DP_HPD GPIO_DDI_MST_IN_HPD
+
#define GPIO_TRIGGER_1 GPIO_EC_HUB1_RESET_L
#define GPIO_TRIGGER_2 GPIO_EC_HUB2_RESET_L
diff --git a/board/gingerbread/ec.tasklist b/board/gingerbread/ec.tasklist
index 1f79cd8fbd..f884f8df16 100644
--- a/board/gingerbread/ec.tasklist
+++ b/board/gingerbread/ec.tasklist
@@ -11,4 +11,5 @@
TASK_ALWAYS_RO(RWSIG, rwsig_task, NULL, 1280) \
TASK_ALWAYS(HOOKS, hook_task, NULL, LARGER_TASK_STACK_SIZE) \
TASK_ALWAYS(CONSOLE, console_task, NULL, VENTI_TASK_STACK_SIZE) \
+ TASK_ALWAYS_RW(PD_C0, pd_task, NULL, VENTI_TASK_STACK_SIZE) \
TASK_ALWAYS_RW(UCPD, ucpd_task, 0, LARGER_TASK_STACK_SIZE)
diff --git a/board/gingerbread/gpio.inc b/board/gingerbread/gpio.inc
index e3bb4e2ad4..532903a98b 100644
--- a/board/gingerbread/gpio.inc
+++ b/board/gingerbread/gpio.inc
@@ -10,10 +10,10 @@
#ifdef SECTION_IS_RW
GPIO_INT(HOST_USBC_PPC_INT_ODL, PIN(C, 1), GPIO_INT_FALLING | GPIO_PULL_UP, ppc_interrupt)
-/* TODO (b/183289386): These singals are required for C0 and C1 operation.
+/* TODO (b/183289386): These singals are required for C1 operation.
* GPIO_INT(USBC_DP_MUX_ALERT_ODL, PIN(C, 12), GPIO_INT_FALLING | GPIO_PULL_UP, tcpc_alert_event)
- * GPIO_INT(DDI_MST_IN_HPD, PIN(C, 14), GPIO_INT_BOTH, hpd_interrupt)
*/
+GPIO_INT(DDI_MST_IN_HPD, PIN(C, 14), GPIO_INT_BOTH, hpd_interrupt)
#endif
/* Power sequencing signals */
diff --git a/board/quiche/board.c b/board/quiche/board.c
index ce70a87e4d..081a279eb6 100644
--- a/board/quiche/board.c
+++ b/board/quiche/board.c
@@ -10,6 +10,7 @@
#include "driver/tcpm/ps8xxx.h"
#include "driver/tcpm/stm32gx.h"
#include "driver/tcpm/tcpci.h"
+#include "driver/usb_mux/ps8822.h"
#include "ec_version.h"
#include "gpio.h"
#include "hooks.h"
@@ -18,13 +19,20 @@
#include "task.h"
#include "uart.h"
#include "usb_descriptor.h"
+#include "usb_mux.h"
#include "usb_pd.h"
#include "usbc_ppc.h"
+#include "usb_pd_dp_ufp.h"
+#include "usb_pe_sm.h"
+#include "usb_prl_sm.h"
+#include "usb_tc_sm.h"
#include "util.h"
#define CPRINTS(format, args...) cprints(CC_SYSTEM, format, ## args)
#define CPRINTF(format, args...) cprintf(CC_SYSTEM, format, ## args)
+#define QUICHE_PD_DEBUG_LVL 1
+
#ifdef SECTION_IS_RW
#define CROS_EC_SECTION "RW"
#else
@@ -32,6 +40,11 @@
#endif
#ifdef SECTION_IS_RW
+static int pd_dual_role_init[CONFIG_USB_PD_PORT_MAX_COUNT] = {
+ PD_DRP_TOGGLE_ON,
+};
+
+
static void ppc_interrupt(enum gpio_signal signal)
{
switch (signal) {
@@ -43,6 +56,11 @@ static void ppc_interrupt(enum gpio_signal signal)
break;
}
}
+
+void hpd_interrupt(enum gpio_signal signal)
+{
+ usb_pd_hpd_edge_event(signal);
+}
#endif /* SECTION_IS_RW */
#include "gpio_list.h" /* Must come after other header files. */
@@ -114,8 +132,9 @@ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = {
const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = {
[USB_PD_PORT_HOST] = {
.usb_port = USB_PD_PORT_HOST,
- .driver = &virtual_usb_mux_driver,
- .hpd_update = &virtual_hpd_update,
+ .i2c_port = I2C_PORT_I2C1,
+ .i2c_addr_flags = PS8822_I2C_ADDR3_FLAG,
+ .driver = &ps8822_usb_mux_driver,
},
};
@@ -129,7 +148,16 @@ struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = {
};
unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips);
-/* Power Delivery and charging functions */
+const struct hpd_to_pd_config_t hpd_config = {
+ .port = USB_PD_PORT_HOST,
+ .signal = GPIO_DDI_MST_IN_HPD,
+};
+
+void board_reset_pd_mcu(void)
+{
+
+}
+
void board_tcpc_init(void)
{
/* Enable PPC interrupts. */
@@ -137,18 +165,11 @@ void board_tcpc_init(void)
}
DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C + 1);
-static void board_select_drp_mode(void)
+enum pd_dual_role_states board_tc_get_initial_drp_mode(int port)
{
- /*
- * Host port should operate as a dual role port. If it attaches as a
- * sink, then it will trigger a PRS to end up as a SRC UFP. The port's
- * DRP state only needs to be set once, after it's initialized in TCPMv2
- * as the default role of sink only.
- */
- pd_set_dual_role(USB_PD_PORT_HOST, PD_DRP_TOGGLE_ON);
- CPRINTS("ucpd: set drp toggle on");
+
+ return pd_dual_role_init[port];
}
-DECLARE_DEFERRED(board_select_drp_mode);
int ppc_get_alert_status(int port)
{
diff --git a/board/quiche/board.h b/board/quiche/board.h
index 960f0e37f0..11887abd05 100644
--- a/board/quiche/board.h
+++ b/board/quiche/board.h
@@ -18,6 +18,7 @@
#define USB_PD_PORT_HOST 0
#define USB_PD_PORT_DP 1
+#define CONFIG_USB_MUX_PS8822
#define CONFIG_USB_PID 0x5048
#define CONFIG_USB_BCD_DEV 0x0001 /* v 0.01 */
@@ -34,12 +35,14 @@
/* Required symbolic I2C port names */
#define I2C_PORT_MP4245 I2C_PORT_I2C3
#define I2C_PORT_EEPROM I2C_PORT_I2C3
-#define MP4245_SLAVE_ADDR MP4245_I2C_ADDR_0_FLAGS
+#define MP4245_I2C_ADDR_FLAGS MP4245_I2C_ADDR_0_FLAGS
#ifndef __ASSEMBLER__
#include "registers.h"
+#define GPIO_DP_HPD GPIO_DDI_MST_IN_HPD
+
#define GPIO_TRIGGER_1 GPIO_TP41
#define GPIO_TRIGGER_2 GPIO_TP73
diff --git a/board/quiche/gpio.inc b/board/quiche/gpio.inc
index 6b70d3cfc6..d9401644ee 100644
--- a/board/quiche/gpio.inc
+++ b/board/quiche/gpio.inc
@@ -13,8 +13,8 @@ GPIO_INT(HOST_USBC_PPC_INT_ODL, PIN(D, 9), GPIO_INT_FALLING | GPIO_PULL_U
/* TODO (b/183289386): These singals are required for C0 and C1 operation
* GPIO_INT(USBC_DP_MUX_ALERT_ODL, PIN(B, 1), GPIO_INT_FALLING | GPIO_PULL_UP, tcpc_alert_event)
* GPIO_INT(USBC_DP_PPC_INT_ODL, PIN(E, 7), GPIO_INT_FALLING | GPIO_PULL_UP, ppc_interrupt)
- * GPIO_INT(DDI_MST_IN_HPD, PIN(C, 14), GPIO_INT_BOTH, hpd_interrupt)
*/
+GPIO_INT(DDI_MST_IN_HPD, PIN(C, 14), GPIO_INT_BOTH, hpd_interrupt)
#endif
/* Power sequencing signals */
diff --git a/include/usb_pd_vdo.h b/include/usb_pd_vdo.h
index b146fde179..9f6e35e117 100644
--- a/include/usb_pd_vdo.h
+++ b/include/usb_pd_vdo.h
@@ -133,9 +133,9 @@ 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 */
+/* UFP VDO Version 1.2; update the value when UFP VDO version changes */
#define VDO_UFP1(cap, ctype, alt, speed) \
- ((0x1) << 29 | ((cap) & 0xf) << 24 \
+ ((0x2) << 29 | ((cap) & 0xf) << 24 \
| ((ctype) & 0x3) << 22 | ((alt) & 0x7) << 3 | ((speed) & 0x7))
/* UFP VDO 1 Alternate Modes */