0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include <linux/io.h>
0013 #include <linux/iopoll.h>
0014 #include <linux/mfd/syscon.h>
0015 #include <linux/module.h>
0016 #include <linux/of_device.h>
0017 #include <linux/phy/phy.h>
0018 #include <linux/platform_device.h>
0019 #include <linux/regmap.h>
0020
0021
0022 #define USB2_PHY_PLL_CTRL_REG0 0x0
0023 #define PLL_REF_DIV_OFF 0
0024 #define PLL_REF_DIV_MASK GENMASK(6, 0)
0025 #define PLL_REF_DIV_5 5
0026 #define PLL_FB_DIV_OFF 16
0027 #define PLL_FB_DIV_MASK GENMASK(24, 16)
0028 #define PLL_FB_DIV_96 96
0029 #define PLL_SEL_LPFR_OFF 28
0030 #define PLL_SEL_LPFR_MASK GENMASK(29, 28)
0031 #define PLL_READY BIT(31)
0032 #define USB2_PHY_CAL_CTRL 0x8
0033 #define PHY_PLLCAL_DONE BIT(31)
0034 #define PHY_IMPCAL_DONE BIT(23)
0035 #define USB2_RX_CHAN_CTRL1 0x18
0036 #define USB2PHY_SQCAL_DONE BIT(31)
0037 #define USB2_PHY_OTG_CTRL 0x34
0038 #define PHY_PU_OTG BIT(4)
0039 #define USB2_PHY_CHRGR_DETECT 0x38
0040 #define PHY_CDP_EN BIT(2)
0041 #define PHY_DCP_EN BIT(3)
0042 #define PHY_PD_EN BIT(4)
0043 #define PHY_PU_CHRG_DTC BIT(5)
0044 #define PHY_CDP_DM_AUTO BIT(7)
0045 #define PHY_ENSWITCH_DP BIT(12)
0046 #define PHY_ENSWITCH_DM BIT(13)
0047
0048
0049 #define USB2_PHY_CTRL(usb32) (usb32 ? 0x20 : 0x4)
0050 #define RB_USB2PHY_PU BIT(0)
0051 #define USB2_DP_PULLDN_DEV_MODE BIT(5)
0052 #define USB2_DM_PULLDN_DEV_MODE BIT(6)
0053 #define RB_USB2PHY_SUSPM(usb32) (usb32 ? BIT(14) : BIT(7))
0054
0055 #define PLL_LOCK_DELAY_US 10000
0056 #define PLL_LOCK_TIMEOUT_US 1000000
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 struct mvebu_a3700_utmi_caps {
0067 int usb32;
0068 const struct phy_ops *ops;
0069 };
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 struct mvebu_a3700_utmi {
0080 void __iomem *regs;
0081 struct regmap *usb_misc;
0082 const struct mvebu_a3700_utmi_caps *caps;
0083 struct phy *phy;
0084 };
0085
0086 static int mvebu_a3700_utmi_phy_power_on(struct phy *phy)
0087 {
0088 struct mvebu_a3700_utmi *utmi = phy_get_drvdata(phy);
0089 struct device *dev = &phy->dev;
0090 int usb32 = utmi->caps->usb32;
0091 int ret = 0;
0092 u32 reg;
0093
0094
0095
0096
0097
0098 reg = readl(utmi->regs + USB2_PHY_PLL_CTRL_REG0);
0099 reg &= ~(PLL_REF_DIV_MASK | PLL_FB_DIV_MASK | PLL_SEL_LPFR_MASK);
0100 reg |= (PLL_REF_DIV_5 << PLL_REF_DIV_OFF) |
0101 (PLL_FB_DIV_96 << PLL_FB_DIV_OFF);
0102 writel(reg, utmi->regs + USB2_PHY_PLL_CTRL_REG0);
0103
0104
0105 regmap_update_bits(utmi->usb_misc, USB2_PHY_CTRL(usb32),
0106 RB_USB2PHY_SUSPM(usb32) | RB_USB2PHY_PU,
0107 RB_USB2PHY_SUSPM(usb32) | RB_USB2PHY_PU);
0108
0109 if (usb32) {
0110
0111 reg = readl(utmi->regs + USB2_PHY_OTG_CTRL);
0112 reg |= PHY_PU_OTG;
0113 writel(reg, utmi->regs + USB2_PHY_OTG_CTRL);
0114
0115
0116 reg = readl(utmi->regs + USB2_PHY_CHRGR_DETECT);
0117 reg &= ~(PHY_CDP_EN | PHY_DCP_EN | PHY_PD_EN | PHY_PU_CHRG_DTC |
0118 PHY_CDP_DM_AUTO | PHY_ENSWITCH_DP | PHY_ENSWITCH_DM);
0119 writel(reg, utmi->regs + USB2_PHY_CHRGR_DETECT);
0120
0121
0122 regmap_update_bits(utmi->usb_misc, USB2_PHY_CTRL(usb32),
0123 USB2_DP_PULLDN_DEV_MODE |
0124 USB2_DM_PULLDN_DEV_MODE, 0);
0125 }
0126
0127
0128 ret = readl_poll_timeout(utmi->regs + USB2_PHY_CAL_CTRL, reg,
0129 reg & PHY_PLLCAL_DONE,
0130 PLL_LOCK_DELAY_US, PLL_LOCK_TIMEOUT_US);
0131 if (ret) {
0132 dev_err(dev, "Failed to end USB2 PLL calibration\n");
0133 return ret;
0134 }
0135
0136
0137 ret = readl_poll_timeout(utmi->regs + USB2_PHY_CAL_CTRL, reg,
0138 reg & PHY_IMPCAL_DONE,
0139 PLL_LOCK_DELAY_US, PLL_LOCK_TIMEOUT_US);
0140 if (ret) {
0141 dev_err(dev, "Failed to end USB2 impedance calibration\n");
0142 return ret;
0143 }
0144
0145
0146 ret = readl_poll_timeout(utmi->regs + USB2_RX_CHAN_CTRL1, reg,
0147 reg & USB2PHY_SQCAL_DONE,
0148 PLL_LOCK_DELAY_US, PLL_LOCK_TIMEOUT_US);
0149 if (ret) {
0150 dev_err(dev, "Failed to end USB2 unknown calibration\n");
0151 return ret;
0152 }
0153
0154
0155 ret = readl_poll_timeout(utmi->regs + USB2_PHY_PLL_CTRL_REG0, reg,
0156 reg & PLL_READY,
0157 PLL_LOCK_DELAY_US, PLL_LOCK_TIMEOUT_US);
0158 if (ret)
0159 dev_err(dev, "Failed to lock USB2 PLL\n");
0160
0161 return ret;
0162 }
0163
0164 static int mvebu_a3700_utmi_phy_power_off(struct phy *phy)
0165 {
0166 struct mvebu_a3700_utmi *utmi = phy_get_drvdata(phy);
0167 int usb32 = utmi->caps->usb32;
0168 u32 reg;
0169
0170
0171 reg = readl(utmi->regs + USB2_PHY_CTRL(usb32));
0172 reg &= ~(RB_USB2PHY_PU | RB_USB2PHY_SUSPM(usb32));
0173 writel(reg, utmi->regs + USB2_PHY_CTRL(usb32));
0174
0175
0176 if (usb32) {
0177 reg = readl(utmi->regs + USB2_PHY_OTG_CTRL);
0178 reg &= ~PHY_PU_OTG;
0179 writel(reg, utmi->regs + USB2_PHY_OTG_CTRL);
0180 }
0181
0182 return 0;
0183 }
0184
0185 static const struct phy_ops mvebu_a3700_utmi_phy_ops = {
0186 .power_on = mvebu_a3700_utmi_phy_power_on,
0187 .power_off = mvebu_a3700_utmi_phy_power_off,
0188 .owner = THIS_MODULE,
0189 };
0190
0191 static const struct mvebu_a3700_utmi_caps mvebu_a3700_utmi_otg_phy_caps = {
0192 .usb32 = true,
0193 .ops = &mvebu_a3700_utmi_phy_ops,
0194 };
0195
0196 static const struct mvebu_a3700_utmi_caps mvebu_a3700_utmi_host_phy_caps = {
0197 .usb32 = false,
0198 .ops = &mvebu_a3700_utmi_phy_ops,
0199 };
0200
0201 static const struct of_device_id mvebu_a3700_utmi_of_match[] = {
0202 {
0203 .compatible = "marvell,a3700-utmi-otg-phy",
0204 .data = &mvebu_a3700_utmi_otg_phy_caps,
0205 },
0206 {
0207 .compatible = "marvell,a3700-utmi-host-phy",
0208 .data = &mvebu_a3700_utmi_host_phy_caps,
0209 },
0210 {},
0211 };
0212 MODULE_DEVICE_TABLE(of, mvebu_a3700_utmi_of_match);
0213
0214 static int mvebu_a3700_utmi_phy_probe(struct platform_device *pdev)
0215 {
0216 struct device *dev = &pdev->dev;
0217 struct mvebu_a3700_utmi *utmi;
0218 struct phy_provider *provider;
0219
0220 utmi = devm_kzalloc(dev, sizeof(*utmi), GFP_KERNEL);
0221 if (!utmi)
0222 return -ENOMEM;
0223
0224
0225 utmi->regs = devm_platform_ioremap_resource(pdev, 0);
0226 if (IS_ERR(utmi->regs))
0227 return PTR_ERR(utmi->regs);
0228
0229
0230 utmi->usb_misc = syscon_regmap_lookup_by_phandle(dev->of_node,
0231 "marvell,usb-misc-reg");
0232 if (IS_ERR(utmi->usb_misc)) {
0233 dev_err(dev,
0234 "Missing USB misc purpose system controller\n");
0235 return PTR_ERR(utmi->usb_misc);
0236 }
0237
0238
0239 utmi->caps = of_device_get_match_data(dev);
0240
0241
0242 utmi->phy = devm_phy_create(dev, NULL, utmi->caps->ops);
0243 if (IS_ERR(utmi->phy)) {
0244 dev_err(dev, "Failed to create the UTMI PHY\n");
0245 return PTR_ERR(utmi->phy);
0246 }
0247
0248 phy_set_drvdata(utmi->phy, utmi);
0249
0250
0251 utmi->caps->ops->power_off(utmi->phy);
0252
0253 provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate);
0254
0255 return PTR_ERR_OR_ZERO(provider);
0256 }
0257
0258 static struct platform_driver mvebu_a3700_utmi_driver = {
0259 .probe = mvebu_a3700_utmi_phy_probe,
0260 .driver = {
0261 .name = "mvebu-a3700-utmi-phy",
0262 .of_match_table = mvebu_a3700_utmi_of_match,
0263 },
0264 };
0265 module_platform_driver(mvebu_a3700_utmi_driver);
0266
0267 MODULE_AUTHOR("Igal Liberman <igall@marvell.com>");
0268 MODULE_AUTHOR("Miquel Raynal <miquel.raynal@bootlin.com>");
0269 MODULE_DESCRIPTION("Marvell EBU A3700 UTMI PHY driver");
0270 MODULE_LICENSE("GPL v2");