summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2014-04-30 15:09:55 -0600
committerMarek Vasut <marex@denx.de>2014-05-15 00:21:17 +0200
commit9b20fe6f1affdfc7441481dc0acb55eadd80134f (patch)
treed5f594acdc8e9509dda572fe3e125cf0303931e7
parent4180b3dba25c2c28cc4502f1c9f1cbad2a9972b8 (diff)
downloadu-boot-imx-9b20fe6f1affdfc7441481dc0acb55eadd80134f.zip
u-boot-imx-9b20fe6f1affdfc7441481dc0acb55eadd80134f.tar.gz
u-boot-imx-9b20fe6f1affdfc7441481dc0acb55eadd80134f.tar.bz2
usb: tegra: fix PHY selection code
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>
-rw-r--r--drivers/usb/host/ehci-tegra.c21
1 files changed, 8 insertions, 13 deletions
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 38db18e..9a9a127 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;
}