diff options
author | Scott Collyer <scollyer@google.com> | 2021-07-16 11:36:24 -0700 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-07-17 02:27:03 +0000 |
commit | 15babbb6461de00403b148dbdb40207a8220e78f (patch) | |
tree | 62f3bc7a5d4db0ffcfa40efbd4b240ed215f8a55 | |
parent | 085164688e25f32004ff2787c10a66a74331e52c (diff) | |
download | chrome-ec-15babbb6461de00403b148dbdb40207a8220e78f.tar.gz |
ALT-DP: Don't send DP_ATTENTION until after DP_CONFIG
This CL adds a new variable to the hpd state that enables the pd
policy layer to inform the hpd->DP_ATTENTION converter that at least
one DP_CONFIG message has been received. This control is used to make
sure that DP_ATTENTION messages aren't sent prior the DFP_D being
configured for DP port mode. Some port partners may get confused if
DP_ATTENTION is sent prior to either DP_CONFIG or DP_STATUS.
BRANCH=quiche
BUG=b:192051705
TEST=verifed on kasumi (grunt) that the display is extended correctly
following usbc hotplug events. Previously, this case was failing 1 out
of 3-4 times.
Signed-off-by: Scott Collyer <scollyer@google.com>
Change-Id: I80d576de7fc0075be2b1a838d1ed764ae7828e8e
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3035785
Tested-by: Scott Collyer <scollyer@chromium.org>
Reviewed-by: Diana Z <dzigterman@chromium.org>
Reviewed-by: Abe Levkoy <alevkoy@chromium.org>
Commit-Queue: Scott Collyer <scollyer@chromium.org>
-rw-r--r-- | common/usbc/usb_pd_dp_ufp.c | 39 | ||||
-rw-r--r-- | include/usb_pd.h | 7 |
2 files changed, 42 insertions, 4 deletions
diff --git a/common/usbc/usb_pd_dp_ufp.c b/common/usbc/usb_pd_dp_ufp.c index d2307a6025..31a3069bb9 100644 --- a/common/usbc/usb_pd_dp_ufp.c +++ b/common/usbc/usb_pd_dp_ufp.c @@ -50,6 +50,7 @@ struct hpd_edge { struct hpd_info { enum hpd_state state; int count; + int send_enable; uint64_t timer; uint64_t last_send_ts; enum hpd_event queue[HPD_QUEUE_DEPTH]; @@ -71,6 +72,17 @@ int pd_ufp_get_dp_opos(int port) return alt_dp_mode_opos[port]; } +void pd_ufp_enable_hpd_send(int port) +{ + /* + * This control is used ensure that a DP_ATTENTION message is not sent + * to the DFP-D before a DP_CONFIG messaage has been received. This + * control is not strictly required by the spec, but some port partners + * will get confused if DP_ATTENTION is sent prior to DP_CONFIG. + */ + hpd.send_enable = 1; +} + static void hpd_to_dp_attention(void) { int port = hpd_config.port; @@ -314,19 +326,37 @@ static void manage_hpd(void) * queued, then send DP_ATTENTION message. */ if (hpd.count > 0) { - if ((get_time().val - hpd.last_send_ts) > HPD_T_MIN_DP_ATTEN) { + /* + * If at least one hpd event is pending in the queue, send + * a DP_ATTENTION message if a DP_CONFIG message has been + * received and have passed the minimum spacing interval. + */ + if (hpd.send_enable && + ((get_time().val - hpd.last_send_ts) > + HPD_T_MIN_DP_ATTEN)) { /* Generate DP_ATTENTION event pending in queue */ hpd_to_dp_attention(); } else { + uint32_t callback_us; + /* * Need to wait until until min spacing requirement of * DP attention messages. Set callback time to the min * value required. This callback time could be changed * based on hpd interrupts. + * + * This wait is also used to prevent a DP_ATTENTION + * message from being sent before at least one DP_CONFIG + * message has been received. If DP_ATTENTION messages + * need to be delayed for this reason, then just wait + * the minimum time spacing. */ - hook_call_deferred(&manage_hpd_data, - HPD_T_MIN_DP_ATTEN - - (get_time().val - hpd.last_send_ts)); + callback_us = HPD_T_MIN_DP_ATTEN - + (get_time().val - hpd.last_send_ts); + if (callback_us <= 0 || + callback_us > HPD_T_MIN_DP_ATTEN) + callback_us = HPD_T_MIN_DP_ATTEN; + hook_call_deferred(&manage_hpd_data, callback_us); } } @@ -374,6 +404,7 @@ void usb_pd_hpd_converter_enable(int enable) hpd.count = 0; hpd.timer = 0; hpd.last_send_ts = 0; + hpd.send_enable = 0; /* Reset hpd signal edges queue */ hpd.edges.head = 0; diff --git a/include/usb_pd.h b/include/usb_pd.h index a0a4c9e790..aed49c8f07 100644 --- a/include/usb_pd.h +++ b/include/usb_pd.h @@ -2177,6 +2177,13 @@ void pd_ufp_set_dp_opos(int port, int opos); */ int pd_ufp_get_dp_opos(int port); +/** + * Notify hpd->pd converter that display is configured + * + * @param port USB-C port number + */ +void pd_ufp_enable_hpd_send(int port); + /* * Returns True if cable supports USB2 connection * |