From: Mike Thompson <mpthomp...@gmail.com>

Improve error reporting for USB device reset and initialization.

Add device definitions for proper use of the clear register with the
specific bits required to power up the USB device upon initialization and
to power down upon shutdown.

Signed-off-by: Mike Thompson <mpthomp...@gmail.com>
Signed-off-by: Fabio Estevam <fabio.este...@freescale.com>
---
 drivers/usb/otg/mxs-phy.c |   57 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 51 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/otg/mxs-phy.c b/drivers/usb/otg/mxs-phy.c
index 8188380..93a48ce 100644
--- a/drivers/usb/otg/mxs-phy.c
+++ b/drivers/usb/otg/mxs-phy.c
@@ -25,10 +25,19 @@
 #define DRIVER_NAME "mxs_phy"
 
 #define HW_USBPHY_PWD                          0x00
+#define HW_USBPHY_PWD_SET                      0x04
+#define HW_USBPHY_PWD_CLR                      0x08
 #define HW_USBPHY_CTRL                         0x30
 #define HW_USBPHY_CTRL_SET                     0x34
 #define HW_USBPHY_CTRL_CLR                     0x38
 
+#define BM_USBPHY_PWD_RXPWDRX                  BIT(20)
+#define BM_USBPHY_PWD_RXPWDIFF                 BIT(19)
+#define BM_USBPHY_PWD_RXPWD1PT1                        BIT(18)
+#define BM_USBPHY_PWD_RXPWDENV                 BIT(17)
+#define BM_USBPHY_PWD_TXPWDV2I                 BIT(12)
+#define BM_USBPHY_PWD_TXPWDIBIAS               BIT(11)
+#define BM_USBPHY_PWD_TXPWDFS                  BIT(10)
 #define BM_USBPHY_CTRL_SFTRST                  BIT(31)
 #define BM_USBPHY_CTRL_CLKGATE                 BIT(30)
 #define BM_USBPHY_CTRL_ENUTMILEVEL3            BIT(15)
@@ -45,36 +54,72 @@ struct mxs_phy {
 
 #define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
 
-static void mxs_phy_hw_init(struct mxs_phy *mxs_phy)
+static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
 {
+       int ret;
        void __iomem *base = mxs_phy->phy.io_priv;
 
-       stmp_reset_block(base + HW_USBPHY_CTRL);
+       /*
+        * Use global device reset function.  Side effect of this
+        * is to soft reset USBPHY_PWD, USBPHY_TX, USBPHY_RX,
+        * and USBPHY_CTRL registers.
+        */
+       ret = stmp_reset_block(base + HW_USBPHY_CTRL);
+       if (ret) {
+               dev_err(mxs_phy->phy.dev, "USB PHY reset failed: %d\n", ret);
+               return ret;
+       }
 
-       /* Power up the PHY */
-       writel_relaxed(0, base + HW_USBPHY_PWD);
+       /* Enable the USB PHY clock after reset. */
+       writel_relaxed(BM_USBPHY_CTRL_SFTRST |
+                       BM_USBPHY_CTRL_CLKGATE,
+                       base + HW_USBPHY_CTRL_CLR);
+
+       /* Power up the PHY after reset. */
+       writel_relaxed(BM_USBPHY_PWD_RXPWDRX |
+                       BM_USBPHY_PWD_RXPWDIFF |
+                       BM_USBPHY_PWD_RXPWD1PT1 |
+                       BM_USBPHY_PWD_RXPWDENV |
+                       BM_USBPHY_PWD_TXPWDV2I |
+                       BM_USBPHY_PWD_TXPWDIBIAS |
+                       BM_USBPHY_PWD_TXPWDFS,
+                       base + HW_USBPHY_PWD_CLR);
 
        /* enable FS/LS device */
        writel_relaxed(BM_USBPHY_CTRL_ENUTMILEVEL2 |
                        BM_USBPHY_CTRL_ENUTMILEVEL3,
                        base + HW_USBPHY_CTRL_SET);
+
+       return 0;
 }
 
 static int mxs_phy_init(struct usb_phy *phy)
 {
+       int ret;
        struct mxs_phy *mxs_phy = to_mxs_phy(phy);
 
        clk_prepare_enable(mxs_phy->clk);
-       mxs_phy_hw_init(mxs_phy);
+       ret = mxs_phy_hw_init(mxs_phy);
        INIT_DELAYED_WORK(&mxs_phy->enhostdiscondetect_work, NULL);
 
-       return 0;
+       return ret;
 }
 
 static void mxs_phy_shutdown(struct usb_phy *phy)
 {
        struct mxs_phy *mxs_phy = to_mxs_phy(phy);
 
+       /* Power down USB receivers and transmitters. */
+       writel_relaxed(BM_USBPHY_PWD_RXPWDRX |
+                       BM_USBPHY_PWD_RXPWDIFF |
+                       BM_USBPHY_PWD_RXPWD1PT1 |
+                       BM_USBPHY_PWD_RXPWDENV |
+                       BM_USBPHY_PWD_TXPWDV2I |
+                       BM_USBPHY_PWD_TXPWDIBIAS |
+                       BM_USBPHY_PWD_TXPWDFS,
+                       phy->io_priv + HW_USBPHY_PWD_SET);
+
+       /* Disable USB PHY clock. */
        writel_relaxed(BM_USBPHY_CTRL_CLKGATE,
                        phy->io_priv + HW_USBPHY_CTRL_SET);
 
-- 
1.7.9.5


--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to