0001
0002
0003
0004
0005
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/property.h>
0014 #include <linux/regmap.h>
0015 #include <linux/reset.h>
0016 #include <linux/phy/phy.h>
0017 #include <linux/platform_device.h>
0018 #include <linux/usb/of.h>
0019
0020 #define REG_CONFIG 0x00
0021 #define REG_CONFIG_CLK_EN BIT(0)
0022 #define REG_CONFIG_CLK_SEL_MASK GENMASK(3, 1)
0023 #define REG_CONFIG_CLK_DIV_MASK GENMASK(10, 4)
0024 #define REG_CONFIG_CLK_32k_ALTSEL BIT(15)
0025 #define REG_CONFIG_TEST_TRIG BIT(31)
0026
0027 #define REG_CTRL 0x04
0028 #define REG_CTRL_SOFT_PRST BIT(0)
0029 #define REG_CTRL_SOFT_HRESET BIT(1)
0030 #define REG_CTRL_SS_SCALEDOWN_MODE_MASK GENMASK(3, 2)
0031 #define REG_CTRL_CLK_DET_RST BIT(4)
0032 #define REG_CTRL_INTR_SEL BIT(5)
0033 #define REG_CTRL_CLK_DETECTED BIT(8)
0034 #define REG_CTRL_SOF_SENT_RCVD_TGL BIT(9)
0035 #define REG_CTRL_SOF_TOGGLE_OUT BIT(10)
0036 #define REG_CTRL_POWER_ON_RESET BIT(15)
0037 #define REG_CTRL_SLEEPM BIT(16)
0038 #define REG_CTRL_TX_BITSTUFF_ENN_H BIT(17)
0039 #define REG_CTRL_TX_BITSTUFF_ENN BIT(18)
0040 #define REG_CTRL_COMMON_ON BIT(19)
0041 #define REG_CTRL_REF_CLK_SEL_MASK GENMASK(21, 20)
0042 #define REG_CTRL_REF_CLK_SEL_SHIFT 20
0043 #define REG_CTRL_FSEL_MASK GENMASK(24, 22)
0044 #define REG_CTRL_FSEL_SHIFT 22
0045 #define REG_CTRL_PORT_RESET BIT(25)
0046 #define REG_CTRL_THREAD_ID_MASK GENMASK(31, 26)
0047
0048 #define REG_ENDP_INTR 0x08
0049
0050
0051 #define REG_ADP_BC 0x0c
0052 #define REG_ADP_BC_VBUS_VLD_EXT_SEL BIT(0)
0053 #define REG_ADP_BC_VBUS_VLD_EXT BIT(1)
0054 #define REG_ADP_BC_OTG_DISABLE BIT(2)
0055 #define REG_ADP_BC_ID_PULLUP BIT(3)
0056 #define REG_ADP_BC_DRV_VBUS BIT(4)
0057 #define REG_ADP_BC_ADP_PRB_EN BIT(5)
0058 #define REG_ADP_BC_ADP_DISCHARGE BIT(6)
0059 #define REG_ADP_BC_ADP_CHARGE BIT(7)
0060 #define REG_ADP_BC_SESS_END BIT(8)
0061 #define REG_ADP_BC_DEVICE_SESS_VLD BIT(9)
0062 #define REG_ADP_BC_B_VALID BIT(10)
0063 #define REG_ADP_BC_A_VALID BIT(11)
0064 #define REG_ADP_BC_ID_DIG BIT(12)
0065 #define REG_ADP_BC_VBUS_VALID BIT(13)
0066 #define REG_ADP_BC_ADP_PROBE BIT(14)
0067 #define REG_ADP_BC_ADP_SENSE BIT(15)
0068 #define REG_ADP_BC_ACA_ENABLE BIT(16)
0069 #define REG_ADP_BC_DCD_ENABLE BIT(17)
0070 #define REG_ADP_BC_VDAT_DET_EN_B BIT(18)
0071 #define REG_ADP_BC_VDAT_SRC_EN_B BIT(19)
0072 #define REG_ADP_BC_CHARGE_SEL BIT(20)
0073 #define REG_ADP_BC_CHARGE_DETECT BIT(21)
0074 #define REG_ADP_BC_ACA_PIN_RANGE_C BIT(22)
0075 #define REG_ADP_BC_ACA_PIN_RANGE_B BIT(23)
0076 #define REG_ADP_BC_ACA_PIN_RANGE_A BIT(24)
0077 #define REG_ADP_BC_ACA_PIN_GND BIT(25)
0078 #define REG_ADP_BC_ACA_PIN_FLOAT BIT(26)
0079
0080 #define REG_DBG_UART 0x10
0081 #define REG_DBG_UART_BYPASS_SEL BIT(0)
0082 #define REG_DBG_UART_BYPASS_DM_EN BIT(1)
0083 #define REG_DBG_UART_BYPASS_DP_EN BIT(2)
0084 #define REG_DBG_UART_BYPASS_DM_DATA BIT(3)
0085 #define REG_DBG_UART_BYPASS_DP_DATA BIT(4)
0086 #define REG_DBG_UART_FSV_MINUS BIT(5)
0087 #define REG_DBG_UART_FSV_PLUS BIT(6)
0088 #define REG_DBG_UART_FSV_BURN_IN_TEST BIT(7)
0089 #define REG_DBG_UART_LOOPBACK_EN_B BIT(8)
0090 #define REG_DBG_UART_SET_IDDQ BIT(9)
0091 #define REG_DBG_UART_ATE_RESET BIT(10)
0092
0093 #define REG_TEST 0x14
0094 #define REG_TEST_DATA_IN_MASK GENMASK(3, 0)
0095 #define REG_TEST_EN_MASK GENMASK(7, 4)
0096 #define REG_TEST_ADDR_MASK GENMASK(11, 8)
0097 #define REG_TEST_DATA_OUT_SEL BIT(12)
0098 #define REG_TEST_CLK BIT(13)
0099 #define REG_TEST_VA_TEST_EN_B_MASK GENMASK(15, 14)
0100 #define REG_TEST_DATA_OUT_MASK GENMASK(19, 16)
0101 #define REG_TEST_DISABLE_ID_PULLUP BIT(20)
0102
0103 #define REG_TUNE 0x18
0104 #define REG_TUNE_TX_RES_TUNE_MASK GENMASK(1, 0)
0105 #define REG_TUNE_TX_HSXV_TUNE_MASK GENMASK(3, 2)
0106 #define REG_TUNE_TX_VREF_TUNE_MASK GENMASK(7, 4)
0107 #define REG_TUNE_TX_RISE_TUNE_MASK GENMASK(9, 8)
0108 #define REG_TUNE_TX_PREEMP_PULSE_TUNE BIT(10)
0109 #define REG_TUNE_TX_PREEMP_AMP_TUNE_MASK GENMASK(12, 11)
0110 #define REG_TUNE_TX_FSLS_TUNE_MASK GENMASK(16, 13)
0111 #define REG_TUNE_SQRX_TUNE_MASK GENMASK(19, 17)
0112 #define REG_TUNE_OTG_TUNE GENMASK(22, 20)
0113 #define REG_TUNE_COMP_DIS_TUNE GENMASK(25, 23)
0114 #define REG_TUNE_HOST_DM_PULLDOWN BIT(26)
0115 #define REG_TUNE_HOST_DP_PULLDOWN BIT(27)
0116
0117 #define RESET_COMPLETE_TIME 500
0118 #define ACA_ENABLE_COMPLETE_TIME 50
0119
0120 struct phy_meson8b_usb2_match_data {
0121 bool host_enable_aca;
0122 };
0123
0124 struct phy_meson8b_usb2_priv {
0125 struct regmap *regmap;
0126 enum usb_dr_mode dr_mode;
0127 struct clk *clk_usb_general;
0128 struct clk *clk_usb;
0129 struct reset_control *reset;
0130 const struct phy_meson8b_usb2_match_data *match;
0131 };
0132
0133 static const struct regmap_config phy_meson8b_usb2_regmap_conf = {
0134 .reg_bits = 8,
0135 .val_bits = 32,
0136 .reg_stride = 4,
0137 .max_register = REG_TUNE,
0138 };
0139
0140 static int phy_meson8b_usb2_power_on(struct phy *phy)
0141 {
0142 struct phy_meson8b_usb2_priv *priv = phy_get_drvdata(phy);
0143 u32 reg;
0144 int ret;
0145
0146 if (!IS_ERR_OR_NULL(priv->reset)) {
0147 ret = reset_control_reset(priv->reset);
0148 if (ret) {
0149 dev_err(&phy->dev, "Failed to trigger USB reset\n");
0150 return ret;
0151 }
0152 }
0153
0154 ret = clk_prepare_enable(priv->clk_usb_general);
0155 if (ret) {
0156 dev_err(&phy->dev, "Failed to enable USB general clock\n");
0157 reset_control_rearm(priv->reset);
0158 return ret;
0159 }
0160
0161 ret = clk_prepare_enable(priv->clk_usb);
0162 if (ret) {
0163 dev_err(&phy->dev, "Failed to enable USB DDR clock\n");
0164 clk_disable_unprepare(priv->clk_usb_general);
0165 reset_control_rearm(priv->reset);
0166 return ret;
0167 }
0168
0169 regmap_update_bits(priv->regmap, REG_CONFIG, REG_CONFIG_CLK_32k_ALTSEL,
0170 REG_CONFIG_CLK_32k_ALTSEL);
0171
0172 regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_REF_CLK_SEL_MASK,
0173 0x2 << REG_CTRL_REF_CLK_SEL_SHIFT);
0174
0175 regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_FSEL_MASK,
0176 0x5 << REG_CTRL_FSEL_SHIFT);
0177
0178
0179 regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET,
0180 REG_CTRL_POWER_ON_RESET);
0181 udelay(RESET_COMPLETE_TIME);
0182 regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET, 0);
0183 udelay(RESET_COMPLETE_TIME);
0184
0185 regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_SOF_TOGGLE_OUT,
0186 REG_CTRL_SOF_TOGGLE_OUT);
0187
0188 if (priv->dr_mode == USB_DR_MODE_HOST) {
0189 regmap_update_bits(priv->regmap, REG_DBG_UART,
0190 REG_DBG_UART_SET_IDDQ, 0);
0191
0192 if (priv->match->host_enable_aca) {
0193 regmap_update_bits(priv->regmap, REG_ADP_BC,
0194 REG_ADP_BC_ACA_ENABLE,
0195 REG_ADP_BC_ACA_ENABLE);
0196
0197 udelay(ACA_ENABLE_COMPLETE_TIME);
0198
0199 regmap_read(priv->regmap, REG_ADP_BC, ®);
0200 if (reg & REG_ADP_BC_ACA_PIN_FLOAT) {
0201 dev_warn(&phy->dev, "USB ID detect failed!\n");
0202 clk_disable_unprepare(priv->clk_usb);
0203 clk_disable_unprepare(priv->clk_usb_general);
0204 reset_control_rearm(priv->reset);
0205 return -EINVAL;
0206 }
0207 }
0208 }
0209
0210 return 0;
0211 }
0212
0213 static int phy_meson8b_usb2_power_off(struct phy *phy)
0214 {
0215 struct phy_meson8b_usb2_priv *priv = phy_get_drvdata(phy);
0216
0217 if (priv->dr_mode == USB_DR_MODE_HOST)
0218 regmap_update_bits(priv->regmap, REG_DBG_UART,
0219 REG_DBG_UART_SET_IDDQ,
0220 REG_DBG_UART_SET_IDDQ);
0221
0222 clk_disable_unprepare(priv->clk_usb);
0223 clk_disable_unprepare(priv->clk_usb_general);
0224 reset_control_rearm(priv->reset);
0225
0226
0227 regmap_update_bits(priv->regmap, REG_CTRL, REG_CTRL_POWER_ON_RESET,
0228 REG_CTRL_POWER_ON_RESET);
0229
0230 return 0;
0231 }
0232
0233 static const struct phy_ops phy_meson8b_usb2_ops = {
0234 .power_on = phy_meson8b_usb2_power_on,
0235 .power_off = phy_meson8b_usb2_power_off,
0236 .owner = THIS_MODULE,
0237 };
0238
0239 static int phy_meson8b_usb2_probe(struct platform_device *pdev)
0240 {
0241 struct phy_meson8b_usb2_priv *priv;
0242 struct phy *phy;
0243 struct phy_provider *phy_provider;
0244 void __iomem *base;
0245
0246 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
0247 if (!priv)
0248 return -ENOMEM;
0249
0250 base = devm_platform_ioremap_resource(pdev, 0);
0251 if (IS_ERR(base))
0252 return PTR_ERR(base);
0253
0254 priv->match = device_get_match_data(&pdev->dev);
0255 if (!priv->match)
0256 return -ENODEV;
0257
0258 priv->regmap = devm_regmap_init_mmio(&pdev->dev, base,
0259 &phy_meson8b_usb2_regmap_conf);
0260 if (IS_ERR(priv->regmap))
0261 return PTR_ERR(priv->regmap);
0262
0263 priv->clk_usb_general = devm_clk_get(&pdev->dev, "usb_general");
0264 if (IS_ERR(priv->clk_usb_general))
0265 return PTR_ERR(priv->clk_usb_general);
0266
0267 priv->clk_usb = devm_clk_get(&pdev->dev, "usb");
0268 if (IS_ERR(priv->clk_usb))
0269 return PTR_ERR(priv->clk_usb);
0270
0271 priv->reset = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
0272 if (IS_ERR(priv->reset))
0273 return dev_err_probe(&pdev->dev, PTR_ERR(priv->reset),
0274 "Failed to get the reset line");
0275
0276 priv->dr_mode = of_usb_get_dr_mode_by_phy(pdev->dev.of_node, -1);
0277 if (priv->dr_mode == USB_DR_MODE_UNKNOWN) {
0278 dev_err(&pdev->dev,
0279 "missing dual role configuration of the controller\n");
0280 return -EINVAL;
0281 }
0282
0283 phy = devm_phy_create(&pdev->dev, NULL, &phy_meson8b_usb2_ops);
0284 if (IS_ERR(phy)) {
0285 return dev_err_probe(&pdev->dev, PTR_ERR(phy),
0286 "failed to create PHY\n");
0287 }
0288
0289 phy_set_drvdata(phy, priv);
0290
0291 phy_provider =
0292 devm_of_phy_provider_register(&pdev->dev, of_phy_simple_xlate);
0293
0294 return PTR_ERR_OR_ZERO(phy_provider);
0295 }
0296
0297 static const struct phy_meson8b_usb2_match_data phy_meson8_usb2_match_data = {
0298 .host_enable_aca = false,
0299 };
0300
0301 static const struct phy_meson8b_usb2_match_data phy_meson8b_usb2_match_data = {
0302 .host_enable_aca = true,
0303 };
0304
0305 static const struct of_device_id phy_meson8b_usb2_of_match[] = {
0306 {
0307 .compatible = "amlogic,meson8-usb2-phy",
0308 .data = &phy_meson8_usb2_match_data
0309 },
0310 {
0311 .compatible = "amlogic,meson8b-usb2-phy",
0312 .data = &phy_meson8b_usb2_match_data
0313 },
0314 {
0315 .compatible = "amlogic,meson8m2-usb2-phy",
0316 .data = &phy_meson8b_usb2_match_data
0317 },
0318 {
0319 .compatible = "amlogic,meson-gxbb-usb2-phy",
0320 .data = &phy_meson8b_usb2_match_data
0321 },
0322 { }
0323 };
0324 MODULE_DEVICE_TABLE(of, phy_meson8b_usb2_of_match);
0325
0326 static struct platform_driver phy_meson8b_usb2_driver = {
0327 .probe = phy_meson8b_usb2_probe,
0328 .driver = {
0329 .name = "phy-meson-usb2",
0330 .of_match_table = phy_meson8b_usb2_of_match,
0331 },
0332 };
0333 module_platform_driver(phy_meson8b_usb2_driver);
0334
0335 MODULE_AUTHOR("Martin Blumenstingl <martin.blumenstingl@googlemail.com>");
0336 MODULE_DESCRIPTION("Meson8, Meson8b, Meson8m2 and GXBB USB2 PHY driver");
0337 MODULE_LICENSE("GPL");