From 211facccfdb286a10e9d0f0a44a5d8231c0a49c2 Mon Sep 17 00:00:00 2001 From: Ting Shen Date: Wed, 22 Dec 2021 17:27:37 +0800 Subject: cherry: merge HPD select and DP path select callbacks Cherry's customized DP callbacks is out of sync with the original version. This causes DP_PATH_SEL not working properly. To fix this, move DP_PATH_SEL control into svdm_set_hpd_gpio, so we can reuse more parts of common code. BUG=b:211340354, b:206047978 TEST=manually, tested following scenarios 1) StarTech USB-C to HDMI adapter works with both ports. 2) DP_PATH_SEL updates when we replug HDMI dongle to another port. BRANCH=main Signed-off-by: Ting Shen Change-Id: Id4f5bc2e76c58e12b5fe9c51ec1a8ba9718d9167 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3353168 Tested-by: Parker Lin Reviewed-by: Eric Yilun Lin Commit-Queue: Ting Shen --- baseboard/cherry/usb_pd_policy.c | 78 ++++++++++++++++------------------------ 1 file changed, 30 insertions(+), 48 deletions(-) diff --git a/baseboard/cherry/usb_pd_policy.c b/baseboard/cherry/usb_pd_policy.c index 0c7f4dcee5..cae89bffcf 100644 --- a/baseboard/cherry/usb_pd_policy.c +++ b/baseboard/cherry/usb_pd_policy.c @@ -28,21 +28,6 @@ static enum { AUX_PORT_C1HDMI = 1, } aux_port = AUX_PORT_NONE; -int svdm_get_hpd_gpio(int port) -{ - /* HPD is low active, inverse the result */ - return !gpio_get_level(GPIO_EC_AP_DP_HPD_ODL); -} - -void svdm_set_hpd_gpio(int port, int en) -{ - /* - * HPD is low active, inverse the en - * TODO: C0&C1 shares the same HPD, implement FCFS policy. - */ - gpio_set_level(GPIO_EC_AP_DP_HPD_ODL, !en); -} - static void aux_switch_port(int port) { if (port != AUX_PORT_NONE) @@ -66,6 +51,33 @@ static void aux_display_disconnected(int port) aux_switch_port(AUX_PORT_NONE); } +int svdm_get_hpd_gpio(int port) +{ + /* HPD is low active, inverse the result */ + return !gpio_get_level(GPIO_EC_AP_DP_HPD_ODL); +} + +void svdm_set_hpd_gpio(int port, int en) +{ + /* + * Cherry can only output to 1 display port at a time. + * This implements FCFS policy by changing the aux channel. If a + * display is connected to the either port (says A), and the port A + * will be served until the display is disconnected from port A. + * It won't output to the other display which connects to port B. + */ + if (en) { + if (aux_port == AUX_PORT_NONE) + aux_switch_port(port); + } else { + aux_display_disconnected(port); + } + /* + * HPD is low active, inverse the en + */ + gpio_set_level_verbose(CC_USBPD, GPIO_EC_AP_DP_HPD_ODL, !en); +} + __override int svdm_dp_attention(int port, uint32_t *payload) { int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); @@ -115,6 +127,9 @@ __override int svdm_dp_attention(int port, uint32_t *payload) * b/171172053#comment14: since the HPD_DSTREAM_DEBOUNCE_IRQ is * very short (500us), we can use udelay instead of usleep for * more stable pulse period. + * + * Note that this should be the only difference between our code + * and common code. */ udelay(HPD_DSTREAM_DEBOUNCE_IRQ); svdm_set_hpd_gpio(port, 1); @@ -122,23 +137,6 @@ __override int svdm_dp_attention(int port, uint32_t *payload) svdm_set_hpd_gpio(port, lvl); } - /* - * Cherry can only output to 1 display port at a time. - * This implements FCFS policy by changing the aux channel. If a - * display is connected to the either port (says A), and the port A - * will be served until the display is disconnected from port A. - * It won't output to the other display which connects to port B. - */ - if (lvl && aux_port == AUX_PORT_NONE) - /* - * A display is connected, and no display was plugged on either - * port. - */ - aux_switch_port(port); - else if (!lvl) - aux_display_disconnected(port); - - /* set the minimum time delay (2ms) for the next HPD IRQ */ svdm_hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; #endif /* CONFIG_USB_PD_DP_HPD_GPIO */ @@ -156,22 +154,6 @@ __override int svdm_dp_attention(int port, uint32_t *payload) return 1; } -__override void svdm_exit_dp_mode(int port) -{ -#ifdef CONFIG_USB_PD_DP_HPD_GPIO - svdm_set_hpd_gpio(port, 0); -#endif /* CONFIG_USB_PD_DP_HPD_GPIO */ - usb_mux_hpd_update(port, USB_PD_MUX_HPD_LVL_DEASSERTED | - USB_PD_MUX_HPD_IRQ_DEASSERTED); - - aux_display_disconnected(port); - -#ifdef USB_PD_PORT_TCPC_MST - if (port == USB_PD_PORT_TCPC_MST) - baseboard_mst_enable_control(port, 0); -#endif -} - int pd_snk_is_vbus_provided(int port) { static atomic_t vbus_prev[CONFIG_USB_PD_PORT_MAX_COUNT]; -- cgit v1.2.1