0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/bitfield.h>
0012 #include <linux/clk.h>
0013 #include <linux/kernel.h>
0014 #include <linux/mfd/syscon.h>
0015 #include <linux/module.h>
0016 #include <linux/phy/phy.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/regmap.h>
0019
0020 #define SCTRL_SCDEEPSLEEPED (0x0)
0021 #define USB_CLK_SELECTED BIT(20)
0022
0023 #define PERI_CRG_PEREN0 (0x00)
0024 #define PERI_CRG_PERDIS0 (0x04)
0025 #define PERI_CRG_PEREN4 (0x40)
0026 #define PERI_CRG_PERDIS4 (0x44)
0027 #define PERI_CRG_PERRSTEN4 (0x90)
0028 #define PERI_CRG_PERRSTDIS4 (0x94)
0029 #define PERI_CRG_ISODIS (0x148)
0030 #define PERI_CRG_PEREN6 (0x410)
0031 #define PERI_CRG_PERDIS6 (0x414)
0032
0033 #define USB_REFCLK_ISO_EN BIT(25)
0034
0035 #define GT_CLK_USB2PHY_REF BIT(19)
0036
0037 #define PCTRL_PERI_CTRL3 (0x10)
0038 #define PCTRL_PERI_CTRL3_MSK_START (16)
0039 #define USB_TCXO_EN BIT(1)
0040
0041 #define PCTRL_PERI_CTRL24 (0x64)
0042 #define SC_CLK_USB3PHY_3MUX1_SEL BIT(25)
0043
0044 #define USB3OTG_CTRL0 (0x00)
0045 #define USB3OTG_CTRL3 (0x0c)
0046 #define USB3OTG_CTRL4 (0x10)
0047 #define USB3OTG_CTRL5 (0x14)
0048 #define USB3OTG_CTRL7 (0x1c)
0049 #define USB_MISC_CFG50 (0x50)
0050 #define USB_MISC_CFG54 (0x54)
0051 #define USB_MISC_CFG58 (0x58)
0052 #define USB_MISC_CFG5C (0x5c)
0053 #define USB_MISC_CFGA0 (0xa0)
0054 #define TCA_CLK_RST (0x200)
0055 #define TCA_INTR_EN (0x204)
0056 #define TCA_INTR_STS (0x208)
0057 #define TCA_GCFG (0x210)
0058 #define TCA_TCPC (0x214)
0059 #define TCA_SYSMODE_CFG (0x218)
0060 #define TCA_VBUS_CTRL (0x240)
0061
0062 #define CTRL0_USB3_VBUSVLD BIT(7)
0063 #define CTRL0_USB3_VBUSVLD_SEL BIT(6)
0064
0065 #define CTRL3_USB2_VBUSVLDEXT0 BIT(6)
0066 #define CTRL3_USB2_VBUSVLDEXTSEL0 BIT(5)
0067
0068 #define CTRL5_USB2_SIDDQ BIT(0)
0069
0070 #define CTRL7_USB2_REFCLKSEL_MASK GENMASK(4, 3)
0071 #define CTRL7_USB2_REFCLKSEL_ABB (BIT(4) | BIT(3))
0072 #define CTRL7_USB2_REFCLKSEL_PAD BIT(4)
0073
0074 #define CFG50_USB3_PHY_TEST_POWERDOWN BIT(23)
0075
0076 #define CFG54_USB31PHY_CR_ADDR_MASK GENMASK(31, 16)
0077
0078 #define CFG54_USB3PHY_REF_USE_PAD BIT(12)
0079 #define CFG54_PHY0_PMA_PWR_STABLE BIT(11)
0080 #define CFG54_PHY0_PCS_PWR_STABLE BIT(9)
0081 #define CFG54_USB31PHY_CR_ACK BIT(7)
0082 #define CFG54_USB31PHY_CR_WR_EN BIT(5)
0083 #define CFG54_USB31PHY_CR_SEL BIT(4)
0084 #define CFG54_USB31PHY_CR_RD_EN BIT(3)
0085 #define CFG54_USB31PHY_CR_CLK BIT(2)
0086 #define CFG54_USB3_PHY0_ANA_PWR_EN BIT(1)
0087
0088 #define CFG58_USB31PHY_CR_DATA_MASK GENMASK(31, 16)
0089
0090 #define CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN BIT(1)
0091
0092 #define CFGA0_VAUX_RESET BIT(9)
0093 #define CFGA0_USB31C_RESET BIT(8)
0094 #define CFGA0_USB2PHY_REFCLK_SELECT BIT(4)
0095 #define CFGA0_USB3PHY_RESET BIT(1)
0096 #define CFGA0_USB2PHY_POR BIT(0)
0097
0098 #define INTR_EN_XA_TIMEOUT_EVT_EN BIT(1)
0099 #define INTR_EN_XA_ACK_EVT_EN BIT(0)
0100
0101 #define CLK_RST_TCA_REF_CLK_EN BIT(1)
0102 #define CLK_RST_SUSPEND_CLK_EN BIT(0)
0103
0104 #define GCFG_ROLE_HSTDEV BIT(4)
0105 #define GCFG_OP_MODE GENMASK(1, 0)
0106 #define GCFG_OP_MODE_CTRL_SYNC_MODE BIT(0)
0107
0108 #define TCPC_VALID BIT(4)
0109 #define TCPC_LOW_POWER_EN BIT(3)
0110 #define TCPC_MUX_CONTROL_MASK GENMASK(1, 0)
0111 #define TCPC_MUX_CONTROL_USB31 BIT(0)
0112
0113 #define SYSMODE_CFG_TYPEC_DISABLE BIT(3)
0114
0115 #define VBUS_CTRL_POWERPRESENT_OVERRD GENMASK(3, 2)
0116 #define VBUS_CTRL_VBUSVALID_OVERRD GENMASK(1, 0)
0117
0118 #define KIRIN970_USB_DEFAULT_PHY_PARAM (0xfdfee4)
0119 #define KIRIN970_USB_DEFAULT_PHY_VBOOST (0x5)
0120
0121 #define TX_VBOOST_LVL_REG (0xf)
0122 #define TX_VBOOST_LVL_START (6)
0123 #define TX_VBOOST_LVL_ENABLE BIT(9)
0124
0125 struct hi3670_priv {
0126 struct device *dev;
0127 struct regmap *peri_crg;
0128 struct regmap *pctrl;
0129 struct regmap *sctrl;
0130 struct regmap *usb31misc;
0131
0132 u32 eye_diagram_param;
0133 u32 tx_vboost_lvl;
0134
0135 u32 peri_crg_offset;
0136 u32 pctrl_offset;
0137 u32 usb31misc_offset;
0138 };
0139
0140 static int hi3670_phy_cr_clk(struct regmap *usb31misc)
0141 {
0142 int ret;
0143
0144
0145 ret = regmap_update_bits(usb31misc, USB_MISC_CFG54,
0146 CFG54_USB31PHY_CR_CLK, CFG54_USB31PHY_CR_CLK);
0147 if (ret)
0148 return ret;
0149
0150
0151 return regmap_update_bits(usb31misc, USB_MISC_CFG54,
0152 CFG54_USB31PHY_CR_CLK, 0);
0153 }
0154
0155 static int hi3670_phy_cr_set_sel(struct regmap *usb31misc)
0156 {
0157 return regmap_update_bits(usb31misc, USB_MISC_CFG54,
0158 CFG54_USB31PHY_CR_SEL, CFG54_USB31PHY_CR_SEL);
0159 }
0160
0161 static int hi3670_phy_cr_start(struct regmap *usb31misc, int direction)
0162 {
0163 int ret, reg;
0164
0165 if (direction)
0166 reg = CFG54_USB31PHY_CR_WR_EN;
0167 else
0168 reg = CFG54_USB31PHY_CR_RD_EN;
0169
0170 ret = regmap_update_bits(usb31misc, USB_MISC_CFG54, reg, reg);
0171
0172 if (ret)
0173 return ret;
0174
0175 ret = hi3670_phy_cr_clk(usb31misc);
0176 if (ret)
0177 return ret;
0178
0179 return regmap_update_bits(usb31misc, USB_MISC_CFG54,
0180 CFG54_USB31PHY_CR_RD_EN | CFG54_USB31PHY_CR_WR_EN, 0);
0181 }
0182
0183 static int hi3670_phy_cr_wait_ack(struct regmap *usb31misc)
0184 {
0185 u32 reg;
0186 int retry = 10;
0187 int ret;
0188
0189 while (retry-- > 0) {
0190 ret = regmap_read(usb31misc, USB_MISC_CFG54, ®);
0191 if (ret)
0192 return ret;
0193 if ((reg & CFG54_USB31PHY_CR_ACK) == CFG54_USB31PHY_CR_ACK)
0194 return 0;
0195
0196 ret = hi3670_phy_cr_clk(usb31misc);
0197 if (ret)
0198 return ret;
0199
0200 usleep_range(10, 20);
0201 }
0202
0203 return -ETIMEDOUT;
0204 }
0205
0206 static int hi3670_phy_cr_set_addr(struct regmap *usb31misc, u32 addr)
0207 {
0208 u32 reg;
0209 int ret;
0210
0211 ret = regmap_read(usb31misc, USB_MISC_CFG54, ®);
0212 if (ret)
0213 return ret;
0214
0215 reg = FIELD_PREP(CFG54_USB31PHY_CR_ADDR_MASK, addr);
0216
0217 return regmap_update_bits(usb31misc, USB_MISC_CFG54,
0218 CFG54_USB31PHY_CR_ADDR_MASK, reg);
0219 }
0220
0221 static int hi3670_phy_cr_read(struct regmap *usb31misc, u32 addr, u32 *val)
0222 {
0223 int reg, i, ret;
0224
0225 for (i = 0; i < 100; i++) {
0226 ret = hi3670_phy_cr_clk(usb31misc);
0227 if (ret)
0228 return ret;
0229 }
0230
0231 ret = hi3670_phy_cr_set_sel(usb31misc);
0232 if (ret)
0233 return ret;
0234
0235 ret = hi3670_phy_cr_set_addr(usb31misc, addr);
0236 if (ret)
0237 return ret;
0238
0239 ret = hi3670_phy_cr_start(usb31misc, 0);
0240 if (ret)
0241 return ret;
0242
0243 ret = hi3670_phy_cr_wait_ack(usb31misc);
0244 if (ret)
0245 return ret;
0246
0247 ret = regmap_read(usb31misc, USB_MISC_CFG58, ®);
0248 if (ret)
0249 return ret;
0250
0251 *val = FIELD_GET(CFG58_USB31PHY_CR_DATA_MASK, reg);
0252
0253 return 0;
0254 }
0255
0256 static int hi3670_phy_cr_write(struct regmap *usb31misc, u32 addr, u32 val)
0257 {
0258 int i;
0259 int ret;
0260
0261 for (i = 0; i < 100; i++) {
0262 ret = hi3670_phy_cr_clk(usb31misc);
0263 if (ret)
0264 return ret;
0265 }
0266
0267 ret = hi3670_phy_cr_set_sel(usb31misc);
0268 if (ret)
0269 return ret;
0270
0271 ret = hi3670_phy_cr_set_addr(usb31misc, addr);
0272 if (ret)
0273 return ret;
0274
0275 ret = regmap_write(usb31misc, USB_MISC_CFG58,
0276 FIELD_PREP(CFG58_USB31PHY_CR_DATA_MASK, val));
0277 if (ret)
0278 return ret;
0279
0280 ret = hi3670_phy_cr_start(usb31misc, 1);
0281 if (ret)
0282 return ret;
0283
0284 return hi3670_phy_cr_wait_ack(usb31misc);
0285 }
0286
0287 static int hi3670_phy_set_params(struct hi3670_priv *priv)
0288 {
0289 u32 reg;
0290 int ret;
0291 int retry = 3;
0292
0293 ret = regmap_write(priv->usb31misc, USB3OTG_CTRL4,
0294 priv->eye_diagram_param);
0295 if (ret) {
0296 dev_err(priv->dev, "set USB3OTG_CTRL4 failed\n");
0297 return ret;
0298 }
0299
0300 while (retry-- > 0) {
0301 ret = hi3670_phy_cr_read(priv->usb31misc,
0302 TX_VBOOST_LVL_REG, ®);
0303 if (!ret)
0304 break;
0305
0306 if (ret != -ETIMEDOUT) {
0307 dev_err(priv->dev, "read TX_VBOOST_LVL_REG failed\n");
0308 return ret;
0309 }
0310 }
0311 if (ret)
0312 return ret;
0313
0314 reg |= (TX_VBOOST_LVL_ENABLE | (priv->tx_vboost_lvl << TX_VBOOST_LVL_START));
0315 ret = hi3670_phy_cr_write(priv->usb31misc, TX_VBOOST_LVL_REG, reg);
0316 if (ret)
0317 dev_err(priv->dev, "write TX_VBOOST_LVL_REG failed\n");
0318
0319 return ret;
0320 }
0321
0322 static bool hi3670_is_abbclk_selected(struct hi3670_priv *priv)
0323 {
0324 u32 reg;
0325
0326 if (!priv->sctrl) {
0327 dev_err(priv->dev, "priv->sctrl is null!\n");
0328 return false;
0329 }
0330
0331 if (regmap_read(priv->sctrl, SCTRL_SCDEEPSLEEPED, ®)) {
0332 dev_err(priv->dev, "SCTRL_SCDEEPSLEEPED read failed!\n");
0333 return false;
0334 }
0335
0336 if ((reg & USB_CLK_SELECTED) == 0)
0337 return false;
0338
0339 return true;
0340 }
0341
0342 static int hi3670_config_phy_clock(struct hi3670_priv *priv)
0343 {
0344 u32 val, mask;
0345 int ret;
0346
0347 if (!hi3670_is_abbclk_selected(priv)) {
0348
0349 ret = regmap_write(priv->peri_crg, PERI_CRG_ISODIS,
0350 USB_REFCLK_ISO_EN);
0351 if (ret)
0352 goto out;
0353
0354
0355 ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
0356 USB_TCXO_EN |
0357 (USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START));
0358
0359
0360 mask = SC_CLK_USB3PHY_3MUX1_SEL;
0361 ret = regmap_update_bits(priv->pctrl,
0362 PCTRL_PERI_CTRL24, mask, 0);
0363 if (ret)
0364 goto out;
0365
0366 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
0367 CFGA0_USB2PHY_REFCLK_SELECT, 0);
0368 if (ret)
0369 goto out;
0370
0371 ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
0372 if (ret)
0373 goto out;
0374 val &= ~CTRL7_USB2_REFCLKSEL_MASK;
0375 val |= CTRL7_USB2_REFCLKSEL_ABB;
0376 ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
0377 if (ret)
0378 goto out;
0379
0380 return 0;
0381 }
0382
0383 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
0384 CFG54_USB3PHY_REF_USE_PAD,
0385 CFG54_USB3PHY_REF_USE_PAD);
0386 if (ret)
0387 goto out;
0388
0389 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0,
0390 CFGA0_USB2PHY_REFCLK_SELECT,
0391 CFGA0_USB2PHY_REFCLK_SELECT);
0392 if (ret)
0393 goto out;
0394
0395 ret = regmap_read(priv->usb31misc, USB3OTG_CTRL7, &val);
0396 if (ret)
0397 goto out;
0398 val &= ~CTRL7_USB2_REFCLKSEL_MASK;
0399 val |= CTRL7_USB2_REFCLKSEL_PAD;
0400 ret = regmap_write(priv->usb31misc, USB3OTG_CTRL7, val);
0401 if (ret)
0402 goto out;
0403
0404 ret = regmap_write(priv->peri_crg,
0405 PERI_CRG_PEREN6, GT_CLK_USB2PHY_REF);
0406 if (ret)
0407 goto out;
0408
0409 return 0;
0410 out:
0411 dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
0412 return ret;
0413 }
0414
0415 static int hi3670_config_tca(struct hi3670_priv *priv)
0416 {
0417 u32 val, mask;
0418 int ret;
0419
0420 ret = regmap_write(priv->usb31misc, TCA_INTR_STS, 0xffff);
0421 if (ret)
0422 goto out;
0423
0424 ret = regmap_write(priv->usb31misc, TCA_INTR_EN,
0425 INTR_EN_XA_TIMEOUT_EVT_EN | INTR_EN_XA_ACK_EVT_EN);
0426 if (ret)
0427 goto out;
0428
0429 mask = CLK_RST_TCA_REF_CLK_EN | CLK_RST_SUSPEND_CLK_EN;
0430 ret = regmap_update_bits(priv->usb31misc, TCA_CLK_RST, mask, 0);
0431 if (ret)
0432 goto out;
0433
0434 ret = regmap_update_bits(priv->usb31misc, TCA_GCFG,
0435 GCFG_ROLE_HSTDEV | GCFG_OP_MODE,
0436 GCFG_ROLE_HSTDEV | GCFG_OP_MODE_CTRL_SYNC_MODE);
0437 if (ret)
0438 goto out;
0439
0440 ret = regmap_update_bits(priv->usb31misc, TCA_SYSMODE_CFG,
0441 SYSMODE_CFG_TYPEC_DISABLE, 0);
0442 if (ret)
0443 goto out;
0444
0445 ret = regmap_read(priv->usb31misc, TCA_TCPC, &val);
0446 if (ret)
0447 goto out;
0448 val &= ~(TCPC_VALID | TCPC_LOW_POWER_EN | TCPC_MUX_CONTROL_MASK);
0449 val |= (TCPC_VALID | TCPC_MUX_CONTROL_USB31);
0450 ret = regmap_write(priv->usb31misc, TCA_TCPC, val);
0451 if (ret)
0452 goto out;
0453
0454 ret = regmap_write(priv->usb31misc, TCA_VBUS_CTRL,
0455 VBUS_CTRL_POWERPRESENT_OVERRD | VBUS_CTRL_VBUSVALID_OVERRD);
0456 if (ret)
0457 goto out;
0458
0459 return 0;
0460 out:
0461 dev_err(priv->dev, "failed to config phy clock ret: %d\n", ret);
0462 return ret;
0463 }
0464
0465 static int hi3670_phy_init(struct phy *phy)
0466 {
0467 struct hi3670_priv *priv = phy_get_drvdata(phy);
0468 u32 val;
0469 int ret;
0470
0471
0472 val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET |
0473 CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
0474 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, 0);
0475 if (ret)
0476 goto out;
0477
0478 ret = hi3670_config_phy_clock(priv);
0479 if (ret)
0480 goto out;
0481
0482
0483 ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL5,
0484 CTRL5_USB2_SIDDQ, 0);
0485 if (ret)
0486 goto out;
0487
0488
0489 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG50,
0490 CFG50_USB3_PHY_TEST_POWERDOWN, 0);
0491 if (ret)
0492 goto out;
0493
0494
0495 val = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
0496 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
0497 if (ret)
0498 goto out;
0499
0500 usleep_range(100, 120);
0501
0502
0503 val = CFG54_USB3_PHY0_ANA_PWR_EN | CFG54_PHY0_PCS_PWR_STABLE |
0504 CFG54_PHY0_PMA_PWR_STABLE;
0505 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG54,
0506 val, val);
0507 if (ret)
0508 goto out;
0509
0510 ret = hi3670_config_tca(priv);
0511 if (ret)
0512 goto out;
0513
0514
0515 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFG5C,
0516 CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN,
0517 CFG5C_USB3_PHY0_SS_MPLLA_SSC_EN);
0518 if (ret)
0519 goto out;
0520
0521
0522 val = CFGA0_VAUX_RESET | CFGA0_USB31C_RESET;
0523 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, val, val);
0524 if (ret)
0525 goto out;
0526
0527 usleep_range(100, 120);
0528
0529
0530 val = CTRL0_USB3_VBUSVLD | CTRL0_USB3_VBUSVLD_SEL;
0531 ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL0, val, val);
0532 if (ret)
0533 goto out;
0534
0535 val = CTRL3_USB2_VBUSVLDEXT0 | CTRL3_USB2_VBUSVLDEXTSEL0;
0536 ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL3, val, val);
0537 if (ret)
0538 goto out;
0539
0540 usleep_range(100, 120);
0541
0542 ret = hi3670_phy_set_params(priv);
0543 if (ret)
0544 goto out;
0545
0546 return 0;
0547 out:
0548 dev_err(priv->dev, "failed to init phy ret: %d\n", ret);
0549 return ret;
0550 }
0551
0552 static int hi3670_phy_exit(struct phy *phy)
0553 {
0554 struct hi3670_priv *priv = phy_get_drvdata(phy);
0555 u32 mask;
0556 int ret;
0557
0558
0559 mask = CFGA0_USB3PHY_RESET | CFGA0_USB2PHY_POR;
0560 ret = regmap_update_bits(priv->usb31misc, USB_MISC_CFGA0, mask, 0);
0561 if (ret)
0562 goto out;
0563
0564 if (!hi3670_is_abbclk_selected(priv)) {
0565
0566 ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
0567 USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START);
0568 } else {
0569 ret = regmap_write(priv->peri_crg, PERI_CRG_PERDIS6,
0570 GT_CLK_USB2PHY_REF);
0571 if (ret)
0572 goto out;
0573 }
0574
0575 return 0;
0576 out:
0577 dev_err(priv->dev, "failed to exit phy ret: %d\n", ret);
0578 return ret;
0579 }
0580
0581 static const struct phy_ops hi3670_phy_ops = {
0582 .init = hi3670_phy_init,
0583 .exit = hi3670_phy_exit,
0584 .owner = THIS_MODULE,
0585 };
0586
0587 static int hi3670_phy_probe(struct platform_device *pdev)
0588 {
0589 struct phy_provider *phy_provider;
0590 struct device *dev = &pdev->dev;
0591 struct phy *phy;
0592 struct hi3670_priv *priv;
0593
0594 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0595 if (!priv)
0596 return -ENOMEM;
0597
0598 priv->dev = dev;
0599 priv->peri_crg = syscon_regmap_lookup_by_phandle(dev->of_node,
0600 "hisilicon,pericrg-syscon");
0601 if (IS_ERR(priv->peri_crg)) {
0602 dev_err(dev, "no hisilicon,pericrg-syscon\n");
0603 return PTR_ERR(priv->peri_crg);
0604 }
0605
0606 priv->pctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
0607 "hisilicon,pctrl-syscon");
0608 if (IS_ERR(priv->pctrl)) {
0609 dev_err(dev, "no hisilicon,pctrl-syscon\n");
0610 return PTR_ERR(priv->pctrl);
0611 }
0612
0613 priv->sctrl = syscon_regmap_lookup_by_phandle(dev->of_node,
0614 "hisilicon,sctrl-syscon");
0615 if (IS_ERR(priv->sctrl)) {
0616 dev_err(dev, "no hisilicon,sctrl-syscon\n");
0617 return PTR_ERR(priv->sctrl);
0618 }
0619
0620
0621 priv->usb31misc = syscon_node_to_regmap(dev->parent->of_node);
0622 if (IS_ERR(priv->usb31misc)) {
0623 dev_err(dev, "no hisilicon,usb3-otg-bc-syscon\n");
0624 return PTR_ERR(priv->usb31misc);
0625 }
0626
0627 if (of_property_read_u32(dev->of_node, "hisilicon,eye-diagram-param",
0628 &priv->eye_diagram_param))
0629 priv->eye_diagram_param = KIRIN970_USB_DEFAULT_PHY_PARAM;
0630
0631 if (of_property_read_u32(dev->of_node, "hisilicon,tx-vboost-lvl",
0632 &priv->tx_vboost_lvl))
0633 priv->tx_vboost_lvl = KIRIN970_USB_DEFAULT_PHY_VBOOST;
0634
0635 phy = devm_phy_create(dev, NULL, &hi3670_phy_ops);
0636 if (IS_ERR(phy))
0637 return PTR_ERR(phy);
0638
0639 phy_set_drvdata(phy, priv);
0640 phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
0641 return PTR_ERR_OR_ZERO(phy_provider);
0642 }
0643
0644 static const struct of_device_id hi3670_phy_of_match[] = {
0645 { .compatible = "hisilicon,hi3670-usb-phy" },
0646 { },
0647 };
0648 MODULE_DEVICE_TABLE(of, hi3670_phy_of_match);
0649
0650 static struct platform_driver hi3670_phy_driver = {
0651 .probe = hi3670_phy_probe,
0652 .driver = {
0653 .name = "hi3670-usb-phy",
0654 .of_match_table = hi3670_phy_of_match,
0655 }
0656 };
0657 module_platform_driver(hi3670_phy_driver);
0658
0659 MODULE_AUTHOR("Yu Chen <chenyu56@huawei.com>");
0660 MODULE_LICENSE("GPL v2");
0661 MODULE_DESCRIPTION("Hilisicon Kirin970 USB31 PHY Driver");