Lines Matching +full:phy +full:- +full:mode

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>
58 struct phy *phy; member
59 unsigned int mode; member
77 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_addr()
78 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_addr()
80 regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_CAP_ADDR); in phy_g12a_usb3_pcie_cr_bus_addr()
82 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_addr()
88 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_addr()
90 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_addr()
110 regmap_write(priv->regmap, PHY_R4, 0); in phy_g12a_usb3_pcie_cr_bus_read()
111 regmap_write(priv->regmap, PHY_R4, PHY_R4_PHY_CR_READ); in phy_g12a_usb3_pcie_cr_bus_read()
113 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_read()
121 regmap_write(priv->regmap, PHY_R4, 0); in phy_g12a_usb3_pcie_cr_bus_read()
123 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_read()
145 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_write()
146 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_write()
148 regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_CAP_DATA); in phy_g12a_usb3_pcie_cr_bus_write()
150 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_write()
156 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_write()
158 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_write()
164 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_write()
166 regmap_write(priv->regmap, PHY_R4, reg | PHY_R4_PHY_CR_WRITE); in phy_g12a_usb3_pcie_cr_bus_write()
168 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_write()
174 regmap_write(priv->regmap, PHY_R4, reg); in phy_g12a_usb3_pcie_cr_bus_write()
176 ret = regmap_read_poll_timeout(priv->regmap, PHY_R5, val, in phy_g12a_usb3_pcie_cr_bus_write()
194 static int phy_g12a_usb3_init(struct phy *phy) in phy_g12a_usb3_init() argument
196 struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); in phy_g12a_usb3_init()
199 /* Switch PHY to USB3 */ in phy_g12a_usb3_init()
201 regmap_update_bits(priv->regmap, PHY_R0, in phy_g12a_usb3_init()
208 * in HS mode instead of SS mode. Workaround it by asserting in phy_g12a_usb3_init()
210 * mode in phy_g12a_usb3_init()
212 ret = regmap_update_bits(priv->regmap_cr, 0x102d, BIT(7), BIT(7)); in phy_g12a_usb3_init()
216 ret = regmap_update_bits(priv->regmap_cr, 0x1010, 0xff0, 20); in phy_g12a_usb3_init()
227 ret = regmap_read(priv->regmap_cr, 0x1006, &data); in phy_g12a_usb3_init()
236 ret = regmap_write(priv->regmap_cr, 0x1006, data); in phy_g12a_usb3_init()
246 ret = regmap_read(priv->regmap_cr, 0x1002, &data); in phy_g12a_usb3_init()
254 ret = regmap_write(priv->regmap_cr, 0x1002, data); in phy_g12a_usb3_init()
259 ret = regmap_update_bits(priv->regmap_cr, 0x30, 0xf << 4, 8 << 4); in phy_g12a_usb3_init()
263 regmap_update_bits(priv->regmap, PHY_R2, in phy_g12a_usb3_init()
267 regmap_update_bits(priv->regmap, PHY_R1, in phy_g12a_usb3_init()
275 static int phy_g12a_usb3_pcie_init(struct phy *phy) in phy_g12a_usb3_pcie_init() argument
277 struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); in phy_g12a_usb3_pcie_init()
280 ret = reset_control_reset(priv->reset); in phy_g12a_usb3_pcie_init()
284 if (priv->mode == PHY_TYPE_USB3) in phy_g12a_usb3_pcie_init()
285 return phy_g12a_usb3_init(phy); in phy_g12a_usb3_pcie_init()
288 /* TODO figure out when the bootloader has set USB3 mode before */ in phy_g12a_usb3_pcie_init()
289 regmap_update_bits(priv->regmap, PHY_R0, in phy_g12a_usb3_pcie_init()
296 static int phy_g12a_usb3_pcie_exit(struct phy *phy) in phy_g12a_usb3_pcie_exit() argument
298 struct phy_g12a_usb3_pcie_priv *priv = phy_get_drvdata(phy); in phy_g12a_usb3_pcie_exit()
300 return reset_control_reset(priv->reset); in phy_g12a_usb3_pcie_exit()
303 static struct phy *phy_g12a_usb3_pcie_xlate(struct device *dev, in phy_g12a_usb3_pcie_xlate()
307 unsigned int mode; in phy_g12a_usb3_pcie_xlate() local
309 if (args->args_count < 1) { in phy_g12a_usb3_pcie_xlate()
311 return ERR_PTR(-EINVAL); in phy_g12a_usb3_pcie_xlate()
314 mode = args->args[0]; in phy_g12a_usb3_pcie_xlate()
316 if (mode != PHY_TYPE_USB3 && mode != PHY_TYPE_PCIE) { in phy_g12a_usb3_pcie_xlate()
317 dev_err(dev, "invalid phy mode select argument\n"); in phy_g12a_usb3_pcie_xlate()
318 return ERR_PTR(-EINVAL); in phy_g12a_usb3_pcie_xlate()
321 priv->mode = mode; in phy_g12a_usb3_pcie_xlate()
323 return priv->phy; in phy_g12a_usb3_pcie_xlate()
334 struct device *dev = &pdev->dev; in phy_g12a_usb3_pcie_probe()
335 struct device_node *np = dev->of_node; in phy_g12a_usb3_pcie_probe()
344 return -ENOMEM; in phy_g12a_usb3_pcie_probe()
351 priv->regmap = devm_regmap_init_mmio(dev, base, in phy_g12a_usb3_pcie_probe()
353 if (IS_ERR(priv->regmap)) in phy_g12a_usb3_pcie_probe()
354 return PTR_ERR(priv->regmap); in phy_g12a_usb3_pcie_probe()
356 priv->regmap_cr = devm_regmap_init(dev, NULL, priv, in phy_g12a_usb3_pcie_probe()
358 if (IS_ERR(priv->regmap_cr)) in phy_g12a_usb3_pcie_probe()
359 return PTR_ERR(priv->regmap_cr); in phy_g12a_usb3_pcie_probe()
361 priv->clk_ref = devm_clk_get(dev, "ref_clk"); in phy_g12a_usb3_pcie_probe()
362 if (IS_ERR(priv->clk_ref)) in phy_g12a_usb3_pcie_probe()
363 return PTR_ERR(priv->clk_ref); in phy_g12a_usb3_pcie_probe()
365 ret = clk_prepare_enable(priv->clk_ref); in phy_g12a_usb3_pcie_probe()
369 priv->reset = devm_reset_control_array_get(dev, false, false); in phy_g12a_usb3_pcie_probe()
370 if (IS_ERR(priv->reset)) in phy_g12a_usb3_pcie_probe()
371 return PTR_ERR(priv->reset); in phy_g12a_usb3_pcie_probe()
373 priv->phy = devm_phy_create(dev, np, &phy_g12a_usb3_pcie_ops); in phy_g12a_usb3_pcie_probe()
374 if (IS_ERR(priv->phy)) { in phy_g12a_usb3_pcie_probe()
375 ret = PTR_ERR(priv->phy); in phy_g12a_usb3_pcie_probe()
376 if (ret != -EPROBE_DEFER) in phy_g12a_usb3_pcie_probe()
377 dev_err(dev, "failed to create PHY\n"); in phy_g12a_usb3_pcie_probe()
382 phy_set_drvdata(priv->phy, priv); in phy_g12a_usb3_pcie_probe()
391 clk_disable_unprepare(priv->clk_ref); in phy_g12a_usb3_pcie_probe()
397 { .compatible = "amlogic,g12a-usb3-pcie-phy", },
405 .name = "phy-g12a-usb3-pcie",
412 MODULE_DESCRIPTION("Amlogic G12A USB3 + PCIE Combo PHY driver");