0001
0002
0003
0004
0005
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
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
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
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
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
0123 #define MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS BIT(0)
0124
0125
0126
0127
0128
0129
0130 #define MXS_PHY_ABNORMAL_IN_SUSPEND BIT(1)
0131
0132
0133
0134
0135
0136 #define MXS_PHY_SENDING_SOF_TOO_FAST BIT(2)
0137
0138
0139
0140
0141
0142
0143
0144 #define MXS_PHY_NEED_IP_FIX BIT(3)
0145
0146
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 { }
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
0226
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
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
0292 writel(0, base + HW_USBPHY_PWD);
0293
0294
0295
0296
0297
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
0317
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
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
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
0406 if (!(mxs_phy->data->flags & MXS_PHY_DISCONNECT_LINE_WITHOUT_VBUS))
0407 return;
0408
0409
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
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
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
0496
0497
0498
0499 if (low_speed_connection & vbus_is_on) {
0500
0501
0502
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
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
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
0585 regmap_write(regmap, ANADIG_USB1_CHRG_DETECT_CLR,
0586 ANADIG_USB1_CHRG_DETECT_EN_B);
0587
0588
0589
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
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
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
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
0632
0633
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
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
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
0658
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
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
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
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
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
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
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
0768
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
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
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");