Lines Matching +full:phy +full:- +full:pma

1 // SPDX-License-Identifier: GPL-2.0
3 * Rockchip PCIE3.0 phy driver
16 #include <linux/phy/pcie.h>
17 #include <linux/phy/phy.h>
20 #include <dt-bindings/phy/phy-snps-pcie3.h>
49 struct phy *phy; member
59 static int rockchip_p3phy_set_mode(struct phy *phy, enum phy_mode mode, int submode) in rockchip_p3phy_set_mode() argument
61 struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy); in rockchip_p3phy_set_mode()
66 priv->mode = PHY_MODE_PCIE_RC; in rockchip_p3phy_set_mode()
69 priv->mode = PHY_MODE_PCIE_EP; in rockchip_p3phy_set_mode()
72 priv->is_bifurcation = true; in rockchip_p3phy_set_mode()
76 return -EINVAL; in rockchip_p3phy_set_mode()
83 #include "phy-rockchip-snps-pcie3.fw"
92 /* Deassert PCIe PMA output clamp mode */ in rockchip_p3phy_rk3568_init()
93 regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, in rockchip_p3phy_rk3568_init()
96 if (priv->is_bifurcation) { in rockchip_p3phy_rk3568_init()
97 regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON6, in rockchip_p3phy_rk3568_init()
99 regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON1, in rockchip_p3phy_rk3568_init()
102 regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON4, in rockchip_p3phy_rk3568_init()
104 regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON4, in rockchip_p3phy_rk3568_init()
107 reset_control_deassert(priv->p30phy); in rockchip_p3phy_rk3568_init()
108 ret = regmap_read_poll_timeout(priv->phy_grf, in rockchip_p3phy_rk3568_init()
118 regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, in rockchip_p3phy_rk3568_init()
121 writel(phy_fw[i], priv->mmio + (i<<2)); in rockchip_p3phy_rk3568_init()
124 regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON9, in rockchip_p3phy_rk3568_init()
126 regmap_write(priv->phy_grf, GRF_PCIE30PHY_CON4, in rockchip_p3phy_rk3568_init()
142 /* Deassert PCIe PMA output clamp mode */ in rockchip_p3phy_rk3588_init()
143 regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, in rockchip_p3phy_rk3588_init()
146 reset_control_deassert(priv->p30phy); in rockchip_p3phy_rk3588_init()
148 ret = regmap_read_poll_timeout(priv->phy_grf, in rockchip_p3phy_rk3588_init()
152 ret |= regmap_read_poll_timeout(priv->phy_grf, in rockchip_p3phy_rk3588_init()
166 static int rochchip_p3phy_init(struct phy *phy) in rochchip_p3phy_init() argument
168 struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy); in rochchip_p3phy_init()
171 ret = clk_bulk_prepare_enable(priv->num_clks, priv->clks); in rochchip_p3phy_init()
177 reset_control_assert(priv->p30phy); in rochchip_p3phy_init()
180 if (priv->ops->phy_init) { in rochchip_p3phy_init()
181 ret = priv->ops->phy_init(priv); in rochchip_p3phy_init()
183 clk_bulk_disable_unprepare(priv->num_clks, priv->clks); in rochchip_p3phy_init()
189 static int rochchip_p3phy_exit(struct phy *phy) in rochchip_p3phy_exit() argument
191 struct rockchip_p3phy_priv *priv = phy_get_drvdata(phy); in rochchip_p3phy_exit()
192 clk_bulk_disable_unprepare(priv->num_clks, priv->clks); in rochchip_p3phy_exit()
193 reset_control_assert(priv->p30phy); in rochchip_p3phy_exit()
207 struct device *dev = &pdev->dev; in rockchip_p3phy_probe()
209 struct device_node *np = dev->of_node; in rockchip_p3phy_probe()
216 return -ENOMEM; in rockchip_p3phy_probe()
219 priv->mmio = devm_ioremap_resource(dev, res); in rockchip_p3phy_probe()
220 if (IS_ERR(priv->mmio)) { in rockchip_p3phy_probe()
221 ret = PTR_ERR(priv->mmio); in rockchip_p3phy_probe()
225 priv->ops = of_device_get_match_data(&pdev->dev); in rockchip_p3phy_probe()
226 if (!priv->ops) { in rockchip_p3phy_probe()
227 dev_err(&pdev->dev, "no of match data provided\n"); in rockchip_p3phy_probe()
228 return -EINVAL; in rockchip_p3phy_probe()
231 priv->phy_grf = syscon_regmap_lookup_by_phandle(np, "rockchip,phy-grf"); in rockchip_p3phy_probe()
232 if (IS_ERR(priv->phy_grf)) { in rockchip_p3phy_probe()
234 return PTR_ERR(priv->phy_grf); in rockchip_p3phy_probe()
237 priv->pipe_grf = syscon_regmap_lookup_by_phandle(dev->of_node, in rockchip_p3phy_probe()
238 "rockchip,pipe-grf"); in rockchip_p3phy_probe()
239 if (IS_ERR(priv->pipe_grf)) in rockchip_p3phy_probe()
242 ret = device_property_read_u32(dev, "rockchip,pcie30-phymode", &val); in rockchip_p3phy_probe()
244 priv->pcie30_phymode = val; in rockchip_p3phy_probe()
246 priv->pcie30_phymode = PHY_MODE_PCIE_AGGREGATION; in rockchip_p3phy_probe()
249 if (priv->pcie30_phymode > 4) in rockchip_p3phy_probe()
250 priv->pcie30_phymode = PHY_MODE_PCIE_AGGREGATION; in rockchip_p3phy_probe()
252 regmap_write(priv->phy_grf, RK3588_PCIE3PHY_GRF_CMN_CON0, in rockchip_p3phy_probe()
253 (0x7<<16) | priv->pcie30_phymode); in rockchip_p3phy_probe()
256 if (!IS_ERR(priv->pipe_grf)) { in rockchip_p3phy_probe()
257 reg = priv->pcie30_phymode & 3; in rockchip_p3phy_probe()
259 regmap_write(priv->pipe_grf, PHP_GRF_PCIESEL_CON, in rockchip_p3phy_probe()
263 priv->phy = devm_phy_create(dev, NULL, &rochchip_p3phy_ops); in rockchip_p3phy_probe()
264 if (IS_ERR(priv->phy)) { in rockchip_p3phy_probe()
266 return PTR_ERR(priv->phy); in rockchip_p3phy_probe()
269 priv->p30phy = devm_reset_control_get(dev, "phy"); in rockchip_p3phy_probe()
270 if (IS_ERR(priv->p30phy)) { in rockchip_p3phy_probe()
271 dev_warn(dev, "no phy reset control specified\n"); in rockchip_p3phy_probe()
272 priv->p30phy = NULL; in rockchip_p3phy_probe()
275 priv->num_clks = devm_clk_bulk_get_all(dev, &priv->clks); in rockchip_p3phy_probe()
276 if (priv->num_clks < 1) in rockchip_p3phy_probe()
277 return -ENODEV; in rockchip_p3phy_probe()
280 phy_set_drvdata(priv->phy, priv); in rockchip_p3phy_probe()
286 { .compatible = "rockchip,rk3568-pcie3-phy", .data = &rk3568_ops },
287 { .compatible = "rockchip,rk3588-pcie3-phy", .data = &rk3588_ops },
295 .name = "rockchip-snps-pcie3-phy",
300 MODULE_DESCRIPTION("Rockchip Synopsys PCIe 3.0 PHY driver");