usb: tegra: fix PHY selection code
authorStephen Warren <swarren@nvidia.com>
Wed, 30 Apr 2014 21:09:55 +0000 (15:09 -0600)
committerMarek Vasut <marex@denx.de>
Wed, 14 May 2014 22:21:17 +0000 (00:21 +0200)
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

index 38db18e2c9ea34c56140ee9385579cc5c34cfbc8..9a9a1277d1604b88e375cb79937148eadc2f20ad 100644 (file)
@@ -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;
 }