From 5b521e3ac66fcd576db0fdf0de78b5d5d67768ed Mon Sep 17 00:00:00 2001 From: Caveh Jalali Date: Wed, 11 Apr 2018 19:42:59 -0700 Subject: atlas: manage USB-C high speed muxes this adds control over the USB high speed muxes as a function of DP HPD. this allows an external monitor to be added/removed with chromeos extending the display as appropriate. BUG=b:77151172 BRANCH=none TEST=chromeos detects external monitor plugin and extends display Change-Id: I7df7a8136ddaa4eeaca800d29b46350dafd8f838 Signed-off-by: Caveh Jalali Reviewed-on: https://chromium-review.googlesource.com/1009208 Commit-Ready: Caveh Jalali Tested-by: Caveh Jalali Reviewed-by: Aseda Aboagye Reviewed-by: Duncan Laurie --- board/atlas/board.c | 14 ++++++++++++++ board/atlas/usb_pd_policy.c | 9 +++++++++ 2 files changed, 23 insertions(+) diff --git a/board/atlas/board.c b/board/atlas/board.c index 1399c6040d..a5d297117e 100644 --- a/board/atlas/board.c +++ b/board/atlas/board.c @@ -173,10 +173,12 @@ struct usb_mux usb_muxes[CONFIG_USB_PD_PORT_COUNT] = { { .port_addr = 0, .driver = &tcpci_tcpm_usb_mux_driver, + .hpd_update = &ps8xxx_tcpc_update_hpd_status, }, { .port_addr = 1, .driver = &tcpci_tcpm_usb_mux_driver, + .hpd_update = &ps8xxx_tcpc_update_hpd_status, }, }; @@ -189,12 +191,24 @@ void board_reset_pd_mcu(void) void board_tcpc_init(void) { + int port; + /* Only reset TCPC if not sysjump */ if (!system_jumped_to_this_image()) board_reset_pd_mcu(); gpio_enable_interrupt(GPIO_USB_C0_PD_INT_ODL); gpio_enable_interrupt(GPIO_USB_C1_PD_INT_ODL); + + /* + * Initialize HPD to low; after sysjump SOC needs to see + * HPD pulse to enable video path + */ + for (port = 0; port < CONFIG_USB_PD_PORT_COUNT; port++) { + const struct usb_mux *mux = &usb_muxes[port]; + + mux->hpd_update(port, 0, 0); + } } DECLARE_HOOK(HOOK_INIT, board_tcpc_init, HOOK_PRIO_INIT_I2C+1); diff --git a/board/atlas/usb_pd_policy.c b/board/atlas/usb_pd_policy.c index 8ce281cf3a..322bd4bb23 100644 --- a/board/atlas/usb_pd_policy.c +++ b/board/atlas/usb_pd_policy.c @@ -342,6 +342,8 @@ static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_COUNT]; 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; @@ -350,6 +352,8 @@ static void svdm_dp_post_config(int port) /* set the minimum time delay (2ms) for the next HPD IRQ */ hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; + + mux->hpd_update(port, 1, 0); } static int svdm_dp_attention(int port, uint32_t *payload) @@ -358,6 +362,7 @@ 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]); enum gpio_signal hpd = PORT_TO_HPD(port); + const struct usb_mux *mux = &usb_muxes[port]; cur_lvl = gpio_get_level(hpd); dp_status[port] = payload[1]; @@ -390,14 +395,18 @@ static int svdm_dp_attention(int port, uint32_t *payload) /* set the minimum time delay (2ms) for the next HPD IRQ */ hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; } + 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); gpio_set_level(PORT_TO_HPD(port), 0); + mux->hpd_update(port, 0, 0); } static int svdm_enter_gfu_mode(int port, uint32_t mode_caps) -- cgit v1.2.1