Skip to contentSkip to conversation

usb: tegra: fix PHY selection code

PATCH New Stephen Warren 3 participants 10 messages Apr 30, 2014 – May 14, 2014

Subsystems (4)
lore
Share & tools
lore
#0 lore raw

PATCH 1/3 usb: tegra: fix PHY selection code

From: Stephen Warren <[email protected]>

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.

---
 drivers/usb/host/ehci-tegra.c | 21 ++++++++-------------
 1 file changed, 8 insertions(+), 13 deletions(-)
drivers/usb/host/ehci-tegra.c +8 -13
index 38db18e2c9ea..9a9a1277d160 100644
@@ -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;
 }
 
Signature · 1 line
1.8.1.5
#1 lore raw

PATCH 2/3 usb: tegra: refactor PHY type selection

From: Stephen Warren <[email protected]>

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.

---
 drivers/usb/host/ehci-tegra.c | 58 +++++++++++++++++++++----------------------
 1 file changed, 28 insertions(+), 30 deletions(-)
drivers/usb/host/ehci-tegra.c +28 -30
index 9a9a1277d160..55a546e4d3da 100644
@@ -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);
Signature · 1 line
1.8.1.5
#2 lore raw

PATCH 3/3 usb: tegra: support device mode

In reply to Stephen Warren

From: Stephen Warren <[email protected]>

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.

---
 arch/arm/include/asm/arch-tegra/usb.h |   2 +
 drivers/usb/host/ehci-tegra.c         | 114 +++++++++++++++++++++++++---------
 2 files changed, 86 insertions(+), 30 deletions(-)
arch/arm/include/asm/arch-tegra/usb.h +2 -0
index ceb7bcd9cfb9..c817088fa57e 100644
@@ -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);
drivers/usb/host/ehci-tegra.c +84 -30

202 lines not on this page · raw message

Signature · 1 line
1.8.1.5
#3 lore raw

PATCH 1/3 usb: tegra: fix PHY selection code

In reply to Stephen Warren
Quoted 16 lines · Stephen Warren

From: Stephen Warren <[email protected]>

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.

Quoted 4 lines

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

#4 lore raw

PATCH 1/3 usb: tegra: fix PHY selection code

Quoted 17 lines · Marek Vasut
Quoted 16 lines · Stephen Warren

From: Stephen Warren <[email protected]>

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.

Quoted 6 lines
Quoted 4 lines

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.

#5 lore raw

PATCH 1/3 usb: tegra: fix PHY selection code

Quoted 36 lines · Stephen Warren
Quoted 17 lines · Marek Vasut
Quoted 16 lines · Stephen Warren

From: Stephen Warren <[email protected]>

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.

Quoted 6 lines
Quoted 4 lines

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:

Quoted 8 lines

* 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

#6 lore raw

PATCH 1/3 usb: tegra: fix PHY selection code

Quoted 40 lines · Marek Vasut
Quoted 39 lines · Stephen Warren
Quoted 17 lines · Marek Vasut
Quoted 16 lines · Stephen Warren

From: Stephen Warren <[email protected]>

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.

Quoted 6 lines
Quoted 4 lines

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.

Quoted 7 lines
Quoted 5 lines

* 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.

#7 lore raw

PATCH 1/3 usb: tegra: fix PHY selection code

In reply to Marek Vasut
Quoted 40 lines · Marek Vasut
Quoted 39 lines · Stephen Warren
Quoted 17 lines · Marek Vasut
Quoted 16 lines · Stephen Warren

From: Stephen Warren <[email protected]>

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.

Quoted 6 lines
Quoted 4 lines

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.

Quoted 7 lines
Quoted 5 lines

* 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?

Applied
#8 lore raw

PATCH 1/3 usb: tegra: fix PHY selection code

Quoted 20 lines · Stephen Warren
Quoted 19 lines · Marek Vasut
Quoted 18 lines · Stephen Warren
Quoted 17 lines · Marek Vasut
Quoted 16 lines · Stephen Warren

From: Stephen Warren <[email protected]>

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.

Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
Quoted 4 lines

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

#9 lore raw

PATCH 1/3 usb: tegra: fix PHY selection code

In reply to Stephen Warren

Am 2014-04-30 23:09, schrieb Stephen Warren:

Quoted 8 lines

From: Stephen Warren <[email protected]>

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.

Quoted 7 lines

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 <[email protected]>

--
Stefan