summaryrefslogtreecommitdiff
path: root/common/usbc
diff options
context:
space:
mode:
authorScott Collyer <scollyer@google.com>2021-07-16 11:36:24 -0700
committerCommit Bot <commit-bot@chromium.org>2021-07-17 02:27:03 +0000
commit15babbb6461de00403b148dbdb40207a8220e78f (patch)
tree62f3bc7a5d4db0ffcfa40efbd4b240ed215f8a55 /common/usbc
parent085164688e25f32004ff2787c10a66a74331e52c (diff)
downloadchrome-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>
Diffstat (limited to 'common/usbc')
-rw-r--r--common/usbc/usb_pd_dp_ufp.c39
1 files changed, 35 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;