summaryrefslogtreecommitdiff
path: root/board/strago
diff options
context:
space:
mode:
authorKevin K Wong <kevin.k.wong@intel.com>2017-04-06 22:39:01 -0700
committerchrome-bot <chrome-bot@chromium.org>2017-05-29 03:28:25 -0700
commit03a665939f8adef0f8fd5a170f859210f65d2c54 (patch)
treeb9da51dc9bdecefebc13ffae238de8a895a60cf4 /board/strago
parent6bbcf5b3f8fac6c6d4f8ea9edef470cf4887f1a7 (diff)
downloadchrome-ec-03a665939f8adef0f8fd5a170f859210f65d2c54.tar.gz
pd: ensure tighter timings for IRQ_HPD pulse
In order to ensure we are always meeting the deadlines for the IRQ_HPD pulse, increase the priority of the processing by moving the rising edge from the low-priority HOOK task (in a deferred function) to the caller task (which is the high-priority PD task). The downside is we are now sleeping in the PD task blocking the processing of the PD messages during this time. Changed HPD_DSTREAM_DEBOUNCE_IRQ to 500us instead of 750us. According to DP spec, the IRQ_HPD pulse width is between 500us and 1000us. Ensure there is a minimum of 2ms delay in between each IRQ_HPD as specified by the DP spec, by sleeping before sending the next pulse if needed. (in practice, this should not wait if we are not too off processing the messages) BUG=chromium:711334 BRANCH=glados strago reef oak TEST=manual, on SKL platform with kernel 3.18 and MST, verify display is functional on USB-C dock. Change-Id: Ib2e9dd608c5f1c671cc5a0fd979a5742101375ff Signed-off-by: Kevin K Wong <kevin.k.wong@intel.com> Signed-off-by: Vincent Palatin <vpalatin@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/508629 Reviewed-by: Todd Broch <tbroch@chromium.org>
Diffstat (limited to 'board/strago')
-rw-r--r--board/strago/usb_pd_policy.c30
1 files changed, 21 insertions, 9 deletions
diff --git a/board/strago/usb_pd_policy.c b/board/strago/usb_pd_policy.c
index 214d52295e..e252f98dc9 100644
--- a/board/strago/usb_pd_policy.c
+++ b/board/strago/usb_pd_policy.c
@@ -263,6 +263,12 @@ static int svdm_dp_config(int port, uint32_t *payload)
return 2;
};
+/*
+ * timestamp of the next possible toggle to ensure the 2-ms spacing
+ * between IRQ_HPD.
+ */
+static uint64_t hpd_deadline[CONFIG_USB_PD_PORT_COUNT];
+
static void svdm_dp_post_config(int port)
{
dp_flags |= DP_FLAGS_DP_ON;
@@ -270,15 +276,10 @@ static void svdm_dp_post_config(int port)
return;
gpio_set_level(GPIO_USB_C0_DP_HPD, 1);
+ /* set the minimum time delay (2ms) for the next HPD IRQ */
+ hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
}
-static void hpd0_irq_deferred(void)
-{
- gpio_set_level(GPIO_USB_C0_DP_HPD, 1);
-}
-
-DECLARE_DEFERRED(hpd0_irq_deferred);
-
static int svdm_dp_attention(int port, uint32_t *payload)
{
int cur_lvl;
@@ -297,14 +298,25 @@ static int svdm_dp_attention(int port, uint32_t *payload)
}
if (irq & cur_lvl) {
+ uint64_t now = get_time().val;
+ /* wait for the minimum spacing between IRQ_HPD if needed */
+ if (now < hpd_deadline[port])
+ usleep(hpd_deadline[port] - now);
+
+ /* generate IRQ_HPD pulse */
gpio_set_level(hpd, 0);
- hook_call_deferred(&hpd0_irq_deferred_data,
- HPD_DSTREAM_DEBOUNCE_IRQ);
+ usleep(HPD_DSTREAM_DEBOUNCE_IRQ);
+ gpio_set_level(GPIO_USB_C0_DP_HPD, 1);
+
+ /* set the minimum time delay (2ms) for the next HPD IRQ */
+ hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
} else if (irq & !cur_lvl) {
CPRINTF("ERR:HPD:IRQ&LOW\n");
return 0; /* nak */
} else {
gpio_set_level(hpd, lvl);
+ /* set the minimum time delay (2ms) for the next HPD IRQ */
+ hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
}
/* ack */
return 1;