Lines Matching +full:g12a +full:- +full:usb2 +full:- +full:phy
1 // SPDX-License-Identifier: GPL-2.0
3 * Meson G12A USB2 PHY driver
20 #include <linux/phy/phy.h>
169 static int phy_meson_g12a_usb2_init(struct phy *phy) in phy_meson_g12a_usb2_init() argument
171 struct phy_meson_g12a_usb2_priv *priv = phy_get_drvdata(phy); in phy_meson_g12a_usb2_init()
175 ret = clk_prepare_enable(priv->clk); in phy_meson_g12a_usb2_init()
179 ret = reset_control_reset(priv->reset); in phy_meson_g12a_usb2_init()
181 clk_disable_unprepare(priv->clk); in phy_meson_g12a_usb2_init()
188 regmap_update_bits(priv->regmap, PHY_CTRL_R21, in phy_meson_g12a_usb2_init()
192 regmap_write(priv->regmap, PHY_CTRL_R16, in phy_meson_g12a_usb2_init()
201 regmap_write(priv->regmap, PHY_CTRL_R17, in phy_meson_g12a_usb2_init()
220 if (priv->soc_id == MESON_SOC_A1) in phy_meson_g12a_usb2_init()
223 regmap_write(priv->regmap, PHY_CTRL_R18, value); in phy_meson_g12a_usb2_init()
228 regmap_write(priv->regmap, PHY_CTRL_R16, in phy_meson_g12a_usb2_init()
236 /* PHY Tuning */ in phy_meson_g12a_usb2_init()
237 regmap_write(priv->regmap, PHY_CTRL_R20, in phy_meson_g12a_usb2_init()
247 if (priv->soc_id == MESON_SOC_G12A) in phy_meson_g12a_usb2_init()
248 regmap_write(priv->regmap, PHY_CTRL_R4, in phy_meson_g12a_usb2_init()
255 else if (priv->soc_id == MESON_SOC_A1) { in phy_meson_g12a_usb2_init()
256 regmap_write(priv->regmap, PHY_CTRL_R21, in phy_meson_g12a_usb2_init()
262 regmap_write(priv->regmap, PHY_CTRL_R13, in phy_meson_g12a_usb2_init()
267 regmap_write(priv->regmap, PHY_CTRL_R3, in phy_meson_g12a_usb2_init()
272 if (priv->soc_id == MESON_SOC_G12A) { in phy_meson_g12a_usb2_init()
274 regmap_write(priv->regmap, PHY_CTRL_R14, 0); in phy_meson_g12a_usb2_init()
275 regmap_write(priv->regmap, PHY_CTRL_R13, in phy_meson_g12a_usb2_init()
283 static int phy_meson_g12a_usb2_exit(struct phy *phy) in phy_meson_g12a_usb2_exit() argument
285 struct phy_meson_g12a_usb2_priv *priv = phy_get_drvdata(phy); in phy_meson_g12a_usb2_exit()
288 ret = reset_control_reset(priv->reset); in phy_meson_g12a_usb2_exit()
290 clk_disable_unprepare(priv->clk); in phy_meson_g12a_usb2_exit()
304 struct device *dev = &pdev->dev; in phy_meson_g12a_usb2_probe()
307 struct phy *phy; in phy_meson_g12a_usb2_probe() local
313 return -ENOMEM; in phy_meson_g12a_usb2_probe()
315 priv->dev = dev; in phy_meson_g12a_usb2_probe()
322 priv->soc_id = (uintptr_t)of_device_get_match_data(&pdev->dev); in phy_meson_g12a_usb2_probe()
324 priv->regmap = devm_regmap_init_mmio(dev, base, in phy_meson_g12a_usb2_probe()
326 if (IS_ERR(priv->regmap)) in phy_meson_g12a_usb2_probe()
327 return PTR_ERR(priv->regmap); in phy_meson_g12a_usb2_probe()
329 priv->clk = devm_clk_get(dev, "xtal"); in phy_meson_g12a_usb2_probe()
330 if (IS_ERR(priv->clk)) in phy_meson_g12a_usb2_probe()
331 return PTR_ERR(priv->clk); in phy_meson_g12a_usb2_probe()
333 priv->reset = devm_reset_control_get(dev, "phy"); in phy_meson_g12a_usb2_probe()
334 if (IS_ERR(priv->reset)) in phy_meson_g12a_usb2_probe()
335 return PTR_ERR(priv->reset); in phy_meson_g12a_usb2_probe()
337 ret = reset_control_deassert(priv->reset); in phy_meson_g12a_usb2_probe()
341 phy = devm_phy_create(dev, NULL, &phy_meson_g12a_usb2_ops); in phy_meson_g12a_usb2_probe()
342 if (IS_ERR(phy)) { in phy_meson_g12a_usb2_probe()
343 ret = PTR_ERR(phy); in phy_meson_g12a_usb2_probe()
344 if (ret != -EPROBE_DEFER) in phy_meson_g12a_usb2_probe()
345 dev_err(dev, "failed to create PHY\n"); in phy_meson_g12a_usb2_probe()
350 phy_set_bus_width(phy, 8); in phy_meson_g12a_usb2_probe()
351 phy_set_drvdata(phy, priv); in phy_meson_g12a_usb2_probe()
360 .compatible = "amlogic,g12a-usb2-phy",
364 .compatible = "amlogic,a1-usb2-phy",
374 .name = "phy-meson-g12a-usb2",
382 MODULE_DESCRIPTION("Meson G12A USB2 PHY driver");