summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWai-Hong Tam <waihong@google.com>2019-11-22 16:18:42 +0800
committerCommit Bot <commit-bot@chromium.org>2019-11-28 03:16:27 +0000
commit43c067e3b883f2e2685802700f1d0419b4618ff6 (patch)
tree623e6d4e645d8712b9a8aa76b5b2f8d983dd624f
parent74237689eb277bf1fe0e682cb256825508fa511f (diff)
downloadchrome-ec-43c067e3b883f2e2685802700f1d0419b4618ff6.tar.gz
Trogdor: Regenerate HPD through a GPIO to signal AP
Add this extra way to signal AP for the HPD event, for experiment. Will keep only one of them in production. Also wake AP from suspend when entering DP alt-mode or HPD event. BRANCH=None BUG=b:143616352 TEST=BOARD=trogdor make Change-Id: I398d5f9c7340d35abde201b9f04a1bcfa3c56d62 Signed-off-by: Wai-Hong Tam <waihong@google.com> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/1930518
-rw-r--r--board/trogdor/gpio.inc6
-rw-r--r--board/trogdor/usb_pd_policy.c51
2 files changed, 51 insertions, 6 deletions
diff --git a/board/trogdor/gpio.inc b/board/trogdor/gpio.inc
index c12b7be6e9..8821a74e65 100644
--- a/board/trogdor/gpio.inc
+++ b/board/trogdor/gpio.inc
@@ -82,11 +82,7 @@ GPIO(USB_C0_PD_RST_L, PIN(F, 1), GPIO_OUT_HIGH) /* Port-0 TCPC chip reset
GPIO(USB_C1_PD_RST_ODL, PIN(E, 4), GPIO_ODR_HIGH) /* Port-1 TCPC chip reset */
GPIO(DP_MUX_OE_L, PIN(9, 6), GPIO_OUT_HIGH) /* DP mux enable */
GPIO(DP_MUX_SEL, PIN(4, 5), GPIO_OUT_HIGH) /* DP mux selection: L:C0, H:C1 */
-/*
- * TODO(waihong): Implement regenerating HPD through this GPIO to signal AP, if
- * the virtual USB mux (over EC host event) not work.
- */
-GPIO(DP_HOT_PLUG_DET, PIN(9, 5), GPIO_INPUT) /* DP HPD to AP */
+GPIO(DP_HOT_PLUG_DET, PIN(9, 5), GPIO_OUT_LOW) /* DP HPD to AP */
/* TODO(waihong): Remove it from schematic. No use. */
GPIO(USBC_MUX_CONF0, PIN(5, 1), GPIO_INPUT)
diff --git a/board/trogdor/usb_pd_policy.c b/board/trogdor/usb_pd_policy.c
index 56756e5abc..14c0ead6b6 100644
--- a/board/trogdor/usb_pd_policy.c
+++ b/board/trogdor/usb_pd_policy.c
@@ -4,6 +4,7 @@
*/
#include "charge_manager.h"
+#include "chipset.h"
#include "console.h"
#include "gpio.h"
#include "pi3usb9281.h"
@@ -274,6 +275,13 @@ static int svdm_enter_dp_mode(int port, uint32_t mode_caps)
/* Only enter mode if device is DFP_D capable */
if (mode_caps & MODE_DP_SNK) {
svdm_safe_dp_mode(port);
+
+ if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND))
+ /*
+ * Wake the system up since we're entering DP AltMode.
+ */
+ pd_notify_dp_alt_mode_entry();
+
return 0;
}
@@ -339,11 +347,19 @@ static int is_dp_muxable(int port)
return 1;
}
+/*
+ * Timestamp of the next possible toggle to ensure the 2-ms spacing
+ * between IRQ_HPD.
+ */
+static uint64_t hpd_deadline;
+
static int svdm_dp_attention(int port, uint32_t *payload)
{
+ enum gpio_signal hpd = GPIO_DP_HOT_PLUG_DET;
int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]);
int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]);
const struct usb_mux *mux = &usb_muxes[port];
+ int cur_lvl = gpio_get_level(hpd);
dp_status[port] = payload[1];
@@ -381,9 +397,42 @@ static int svdm_dp_attention(int port, uint32_t *payload)
USB_SWITCH_CONNECT, pd_get_polarity(port));
}
- /* Signal AP for the HPD event */
+ if (chipset_in_state(CHIPSET_STATE_ANY_SUSPEND) &&
+ (irq || lvl))
+ /*
+ * Wake up the AP. IRQ or level high indicates a DP sink is now
+ * present.
+ */
+ pd_notify_dp_alt_mode_entry();
+
+ /* TODO(waihong): Keep only one of the following ways to signal AP */
+
+ /* Signal AP for the HPD event, through EC host event */
mux->hpd_update(port, lvl, irq);
+ /* Signal AP for the HPD event, through GPIO to AP */
+ if (irq & cur_lvl) {
+ uint64_t now = get_time().val;
+ /* Wait for the minimum spacing between IRQ_HPD if needed */
+ if (now < hpd_deadline)
+ usleep(hpd_deadline - now);
+
+ /* Generate IRQ_HPD pulse */
+ gpio_set_level(hpd, 0);
+ usleep(HPD_DSTREAM_DEBOUNCE_IRQ);
+ gpio_set_level(hpd, 1);
+
+ /* Set the minimum time delay (2ms) for the next HPD IRQ */
+ hpd_deadline = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
+ } else if (irq & !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 = get_time().val + HPD_USTREAM_DEBOUNCE_LVL;
+ }
+
return 1; /* Ack */
}