Patrick Georgi (pgeorgi@google.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/17628
-gerrit
commit b02c66a82d452a22109224d2c69ab2bb7ae34525 Author: Julius Werner jwerner@chromium.org Date: Mon Nov 21 20:14:18 2016 -0800
google/gru: Power-cycle USB ports in developer/recovery modes
Gru only uses USB 2.0 in firmware to avoid all the madness associated with Type-C port orientation and USB 3.0 tuning. We do this by isolating the SuperSpeed lines in the Type-C PHY so it looks like they aren't connected to the device.
Unfortunately, some devices seem to already get "locked" into SuperSpeed mode as soon as they detect Rx terminations once, and can never snap out again on their own. Since the terminations are already connected during power-on reset we cannot disable them fast enough to prevent this, and the only solution we found to date is to power-cycle the whole USB port.
Now, Gru's USB port power is controlled by the EC, and unfortunately we have no direct host command to control it. We do however have a command to force a certain USB PD "role", and forcing our host into "sink" mode makes it stop sourcing power to the port. So for lack of a saner solution we'll use this to work around our problem.
BRANCH=gru BUG=chrome-os-partner:59346 TEST=Booted Kevin in recovery mode, confirmed that my "problem stick" gets detected immediately (whereas previously I had to unplug/replug it). Booted Kevin to OS in both developer and normal mode and confirmed that USB still seems to work.
Change-Id: Ib3cceba9baa170b13f01bd5c01bd413be5b441ba Signed-off-by: Patrick Georgi pgeorgi@chromium.org Original-Commit-Id: cd695eda33299e50362f1096c46f2f5260c49036 Original-Change-Id: I2db3d6d3710d18a8b8030e94eb1ac2e931f22638 Original-Signed-off-by: Julius Werner jwerner@chromium.org Original-Reviewed-on: https://chromium-review.googlesource.com/413031 --- src/mainboard/google/gru/mainboard.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+)
diff --git a/src/mainboard/google/gru/mainboard.c b/src/mainboard/google/gru/mainboard.c index 7e360e7..dd986c4 100644 --- a/src/mainboard/google/gru/mainboard.c +++ b/src/mainboard/google/gru/mainboard.c @@ -15,9 +15,11 @@ */
#include <boardid.h> +#include <console/console.h> #include <delay.h> #include <device/device.h> #include <device/i2c.h> +#include <ec/google/chromeec/ec.h> #include <gpio.h> #include <soc/bl31_plat_params.h> #include <soc/clock.h> @@ -230,6 +232,17 @@ static void configure_display(void) gpio_output(GPIO(4, D, 3), 1); /* CPU3_EDP_VDDEN for P3.3V_DISP */ }
+static void usb_power_cycle(int port) +{ + if (google_chromeec_set_usb_pd_role(port, USB_PD_CTRL_ROLE_FORCE_SINK)) + printk(BIOS_ERR, "ERROR: Cannot force USB%d PD sink\n", port); + + mdelay(10); /* Make sure USB stick is fully depowered. */ + + if (google_chromeec_set_usb_pd_role(port, USB_PD_CTRL_ROLE_TOGGLE_ON)) + printk(BIOS_ERR, "ERROR: Cannot restore USB%d PD mode\n", port); +} + static void setup_usb(void) { /* A few magic PHY tuning values that improve eye diagram amplitude @@ -269,6 +282,17 @@ static void setup_usb(void)
setup_usb_otg0(); setup_usb_otg1(); + + /* + * Need to power-cycle USB ports for use in firmware, since some devices + * can't fall back to USB 2.0 after they saw SuperSpeed terminations. + * This takes about a dozen milliseconds, so only do it in boot modes + * that have firmware UI (which one could select USB boot from). + */ + if (display_init_required()) { + usb_power_cycle(0); + usb_power_cycle(1); + } }
static void mainboard_init(device_t dev)