Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Phy provider for USB 3.1 controller on HiSilicon Kirin970 platform
0004  *
0005  * Copyright (C) 2017-2020 Hilisicon Electronics Co., Ltd.
0006  *      http://www.huawei.com
0007  *
0008  * Authors: Yu Chen <chenyu56@huawei.com>
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     /* Clock up */
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     /* Clock down */
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, &reg);
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, &reg);
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, &reg);
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, &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, &reg)) {
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         /* usb refclk iso disable */
0349         ret = regmap_write(priv->peri_crg, PERI_CRG_ISODIS,
0350                    USB_REFCLK_ISO_EN);
0351         if (ret)
0352             goto out;
0353 
0354         /* enable usb_tcxo_en */
0355         ret = regmap_write(priv->pctrl, PCTRL_PERI_CTRL3,
0356                    USB_TCXO_EN |
0357                    (USB_TCXO_EN << PCTRL_PERI_CTRL3_MSK_START));
0358 
0359         /* select usbphy clk from abb */
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     /* assert controller */
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     /* Exit from IDDQ mode */
0483     ret = regmap_update_bits(priv->usb31misc, USB3OTG_CTRL5,
0484                  CTRL5_USB2_SIDDQ, 0);
0485     if (ret)
0486         goto out;
0487 
0488     /* Release USB31 PHY out of TestPowerDown mode */
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     /* Deassert phy */
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     /* Tell the PHY power is stable */
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     /* Enable SSC */
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     /* Deassert controller */
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     /* Set fake vbus valid signal */
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     /* Assert phy */
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         /* disable usb_tcxo_en */
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     /* node of hi3670 phy is a sub-node of usb3_otg_bc */
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");