Lines Matching +full:usb2 +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0
9 * Marvell A3700 UTMI PHY driver
17 #include <linux/phy/phy.h>
21 /* Armada 3700 UTMI PHY registers */
59 * struct mvebu_a3700_utmi_caps - PHY capabilities
61 * @usb32: Flag indicating which PHY is in use (impacts the register map):
62 * - The UTMI PHY wired to the USB3/USB2 controller (otg)
63 * - The UTMI PHY wired to the USB2 controller (host only)
64 * @ops: PHY operations
72 * struct mvebu_a3700_utmi - PHY driver data
74 * @regs: PHY registers
75 * @usb_misc: Regmap with USB miscellaneous registers including PHY ones
76 * @caps: PHY capabilities
77 * @phy: PHY handle
83 struct phy *phy; member
86 static int mvebu_a3700_utmi_phy_power_on(struct phy *phy) in mvebu_a3700_utmi_phy_power_on() argument
88 struct mvebu_a3700_utmi *utmi = phy_get_drvdata(phy); in mvebu_a3700_utmi_phy_power_on()
89 struct device *dev = &phy->dev; in mvebu_a3700_utmi_phy_power_on()
90 int usb32 = utmi->caps->usb32; in mvebu_a3700_utmi_phy_power_on()
98 reg = readl(utmi->regs + USB2_PHY_PLL_CTRL_REG0); in mvebu_a3700_utmi_phy_power_on()
102 writel(reg, utmi->regs + USB2_PHY_PLL_CTRL_REG0); in mvebu_a3700_utmi_phy_power_on()
104 /* Enable PHY pull up and disable USB2 suspend */ in mvebu_a3700_utmi_phy_power_on()
105 regmap_update_bits(utmi->usb_misc, USB2_PHY_CTRL(usb32), in mvebu_a3700_utmi_phy_power_on()
111 reg = readl(utmi->regs + USB2_PHY_OTG_CTRL); in mvebu_a3700_utmi_phy_power_on()
113 writel(reg, utmi->regs + USB2_PHY_OTG_CTRL); in mvebu_a3700_utmi_phy_power_on()
115 /* Disable PHY charger detection */ in mvebu_a3700_utmi_phy_power_on()
116 reg = readl(utmi->regs + USB2_PHY_CHRGR_DETECT); in mvebu_a3700_utmi_phy_power_on()
119 writel(reg, utmi->regs + USB2_PHY_CHRGR_DETECT); in mvebu_a3700_utmi_phy_power_on()
121 /* Disable PHY DP/DM pull-down (used for device mode) */ in mvebu_a3700_utmi_phy_power_on()
122 regmap_update_bits(utmi->usb_misc, USB2_PHY_CTRL(usb32), in mvebu_a3700_utmi_phy_power_on()
128 ret = readl_poll_timeout(utmi->regs + USB2_PHY_CAL_CTRL, reg, in mvebu_a3700_utmi_phy_power_on()
132 dev_err(dev, "Failed to end USB2 PLL calibration\n"); in mvebu_a3700_utmi_phy_power_on()
137 ret = readl_poll_timeout(utmi->regs + USB2_PHY_CAL_CTRL, reg, in mvebu_a3700_utmi_phy_power_on()
141 dev_err(dev, "Failed to end USB2 impedance calibration\n"); in mvebu_a3700_utmi_phy_power_on()
146 ret = readl_poll_timeout(utmi->regs + USB2_RX_CHAN_CTRL1, reg, in mvebu_a3700_utmi_phy_power_on()
150 dev_err(dev, "Failed to end USB2 unknown calibration\n"); in mvebu_a3700_utmi_phy_power_on()
155 ret = readl_poll_timeout(utmi->regs + USB2_PHY_PLL_CTRL_REG0, reg, in mvebu_a3700_utmi_phy_power_on()
159 dev_err(dev, "Failed to lock USB2 PLL\n"); in mvebu_a3700_utmi_phy_power_on()
164 static int mvebu_a3700_utmi_phy_power_off(struct phy *phy) in mvebu_a3700_utmi_phy_power_off() argument
166 struct mvebu_a3700_utmi *utmi = phy_get_drvdata(phy); in mvebu_a3700_utmi_phy_power_off()
167 int usb32 = utmi->caps->usb32; in mvebu_a3700_utmi_phy_power_off()
170 /* Disable PHY pull-up and enable USB2 suspend */ in mvebu_a3700_utmi_phy_power_off()
171 reg = readl(utmi->regs + USB2_PHY_CTRL(usb32)); in mvebu_a3700_utmi_phy_power_off()
173 writel(reg, utmi->regs + USB2_PHY_CTRL(usb32)); in mvebu_a3700_utmi_phy_power_off()
177 reg = readl(utmi->regs + USB2_PHY_OTG_CTRL); in mvebu_a3700_utmi_phy_power_off()
179 writel(reg, utmi->regs + USB2_PHY_OTG_CTRL); in mvebu_a3700_utmi_phy_power_off()
203 .compatible = "marvell,a3700-utmi-otg-phy",
207 .compatible = "marvell,a3700-utmi-host-phy",
216 struct device *dev = &pdev->dev; in mvebu_a3700_utmi_phy_probe()
222 return -ENOMEM; in mvebu_a3700_utmi_phy_probe()
225 utmi->regs = devm_platform_ioremap_resource(pdev, 0); in mvebu_a3700_utmi_phy_probe()
226 if (IS_ERR(utmi->regs)) in mvebu_a3700_utmi_phy_probe()
227 return PTR_ERR(utmi->regs); in mvebu_a3700_utmi_phy_probe()
229 /* Get miscellaneous Host/PHY region */ in mvebu_a3700_utmi_phy_probe()
230 utmi->usb_misc = syscon_regmap_lookup_by_phandle(dev->of_node, in mvebu_a3700_utmi_phy_probe()
231 "marvell,usb-misc-reg"); in mvebu_a3700_utmi_phy_probe()
232 if (IS_ERR(utmi->usb_misc)) { in mvebu_a3700_utmi_phy_probe()
235 return PTR_ERR(utmi->usb_misc); in mvebu_a3700_utmi_phy_probe()
238 /* Retrieve PHY capabilities */ in mvebu_a3700_utmi_phy_probe()
239 utmi->caps = of_device_get_match_data(dev); in mvebu_a3700_utmi_phy_probe()
241 /* Instantiate the PHY */ in mvebu_a3700_utmi_phy_probe()
242 utmi->phy = devm_phy_create(dev, NULL, utmi->caps->ops); in mvebu_a3700_utmi_phy_probe()
243 if (IS_ERR(utmi->phy)) { in mvebu_a3700_utmi_phy_probe()
244 dev_err(dev, "Failed to create the UTMI PHY\n"); in mvebu_a3700_utmi_phy_probe()
245 return PTR_ERR(utmi->phy); in mvebu_a3700_utmi_phy_probe()
248 phy_set_drvdata(utmi->phy, utmi); in mvebu_a3700_utmi_phy_probe()
250 /* Ensure the PHY is powered off */ in mvebu_a3700_utmi_phy_probe()
251 utmi->caps->ops->power_off(utmi->phy); in mvebu_a3700_utmi_phy_probe()
261 .name = "mvebu-a3700-utmi-phy",
269 MODULE_DESCRIPTION("Marvell EBU A3700 UTMI PHY driver");