summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTing Shen <phoenixshen@google.com>2022-03-18 16:36:52 +0800
committerCommit Bot <commit-bot@chromium.org>2022-03-22 06:28:18 +0000
commitf31b270f97e2814acb73873c7056057796c09fa0 (patch)
treefb3076a41d3000f735d52498edbdea39388022f5
parent6fab7742bfd363c39c4e94df12d113896633fccf (diff)
downloadchrome-ec-f31b270f97e2814acb73873c7056057796c09fa0.tar.gz
corsola: delay the timing to enter DP mode
Corsola uses USB_PD_MUX_DP_ENABLED flag to select DP path, so we have to delay the USB_PD_MUX_DP_ENABLED flag toggle until attention is received. BUG=b:223087778 TEST=See DP=1 only when connected to display. No "The other port is already muxed" error BRANCH=none Signed-off-by: Ting Shen <phoenixshen@google.com> Change-Id: I3563c818829407c1387016f7a7517f877b648283 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3534748 Reviewed-by: Eric Yilun Lin <yllin@google.com> Commit-Queue: Ting Shen <phoenixshen@chromium.org> Tested-by: Ting Shen <phoenixshen@chromium.org>
-rw-r--r--zephyr/projects/corsola/src/usb_pd_policy.c42
1 files changed, 42 insertions, 0 deletions
diff --git a/zephyr/projects/corsola/src/usb_pd_policy.c b/zephyr/projects/corsola/src/usb_pd_policy.c
index e3d6bf45bb..a33bb1d715 100644
--- a/zephyr/projects/corsola/src/usb_pd_policy.c
+++ b/zephyr/projects/corsola/src/usb_pd_policy.c
@@ -42,6 +42,40 @@ void svdm_set_hpd_gpio(int port, int en)
gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(ec_ap_dp_hpd_odl), !en);
}
+__override int svdm_dp_config(int port, uint32_t *payload)
+{
+ int opos = pd_alt_mode(port, TCPCI_MSG_SOP, USB_SID_DISPLAYPORT);
+ uint8_t pin_mode = get_dp_pin_mode(port);
+ mux_state_t mux_mode = svdm_dp_get_mux_mode(port);
+ int mf_pref = PD_VDO_DPSTS_MF_PREF(dp_status[port]);
+
+ if (!pin_mode)
+ return 0;
+
+ CPRINTS("pin_mode: %x, mf: %d, mux: %d", pin_mode, mf_pref, mux_mode);
+ /*
+ * Defer setting the usb_mux until HPD goes high, svdm_dp_attention().
+ * The AP only supports one DP phy. An external DP mux switches between
+ * the two ports. Should switch those muxes when it is really used,
+ * i.e. HPD high; otherwise, the real use case is preempted, like:
+ * (1) plug a dongle without monitor connected to port-0,
+ * (2) plug a dongle without monitor connected to port-1,
+ * (3) plug a monitor to the port-1 dongle.
+ */
+
+ payload[0] = VDO(USB_SID_DISPLAYPORT, 1,
+ CMD_DP_CONFIG | VDO_OPOS(opos));
+ payload[1] = VDO_DP_CFG(pin_mode, /* pin mode */
+ 1, /* DPv1.3 signaling */
+ 2); /* UFP connected */
+ return 2;
+};
+
+__override void svdm_dp_post_config(int port)
+{
+ dp_flags[port] |= DP_FLAGS_DP_ON;
+}
+
int corsola_is_dp_muxable(int port)
{
int i;
@@ -76,6 +110,14 @@ __override int svdm_dp_attention(int port, uint32_t *payload)
if (lvl) {
gpio_pin_set_dt(GPIO_DT_FROM_NODELABEL(dp_aux_path_sel), port);
CPRINTS("Set DP_AUX_PATH_SEL: %d", port);
+
+ usb_mux_set(port, USB_PD_MUX_DOCK,
+ USB_SWITCH_CONNECT,
+ polarity_rm_dts(pd_get_polarity(port)));
+ } else {
+ usb_mux_set(port, USB_PD_MUX_USB_ENABLED,
+ USB_SWITCH_CONNECT,
+ polarity_rm_dts(pd_get_polarity(port)));
}
if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) &&