diff options
-rw-r--r-- | baseboard/honeybuns/baseboard.h | 5 | ||||
-rw-r--r-- | baseboard/honeybuns/usb_pd_policy.c | 10 | ||||
-rw-r--r-- | board/gingerbread/board.c | 75 | ||||
-rw-r--r-- | board/gingerbread/board.h | 12 | ||||
-rw-r--r-- | board/gingerbread/ec.tasklist | 2 | ||||
-rw-r--r-- | board/gingerbread/gpio.inc | 4 | ||||
-rw-r--r-- | board/quiche/board.c | 73 | ||||
-rw-r--r-- | board/quiche/board.h | 1 | ||||
-rw-r--r-- | board/quiche/ec.tasklist | 2 | ||||
-rw-r--r-- | board/quiche/gpio.inc | 6 |
10 files changed, 169 insertions, 21 deletions
diff --git a/baseboard/honeybuns/baseboard.h b/baseboard/honeybuns/baseboard.h index 1e7a7faba1..a2095deeac 100644 --- a/baseboard/honeybuns/baseboard.h +++ b/baseboard/honeybuns/baseboard.h @@ -121,14 +121,13 @@ enum usb_strings { /* RW Specific Config Options */ #ifdef SECTION_IS_RW +/* No AP on any honeybuns variants */ +#undef CONFIG_USB_PD_HOST_CMD /* USB Type C and USB PD defines */ #define CONFIG_USB_POWER_DELIVERY #define CONFIG_USB_PD_TCPMV2 #define CONFIG_USB_DRP_ACC_TRYSRC -/* No AP on any honeybuns variants */ -#undef CONFIG_USB_PD_HOST_CMD -#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 diff --git a/baseboard/honeybuns/usb_pd_policy.c b/baseboard/honeybuns/usb_pd_policy.c index b638b8536d..5257753204 100644 --- a/baseboard/honeybuns/usb_pd_policy.c +++ b/baseboard/honeybuns/usb_pd_policy.c @@ -42,7 +42,10 @@ const uint32_t pd_src_host_pdo[] = { }; BUILD_ASSERT(ARRAY_SIZE(pd_src_host_pdo) == PDO_IDX_COUNT); -/* PDOs */ +const uint32_t pd_src_display_pdo[] = { + [PDO_IDX_5V] = PDO_FIXED(5000, 3000, PDO_FIXED_FLAGS), +}; + const uint32_t pd_snk_pdo[] = { [PDO_IDX_5V] = PDO_FIXED(5000, 0, PDO_FIXED_FLAGS), }; @@ -55,6 +58,9 @@ int dpm_get_source_pdo(const uint32_t **src_pdo, const int port) if (port == USB_PD_PORT_HOST) { *src_pdo = pd_src_host_pdo; pdo_cnt = ARRAY_SIZE(pd_src_host_pdo); + } else { + *src_pdo = pd_src_display_pdo; + pdo_cnt = ARRAY_SIZE(pd_src_display_pdo); } return pdo_cnt; @@ -171,6 +177,8 @@ int pd_check_data_swap(int port, if (port == 0) swap = (data_role == PD_ROLE_DFP); + else if (port == 1) + swap = (data_role == PD_ROLE_UFP); return swap; } diff --git a/board/gingerbread/board.c b/board/gingerbread/board.c index 82f02da6d3..d20b09b067 100644 --- a/board/gingerbread/board.c +++ b/board/gingerbread/board.c @@ -44,6 +44,7 @@ #ifdef SECTION_IS_RW static int pd_dual_role_init[CONFIG_USB_PD_PORT_MAX_COUNT] = { PD_DRP_TOGGLE_ON, + PD_DRP_FORCE_SOURCE, }; static void ppc_interrupt(enum gpio_signal signal) @@ -58,6 +59,21 @@ static void ppc_interrupt(enum gpio_signal signal) } } +static void tcpc_alert_event(enum gpio_signal s) +{ + int port = -1; + + switch (s) { + case GPIO_USBC_DP_MUX_ALERT_ODL: + port = USB_PD_PORT_DP; + break; + default: + return; + } + + schedule_deferred_pd_interrupt(port); +} + void hpd_interrupt(enum gpio_signal signal) { usb_pd_hpd_edge_event(signal); @@ -123,11 +139,24 @@ struct ppc_config_t ppc_chips[] = { #endif #ifdef SECTION_IS_RW +/* + * TCPCs: 2 USBC/PD ports + * port 0 -> host port -> STM32G4 UCPD + * port 1 -> user data/display port -> PS8805 + */ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { { .bus_type = EC_BUS_TYPE_EMBEDDED, .drv = &stm32gx_tcpm_drv, }, + { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_I2C3, + .addr_flags = PS8751_I2C_ADDR2_FLAGS, + }, + .drv = &ps8xxx_tcpm_drv, + }, }; const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { @@ -137,15 +166,30 @@ const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { .i2c_addr_flags = TUSB1064_I2C_ADDR0_FLAGS, .driver = &tusb1064_usb_mux_driver, }, + [USB_PD_PORT_DP] = { + .usb_port = USB_PD_PORT_DP, + .i2c_port = I2C_PORT_I2C3, + .i2c_addr_flags = PS8751_I2C_ADDR2_FLAGS, + .driver = &tcpci_tcpm_usb_mux_driver, + .hpd_update = &ps8xxx_tcpc_update_hpd_status, + }, }; /* USB-C PPC Configuration */ struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = { [USB_PD_PORT_HOST] = { - .i2c_port = 2, + .i2c_port = I2C_PORT_I2C3, .i2c_addr_flags = SN5S330_ADDR0_FLAGS, .drv = &sn5s330_drv }, + /* + * TODO(b/159330563): The stub driver has not yet landed (and may not + * land) in TOT. Need to comment this out for now, until the correct + * solution for asymmetrical port hardware exists. + */ + [USB_PD_PORT_DP] = { + /* .drv = &ppc_stub_drv */ + }, }; unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); @@ -156,7 +200,20 @@ const struct hpd_to_pd_config_t hpd_config = { void board_reset_pd_mcu(void) { - + cprints(CC_SYSTEM, "Resetting TCPCs..."); + cflush(); + /* + * Reset all TCPCs. + * C0 -> ucpd (on chip TCPC) + * C1 -> PS8805 TCPC -> USBC_DP_PD_RST_L + * C2 -> PS8803 TCPC -> USBC_UF_RESET_L + */ + gpio_set_level(GPIO_USBC_DP_PD_RST_L, 0); + gpio_set_level(GPIO_USBC_UF_RESET_L, 0); + msleep(PS8805_FW_INIT_DELAY_MS); + gpio_set_level(GPIO_USBC_DP_PD_RST_L, 1); + gpio_set_level(GPIO_USBC_UF_RESET_L, 1); + msleep(PS8805_FW_INIT_DELAY_MS); } @@ -168,6 +225,9 @@ void board_tcpc_init(void) /* Enable PPC interrupts. */ gpio_enable_interrupt(GPIO_HOST_USBC_PPC_INT_ODL); + /* Enable TCPC interrupts. */ + gpio_enable_interrupt(GPIO_USBC_DP_MUX_ALERT_ODL); + /* Enable HPD interrupt */ gpio_enable_interrupt(GPIO_DDI_MST_IN_HPD); @@ -187,6 +247,17 @@ int ppc_get_alert_status(int port) return 0; } +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + + if (!gpio_get_level(GPIO_USBC_DP_MUX_ALERT_ODL) && + gpio_get_level(GPIO_USBC_DP_PD_RST_L)) + status |= PD_STATUS_TCPC_ALERT_1; + + return status; +} + void board_overcurrent_event(int port, int is_overcurrented) { /* TODO: b/ - check correct operation for honeybuns */ diff --git a/board/gingerbread/board.h b/board/gingerbread/board.h index 1c5983cf68..21883367d0 100644 --- a/board/gingerbread/board.h +++ b/board/gingerbread/board.h @@ -14,15 +14,21 @@ /* Optional features */ #define CONFIG_SYSTEM_UNLOCKED /* Allow dangerous commands while in dev. */ -#undef CONFIG_UART_TX_BUF_SIZE -#define CONFIG_UART_TX_BUF_SIZE 4096 +#define CONFIG_WP_ACTIVE_HIGH + +/* Console */ +#define CONFIG_UART_CONSOLE 3 +#define CONFIG_UART_TX_DMA_CH STM32_DMAC_USART3_TX +#define CONFIG_UART_TX_DMA_PH DMAMUX_REQ_USART3_TX /* 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_PD_PORT_MAX_COUNT 2 #define CONFIG_USB_MUX_TUSB1064 +#define CONFIG_USBC_PPC_STUB +#define CONFIG_USB_PD_VBUS_ALERT_TCPC #define CONFIG_USB_PID 0x5049 #define CONFIG_USB_BCD_DEV 0x0001 /* v 0.01 */ diff --git a/board/gingerbread/ec.tasklist b/board/gingerbread/ec.tasklist index f884f8df16..a7c0eb9b2c 100644 --- a/board/gingerbread/ec.tasklist +++ b/board/gingerbread/ec.tasklist @@ -12,4 +12,6 @@ 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(PD_C1, pd_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS_RW(PD_INT_C1, pd_interrupt_handler_task, 1, LARGER_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 532903a98b..0c54a9800d 100644 --- a/board/gingerbread/gpio.inc +++ b/board/gingerbread/gpio.inc @@ -10,9 +10,7 @@ #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 C1 operation. - * GPIO_INT(USBC_DP_MUX_ALERT_ODL, PIN(C, 12), GPIO_INT_FALLING | GPIO_PULL_UP, tcpc_alert_event) - */ +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) #endif diff --git a/board/quiche/board.c b/board/quiche/board.c index 081a279eb6..45dbe7d2dc 100644 --- a/board/quiche/board.c +++ b/board/quiche/board.c @@ -42,21 +42,38 @@ #ifdef SECTION_IS_RW static int pd_dual_role_init[CONFIG_USB_PD_PORT_MAX_COUNT] = { PD_DRP_TOGGLE_ON, + PD_DRP_FORCE_SOURCE, }; - static void ppc_interrupt(enum gpio_signal signal) { switch (signal) { case GPIO_HOST_USBC_PPC_INT_ODL: sn5s330_interrupt(USB_PD_PORT_HOST); break; + case GPIO_USBC_DP_PPC_INT_ODL: + sn5s330_interrupt(USB_PD_PORT_DP); + break; default: break; } } +static void tcpc_alert_event(enum gpio_signal s) +{ + int port = -1; + + switch (s) { + case GPIO_USBC_DP_MUX_ALERT_ODL: + port = USB_PD_PORT_DP; + break; + default: + return; + } + schedule_deferred_pd_interrupt(port); +} + void hpd_interrupt(enum gpio_signal signal) { usb_pd_hpd_edge_event(signal); @@ -123,10 +140,18 @@ struct ppc_config_t ppc_chips[] = { #ifdef SECTION_IS_RW /* TCPCs */ const struct tcpc_config_t tcpc_config[CONFIG_USB_PD_PORT_MAX_COUNT] = { - { + [USB_PD_PORT_HOST] = { .bus_type = EC_BUS_TYPE_EMBEDDED, .drv = &stm32gx_tcpm_drv, }, + [USB_PD_PORT_DP] = { + .bus_type = EC_BUS_TYPE_I2C, + .i2c_info = { + .port = I2C_PORT_I2C1, + .addr_flags = PS8751_I2C_ADDR2_FLAGS, + }, + .drv = &ps8xxx_tcpm_drv, + }, }; const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { @@ -136,6 +161,13 @@ const struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_MAX_COUNT] = { .i2c_addr_flags = PS8822_I2C_ADDR3_FLAG, .driver = &ps8822_usb_mux_driver, }, + [USB_PD_PORT_DP] = { + .usb_port = USB_PD_PORT_DP, + .i2c_port = I2C_PORT_I2C1, + .i2c_addr_flags = PS8751_I2C_ADDR2_FLAGS, + .driver = &tcpci_tcpm_usb_mux_driver, + .hpd_update = &ps8xxx_tcpc_update_hpd_status, + }, }; /* USB-C PPC Configuration */ @@ -145,6 +177,11 @@ struct ppc_config_t ppc_chips[CONFIG_USB_PD_PORT_MAX_COUNT] = { .i2c_addr_flags = SN5S330_ADDR0_FLAGS, .drv = &sn5s330_drv }, + [USB_PD_PORT_DP] = { + .i2c_port = I2C_PORT_I2C1, + .i2c_addr_flags = SN5S330_ADDR2_FLAGS, + .drv = &sn5s330_drv + }, }; unsigned int ppc_cnt = ARRAY_SIZE(ppc_chips); @@ -155,19 +192,32 @@ const struct hpd_to_pd_config_t hpd_config = { void board_reset_pd_mcu(void) { - + cprints(CC_SYSTEM, "Resetting TCPCs..."); + cflush(); + gpio_set_level(GPIO_USBC_DP_PD_RST_L, 0); + gpio_set_level(GPIO_USBC_UF_RESET_L, 0); + msleep(PS8805_FW_INIT_DELAY_MS); + gpio_set_level(GPIO_USBC_DP_PD_RST_L, 1); + gpio_set_level(GPIO_USBC_UF_RESET_L, 1); + msleep(PS8805_FW_INIT_DELAY_MS); } void board_tcpc_init(void) { + board_reset_pd_mcu(); + /* Enable PPC interrupts. */ gpio_enable_interrupt(GPIO_HOST_USBC_PPC_INT_ODL); + gpio_enable_interrupt(GPIO_USBC_DP_PPC_INT_ODL); + /* Enable HPD interrupt */ + gpio_enable_interrupt(GPIO_DDI_MST_IN_HPD); + /* Enable TCPC interrupts. */ + gpio_enable_interrupt(GPIO_USBC_DP_MUX_ALERT_ODL); } -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]; } @@ -175,10 +225,23 @@ int ppc_get_alert_status(int port) { if (port == USB_PD_PORT_HOST) return gpio_get_level(GPIO_HOST_USBC_PPC_INT_ODL) == 0; + else if (port == USB_PD_PORT_DP) + return gpio_get_level(GPIO_USBC_DP_PPC_INT_ODL) == 0; return 0; } +uint16_t tcpc_get_alert_status(void) +{ + uint16_t status = 0; + + if (!gpio_get_level(GPIO_USBC_DP_MUX_ALERT_ODL) && + gpio_get_level(GPIO_USBC_DP_PD_RST_L)) + status |= PD_STATUS_TCPC_ALERT_1; + + return status; +} + void board_overcurrent_event(int port, int is_overcurrented) { /* TODO(b/174825406): check correct operation for honeybuns */ diff --git a/board/quiche/board.h b/board/quiche/board.h index 11887abd05..16bd2de2b7 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_PD_PORT_MAX_COUNT 2 #define CONFIG_USB_MUX_PS8822 #define CONFIG_USB_PID 0x5048 diff --git a/board/quiche/ec.tasklist b/board/quiche/ec.tasklist index f884f8df16..a7c0eb9b2c 100644 --- a/board/quiche/ec.tasklist +++ b/board/quiche/ec.tasklist @@ -12,4 +12,6 @@ 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(PD_C1, pd_task, NULL, VENTI_TASK_STACK_SIZE) \ + TASK_ALWAYS_RW(PD_INT_C1, pd_interrupt_handler_task, 1, LARGER_TASK_STACK_SIZE) \ TASK_ALWAYS_RW(UCPD, ucpd_task, 0, LARGER_TASK_STACK_SIZE) diff --git a/board/quiche/gpio.inc b/board/quiche/gpio.inc index d9401644ee..7e3b9345e6 100644 --- a/board/quiche/gpio.inc +++ b/board/quiche/gpio.inc @@ -10,10 +10,8 @@ #ifdef SECTION_IS_RW GPIO_INT(HOST_USBC_PPC_INT_ODL, PIN(D, 9), GPIO_INT_FALLING | GPIO_PULL_UP, ppc_interrupt) -/* 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(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) #endif |