Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Meson GXL and GXM USB2 PHY driver
0004  *
0005  * Copyright (C) 2017 Martin Blumenstingl <martin.blumenstingl@googlemail.com>
0006  */
0007 
0008 #include <linux/clk.h>
0009 #include <linux/delay.h>
0010 #include <linux/io.h>
0011 #include <linux/module.h>
0012 #include <linux/of_device.h>
0013 #include <linux/regmap.h>
0014 #include <linux/reset.h>
0015 #include <linux/phy/phy.h>
0016 #include <linux/platform_device.h>
0017 
0018 /* bits [31:27] are read-only */
0019 #define U2P_R0                          0x0
0020     #define U2P_R0_BYPASS_SEL               BIT(0)
0021     #define U2P_R0_BYPASS_DM_EN             BIT(1)
0022     #define U2P_R0_BYPASS_DP_EN             BIT(2)
0023     #define U2P_R0_TXBITSTUFF_ENH               BIT(3)
0024     #define U2P_R0_TXBITSTUFF_EN                BIT(4)
0025     #define U2P_R0_DM_PULLDOWN              BIT(5)
0026     #define U2P_R0_DP_PULLDOWN              BIT(6)
0027     #define U2P_R0_DP_VBUS_VLD_EXT_SEL          BIT(7)
0028     #define U2P_R0_DP_VBUS_VLD_EXT              BIT(8)
0029     #define U2P_R0_ADP_PRB_EN               BIT(9)
0030     #define U2P_R0_ADP_DISCHARGE                BIT(10)
0031     #define U2P_R0_ADP_CHARGE               BIT(11)
0032     #define U2P_R0_DRV_VBUS                 BIT(12)
0033     #define U2P_R0_ID_PULLUP                BIT(13)
0034     #define U2P_R0_LOOPBACK_EN_B                BIT(14)
0035     #define U2P_R0_OTG_DISABLE              BIT(15)
0036     #define U2P_R0_COMMON_ONN               BIT(16)
0037     #define U2P_R0_FSEL_MASK                GENMASK(19, 17)
0038     #define U2P_R0_REF_CLK_SEL_MASK             GENMASK(21, 20)
0039     #define U2P_R0_POWER_ON_RESET               BIT(22)
0040     #define U2P_R0_V_ATE_TEST_EN_B_MASK         GENMASK(24, 23)
0041     #define U2P_R0_ID_SET_ID_DQ             BIT(25)
0042     #define U2P_R0_ATE_RESET                BIT(26)
0043     #define U2P_R0_FSV_MINUS                BIT(27)
0044     #define U2P_R0_FSV_PLUS                 BIT(28)
0045     #define U2P_R0_BYPASS_DM_DATA               BIT(29)
0046     #define U2P_R0_BYPASS_DP_DATA               BIT(30)
0047 
0048 #define U2P_R1                          0x4
0049     #define U2P_R1_BURN_IN_TEST             BIT(0)
0050     #define U2P_R1_ACA_ENABLE               BIT(1)
0051     #define U2P_R1_DCD_ENABLE               BIT(2)
0052     #define U2P_R1_VDAT_SRC_EN_B                BIT(3)
0053     #define U2P_R1_VDAT_DET_EN_B                BIT(4)
0054     #define U2P_R1_CHARGES_SEL              BIT(5)
0055     #define U2P_R1_TX_PREEMP_PULSE_TUNE         BIT(6)
0056     #define U2P_R1_TX_PREEMP_AMP_TUNE_MASK          GENMASK(8, 7)
0057     #define U2P_R1_TX_RES_TUNE_MASK             GENMASK(10, 9)
0058     #define U2P_R1_TX_RISE_TUNE_MASK            GENMASK(12, 11)
0059     #define U2P_R1_TX_VREF_TUNE_MASK            GENMASK(16, 13)
0060     #define U2P_R1_TX_FSLS_TUNE_MASK            GENMASK(20, 17)
0061     #define U2P_R1_TX_HSXV_TUNE_MASK            GENMASK(22, 21)
0062     #define U2P_R1_OTG_TUNE_MASK                GENMASK(25, 23)
0063     #define U2P_R1_SQRX_TUNE_MASK               GENMASK(28, 26)
0064     #define U2P_R1_COMP_DIS_TUNE_MASK           GENMASK(31, 29)
0065 
0066 /* bits [31:14] are read-only */
0067 #define U2P_R2                          0x8
0068     #define U2P_R2_TESTDATA_IN_MASK             GENMASK(7, 0)
0069     #define U2P_R2_TESTADDR_MASK                GENMASK(11, 8)
0070     #define U2P_R2_TESTDATA_OUT_SEL             BIT(12)
0071     #define U2P_R2_TESTCLK                  BIT(13)
0072     #define U2P_R2_TESTDATA_OUT_MASK            GENMASK(17, 14)
0073     #define U2P_R2_ACA_PIN_RANGE_C              BIT(18)
0074     #define U2P_R2_ACA_PIN_RANGE_B              BIT(19)
0075     #define U2P_R2_ACA_PIN_RANGE_A              BIT(20)
0076     #define U2P_R2_ACA_PIN_GND              BIT(21)
0077     #define U2P_R2_ACA_PIN_FLOAT                BIT(22)
0078     #define U2P_R2_CHARGE_DETECT                BIT(23)
0079     #define U2P_R2_DEVICE_SESSION_VALID         BIT(24)
0080     #define U2P_R2_ADP_PROBE                BIT(25)
0081     #define U2P_R2_ADP_SENSE                BIT(26)
0082     #define U2P_R2_SESSION_END              BIT(27)
0083     #define U2P_R2_VBUS_VALID               BIT(28)
0084     #define U2P_R2_B_VALID                  BIT(29)
0085     #define U2P_R2_A_VALID                  BIT(30)
0086     #define U2P_R2_ID_DIG                   BIT(31)
0087 
0088 #define U2P_R3                          0xc
0089 
0090 #define RESET_COMPLETE_TIME             500
0091 
0092 struct phy_meson_gxl_usb2_priv {
0093     struct regmap       *regmap;
0094     enum phy_mode       mode;
0095     int         is_enabled;
0096     struct clk      *clk;
0097     struct reset_control    *reset;
0098 };
0099 
0100 static const struct regmap_config phy_meson_gxl_usb2_regmap_conf = {
0101     .reg_bits = 8,
0102     .val_bits = 32,
0103     .reg_stride = 4,
0104     .max_register = U2P_R3,
0105 };
0106 
0107 static int phy_meson_gxl_usb2_init(struct phy *phy)
0108 {
0109     struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
0110     int ret;
0111 
0112     ret = reset_control_reset(priv->reset);
0113     if (ret)
0114         return ret;
0115 
0116     ret = clk_prepare_enable(priv->clk);
0117     if (ret) {
0118         reset_control_rearm(priv->reset);
0119         return ret;
0120     }
0121 
0122     return 0;
0123 }
0124 
0125 static int phy_meson_gxl_usb2_exit(struct phy *phy)
0126 {
0127     struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
0128 
0129     clk_disable_unprepare(priv->clk);
0130     reset_control_rearm(priv->reset);
0131 
0132     return 0;
0133 }
0134 
0135 static int phy_meson_gxl_usb2_reset(struct phy *phy)
0136 {
0137     struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
0138 
0139     if (priv->is_enabled) {
0140         /* reset the PHY and wait until settings are stabilized */
0141         regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
0142                    U2P_R0_POWER_ON_RESET);
0143         udelay(RESET_COMPLETE_TIME);
0144         regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
0145                    0);
0146         udelay(RESET_COMPLETE_TIME);
0147     }
0148 
0149     return 0;
0150 }
0151 
0152 static int phy_meson_gxl_usb2_set_mode(struct phy *phy,
0153                        enum phy_mode mode, int submode)
0154 {
0155     struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
0156 
0157     switch (mode) {
0158     case PHY_MODE_USB_HOST:
0159     case PHY_MODE_USB_OTG:
0160         regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
0161                    U2P_R0_DM_PULLDOWN);
0162         regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
0163                    U2P_R0_DP_PULLDOWN);
0164         regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP,
0165                    U2P_R0_ID_PULLUP);
0166         break;
0167 
0168     case PHY_MODE_USB_DEVICE:
0169         regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DM_PULLDOWN,
0170                    0);
0171         regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_DP_PULLDOWN,
0172                    0);
0173         regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_ID_PULLUP,
0174                    U2P_R0_ID_PULLUP);
0175         break;
0176 
0177     default:
0178         return -EINVAL;
0179     }
0180 
0181     phy_meson_gxl_usb2_reset(phy);
0182 
0183     priv->mode = mode;
0184 
0185     return 0;
0186 }
0187 
0188 static int phy_meson_gxl_usb2_power_off(struct phy *phy)
0189 {
0190     struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
0191 
0192     priv->is_enabled = 0;
0193 
0194     /* power off the PHY by putting it into reset mode */
0195     regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET,
0196                U2P_R0_POWER_ON_RESET);
0197 
0198     return 0;
0199 }
0200 
0201 static int phy_meson_gxl_usb2_power_on(struct phy *phy)
0202 {
0203     struct phy_meson_gxl_usb2_priv *priv = phy_get_drvdata(phy);
0204     int ret;
0205 
0206     priv->is_enabled = 1;
0207 
0208     /* power on the PHY by taking it out of reset mode */
0209     regmap_update_bits(priv->regmap, U2P_R0, U2P_R0_POWER_ON_RESET, 0);
0210 
0211     ret = phy_meson_gxl_usb2_set_mode(phy, priv->mode, 0);
0212     if (ret) {
0213         phy_meson_gxl_usb2_power_off(phy);
0214 
0215         dev_err(&phy->dev, "Failed to initialize PHY with mode %d\n",
0216             priv->mode);
0217         return ret;
0218     }
0219 
0220     return 0;
0221 }
0222 
0223 static const struct phy_ops phy_meson_gxl_usb2_ops = {
0224     .init       = phy_meson_gxl_usb2_init,
0225     .exit       = phy_meson_gxl_usb2_exit,
0226     .power_on   = phy_meson_gxl_usb2_power_on,
0227     .power_off  = phy_meson_gxl_usb2_power_off,
0228     .set_mode   = phy_meson_gxl_usb2_set_mode,
0229     .reset      = phy_meson_gxl_usb2_reset,
0230     .owner      = THIS_MODULE,
0231 };
0232 
0233 static int phy_meson_gxl_usb2_probe(struct platform_device *pdev)
0234 {
0235     struct device *dev = &pdev->dev;
0236     struct phy_provider *phy_provider;
0237     struct phy_meson_gxl_usb2_priv *priv;
0238     struct phy *phy;
0239     void __iomem *base;
0240     int ret;
0241 
0242     priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
0243     if (!priv)
0244         return -ENOMEM;
0245 
0246     platform_set_drvdata(pdev, priv);
0247 
0248     base = devm_platform_ioremap_resource(pdev, 0);
0249     if (IS_ERR(base))
0250         return PTR_ERR(base);
0251 
0252     /* start in host mode */
0253     priv->mode = PHY_MODE_USB_HOST;
0254 
0255     priv->regmap = devm_regmap_init_mmio(dev, base,
0256                          &phy_meson_gxl_usb2_regmap_conf);
0257     if (IS_ERR(priv->regmap))
0258         return PTR_ERR(priv->regmap);
0259 
0260     priv->clk = devm_clk_get_optional(dev, "phy");
0261     if (IS_ERR(priv->clk))
0262         return PTR_ERR(priv->clk);
0263 
0264     priv->reset = devm_reset_control_get_optional_shared(dev, "phy");
0265     if (IS_ERR(priv->reset))
0266         return PTR_ERR(priv->reset);
0267 
0268     phy = devm_phy_create(dev, NULL, &phy_meson_gxl_usb2_ops);
0269     if (IS_ERR(phy)) {
0270         ret = PTR_ERR(phy);
0271         if (ret != -EPROBE_DEFER)
0272             dev_err(dev, "failed to create PHY\n");
0273 
0274         return ret;
0275     }
0276 
0277     phy_set_drvdata(phy, priv);
0278 
0279     phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
0280 
0281     return PTR_ERR_OR_ZERO(phy_provider);
0282 }
0283 
0284 static const struct of_device_id phy_meson_gxl_usb2_of_match[] = {
0285     { .compatible = "amlogic,meson-gxl-usb2-phy", },
0286     { },
0287 };
0288 MODULE_DEVICE_TABLE(of, phy_meson_gxl_usb2_of_match);
0289 
0290 static struct platform_driver phy_meson_gxl_usb2_driver = {
0291     .probe  = phy_meson_gxl_usb2_probe,
0292     .driver = {
0293         .name       = "phy-meson-gxl-usb2",
0294         .of_match_table = phy_meson_gxl_usb2_of_match,
0295     },
0296 };
0297 module_platform_driver(phy_meson_gxl_usb2_driver);
0298 
0299 MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
0300 MODULE_DESCRIPTION("Meson GXL and GXM USB2 PHY driver");
0301 MODULE_LICENSE("GPL v2");