Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Copyright 2012-2014 Freescale Semiconductor, Inc.
0004  * Copyright (C) 2012 Marek Vasut <marex@denx.de>
0005  * on behalf of DENX Software Engineering GmbH
0006  */
0007 
0008 #include <linux/module.h>
0009 #include <linux/kernel.h>
0010 #include <linux/platform_device.h>
0011 #include <linux/clk.h>
0012 #include <linux/usb/otg.h>
0013 #include <linux/stmp_device.h>
0014 #include <linux/delay.h>
0015 #include <linux/err.h>
0016 #include <linux/io.h>
0017 #include <linux/of_device.h>
0018 #include <linux/regmap.h>
0019 #include <linux/mfd/syscon.h>
0020 #include <linux/iopoll.h>
0021 
0022 #define DRIVER_NAME "mxs_phy"
0023 
0024 /* Register Macro */
0025 #define HW_USBPHY_PWD               0x00
0026 #define HW_USBPHY_TX                0x10
0027 #define HW_USBPHY_CTRL              0x30
0028 #define HW_USBPHY_CTRL_SET          0x34
0029 #define HW_USBPHY_CTRL_CLR          0x38
0030 
0031 #define HW_USBPHY_DEBUG_SET         0x54
0032 #define HW_USBPHY_DEBUG_CLR         0x58
0033 
0034 #define HW_USBPHY_IP                0x90
0035 #define HW_USBPHY_IP_SET            0x94
0036 #define HW_USBPHY_IP_CLR            0x98
0037 
0038 #define GM_USBPHY_TX_TXCAL45DP(x)            (((x) & 0xf) << 16)
0039 #define GM_USBPHY_TX_TXCAL45DN(x)            (((x) & 0xf) << 8)
0040 #define GM_USBPHY_TX_D_CAL(x)                (((x) & 0xf) << 0)
0041 
0042 /* imx7ulp */
0043 #define HW_USBPHY_PLL_SIC           0xa0
0044 #define HW_USBPHY_PLL_SIC_SET           0xa4
0045 #define HW_USBPHY_PLL_SIC_CLR           0xa8
0046 
0047 #define BM_USBPHY_CTRL_SFTRST           BIT(31)
0048 #define BM_USBPHY_CTRL_CLKGATE          BIT(30)
0049 #define BM_USBPHY_CTRL_OTG_ID_VALUE     BIT(27)
0050 #define BM_USBPHY_CTRL_ENAUTOSET_USBCLKS    BIT(26)
0051 #define BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE BIT(25)
0052 #define BM_USBPHY_CTRL_ENVBUSCHG_WKUP       BIT(23)
0053 #define BM_USBPHY_CTRL_ENIDCHG_WKUP     BIT(22)
0054 #define BM_USBPHY_CTRL_ENDPDMCHG_WKUP       BIT(21)
0055 #define BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD    BIT(20)
0056 #define BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE    BIT(19)
0057 #define BM_USBPHY_CTRL_ENAUTO_PWRON_PLL     BIT(18)
0058 #define BM_USBPHY_CTRL_ENUTMILEVEL3     BIT(15)
0059 #define BM_USBPHY_CTRL_ENUTMILEVEL2     BIT(14)
0060 #define BM_USBPHY_CTRL_ENHOSTDISCONDETECT   BIT(1)
0061 
0062 #define BM_USBPHY_IP_FIX                       (BIT(17) | BIT(18))
0063 
0064 #define BM_USBPHY_DEBUG_CLKGATE         BIT(30)
0065 /* imx7ulp */
0066 #define BM_USBPHY_PLL_LOCK          BIT(31)
0067 #define BM_USBPHY_PLL_REG_ENABLE        BIT(21)
0068 #define BM_USBPHY_PLL_BYPASS            BIT(16)
0069 #define BM_USBPHY_PLL_POWER         BIT(12)
0070 #define BM_USBPHY_PLL_EN_USB_CLKS       BIT(6)
0071 
0072 /* Anatop Registers */
0073 #define ANADIG_ANA_MISC0            0x150
0074 #define ANADIG_ANA_MISC0_SET            0x154
0075 #define ANADIG_ANA_MISC0_CLR            0x158
0076 
0077 #define ANADIG_USB1_CHRG_DETECT_SET     0x1b4
0078 #define ANADIG_USB1_CHRG_DETECT_CLR     0x1b8
0079 #define ANADIG_USB2_CHRG_DETECT_SET     0x214
0080 #define ANADIG_USB1_CHRG_DETECT_EN_B        BIT(20)
0081 #define ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B  BIT(19)
0082 #define ANADIG_USB1_CHRG_DETECT_CHK_CONTACT BIT(18)
0083 
0084 #define ANADIG_USB1_VBUS_DET_STAT       0x1c0
0085 #define ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID    BIT(3)
0086 
0087 #define ANADIG_USB1_CHRG_DET_STAT       0x1d0
0088 #define ANADIG_USB1_CHRG_DET_STAT_DM_STATE  BIT(2)
0089 #define ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED BIT(1)
0090 #define ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT  BIT(0)
0091 
0092 #define ANADIG_USB2_VBUS_DET_STAT       0x220
0093 
0094 #define ANADIG_USB1_LOOPBACK_SET        0x1e4
0095 #define ANADIG_USB1_LOOPBACK_CLR        0x1e8
0096 #define ANADIG_USB1_LOOPBACK_UTMI_TESTSTART BIT(0)
0097 
0098 #define ANADIG_USB2_LOOPBACK_SET        0x244
0099 #define ANADIG_USB2_LOOPBACK_CLR        0x248
0100 
0101 #define ANADIG_USB1_MISC            0x1f0
0102 #define ANADIG_USB2_MISC            0x250
0103 
0104 #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG    BIT(12)
0105 #define BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL BIT(11)
0106 
0107 #define BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID BIT(3)
0108 #define BM_ANADIG_USB2_VBUS_DET_STAT_VBUS_VALID BIT(3)
0109 
0110 #define BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1   BIT(2)
0111 #define BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN  BIT(5)
0112 #define BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1   BIT(2)
0113 #define BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN  BIT(5)
0114 
0115 #define BM_ANADIG_USB1_MISC_RX_VPIN_FS      BIT(29)
0116 #define BM_ANADIG_USB1_MISC_RX_VMIN_FS      BIT(28)
0117 #define BM_ANADIG_USB2_MISC_RX_VPIN_FS      BIT(29)
0118 #define BM_ANADIG_USB2_MISC_RX_VMIN_FS      BIT(28)
0119 
0120 #define to_mxs_phy(p) container_of((p), struct mxs_phy, phy)
0121 
0122 /* Do disconnection between PHY and controller without vbus */
0123 #define MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS    BIT(0)
0124 
0125 /*
0126  * The PHY will be in messy if there is a wakeup after putting
0127  * bus to suspend (set portsc.suspendM) but before setting PHY to low
0128  * power mode (set portsc.phcd).
0129  */
0130 #define MXS_PHY_ABNORMAL_IN_SUSPEND     BIT(1)
0131 
0132 /*
0133  * The SOF sends too fast after resuming, it will cause disconnection
0134  * between host and high speed device.
0135  */
0136 #define MXS_PHY_SENDING_SOF_TOO_FAST        BIT(2)
0137 
0138 /*
0139  * IC has bug fixes logic, they include
0140  * MXS_PHY_ABNORMAL_IN_SUSPEND and MXS_PHY_SENDING_SOF_TOO_FAST
0141  * which are described at above flags, the RTL will handle it
0142  * according to different versions.
0143  */
0144 #define MXS_PHY_NEED_IP_FIX         BIT(3)
0145 
0146 /* Minimum and maximum values for device tree entries */
0147 #define MXS_PHY_TX_CAL45_MIN            30
0148 #define MXS_PHY_TX_CAL45_MAX            55
0149 #define MXS_PHY_TX_D_CAL_MIN            79
0150 #define MXS_PHY_TX_D_CAL_MAX            119
0151 
0152 struct mxs_phy_data {
0153     unsigned int flags;
0154 };
0155 
0156 static const struct mxs_phy_data imx23_phy_data = {
0157     .flags = MXS_PHY_ABNORMAL_IN_SUSPEND | MXS_PHY_SENDING_SOF_TOO_FAST,
0158 };
0159 
0160 static const struct mxs_phy_data imx6q_phy_data = {
0161     .flags = MXS_PHY_SENDING_SOF_TOO_FAST |
0162         MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
0163         MXS_PHY_NEED_IP_FIX,
0164 };
0165 
0166 static const struct mxs_phy_data imx6sl_phy_data = {
0167     .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
0168         MXS_PHY_NEED_IP_FIX,
0169 };
0170 
0171 static const struct mxs_phy_data vf610_phy_data = {
0172     .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS |
0173         MXS_PHY_NEED_IP_FIX,
0174 };
0175 
0176 static const struct mxs_phy_data imx6sx_phy_data = {
0177     .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
0178 };
0179 
0180 static const struct mxs_phy_data imx6ul_phy_data = {
0181     .flags = MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS,
0182 };
0183 
0184 static const struct mxs_phy_data imx7ulp_phy_data = {
0185 };
0186 
0187 static const struct of_device_id mxs_phy_dt_ids[] = {
0188     { .compatible = "fsl,imx6sx-usbphy", .data = &imx6sx_phy_data, },
0189     { .compatible = "fsl,imx6sl-usbphy", .data = &imx6sl_phy_data, },
0190     { .compatible = "fsl,imx6q-usbphy", .data = &imx6q_phy_data, },
0191     { .compatible = "fsl,imx23-usbphy", .data = &imx23_phy_data, },
0192     { .compatible = "fsl,vf610-usbphy", .data = &vf610_phy_data, },
0193     { .compatible = "fsl,imx6ul-usbphy", .data = &imx6ul_phy_data, },
0194     { .compatible = "fsl,imx7ulp-usbphy", .data = &imx7ulp_phy_data, },
0195     { /* sentinel */ }
0196 };
0197 MODULE_DEVICE_TABLE(of, mxs_phy_dt_ids);
0198 
0199 struct mxs_phy {
0200     struct usb_phy phy;
0201     struct clk *clk;
0202     const struct mxs_phy_data *data;
0203     struct regmap *regmap_anatop;
0204     int port_id;
0205     u32 tx_reg_set;
0206     u32 tx_reg_mask;
0207 };
0208 
0209 static inline bool is_imx6q_phy(struct mxs_phy *mxs_phy)
0210 {
0211     return mxs_phy->data == &imx6q_phy_data;
0212 }
0213 
0214 static inline bool is_imx6sl_phy(struct mxs_phy *mxs_phy)
0215 {
0216     return mxs_phy->data == &imx6sl_phy_data;
0217 }
0218 
0219 static inline bool is_imx7ulp_phy(struct mxs_phy *mxs_phy)
0220 {
0221     return mxs_phy->data == &imx7ulp_phy_data;
0222 }
0223 
0224 /*
0225  * PHY needs some 32K cycles to switch from 32K clock to
0226  * bus (such as AHB/AXI, etc) clock.
0227  */
0228 static void mxs_phy_clock_switch_delay(void)
0229 {
0230     usleep_range(300, 400);
0231 }
0232 
0233 static void mxs_phy_tx_init(struct mxs_phy *mxs_phy)
0234 {
0235     void __iomem *base = mxs_phy->phy.io_priv;
0236     u32 phytx;
0237 
0238     /* Update TX register if there is anything to write */
0239     if (mxs_phy->tx_reg_mask) {
0240         phytx = readl(base + HW_USBPHY_TX);
0241         phytx &= ~mxs_phy->tx_reg_mask;
0242         phytx |= mxs_phy->tx_reg_set;
0243         writel(phytx, base + HW_USBPHY_TX);
0244     }
0245 }
0246 
0247 static int mxs_phy_pll_enable(void __iomem *base, bool enable)
0248 {
0249     int ret = 0;
0250 
0251     if (enable) {
0252         u32 value;
0253 
0254         writel(BM_USBPHY_PLL_REG_ENABLE, base + HW_USBPHY_PLL_SIC_SET);
0255         writel(BM_USBPHY_PLL_BYPASS, base + HW_USBPHY_PLL_SIC_CLR);
0256         writel(BM_USBPHY_PLL_POWER, base + HW_USBPHY_PLL_SIC_SET);
0257         ret = readl_poll_timeout(base + HW_USBPHY_PLL_SIC,
0258             value, (value & BM_USBPHY_PLL_LOCK) != 0,
0259             100, 10000);
0260         if (ret)
0261             return ret;
0262 
0263         writel(BM_USBPHY_PLL_EN_USB_CLKS, base +
0264                 HW_USBPHY_PLL_SIC_SET);
0265     } else {
0266         writel(BM_USBPHY_PLL_EN_USB_CLKS, base +
0267                 HW_USBPHY_PLL_SIC_CLR);
0268         writel(BM_USBPHY_PLL_POWER, base + HW_USBPHY_PLL_SIC_CLR);
0269         writel(BM_USBPHY_PLL_BYPASS, base + HW_USBPHY_PLL_SIC_SET);
0270         writel(BM_USBPHY_PLL_REG_ENABLE, base + HW_USBPHY_PLL_SIC_CLR);
0271     }
0272 
0273     return ret;
0274 }
0275 
0276 static int mxs_phy_hw_init(struct mxs_phy *mxs_phy)
0277 {
0278     int ret;
0279     void __iomem *base = mxs_phy->phy.io_priv;
0280 
0281     if (is_imx7ulp_phy(mxs_phy)) {
0282         ret = mxs_phy_pll_enable(base, true);
0283         if (ret)
0284             return ret;
0285     }
0286 
0287     ret = stmp_reset_block(base + HW_USBPHY_CTRL);
0288     if (ret)
0289         goto disable_pll;
0290 
0291     /* Power up the PHY */
0292     writel(0, base + HW_USBPHY_PWD);
0293 
0294     /*
0295      * USB PHY Ctrl Setting
0296      * - Auto clock/power on
0297      * - Enable full/low speed support
0298      */
0299     writel(BM_USBPHY_CTRL_ENAUTOSET_USBCLKS |
0300         BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE |
0301         BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD |
0302         BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE |
0303         BM_USBPHY_CTRL_ENAUTO_PWRON_PLL |
0304         BM_USBPHY_CTRL_ENUTMILEVEL2 |
0305         BM_USBPHY_CTRL_ENUTMILEVEL3,
0306            base + HW_USBPHY_CTRL_SET);
0307 
0308     if (mxs_phy->data->flags & MXS_PHY_NEED_IP_FIX)
0309         writel(BM_USBPHY_IP_FIX, base + HW_USBPHY_IP_SET);
0310 
0311     if (mxs_phy->regmap_anatop) {
0312         unsigned int reg = mxs_phy->port_id ?
0313             ANADIG_USB1_CHRG_DETECT_SET :
0314             ANADIG_USB2_CHRG_DETECT_SET;
0315         /*
0316          * The external charger detector needs to be disabled,
0317          * or the signal at DP will be poor
0318          */
0319         regmap_write(mxs_phy->regmap_anatop, reg,
0320                  ANADIG_USB1_CHRG_DETECT_EN_B |
0321                  ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
0322     }
0323 
0324     mxs_phy_tx_init(mxs_phy);
0325 
0326     return 0;
0327 
0328 disable_pll:
0329     if (is_imx7ulp_phy(mxs_phy))
0330         mxs_phy_pll_enable(base, false);
0331     return ret;
0332 }
0333 
0334 /* Return true if the vbus is there */
0335 static bool mxs_phy_get_vbus_status(struct mxs_phy *mxs_phy)
0336 {
0337     unsigned int vbus_value = 0;
0338 
0339     if (!mxs_phy->regmap_anatop)
0340         return false;
0341 
0342     if (mxs_phy->port_id == 0)
0343         regmap_read(mxs_phy->regmap_anatop,
0344             ANADIG_USB1_VBUS_DET_STAT,
0345             &vbus_value);
0346     else if (mxs_phy->port_id == 1)
0347         regmap_read(mxs_phy->regmap_anatop,
0348             ANADIG_USB2_VBUS_DET_STAT,
0349             &vbus_value);
0350 
0351     if (vbus_value & BM_ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID)
0352         return true;
0353     else
0354         return false;
0355 }
0356 
0357 static void __mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool disconnect)
0358 {
0359     void __iomem *base = mxs_phy->phy.io_priv;
0360     u32 reg;
0361 
0362     if (disconnect)
0363         writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
0364             base + HW_USBPHY_DEBUG_CLR);
0365 
0366     if (mxs_phy->port_id == 0) {
0367         reg = disconnect ? ANADIG_USB1_LOOPBACK_SET
0368             : ANADIG_USB1_LOOPBACK_CLR;
0369         regmap_write(mxs_phy->regmap_anatop, reg,
0370             BM_ANADIG_USB1_LOOPBACK_UTMI_DIG_TST1 |
0371             BM_ANADIG_USB1_LOOPBACK_TSTI_TX_EN);
0372     } else if (mxs_phy->port_id == 1) {
0373         reg = disconnect ? ANADIG_USB2_LOOPBACK_SET
0374             : ANADIG_USB2_LOOPBACK_CLR;
0375         regmap_write(mxs_phy->regmap_anatop, reg,
0376             BM_ANADIG_USB2_LOOPBACK_UTMI_DIG_TST1 |
0377             BM_ANADIG_USB2_LOOPBACK_TSTI_TX_EN);
0378     }
0379 
0380     if (!disconnect)
0381         writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
0382             base + HW_USBPHY_DEBUG_SET);
0383 
0384     /* Delay some time, and let Linestate be SE0 for controller */
0385     if (disconnect)
0386         usleep_range(500, 1000);
0387 }
0388 
0389 static bool mxs_phy_is_otg_host(struct mxs_phy *mxs_phy)
0390 {
0391     void __iomem *base = mxs_phy->phy.io_priv;
0392     u32 phyctrl = readl(base + HW_USBPHY_CTRL);
0393 
0394     if (IS_ENABLED(CONFIG_USB_OTG) &&
0395             !(phyctrl & BM_USBPHY_CTRL_OTG_ID_VALUE))
0396         return true;
0397 
0398     return false;
0399 }
0400 
0401 static void mxs_phy_disconnect_line(struct mxs_phy *mxs_phy, bool on)
0402 {
0403     bool vbus_is_on = false;
0404 
0405     /* If the SoCs don't need to disconnect line without vbus, quit */
0406     if (!(mxs_phy->data->flags & MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS))
0407         return;
0408 
0409     /* If the SoCs don't have anatop, quit */
0410     if (!mxs_phy->regmap_anatop)
0411         return;
0412 
0413     vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
0414 
0415     if (on && !vbus_is_on && !mxs_phy_is_otg_host(mxs_phy))
0416         __mxs_phy_disconnect_line(mxs_phy, true);
0417     else
0418         __mxs_phy_disconnect_line(mxs_phy, false);
0419 
0420 }
0421 
0422 static int mxs_phy_init(struct usb_phy *phy)
0423 {
0424     int ret;
0425     struct mxs_phy *mxs_phy = to_mxs_phy(phy);
0426 
0427     mxs_phy_clock_switch_delay();
0428     ret = clk_prepare_enable(mxs_phy->clk);
0429     if (ret)
0430         return ret;
0431 
0432     return mxs_phy_hw_init(mxs_phy);
0433 }
0434 
0435 static void mxs_phy_shutdown(struct usb_phy *phy)
0436 {
0437     struct mxs_phy *mxs_phy = to_mxs_phy(phy);
0438     u32 value = BM_USBPHY_CTRL_ENVBUSCHG_WKUP |
0439             BM_USBPHY_CTRL_ENDPDMCHG_WKUP |
0440             BM_USBPHY_CTRL_ENIDCHG_WKUP |
0441             BM_USBPHY_CTRL_ENAUTOSET_USBCLKS |
0442             BM_USBPHY_CTRL_ENAUTOCLR_USBCLKGATE |
0443             BM_USBPHY_CTRL_ENAUTOCLR_PHY_PWD |
0444             BM_USBPHY_CTRL_ENAUTOCLR_CLKGATE |
0445             BM_USBPHY_CTRL_ENAUTO_PWRON_PLL;
0446 
0447     writel(value, phy->io_priv + HW_USBPHY_CTRL_CLR);
0448     writel(0xffffffff, phy->io_priv + HW_USBPHY_PWD);
0449 
0450     writel(BM_USBPHY_CTRL_CLKGATE,
0451            phy->io_priv + HW_USBPHY_CTRL_SET);
0452 
0453     if (is_imx7ulp_phy(mxs_phy))
0454         mxs_phy_pll_enable(phy->io_priv, false);
0455 
0456     clk_disable_unprepare(mxs_phy->clk);
0457 }
0458 
0459 static bool mxs_phy_is_low_speed_connection(struct mxs_phy *mxs_phy)
0460 {
0461     unsigned int line_state;
0462     /* bit definition is the same for all controllers */
0463     unsigned int dp_bit = BM_ANADIG_USB1_MISC_RX_VPIN_FS,
0464              dm_bit = BM_ANADIG_USB1_MISC_RX_VMIN_FS;
0465     unsigned int reg = ANADIG_USB1_MISC;
0466 
0467     /* If the SoCs don't have anatop, quit */
0468     if (!mxs_phy->regmap_anatop)
0469         return false;
0470 
0471     if (mxs_phy->port_id == 0)
0472         reg = ANADIG_USB1_MISC;
0473     else if (mxs_phy->port_id == 1)
0474         reg = ANADIG_USB2_MISC;
0475 
0476     regmap_read(mxs_phy->regmap_anatop, reg, &line_state);
0477 
0478     if ((line_state & (dp_bit | dm_bit)) ==  dm_bit)
0479         return true;
0480     else
0481         return false;
0482 }
0483 
0484 static int mxs_phy_suspend(struct usb_phy *x, int suspend)
0485 {
0486     int ret;
0487     struct mxs_phy *mxs_phy = to_mxs_phy(x);
0488     bool low_speed_connection, vbus_is_on;
0489 
0490     low_speed_connection = mxs_phy_is_low_speed_connection(mxs_phy);
0491     vbus_is_on = mxs_phy_get_vbus_status(mxs_phy);
0492 
0493     if (suspend) {
0494         /*
0495          * FIXME: Do not power down RXPWD1PT1 bit for low speed
0496          * connect. The low speed connection will have problem at
0497          * very rare cases during usb suspend and resume process.
0498          */
0499         if (low_speed_connection & vbus_is_on) {
0500             /*
0501              * If value to be set as pwd value is not 0xffffffff,
0502              * several 32Khz cycles are needed.
0503              */
0504             mxs_phy_clock_switch_delay();
0505             writel(0xffbfffff, x->io_priv + HW_USBPHY_PWD);
0506         } else {
0507             writel(0xffffffff, x->io_priv + HW_USBPHY_PWD);
0508         }
0509         writel(BM_USBPHY_CTRL_CLKGATE,
0510                x->io_priv + HW_USBPHY_CTRL_SET);
0511         clk_disable_unprepare(mxs_phy->clk);
0512     } else {
0513         mxs_phy_clock_switch_delay();
0514         ret = clk_prepare_enable(mxs_phy->clk);
0515         if (ret)
0516             return ret;
0517         writel(BM_USBPHY_CTRL_CLKGATE,
0518                x->io_priv + HW_USBPHY_CTRL_CLR);
0519         writel(0, x->io_priv + HW_USBPHY_PWD);
0520     }
0521 
0522     return 0;
0523 }
0524 
0525 static int mxs_phy_set_wakeup(struct usb_phy *x, bool enabled)
0526 {
0527     struct mxs_phy *mxs_phy = to_mxs_phy(x);
0528     u32 value = BM_USBPHY_CTRL_ENVBUSCHG_WKUP |
0529             BM_USBPHY_CTRL_ENDPDMCHG_WKUP |
0530                 BM_USBPHY_CTRL_ENIDCHG_WKUP;
0531     if (enabled) {
0532         mxs_phy_disconnect_line(mxs_phy, true);
0533         writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_SET);
0534     } else {
0535         writel_relaxed(value, x->io_priv + HW_USBPHY_CTRL_CLR);
0536         mxs_phy_disconnect_line(mxs_phy, false);
0537     }
0538 
0539     return 0;
0540 }
0541 
0542 static int mxs_phy_on_connect(struct usb_phy *phy,
0543         enum usb_device_speed speed)
0544 {
0545     dev_dbg(phy->dev, "%s device has connected\n",
0546         (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
0547 
0548     if (speed == USB_SPEED_HIGH)
0549         writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
0550                phy->io_priv + HW_USBPHY_CTRL_SET);
0551 
0552     return 0;
0553 }
0554 
0555 static int mxs_phy_on_disconnect(struct usb_phy *phy,
0556         enum usb_device_speed speed)
0557 {
0558     dev_dbg(phy->dev, "%s device has disconnected\n",
0559         (speed == USB_SPEED_HIGH) ? "HS" : "FS/LS");
0560 
0561     /* Sometimes, the speed is not high speed when the error occurs */
0562     if (readl(phy->io_priv + HW_USBPHY_CTRL) &
0563             BM_USBPHY_CTRL_ENHOSTDISCONDETECT)
0564         writel(BM_USBPHY_CTRL_ENHOSTDISCONDETECT,
0565                phy->io_priv + HW_USBPHY_CTRL_CLR);
0566 
0567     return 0;
0568 }
0569 
0570 #define MXS_USB_CHARGER_DATA_CONTACT_TIMEOUT    100
0571 static int mxs_charger_data_contact_detect(struct mxs_phy *x)
0572 {
0573     struct regmap *regmap = x->regmap_anatop;
0574     int i, stable_contact_count = 0;
0575     u32 val;
0576 
0577     /* Check if vbus is valid */
0578     regmap_read(regmap, ANADIG_USB1_VBUS_DET_STAT, &val);
0579     if (!(val & ANADIG_USB1_VBUS_DET_STAT_VBUS_VALID)) {
0580         dev_err(x->phy.dev, "vbus is not valid\n");
0581         return -EINVAL;
0582     }
0583 
0584     /* Enable charger detector */
0585     regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_CLR,
0586                 ANADIG_USB1_CHRG_DETECT_EN_B);
0587     /*
0588      * - Do not check whether a charger is connected to the USB port
0589      * - Check whether the USB plug has been in contact with each other
0590      */
0591     regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_SET,
0592             ANADIG_USB1_CHRG_DETECT_CHK_CONTACT |
0593             ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
0594 
0595     /* Check if plug is connected */
0596     for (i = 0; i < MXS_USB_CHARGER_DATA_CONTACT_TIMEOUT; i++) {
0597         regmap_read(regmap, ANADIG_USB1_CHRG_DET_STAT, &val);
0598         if (val & ANADIG_USB1_CHRG_DET_STAT_PLUG_CONTACT) {
0599             stable_contact_count++;
0600             if (stable_contact_count > 5)
0601                 /* Data pin makes contact */
0602                 break;
0603             else
0604                 usleep_range(5000, 10000);
0605         } else {
0606             stable_contact_count = 0;
0607             usleep_range(5000, 6000);
0608         }
0609     }
0610 
0611     if (i == MXS_USB_CHARGER_DATA_CONTACT_TIMEOUT) {
0612         dev_err(x->phy.dev,
0613             "Data pin can't make good contact.\n");
0614         /* Disable charger detector */
0615         regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_SET,
0616                 ANADIG_USB1_CHRG_DETECT_EN_B |
0617                 ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
0618         return -ENXIO;
0619     }
0620 
0621     return 0;
0622 }
0623 
0624 static enum usb_charger_type mxs_charger_primary_detection(struct mxs_phy *x)
0625 {
0626     struct regmap *regmap = x->regmap_anatop;
0627     enum usb_charger_type chgr_type = UNKNOWN_TYPE;
0628     u32 val;
0629 
0630     /*
0631      * - Do check whether a charger is connected to the USB port
0632      * - Do not Check whether the USB plug has been in contact with
0633      *   each other
0634      */
0635     regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_CLR,
0636             ANADIG_USB1_CHRG_DETECT_CHK_CONTACT |
0637             ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
0638 
0639     msleep(100);
0640 
0641     /* Check if it is a charger */
0642     regmap_read(regmap, ANADIG_USB1_CHRG_DET_STAT, &val);
0643     if (!(val & ANADIG_USB1_CHRG_DET_STAT_CHRG_DETECTED)) {
0644         chgr_type = SDP_TYPE;
0645         dev_dbg(x->phy.dev, "It is a standard downstream port\n");
0646     }
0647 
0648     /* Disable charger detector */
0649     regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_SET,
0650             ANADIG_USB1_CHRG_DETECT_EN_B |
0651             ANADIG_USB1_CHRG_DETECT_CHK_CHRG_B);
0652 
0653     return chgr_type;
0654 }
0655 
0656 /*
0657  * It must be called after DP is pulled up, which is used to
0658  * differentiate DCP and CDP.
0659  */
0660 static enum usb_charger_type mxs_charger_secondary_detection(struct mxs_phy *x)
0661 {
0662     struct regmap *regmap = x->regmap_anatop;
0663     int val;
0664 
0665     msleep(80);
0666 
0667     regmap_read(regmap, ANADIG_USB1_CHRG_DET_STAT, &val);
0668     if (val & ANADIG_USB1_CHRG_DET_STAT_DM_STATE) {
0669         dev_dbg(x->phy.dev, "It is a dedicate charging port\n");
0670         return DCP_TYPE;
0671     } else {
0672         dev_dbg(x->phy.dev, "It is a charging downstream port\n");
0673         return CDP_TYPE;
0674     }
0675 }
0676 
0677 static enum usb_charger_type mxs_phy_charger_detect(struct usb_phy *phy)
0678 {
0679     struct mxs_phy *mxs_phy = to_mxs_phy(phy);
0680     struct regmap *regmap = mxs_phy->regmap_anatop;
0681     void __iomem *base = phy->io_priv;
0682     enum usb_charger_type chgr_type = UNKNOWN_TYPE;
0683 
0684     if (!regmap)
0685         return UNKNOWN_TYPE;
0686 
0687     if (mxs_charger_data_contact_detect(mxs_phy))
0688         return chgr_type;
0689 
0690     chgr_type = mxs_charger_primary_detection(mxs_phy);
0691 
0692     if (chgr_type != SDP_TYPE) {
0693         /* Pull up DP via test */
0694         writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
0695                 base + HW_USBPHY_DEBUG_CLR);
0696         regmap_write(regmap, ANADIG_USB1_LOOPBACK_SET,
0697                 ANADIG_USB1_LOOPBACK_UTMI_TESTSTART);
0698 
0699         chgr_type = mxs_charger_secondary_detection(mxs_phy);
0700 
0701         /* Stop the test */
0702         regmap_write(regmap, ANADIG_USB1_LOOPBACK_CLR,
0703                 ANADIG_USB1_LOOPBACK_UTMI_TESTSTART);
0704         writel_relaxed(BM_USBPHY_DEBUG_CLKGATE,
0705                 base + HW_USBPHY_DEBUG_SET);
0706     }
0707 
0708     return chgr_type;
0709 }
0710 
0711 static int mxs_phy_probe(struct platform_device *pdev)
0712 {
0713     void __iomem *base;
0714     struct clk *clk;
0715     struct mxs_phy *mxs_phy;
0716     int ret;
0717     struct device_node *np = pdev->dev.of_node;
0718     u32 val;
0719 
0720     base = devm_platform_ioremap_resource(pdev, 0);
0721     if (IS_ERR(base))
0722         return PTR_ERR(base);
0723 
0724     clk = devm_clk_get(&pdev->dev, NULL);
0725     if (IS_ERR(clk)) {
0726         dev_err(&pdev->dev,
0727             "can't get the clock, err=%ld", PTR_ERR(clk));
0728         return PTR_ERR(clk);
0729     }
0730 
0731     mxs_phy = devm_kzalloc(&pdev->dev, sizeof(*mxs_phy), GFP_KERNEL);
0732     if (!mxs_phy)
0733         return -ENOMEM;
0734 
0735     /* Some SoCs don't have anatop registers */
0736     if (of_get_property(np, "fsl,anatop", NULL)) {
0737         mxs_phy->regmap_anatop = syscon_regmap_lookup_by_phandle
0738             (np, "fsl,anatop");
0739         if (IS_ERR(mxs_phy->regmap_anatop)) {
0740             dev_dbg(&pdev->dev,
0741                 "failed to find regmap for anatop\n");
0742             return PTR_ERR(mxs_phy->regmap_anatop);
0743         }
0744     }
0745 
0746     /* Precompute which bits of the TX register are to be updated, if any */
0747     if (!of_property_read_u32(np, "fsl,tx-cal-45-dn-ohms", &val) &&
0748         val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) {
0749         /* Scale to a 4-bit value */
0750         val = (MXS_PHY_TX_CAL45_MAX - val) * 0xF
0751             / (MXS_PHY_TX_CAL45_MAX - MXS_PHY_TX_CAL45_MIN);
0752         mxs_phy->tx_reg_mask |= GM_USBPHY_TX_TXCAL45DN(~0);
0753         mxs_phy->tx_reg_set  |= GM_USBPHY_TX_TXCAL45DN(val);
0754     }
0755 
0756     if (!of_property_read_u32(np, "fsl,tx-cal-45-dp-ohms", &val) &&
0757         val >= MXS_PHY_TX_CAL45_MIN && val <= MXS_PHY_TX_CAL45_MAX) {
0758         /* Scale to a 4-bit value. */
0759         val = (MXS_PHY_TX_CAL45_MAX - val) * 0xF
0760             / (MXS_PHY_TX_CAL45_MAX - MXS_PHY_TX_CAL45_MIN);
0761         mxs_phy->tx_reg_mask |= GM_USBPHY_TX_TXCAL45DP(~0);
0762         mxs_phy->tx_reg_set  |= GM_USBPHY_TX_TXCAL45DP(val);
0763     }
0764 
0765     if (!of_property_read_u32(np, "fsl,tx-d-cal", &val) &&
0766         val >= MXS_PHY_TX_D_CAL_MIN && val <= MXS_PHY_TX_D_CAL_MAX) {
0767         /* Scale to a 4-bit value.  Round up the values and heavily
0768          * weight the rounding by adding 2/3 of the denominator.
0769          */
0770         val = ((MXS_PHY_TX_D_CAL_MAX - val) * 0xF
0771             + (MXS_PHY_TX_D_CAL_MAX - MXS_PHY_TX_D_CAL_MIN) * 2/3)
0772             / (MXS_PHY_TX_D_CAL_MAX - MXS_PHY_TX_D_CAL_MIN);
0773         mxs_phy->tx_reg_mask |= GM_USBPHY_TX_D_CAL(~0);
0774         mxs_phy->tx_reg_set  |= GM_USBPHY_TX_D_CAL(val);
0775     }
0776 
0777     ret = of_alias_get_id(np, "usbphy");
0778     if (ret < 0)
0779         dev_dbg(&pdev->dev, "failed to get alias id, errno %d\n", ret);
0780     mxs_phy->port_id = ret;
0781 
0782     mxs_phy->phy.io_priv        = base;
0783     mxs_phy->phy.dev        = &pdev->dev;
0784     mxs_phy->phy.label      = DRIVER_NAME;
0785     mxs_phy->phy.init       = mxs_phy_init;
0786     mxs_phy->phy.shutdown       = mxs_phy_shutdown;
0787     mxs_phy->phy.set_suspend    = mxs_phy_suspend;
0788     mxs_phy->phy.notify_connect = mxs_phy_on_connect;
0789     mxs_phy->phy.notify_disconnect  = mxs_phy_on_disconnect;
0790     mxs_phy->phy.type       = USB_PHY_TYPE_USB2;
0791     mxs_phy->phy.set_wakeup     = mxs_phy_set_wakeup;
0792     mxs_phy->phy.charger_detect = mxs_phy_charger_detect;
0793 
0794     mxs_phy->clk = clk;
0795     mxs_phy->data = of_device_get_match_data(&pdev->dev);
0796 
0797     platform_set_drvdata(pdev, mxs_phy);
0798 
0799     device_set_wakeup_capable(&pdev->dev, true);
0800 
0801     return usb_add_phy_dev(&mxs_phy->phy);
0802 }
0803 
0804 static int mxs_phy_remove(struct platform_device *pdev)
0805 {
0806     struct mxs_phy *mxs_phy = platform_get_drvdata(pdev);
0807 
0808     usb_remove_phy(&mxs_phy->phy);
0809 
0810     return 0;
0811 }
0812 
0813 #ifdef CONFIG_PM_SLEEP
0814 static void mxs_phy_enable_ldo_in_suspend(struct mxs_phy *mxs_phy, bool on)
0815 {
0816     unsigned int reg = on ? ANADIG_ANA_MISC0_SET : ANADIG_ANA_MISC0_CLR;
0817 
0818     /* If the SoCs don't have anatop, quit */
0819     if (!mxs_phy->regmap_anatop)
0820         return;
0821 
0822     if (is_imx6q_phy(mxs_phy))
0823         regmap_write(mxs_phy->regmap_anatop, reg,
0824             BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG);
0825     else if (is_imx6sl_phy(mxs_phy))
0826         regmap_write(mxs_phy->regmap_anatop,
0827             reg, BM_ANADIG_ANA_MISC0_STOP_MODE_CONFIG_SL);
0828 }
0829 
0830 static int mxs_phy_system_suspend(struct device *dev)
0831 {
0832     struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
0833 
0834     if (device_may_wakeup(dev))
0835         mxs_phy_enable_ldo_in_suspend(mxs_phy, true);
0836 
0837     return 0;
0838 }
0839 
0840 static int mxs_phy_system_resume(struct device *dev)
0841 {
0842     struct mxs_phy *mxs_phy = dev_get_drvdata(dev);
0843 
0844     if (device_may_wakeup(dev))
0845         mxs_phy_enable_ldo_in_suspend(mxs_phy, false);
0846 
0847     return 0;
0848 }
0849 #endif /* CONFIG_PM_SLEEP */
0850 
0851 static SIMPLE_DEV_PM_OPS(mxs_phy_pm, mxs_phy_system_suspend,
0852         mxs_phy_system_resume);
0853 
0854 static struct platform_driver mxs_phy_driver = {
0855     .probe = mxs_phy_probe,
0856     .remove = mxs_phy_remove,
0857     .driver = {
0858         .name = DRIVER_NAME,
0859         .of_match_table = mxs_phy_dt_ids,
0860         .pm = &mxs_phy_pm,
0861      },
0862 };
0863 
0864 static int __init mxs_phy_module_init(void)
0865 {
0866     return platform_driver_register(&mxs_phy_driver);
0867 }
0868 postcore_initcall(mxs_phy_module_init);
0869 
0870 static void __exit mxs_phy_module_exit(void)
0871 {
0872     platform_driver_unregister(&mxs_phy_driver);
0873 }
0874 module_exit(mxs_phy_module_exit);
0875 
0876 MODULE_ALIAS("platform:mxs-usb-phy");
0877 MODULE_AUTHOR("Marek Vasut <marex@denx.de>");
0878 MODULE_AUTHOR("Richard Zhao <richard.zhao@freescale.com>");
0879 MODULE_DESCRIPTION("Freescale MXS USB PHY driver");
0880 MODULE_LICENSE("GPL");