Lines Matching +full:g12a +full:- +full:usb3 +full:- +full:pcie +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0
3 * Amlogic G12A USB3 + PCIE Combo PHY driver
15 #include <linux/phy/phy.h>
19 #include <dt-bindings/phy/phy.h>
60 struct phy *phy; member
79 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_addr()
80 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_addr()
82 regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_CAP_ADDR); in phy_g12a_usb3_pcie_cr_bus_addr()
84 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_addr()
90 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_addr()
92 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_addr()
112 regmap_write(priv->regmap, PHY_R4, 0); in phy_g12a_usb3_pcie_cr_bus_read()
113 regmap_write(priv->regmap, PHY_R4, PHY_R4_PHY_CR_READ); in phy_g12a_usb3_pcie_cr_bus_read()
115 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_read()
123 regmap_write(priv->regmap, PHY_R4, 0); in phy_g12a_usb3_pcie_cr_bus_read()
125 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_read()
147 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_write()
148 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_write()
150 regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_CAP_DATA); in phy_g12a_usb3_pcie_cr_bus_write()
152 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_write()
158 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_write()
160 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_write()
166 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_write()
168 regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_WRITE); in phy_g12a_usb3_pcie_cr_bus_write()
170 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_write()
176 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_write()
178 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_write()
196 static int phy_g12a_usb3_init(struct phy *phy) in phy_g12a_usb3_init() argument
198 struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); in phy_g12a_usb3_init()
201 ret = reset_control_reset(priv->reset); in phy_g12a_usb3_init()
205 /* Switch PHY to USB3 */ in phy_g12a_usb3_init()
206 /* TODO figure out how to handle when PCIe was set in the bootloader */ in phy_g12a_usb3_init()
207 regmap_update_bits(priv->regmap, PHY_R0, in phy_g12a_usb3_init()
218 ret = regmap_update_bits(priv->regmap_cr, 0x102d, BIT(7), BIT(7)); in phy_g12a_usb3_init()
222 ret = regmap_update_bits(priv->regmap_cr, 0x1010, 0xff0, 20); in phy_g12a_usb3_init()
233 ret = regmap_read(priv->regmap_cr, 0x1006, &data); in phy_g12a_usb3_init()
242 ret = regmap_write(priv->regmap_cr, 0x1006, data); in phy_g12a_usb3_init()
252 ret = regmap_read(priv->regmap_cr, 0x1002, &data); in phy_g12a_usb3_init()
260 ret = regmap_write(priv->regmap_cr, 0x1002, data); in phy_g12a_usb3_init()
265 ret = regmap_update_bits(priv->regmap_cr, 0x30, 0xf << 4, 8 << 4); in phy_g12a_usb3_init()
269 regmap_update_bits(priv->regmap, PHY_R2, in phy_g12a_usb3_init()
273 regmap_update_bits(priv->regmap, PHY_R1, in phy_g12a_usb3_init()
281 static int phy_g12a_usb3_pcie_power_on(struct phy *phy) in phy_g12a_usb3_pcie_power_on() argument
283 struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); in phy_g12a_usb3_pcie_power_on()
285 if (priv->mode == PHY_TYPE_USB3) in phy_g12a_usb3_pcie_power_on()
288 regmap_update_bits(priv->regmap, PHY_R0, in phy_g12a_usb3_pcie_power_on()
295 static int phy_g12a_usb3_pcie_power_off(struct phy *phy) in phy_g12a_usb3_pcie_power_off() argument
297 struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); in phy_g12a_usb3_pcie_power_off()
299 if (priv->mode == PHY_TYPE_USB3) in phy_g12a_usb3_pcie_power_off()
302 regmap_update_bits(priv->regmap, PHY_R0, in phy_g12a_usb3_pcie_power_off()
309 static int phy_g12a_usb3_pcie_reset(struct phy *phy) in phy_g12a_usb3_pcie_reset() argument
311 struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); in phy_g12a_usb3_pcie_reset()
314 if (priv->mode == PHY_TYPE_USB3) in phy_g12a_usb3_pcie_reset()
317 ret = reset_control_assert(priv->reset); in phy_g12a_usb3_pcie_reset()
323 ret = reset_control_deassert(priv->reset); in phy_g12a_usb3_pcie_reset()
332 static int phy_g12a_usb3_pcie_init(struct phy *phy) in phy_g12a_usb3_pcie_init() argument
334 struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); in phy_g12a_usb3_pcie_init()
336 if (priv->mode == PHY_TYPE_USB3) in phy_g12a_usb3_pcie_init()
337 return phy_g12a_usb3_init(phy); in phy_g12a_usb3_pcie_init()
342 static int phy_g12a_usb3_pcie_exit(struct phy *phy) in phy_g12a_usb3_pcie_exit() argument
344 struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); in phy_g12a_usb3_pcie_exit()
346 if (priv->mode == PHY_TYPE_USB3) in phy_g12a_usb3_pcie_exit()
347 return reset_control_reset(priv->reset); in phy_g12a_usb3_pcie_exit()
352 static struct phy *phy_g12a_usb3_pcie_xlate(struct device *dev, in phy_g12a_usb3_pcie_xlate()
358 if (args->args_count < 1) { in phy_g12a_usb3_pcie_xlate()
360 return ERR_PTR(-EINVAL); in phy_g12a_usb3_pcie_xlate()
363 mode = args->args[0]; in phy_g12a_usb3_pcie_xlate()
366 dev_err(dev, "invalid phy mode select argument\n"); in phy_g12a_usb3_pcie_xlate()
367 return ERR_PTR(-EINVAL); in phy_g12a_usb3_pcie_xlate()
370 priv->mode = mode; in phy_g12a_usb3_pcie_xlate()
372 return priv->phy; in phy_g12a_usb3_pcie_xlate()
386 struct device *dev = &pdev->dev; in phy_g12a_usb3_pcie_probe()
387 struct device_node *np = dev->of_node; in phy_g12a_usb3_pcie_probe()
394 return -ENOMEM; in phy_g12a_usb3_pcie_probe()
400 priv->regmap = devm_regmap_init_mmio(dev, base, in phy_g12a_usb3_pcie_probe()
402 if (IS_ERR(priv->regmap)) in phy_g12a_usb3_pcie_probe()
403 return PTR_ERR(priv->regmap); in phy_g12a_usb3_pcie_probe()
405 priv->regmap_cr = devm_regmap_init(dev, NULL, priv, in phy_g12a_usb3_pcie_probe()
407 if (IS_ERR(priv->regmap_cr)) in phy_g12a_usb3_pcie_probe()
408 return PTR_ERR(priv->regmap_cr); in phy_g12a_usb3_pcie_probe()
410 priv->clk_ref = devm_clk_get_enabled(dev, "ref_clk"); in phy_g12a_usb3_pcie_probe()
411 if (IS_ERR(priv->clk_ref)) in phy_g12a_usb3_pcie_probe()
412 return PTR_ERR(priv->clk_ref); in phy_g12a_usb3_pcie_probe()
414 priv->reset = devm_reset_control_array_get_exclusive(dev); in phy_g12a_usb3_pcie_probe()
415 if (IS_ERR(priv->reset)) in phy_g12a_usb3_pcie_probe()
416 return PTR_ERR(priv->reset); in phy_g12a_usb3_pcie_probe()
418 priv->phy = devm_phy_create(dev, np, &phy_g12a_usb3_pcie_ops); in phy_g12a_usb3_pcie_probe()
419 if (IS_ERR(priv->phy)) in phy_g12a_usb3_pcie_probe()
420 return dev_err_probe(dev, PTR_ERR(priv->phy), "failed to create PHY\n"); in phy_g12a_usb3_pcie_probe()
422 phy_set_drvdata(priv->phy, priv); in phy_g12a_usb3_pcie_probe()
431 { .compatible = "amlogic,g12a-usb3-pcie-phy", },
439 .name = "phy-g12a-usb3-pcie",
446 MODULE_DESCRIPTION("Amlogic G12A USB3 + PCIE Combo PHY driver");