diff options
author | Scott Collyer <scollyer@google.com> | 2021-02-16 13:38:33 -0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-03-24 23:33:07 +0000 |
commit | 2cee0e2eb293cea2ccc1ae782de85480dc04d808 (patch) | |
tree | af410ddfd0b033f7029aafadc8de03effbb65e67 | |
parent | 1403ddcbbdea6a55db88465659af5f0cc79ace82 (diff) | |
download | chrome-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.c | 8 | ||||
-rw-r--r-- | baseboard/honeybuns/baseboard.h | 31 | ||||
-rw-r--r-- | baseboard/honeybuns/usb_pd_policy.c | 345 | ||||
-rw-r--r-- | board/gingerbread/board.c | 48 | ||||
-rw-r--r-- | board/gingerbread/board.h | 6 | ||||
-rw-r--r-- | board/gingerbread/ec.tasklist | 1 | ||||
-rw-r--r-- | board/gingerbread/gpio.inc | 4 | ||||
-rw-r--r-- | board/quiche/board.c | 47 | ||||
-rw-r--r-- | board/quiche/board.h | 5 | ||||
-rw-r--r-- | board/quiche/gpio.inc | 2 | ||||
-rw-r--r-- | include/usb_pd_vdo.h | 4 |
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 */ |