diff options
author | Aseda Aboagye <aaboagye@google.com> | 2018-01-25 15:16:19 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-02-05 19:08:39 -0800 |
commit | 06bbd9dd6c65bb9197bf362a2229134b090813d8 (patch) | |
tree | 35c5272f98745e95415080190376105f6f9a0104 | |
parent | bce23786d0bf606326b7acd752017732da896d11 (diff) | |
download | chrome-ec-06bbd9dd6c65bb9197bf362a2229134b090813d8.tar.gz |
meowth: zoombini: Add HPD support.
The HPD pins for meowth and zoombini go from the EC to the AP. This
commit drives the HPD correctly.
BUG=b:72413020
BRANCH=None
TEST=Flash meowth; Use a couple charge-through hubs, unplug HDMI cable,
replug, verify AP sees new DP sink.
Change-Id: Ie1f86378c59fc4a717edc537ff8afe01b21d9b68
Signed-off-by: Aseda Aboagye <aaboagye@google.com>
Reviewed-on: https://chromium-review.googlesource.com/888226
Commit-Ready: Aseda Aboagye <aaboagye@chromium.org>
Tested-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Edward Hill <ecgh@chromium.org>
-rw-r--r-- | board/zoombini/gpio.inc | 5 | ||||
-rw-r--r-- | board/zoombini/usb_pd_policy.c | 47 |
2 files changed, 51 insertions, 1 deletions
diff --git a/board/zoombini/gpio.inc b/board/zoombini/gpio.inc index 7b04a0651a..025841e1d9 100644 --- a/board/zoombini/gpio.inc +++ b/board/zoombini/gpio.inc @@ -87,6 +87,9 @@ GPIO(USB_C2_BC12_CHG_DET, PIN(E, 4), GPIO_INPUT) GPIO(USB_C0_OC_L, PIN(6, 7), GPIO_ODR_HIGH) GPIO(USB_C1_OC_L, PIN(7, 0), GPIO_ODR_HIGH) GPIO(USB_C2_OC_L, PIN(6, 3), GPIO_ODR_HIGH) +GPIO(USB_C0_DP_HPD, PIN(C, 5), GPIO_OUT_LOW) +GPIO(USB_C1_DP_HPD, PIN(C, 6), GPIO_OUT_LOW) +GPIO(USB_C2_DP_HPD, PIN(C, 7), GPIO_OUT_LOW) GPIO(BOARD_VERSION1, PIN(9, 6), GPIO_INPUT) GPIO(BOARD_VERSION2, PIN(9, 3), GPIO_INPUT) @@ -164,6 +167,8 @@ GPIO(PMIC_EN, PIN(8, 6), GPIO_ODR_LOW) GPIO(USB_C0_OC_L, PIN(6, 7), GPIO_ODR_HIGH) GPIO(USB_C1_OC_L, PIN(7, 0), GPIO_ODR_HIGH) GPIO(ENABLE_BACKLIGHT, PIN(D, 3), GPIO_ODR_LOW) /* EC_BL_EN_OD */ +GPIO(USB_C0_DP_HPD, PIN(C, 5), GPIO_OUT_LOW) +GPIO(USB_C1_DP_HPD, PIN(C, 6), GPIO_OUT_LOW) GPIO(PCH_DSW_PWROK, PIN(3, 7), GPIO_OUT_LOW) /* EC_PCH_DSW_PWROK */ GPIO(PCH_RSMRST_L, PIN(C, 2), GPIO_OUT_LOW) /* EC_PCH_RSMRST_L */ diff --git a/board/zoombini/usb_pd_policy.c b/board/zoombini/usb_pd_policy.c index e5c7a975f7..2a0f580718 100644 --- a/board/zoombini/usb_pd_policy.c +++ b/board/zoombini/usb_pd_policy.c @@ -293,6 +293,18 @@ 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]; + +#ifdef BOARD_MEOWTH +#define PORT_TO_HPD(port) ((port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD) +#else +#define PORT_TO_HPD(port) ((port == 2) ? GPIO_USB_C2_DP_HPD : \ + (port) ? GPIO_USB_C1_DP_HPD : GPIO_USB_C0_DP_HPD) +#endif /* defined(BOARD_MEOWTH) */ static void svdm_dp_post_config(int port) { const struct usb_mux *mux = &usb_muxes[port]; @@ -300,23 +312,55 @@ static void svdm_dp_post_config(int port) dp_flags[port] |= DP_FLAGS_DP_ON; if (!(dp_flags[port] & DP_FLAGS_HPD_HI_PENDING)) return; + + gpio_set_level(PORT_TO_HPD(port), 1); + + /* set the minimum time delay (2ms) for the next HPD IRQ */ + hpd_deadline[port] = get_time().val + HPD_USTREAM_DEBOUNCE_LVL; + mux->hpd_update(port, 1, 0); } static int svdm_dp_attention(int port, uint32_t *payload) { + int cur_lvl; int lvl = PD_VDO_DPSTS_HPD_LVL(payload[1]); int irq = PD_VDO_DPSTS_HPD_IRQ(payload[1]); + enum gpio_signal hpd = PORT_TO_HPD(port); const struct usb_mux *mux = &usb_muxes[port]; + cur_lvl = gpio_get_level(hpd); dp_status[port] = payload[1]; + + /* Its initial DP status message prior to config */ if (!(dp_flags[port] & DP_FLAGS_DP_ON)) { if (lvl) dp_flags[port] |= DP_FLAGS_HPD_HI_PENDING; return 1; } - mux->hpd_update(port, lvl, irq); + 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); + usleep(HPD_DSTREAM_DEBOUNCE_IRQ); + gpio_set_level(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; + } + mux->hpd_update(port, lvl, irq); /* ack */ return 1; } @@ -326,6 +370,7 @@ static void svdm_exit_dp_mode(int port) const struct usb_mux *mux = &usb_muxes[port]; svdm_safe_dp_mode(port); + gpio_set_level(PORT_TO_HPD(port), 0); mux->hpd_update(port, 0, 0); } |