From 4e41a88f9e475631652986a116f07e85d848bf3b Mon Sep 17 00:00:00 2001 From: Matthew Blecker Date: Sun, 4 Aug 2019 14:26:40 -0700 Subject: atlas: Check DP MF-bit against selected pin cfg When we are configuring a Type-C port for DisplayPort alternate mode, we should check to see that the selected pin config supports multi-function mode or not. This commit fixes a bug where we were setting the SuperSpeed muxes based solely upon the Multi-function Preferred bit in the DPStatus VDO. Some Type-C video adapters are buggy and set the MF preferred bit without actually supporting an MF pin configuration. Therefore, we trust the reported supported pin configurations in the DiscMode VDO. BRANCH=master BUG=chromium:919756,b:138874110 TEST=Enable DRM debug by "echo 0xe > /sys/module/drm/parameters/debug" Monitor dmesg. Look for output indicating "Link training successful at 5400000 4 lanes". Look for monitor output at UHD4k60 on Acer B326HK using OSD. Change-Id: I946e601ed672031bc4606878531c561cf487a914 Signed-off-by: Matthew Blecker Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1737273 Reviewed-by: Nitin Kolluru Reviewed-by: Caveh Jalali Tested-by: Nitin Kolluru Commit-Queue: Caveh Jalali --- board/atlas/usb_pd_policy.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'board/atlas/usb_pd_policy.c') diff --git a/board/atlas/usb_pd_policy.c b/board/atlas/usb_pd_policy.c index f9e9d746a9..30bc7c1df9 100644 --- a/board/atlas/usb_pd_policy.c +++ b/board/atlas/usb_pd_policy.c @@ -340,12 +340,20 @@ static int svdm_dp_config(int port, uint32_t *payload) int opos = pd_alt_mode(port, USB_SID_DISPLAYPORT); int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status[port]); int pin_mode = pd_dfp_dp_get_pin_mode(port, dp_status[port]); + enum typec_mux mux_mode; if (!pin_mode) return 0; - usb_mux_set(port, mf_pref ? TYPEC_MUX_DOCK : TYPEC_MUX_DP, - USB_SWITCH_CONNECT, pd_get_polarity(port)); + /* + * Multi-function operation is only allowed if that pin config is + * supported. + */ + mux_mode = ((pin_mode & MODE_DP_PIN_MF_MASK) && mf_pref) ? + TYPEC_MUX_DOCK : TYPEC_MUX_DP; + CPRINTS("pin_mode: 0x%X, mf: %d, mux: %d", pin_mode, mf_pref, mux_mode); + + usb_mux_set(port, mux_mode, USB_SWITCH_CONNECT, pd_get_polarity(port)); payload[0] = VDO(USB_SID_DISPLAYPORT, 1, CMD_DP_CONFIG | VDO_OPOS(opos)); -- cgit v1.2.1