[U-Boot] [PATCH 1/3] usb: tegra: fix PHY selection code

From: Stephen Warren swarren@nvidia.com
The TRM for Tegra30 and later all state that USBMODE_CM_HC must be set before writing to hostpc1_devlc to select which PHY to use for a USB controller. However, neither init_{utmi,ulpi}_usb_controller() do this today, so the register writes they perform for PHY selection do not work.
For the UTMI case, this was hacked around in commit 7e44d9320ed4 "ARM: Tegra: USB: EHCI: Add support for Tegra30/Tegra114" by adding code to ehci_hcd_init() which sets USBMODE_CM_HC and duplicates the PHY selection register write. This code doesn't cover the ULPI case, so I wouldn't be surprised if ULPI doesn't work with the current code, unless the ordering requirement only ends up being an issue in HW for UTMI not ULPI.
This patch fixes init_{utmi,ulpi}_usb_controller() to correctly set USBMODE_CM_HC before selecting the PHY. Now that this works, we can remove the duplicate UTMI-specific code in ehci_hcd_init(), thus simplifying that function.
Cc: Jim Lin jilin@nvidia.com Cc: Stefan Agner stefan@agner.ch Signed-off-by: Stephen Warren swarren@nvidia.com --- drivers/usb/host/ehci-tegra.c | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-)
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 38db18e2c9ea..9a9a1277d160 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -496,6 +496,10 @@ static int init_utmi_usb_controller(struct fdt_usb *config) clrbits_le32(&usbctlr->port_sc1, STS); } #else + /* Set to Host mode after Controller Reset was done */ + clrsetbits_le32(&usbctlr->usb_mode, USBMODE_CM_HC, + USBMODE_CM_HC); + /* Select PHY interface after setting host mode */ clrsetbits_le32(&usbctlr->hostpc1_devlc, PTS_MASK, PTS_UTMI << PTS_SHIFT); clrbits_le32(&usbctlr->hostpc1_devlc, STS); @@ -561,6 +565,10 @@ static int init_ulpi_usb_controller(struct fdt_usb *config) clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, PTS_ULPI << PTS_SHIFT); #else + /* Set to Host mode after Controller Reset was done */ + clrsetbits_le32(&usbctlr->usb_mode, USBMODE_CM_HC, + USBMODE_CM_HC); + /* Select PHY interface after setting host mode */ clrsetbits_le32(&usbctlr->hostpc1_devlc, PTS_MASK, PTS_ULPI << PTS_SHIFT); #endif @@ -788,19 +796,6 @@ success: *hccr = (struct ehci_hccr *)&usbctlr->cap_length; *hcor = (struct ehci_hcor *)&usbctlr->usb_cmd;
- if (controller->has_hostpc) { - /* Set to Host mode after Controller Reset was done */ - clrsetbits_le32(&usbctlr->usb_mode, USBMODE_CM_HC, - USBMODE_CM_HC); - /* Select UTMI parallel interface after setting host mode */ - if (config->utmi) { - clrsetbits_le32((char *)&usbctlr->usb_cmd + - HOSTPC1_DEVLC, PTS_MASK, - PTS_UTMI << PTS_SHIFT); - clrbits_le32((char *)&usbctlr->usb_cmd + - HOSTPC1_DEVLC, STS); - } - } return 0; }

From: Stephen Warren swarren@nvidia.com
Both init_{utmi,ulpi}_usb_controller() have nearly identical code for PHY type selection. Pull this out into a common function to remove the duplication.
Cc: Jim Lin jilin@nvidia.com Cc: Stefan Agner stefan@agner.ch Signed-off-by: Stephen Warren swarren@nvidia.com --- drivers/usb/host/ehci-tegra.c | 58 +++++++++++++++++++++---------------------- 1 file changed, 28 insertions(+), 30 deletions(-)
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 9a9a1277d160..55a546e4d3da 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -293,6 +293,32 @@ static const unsigned *get_pll_timing(void) return timing; }
+/* select the PHY to use with a USB controller */ +static void init_phy_mux(struct fdt_usb *config, uint pts) +{ + struct usb_ctlr *usbctlr = config->reg; + +#if defined(CONFIG_TEGRA20) + if (config->periph_id == PERIPH_ID_USBD) { + clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK, + PTS_UTMI << PTS1_SHIFT); + clrbits_le32(&usbctlr->port_sc1, STS1); + } else { + clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, + PTS_UTMI << PTS_SHIFT); + clrbits_le32(&usbctlr->port_sc1, STS); + } +#else + /* Set to Host mode after Controller Reset was done */ + clrsetbits_le32(&usbctlr->usb_mode, USBMODE_CM_HC, + USBMODE_CM_HC); + /* Select PHY interface after setting host mode */ + clrsetbits_le32(&usbctlr->hostpc1_devlc, PTS_MASK, + pts << PTS_SHIFT); + clrbits_le32(&usbctlr->hostpc1_devlc, STS); +#endif +} + /* set up the UTMI USB controller with the parameters provided */ static int init_utmi_usb_controller(struct fdt_usb *config) { @@ -485,25 +511,7 @@ static int init_utmi_usb_controller(struct fdt_usb *config) clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1);
/* Select UTMI parallel interface */ -#if defined(CONFIG_TEGRA20) - if (config->periph_id == PERIPH_ID_USBD) { - clrsetbits_le32(&usbctlr->port_sc1, PTS1_MASK, - PTS_UTMI << PTS1_SHIFT); - clrbits_le32(&usbctlr->port_sc1, STS1); - } else { - clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, - PTS_UTMI << PTS_SHIFT); - clrbits_le32(&usbctlr->port_sc1, STS); - } -#else - /* Set to Host mode after Controller Reset was done */ - clrsetbits_le32(&usbctlr->usb_mode, USBMODE_CM_HC, - USBMODE_CM_HC); - /* Select PHY interface after setting host mode */ - clrsetbits_le32(&usbctlr->hostpc1_devlc, PTS_MASK, - PTS_UTMI << PTS_SHIFT); - clrbits_le32(&usbctlr->hostpc1_devlc, STS); -#endif + init_phy_mux(config, PTS_UTMI);
/* Deassert power down state */ clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_FORCE_PD_POWERDOWN | @@ -561,17 +569,7 @@ static int init_ulpi_usb_controller(struct fdt_usb *config) ULPI_CLKOUT_PINMUX_BYP | ULPI_OUTPUT_PINMUX_BYP);
/* Select ULPI parallel interface */ -#if defined(CONFIG_TEGRA20) - clrsetbits_le32(&usbctlr->port_sc1, PTS_MASK, - PTS_ULPI << PTS_SHIFT); -#else - /* Set to Host mode after Controller Reset was done */ - clrsetbits_le32(&usbctlr->usb_mode, USBMODE_CM_HC, - USBMODE_CM_HC); - /* Select PHY interface after setting host mode */ - clrsetbits_le32(&usbctlr->hostpc1_devlc, PTS_MASK, - PTS_ULPI << PTS_SHIFT); -#endif + init_phy_mux(config, PTS_ULPI);
/* enable ULPI transceiver */ setbits_le32(&usbctlr->susp_ctrl, ULPI_PHY_ENB);

From: Stephen Warren swarren@nvidia.com
A few changes are made to the Tegra EHCI driver so that it can set everything up for device-mode operation on the first USB controller. This can be used in conjunction with ci_udc.c to operate as a USB device.
Detailed changes are:
* Rename set_host_mode() to set_up_vbus() since that's really what it does.
* Modify set_up_vbus() to know whether it's initializing in host or device mode, and:
- Skip the external VBUS check in device mode, since external VBUS is expected in this case.
- Disable VBUS output in device mode.
* Modify init_phy_mux() to know whether it's initializing in host or device mode, and hence skip setting USBMODE_CM_HC (which enables host mode) in device mode. See the comments in that function for why this is safe w.r.t. the ordering requirements of PHY selection.
* Modify init_utmi_usb_controller() to force "b session valid" in device mode, since the HW requires this. This is done in UTMI-specific code, since we only support device mode on the first USB controller, and that controller can only talk to a UTMI PHY.
* Enhance ehci_hcd_init() to error-check the requested host-/device-mode vs. the dr_mode (dual-role mode) value present in device tree, and the HW configurations which support device mode.
* Enhance ehci_hcd_init() not to skip HW initialization when switching between host and device mode on a controller. This requires remembering which mode the last initialization used.
Cc: Jim Lin jilin@nvidia.com Cc: Stefan Agner stefan@agner.ch Signed-off-by: Stephen Warren swarren@nvidia.com --- arch/arm/include/asm/arch-tegra/usb.h | 2 + drivers/usb/host/ehci-tegra.c | 114 +++++++++++++++++++++++++--------- 2 files changed, 86 insertions(+), 30 deletions(-)
diff --git a/arch/arm/include/asm/arch-tegra/usb.h b/arch/arm/include/asm/arch-tegra/usb.h index ceb7bcd9cfb9..c817088fa57e 100644 --- a/arch/arm/include/asm/arch-tegra/usb.h +++ b/arch/arm/include/asm/arch-tegra/usb.h @@ -349,6 +349,8 @@ struct usb_ctlr {
/* USB3_IF_USB_PHY_VBUS_SENSORS_0 */ #define VBUS_VLD_STS (1 << 26) +#define VBUS_B_SESS_VLD_SW_VALUE (1 << 12) +#define VBUS_B_SESS_VLD_SW_EN (1 << 11)
/* Setup USB on the board */ int usb_process_devicetree(const void *blob); diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 55a546e4d3da..33e5ea9ebdd0 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -69,6 +69,7 @@ struct fdt_usb { unsigned enabled:1; /* 1 to enable, 0 to disable */ unsigned has_legacy_mode:1; /* 1 if this port has legacy mode */ unsigned initialized:1; /* has this port already been initialized? */ + enum usb_init_type init_type; enum dr_mode dr_mode; /* dual role mode */ enum periph_id periph_id;/* peripheral id */ struct fdt_gpio_state vbus_gpio; /* GPIO for vbus enable */ @@ -237,29 +238,31 @@ int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg) return PORTSC_PSPD(reg); }
-/* Put the port into host mode */ -static void set_host_mode(struct fdt_usb *config) +/* Set up VBUS for host/device mode */ +static void set_up_vbus(struct fdt_usb *config, enum usb_init_type init) { /* - * If we are an OTG port, check if remote host is driving VBus and - * bail out in this case. + * If we are an OTG port initializing in host mode, + * check if remote host is driving VBus and bail out in this case. */ - if (config->dr_mode == DR_MODE_OTG && - (readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS)) + if (init == USB_INIT_HOST && + config->dr_mode == DR_MODE_OTG && + (readl(&config->reg->phy_vbus_sensors) & VBUS_VLD_STS)) { + printf("tegrausb: VBUS input active; not enabling as host\n"); return; + }
- /* - * If not driving, we set the GPIO to enable VBUS. We assume - * that the pinmux is set up correctly for this. - */ if (fdt_gpio_isvalid(&config->vbus_gpio)) { + int vbus_value; + fdtdec_setup_gpio(&config->vbus_gpio); - gpio_direction_output(config->vbus_gpio.gpio, - (config->vbus_gpio.flags & FDT_GPIO_ACTIVE_LOW) ? - 0 : 1); - debug("set_host_mode: GPIO %d %s\n", config->vbus_gpio.gpio, - (config->vbus_gpio.flags & FDT_GPIO_ACTIVE_LOW) ? - "low" : "high"); + + vbus_value = (init == USB_INIT_HOST) ^ + !!(config->vbus_gpio.flags & FDT_GPIO_ACTIVE_LOW); + gpio_direction_output(config->vbus_gpio.gpio, vbus_value); + + debug("set_up_vbus: GPIO %d %d\n", config->vbus_gpio.gpio, + vbus_value); } }
@@ -294,7 +297,8 @@ static const unsigned *get_pll_timing(void) }
/* select the PHY to use with a USB controller */ -static void init_phy_mux(struct fdt_usb *config, uint pts) +static void init_phy_mux(struct fdt_usb *config, uint pts, + enum usb_init_type init) { struct usb_ctlr *usbctlr = config->reg;
@@ -309,10 +313,16 @@ static void init_phy_mux(struct fdt_usb *config, uint pts) clrbits_le32(&usbctlr->port_sc1, STS); } #else - /* Set to Host mode after Controller Reset was done */ + /* Set to Host mode (if applicable) after Controller Reset was done */ clrsetbits_le32(&usbctlr->usb_mode, USBMODE_CM_HC, - USBMODE_CM_HC); - /* Select PHY interface after setting host mode */ + (init == USB_INIT_HOST) ? USBMODE_CM_HC : 0); + /* + * Select PHY interface after setting host mode. + * For device mode, the ordering requirement is not an issue, since + * only the first USB controller supports device mode, and that USB + * controller can only talk to a UTMI PHY, so the PHY selection is + * already made at reset time, so this write is a no-op. + */ clrsetbits_le32(&usbctlr->hostpc1_devlc, PTS_MASK, pts << PTS_SHIFT); clrbits_le32(&usbctlr->hostpc1_devlc, STS); @@ -320,9 +330,10 @@ static void init_phy_mux(struct fdt_usb *config, uint pts) }
/* set up the UTMI USB controller with the parameters provided */ -static int init_utmi_usb_controller(struct fdt_usb *config) +static int init_utmi_usb_controller(struct fdt_usb *config, + enum usb_init_type init) { - u32 val; + u32 b_sess_valid_mask, val; int loop_count; const unsigned *timing; struct usb_ctlr *usbctlr = config->reg; @@ -340,6 +351,10 @@ static int init_utmi_usb_controller(struct fdt_usb *config) /* Follow the crystal clock disable by >100ns delay */ udelay(1);
+ b_sess_valid_mask = (VBUS_B_SESS_VLD_SW_VALUE | VBUS_B_SESS_VLD_SW_EN); + clrsetbits_le32(&usbctlr->phy_vbus_sensors, b_sess_valid_mask, + (init == USB_INIT_DEVICE) ? b_sess_valid_mask : 0); + /* * To Use the A Session Valid for cable detection logic, VBUS_WAKEUP * mux must be switched to actually use a_sess_vld threshold. @@ -511,7 +526,7 @@ static int init_utmi_usb_controller(struct fdt_usb *config) clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1);
/* Select UTMI parallel interface */ - init_phy_mux(config, PTS_UTMI); + init_phy_mux(config, PTS_UTMI, init);
/* Deassert power down state */ clrbits_le32(&usbctlr->utmip_xcvr_cfg0, UTMIP_FORCE_PD_POWERDOWN | @@ -541,7 +556,8 @@ static int init_utmi_usb_controller(struct fdt_usb *config) #endif
/* set up the ULPI USB controller with the parameters provided */ -static int init_ulpi_usb_controller(struct fdt_usb *config) +static int init_ulpi_usb_controller(struct fdt_usb *config, + enum usb_init_type init) { u32 val; int loop_count; @@ -569,7 +585,7 @@ static int init_ulpi_usb_controller(struct fdt_usb *config) ULPI_CLKOUT_PINMUX_BYP | ULPI_OUTPUT_PINMUX_BYP);
/* Select ULPI parallel interface */ - init_phy_mux(config, PTS_ULPI); + init_phy_mux(config, PTS_ULPI, init);
/* enable ULPI transceiver */ setbits_le32(&usbctlr->susp_ctrl, ULPI_PHY_ENB); @@ -618,7 +634,8 @@ static int init_ulpi_usb_controller(struct fdt_usb *config) return 0; } #else -static int init_ulpi_usb_controller(struct fdt_usb *config) +static int init_ulpi_usb_controller(struct fdt_usb *config, + enum usb_init_type init) { printf("No code to set up ULPI controller, please enable" "CONFIG_USB_ULPI and CONFIG_USB_ULPI_VIEWPORT"); @@ -771,23 +788,60 @@ int ehci_hcd_init(int index, enum usb_init_type init,
config = &port[index];
+ switch (init) { + case USB_INIT_HOST: + switch (config->dr_mode) { + case DR_MODE_HOST: + case DR_MODE_OTG: + break; + default: + printf("tegrausb: Invalid dr_mode %d for host mode\n", + config->dr_mode); + return -1; + } + break; + case USB_INIT_DEVICE: + if (config->periph_id != PERIPH_ID_USBD) { + printf("tegrausb: Device mode only supported on first USB controller\n"); + return -1; + } + if (!config->utmi) { + printf("tegrausb: Device mode only supported with UTMI PHY\n"); + return -1; + } + switch (config->dr_mode) { + case DR_MODE_DEVICE: + case DR_MODE_OTG: + break; + default: + printf("tegrausb: Invalid dr_mode %d for device mode\n", + config->dr_mode); + return -1; + } + break; + default: + printf("tegrausb: Unknown USB_INIT_* %d\n", init); + return -1; + } + /* skip init, if the port is already initialized */ - if (config->initialized) + if (config->initialized && config->init_type == init) goto success;
- if (config->utmi && init_utmi_usb_controller(config)) { + if (config->utmi && init_utmi_usb_controller(config, init)) { printf("tegrausb: Cannot init port %d\n", index); return -1; }
- if (config->ulpi && init_ulpi_usb_controller(config)) { + if (config->ulpi && init_ulpi_usb_controller(config, init)) { printf("tegrausb: Cannot init port %d\n", index); return -1; }
- set_host_mode(config); + set_up_vbus(config, init);
config->initialized = 1; + config->init_type = init;
success: usbctlr = config->reg;

On Wednesday, April 30, 2014 at 11:09:55 PM, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
The TRM for Tegra30 and later all state that USBMODE_CM_HC must be set before writing to hostpc1_devlc to select which PHY to use for a USB controller. However, neither init_{utmi,ulpi}_usb_controller() do this today, so the register writes they perform for PHY selection do not work.
For the UTMI case, this was hacked around in commit 7e44d9320ed4 "ARM: Tegra: USB: EHCI: Add support for Tegra30/Tegra114" by adding code to ehci_hcd_init() which sets USBMODE_CM_HC and duplicates the PHY selection register write. This code doesn't cover the ULPI case, so I wouldn't be surprised if ULPI doesn't work with the current code, unless the ordering requirement only ends up being an issue in HW for UTMI not ULPI.
This patch fixes init_{utmi,ulpi}_usb_controller() to correctly set USBMODE_CM_HC before selecting the PHY. Now that this works, we can remove the duplicate UTMI-specific code in ehci_hcd_init(), thus simplifying that function.
This doesn't apply on u-boot-usb/master , so I cannot pick this, sorry .
Best regards, Marek Vasut

On 05/01/2014 04:49 AM, Marek Vasut wrote:
On Wednesday, April 30, 2014 at 11:09:55 PM, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
The TRM for Tegra30 and later all state that USBMODE_CM_HC must be set before writing to hostpc1_devlc to select which PHY to use for a USB controller. However, neither init_{utmi,ulpi}_usb_controller() do this today, so the register writes they perform for PHY selection do not work.
For the UTMI case, this was hacked around in commit 7e44d9320ed4 "ARM: Tegra: USB: EHCI: Add support for Tegra30/Tegra114" by adding code to ehci_hcd_init() which sets USBMODE_CM_HC and duplicates the PHY selection register write. This code doesn't cover the ULPI case, so I wouldn't be surprised if ULPI doesn't work with the current code, unless the ordering requirement only ends up being an issue in HW for UTMI not ULPI.
This patch fixes init_{utmi,ulpi}_usb_controller() to correctly set USBMODE_CM_HC before selecting the PHY. Now that this works, we can remove the duplicate UTMI-specific code in ehci_hcd_init(), thus simplifying that function.
This doesn't apply on u-boot-usb/master , so I cannot pick this, sorry .
Ah right. That's because I'm working on top of a merge of u-boot-arm/master and u-boot/master, and that includes the following changes to the Tegra USB driver that went in through u-boot-tegra/master -> u-boot-arm/master rather than the USB tree:
8f9fd6caafb8 usb: tegra: combine header file b1d615f3f102 usb: tegra: fix PHY configuration b03f4b3742a7 usb: tegra: fix USB2 powerdown for Tegra30 and later
What's the best fix here:
* Wait until the previous patches get into u-boot/master, and u-boot-usb/master picks them up, and then apply this series.
* Apply this series to u-boot-tegra/master with your ack?
There's little point my rebasing this series on top of u-boot-usb/master, and applying it right now, since that will just cause the same conflicts when u-boot-usb/master gets merged into u-boot/master.
Thanks.

On Thursday, May 01, 2014 at 06:56:24 PM, Stephen Warren wrote:
On 05/01/2014 04:49 AM, Marek Vasut wrote:
On Wednesday, April 30, 2014 at 11:09:55 PM, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
The TRM for Tegra30 and later all state that USBMODE_CM_HC must be set before writing to hostpc1_devlc to select which PHY to use for a USB controller. However, neither init_{utmi,ulpi}_usb_controller() do this today, so the register writes they perform for PHY selection do not work.
For the UTMI case, this was hacked around in commit 7e44d9320ed4 "ARM: Tegra: USB: EHCI: Add support for Tegra30/Tegra114" by adding code to ehci_hcd_init() which sets USBMODE_CM_HC and duplicates the PHY selection register write. This code doesn't cover the ULPI case, so I wouldn't be surprised if ULPI doesn't work with the current code, unless the ordering requirement only ends up being an issue in HW for UTMI not ULPI.
This patch fixes init_{utmi,ulpi}_usb_controller() to correctly set USBMODE_CM_HC before selecting the PHY. Now that this works, we can remove the duplicate UTMI-specific code in ehci_hcd_init(), thus simplifying that function.
This doesn't apply on u-boot-usb/master , so I cannot pick this, sorry .
Ah right. That's because I'm working on top of a merge of u-boot-arm/master and u-boot/master, and that includes the following changes to the Tegra USB driver that went in through u-boot-tegra/master -> u-boot-arm/master rather than the USB tree:
8f9fd6caafb8 usb: tegra: combine header file b1d615f3f102 usb: tegra: fix PHY configuration b03f4b3742a7 usb: tegra: fix USB2 powerdown for Tegra30 and later
What's the best fix here:
- Wait until the previous patches get into u-boot/master, and
u-boot-usb/master picks them up, and then apply this series.
- Apply this series to u-boot-tegra/master with your ack?
There's little point my rebasing this series on top of u-boot-usb/master, and applying it right now, since that will just cause the same conflicts when u-boot-usb/master gets merged into u-boot/master.
Fine, can you poke me when this happens so I can apply ?
Thanks!
Best regards, Marek Vasut

On 05/01/2014 10:47 PM, Marek Vasut wrote:
On Thursday, May 01, 2014 at 06:56:24 PM, Stephen Warren wrote:
On 05/01/2014 04:49 AM, Marek Vasut wrote:
On Wednesday, April 30, 2014 at 11:09:55 PM, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
The TRM for Tegra30 and later all state that USBMODE_CM_HC must be set before writing to hostpc1_devlc to select which PHY to use for a USB controller. However, neither init_{utmi,ulpi}_usb_controller() do this today, so the register writes they perform for PHY selection do not work.
For the UTMI case, this was hacked around in commit 7e44d9320ed4 "ARM: Tegra: USB: EHCI: Add support for Tegra30/Tegra114" by adding code to ehci_hcd_init() which sets USBMODE_CM_HC and duplicates the PHY selection register write. This code doesn't cover the ULPI case, so I wouldn't be surprised if ULPI doesn't work with the current code, unless the ordering requirement only ends up being an issue in HW for UTMI not ULPI.
This patch fixes init_{utmi,ulpi}_usb_controller() to correctly set USBMODE_CM_HC before selecting the PHY. Now that this works, we can remove the duplicate UTMI-specific code in ehci_hcd_init(), thus simplifying that function.
This doesn't apply on u-boot-usb/master , so I cannot pick this, sorry .
Ah right. That's because I'm working on top of a merge of u-boot-arm/master and u-boot/master, and that includes the following changes to the Tegra USB driver that went in through u-boot-tegra/master -> u-boot-arm/master rather than the USB tree:
8f9fd6caafb8 usb: tegra: combine header file b1d615f3f102 usb: tegra: fix PHY configuration b03f4b3742a7 usb: tegra: fix USB2 powerdown for Tegra30 and later
What's the best fix here:
- Wait until the previous patches get into u-boot/master, and
u-boot-usb/master picks them up, and then apply this series.
- Apply this series to u-boot-tegra/master with your ack?
There's little point my rebasing this series on top of u-boot-usb/master, and applying it right now, since that will just cause the same conflicts when u-boot-usb/master gets merged into u-boot/master.
Fine, can you poke me when this happens so I can apply ?
Everything that's needed to apply these patches is now in u-boot/master. I validated that the patches apply there without git issues.

On 05/01/2014 10:47 PM, Marek Vasut wrote:
On Thursday, May 01, 2014 at 06:56:24 PM, Stephen Warren wrote:
On 05/01/2014 04:49 AM, Marek Vasut wrote:
On Wednesday, April 30, 2014 at 11:09:55 PM, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
The TRM for Tegra30 and later all state that USBMODE_CM_HC must be set before writing to hostpc1_devlc to select which PHY to use for a USB controller. However, neither init_{utmi,ulpi}_usb_controller() do this today, so the register writes they perform for PHY selection do not work.
For the UTMI case, this was hacked around in commit 7e44d9320ed4 "ARM: Tegra: USB: EHCI: Add support for Tegra30/Tegra114" by adding code to ehci_hcd_init() which sets USBMODE_CM_HC and duplicates the PHY selection register write. This code doesn't cover the ULPI case, so I wouldn't be surprised if ULPI doesn't work with the current code, unless the ordering requirement only ends up being an issue in HW for UTMI not ULPI.
This patch fixes init_{utmi,ulpi}_usb_controller() to correctly set USBMODE_CM_HC before selecting the PHY. Now that this works, we can remove the duplicate UTMI-specific code in ehci_hcd_init(), thus simplifying that function.
This doesn't apply on u-boot-usb/master , so I cannot pick this, sorry .
Ah right. That's because I'm working on top of a merge of u-boot-arm/master and u-boot/master, and that includes the following changes to the Tegra USB driver that went in through u-boot-tegra/master -> u-boot-arm/master rather than the USB tree:
8f9fd6caafb8 usb: tegra: combine header file b1d615f3f102 usb: tegra: fix PHY configuration b03f4b3742a7 usb: tegra: fix USB2 powerdown for Tegra30 and later
What's the best fix here:
- Wait until the previous patches get into u-boot/master, and
u-boot-usb/master picks them up, and then apply this series.
- Apply this series to u-boot-tegra/master with your ack?
There's little point my rebasing this series on top of u-boot-usb/master, and applying it right now, since that will just cause the same conflicts when u-boot-usb/master gets merged into u-boot/master.
Fine, can you poke me when this happens so I can apply ?
Marek, these patches should apply now. I assume you still have a copy, or should I resend them?

On Wednesday, May 14, 2014 at 07:26:36 PM, Stephen Warren wrote:
On 05/01/2014 10:47 PM, Marek Vasut wrote:
On Thursday, May 01, 2014 at 06:56:24 PM, Stephen Warren wrote:
On 05/01/2014 04:49 AM, Marek Vasut wrote:
On Wednesday, April 30, 2014 at 11:09:55 PM, Stephen Warren wrote:
From: Stephen Warren swarren@nvidia.com
The TRM for Tegra30 and later all state that USBMODE_CM_HC must be set before writing to hostpc1_devlc to select which PHY to use for a USB controller. However, neither init_{utmi,ulpi}_usb_controller() do this today, so the register writes they perform for PHY selection do not work.
For the UTMI case, this was hacked around in commit 7e44d9320ed4 "ARM: Tegra: USB: EHCI: Add support for Tegra30/Tegra114" by adding code to ehci_hcd_init() which sets USBMODE_CM_HC and duplicates the PHY selection register write. This code doesn't cover the ULPI case, so I wouldn't be surprised if ULPI doesn't work with the current code, unless the ordering requirement only ends up being an issue in HW for UTMI not ULPI.
This patch fixes init_{utmi,ulpi}_usb_controller() to correctly set USBMODE_CM_HC before selecting the PHY. Now that this works, we can remove the duplicate UTMI-specific code in ehci_hcd_init(), thus simplifying that function.
This doesn't apply on u-boot-usb/master , so I cannot pick this, sorry .
Applied, thanks.
Best regards, Marek Vasut

Am 2014-04-30 23:09, schrieb Stephen Warren:
From: Stephen Warren swarren@nvidia.com
The TRM for Tegra30 and later all state that USBMODE_CM_HC must be set before writing to hostpc1_devlc to select which PHY to use for a USB controller. However, neither init_{utmi,ulpi}_usb_controller() do this today, so the register writes they perform for PHY selection do not work.
For the UTMI case, this was hacked around in commit 7e44d9320ed4 "ARM: Tegra: USB: EHCI: Add support for Tegra30/Tegra114" by adding code to ehci_hcd_init() which sets USBMODE_CM_HC and duplicates the PHY selection register write. This code doesn't cover the ULPI case, so I wouldn't be surprised if ULPI doesn't work with the current code, unless the ordering requirement only ends up being an issue in HW for UTMI not ULPI.
On Toradex Colibri T30, all USB, including USB2, are using the UTMI phy. I successfully tested this patchset on the Colibri T30 module (not yet in mainline U-Boot).
Tested-by stefan@agner.ch
-- Stefan
participants (3)
-
Marek Vasut
-
Stefan Agner
-
Stephen Warren