From: Mike Thompson <mpthompson@xxxxxxxxx> 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 <mpthompson@xxxxxxxxx> Signed-off-by: Fabio Estevam <fabio.estevam@xxxxxxxxxxxxx> --- 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html