diff options
author | Wai-Hong Tam <waihong@google.com> | 2019-11-22 16:18:42 +0800 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-11-28 03:16:27 +0000 |
commit | 43c067e3b883f2e2685802700f1d0419b4618ff6 (patch) | |
tree | 623e6d4e645d8712b9a8aa76b5b2f8d983dd624f | |
parent | 74237689eb277bf1fe0e682cb256825508fa511f (diff) | |
download | chrome-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.inc | 6 | ||||
-rw-r--r-- | board/trogdor/usb_pd_policy.c | 51 |
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 */ } |