Hello Daniel, On Wed, 6 Dec 2023 01:44:08 +0000 Daniel Golle <daniel@xxxxxxxxxxxxxx> wrote: > Add driver for MediaTek's pextp 10 Gigabit/s Ethernet SerDes PHY which > can be found in the MT7988 SoC. > > The PHY can operates only in PHY_MODE_ETHERNET, the submode is one of > PHY_INTERFACE_MODE_* corresponding to the supported modes: > > * USXGMII > * 10GBase-R > * 5GBase-R > * 2500Base-X > * 1000Base-X > * Cisco SGMII (MAC side) > > In order to work-around a performance issue present on the first of > two PEXTP present in MT7988 special tuning is applied which can be > selected by adding the mediatek,usxgmii-performance-errata property to > the device tree node. > > There is no documentation what-so-ever for the pextp registers and > this driver is based on a GPL licensed implementation found in > MediaTek's SDK. > > Signed-off-by: Daniel Golle <daniel@xxxxxxxxxxxxxx> > --- [...] > + > +static int mtk_pextp_power_on(struct phy *phy) > +{ > + struct mtk_pextp_phy *pextp = phy_get_drvdata(phy); > + int ret; > + > + ret = clk_prepare_enable(pextp->clk[0]); > + if (ret) > + return ret; > + > + return clk_prepare_enable(pextp->clk[1]); > +} clk_bulk operations could be used here > +static int mtk_pextp_power_off(struct phy *phy) > +{ > + struct mtk_pextp_phy *pextp = phy_get_drvdata(phy); > + > + clk_disable_unprepare(pextp->clk[1]); > + clk_disable_unprepare(pextp->clk[0]); > + > + return 0; > +} Here > +static const struct phy_ops mtk_pextp_ops = { > + .power_on = mtk_pextp_power_on, > + .power_off = mtk_pextp_power_off, > + .set_mode = mtk_pextp_set_mode, > + .reset = mtk_pextp_reset, > + .owner = THIS_MODULE, > +}; > + > +static int mtk_pextp_probe(struct platform_device *pdev) > +{ > + struct device_node *np = pdev->dev.of_node; > + struct phy_provider *phy_provider; > + struct mtk_pextp_phy *pextp; > + struct phy *phy; > + > + if (!np) > + return -ENODEV; > + > + pextp = devm_kzalloc(&pdev->dev, sizeof(*pextp), GFP_KERNEL); > + if (!pextp) > + return -ENOMEM; > + > + pextp->base = devm_of_iomap(&pdev->dev, np, 0, NULL); > + if (!pextp->base) > + return -EIO; > + > + pextp->dev = &pdev->dev; > + pextp->clk[0] = devm_clk_get(&pdev->dev, "topxtal"); > + if (IS_ERR(pextp->clk[0])) > + return PTR_ERR(pextp->clk[0]); > + > + pextp->clk[1] = devm_clk_get(&pdev->dev, "xfipll"); > + if (IS_ERR(pextp->clk[1])) > + return PTR_ERR(pextp->clk[1]); And here as well. Thanks, Maxime