cmn_refclk_<p/m> lines in Torrent SERDES are used for an connecting external reference clock. cmn_refclk_<p/m> can also be configured to output the reference clock. In order to drive the refclk out from the SERDES (Cadence Torrent), PHY_EN_REFCLK should be set in SERDES_RST of WIZ. Model PHY_EN_REFCLK as a clock, so that platforms like AM642 EVM can enable it.
Based on: https://lore.kernel.org/r/[email protected] Signed-off-by: George McCollister <[email protected]> --- drivers/phy/ti/phy-j721e-wiz.c | 46 ++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/drivers/phy/ti/phy-j721e-wiz.c b/drivers/phy/ti/phy-j721e-wiz.c index eaf68d18f3a1..466e2a5d0b50 100644 --- a/drivers/phy/ti/phy-j721e-wiz.c +++ b/drivers/phy/ti/phy-j721e-wiz.c @@ -75,6 +75,7 @@ enum wiz_typec_master_lane { static const struct reg_field por_en = REG_FIELD(WIZ_SERDES_CTRL, 31, 31); static const struct reg_field phy_reset_n = REG_FIELD(WIZ_SERDES_RST, 31, 31); +static const struct reg_field phy_en_refclk = REG_FIELD(WIZ_SERDES_RST, 30, 30); static const struct reg_field pll1_refclk_mux_sel = REG_FIELD(WIZ_SERDES_RST, 29, 29); static const struct reg_field pll1_refclk_mux_sel_2 = @@ -534,9 +535,43 @@ static int wiz_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args) return 0; } +static int wiz_phy_en_refclk_enable(struct clk *clk) +{ + struct udevice *dev = clk->dev; + struct wiz_clk *priv = dev_get_priv(dev); + struct wiz *wiz = priv->wiz; + int id; + + id = clk->id >> 10; + if (id != TI_WIZ_PHY_EN_REFCLK) + return 0; + + regmap_field_write(wiz->phy_en_refclk, 1); + + return 0; +} + +static int wiz_phy_en_refclk_disable(struct clk *clk) +{ + struct udevice *dev = clk->dev; + struct wiz_clk *priv = dev_get_priv(dev); + struct wiz *wiz = priv->wiz; + int id; + + id = clk->id >> 10; + if (id != TI_WIZ_PHY_EN_REFCLK) + return 0; + + regmap_field_write(wiz->phy_en_refclk, 0); + + return 0; +} + static const struct clk_ops wiz_clk_ops = { .set_parent = wiz_clk_set_parent, .of_xlate = wiz_clk_of_xlate, + .enable = wiz_phy_en_refclk_enable, + .disable = wiz_phy_en_refclk_disable, }; int wiz_clk_probe(struct udevice *dev) @@ -818,6 +853,12 @@ static int wiz_regfield_init(struct wiz *wiz) return PTR_ERR(wiz->phy_reset_n); } + wiz->phy_en_refclk = devm_regmap_field_alloc(dev, regmap, phy_en_refclk); + if (IS_ERR(wiz->phy_en_refclk)) { + dev_err(dev, "PHY_EN_REFCLK reg field init failed\n"); + return PTR_ERR(wiz->phy_en_refclk); + } + wiz->pma_cmn_refclk_int_mode = devm_regmap_field_alloc(dev, regmap, pma_cmn_refclk_int_mode); if (IS_ERR(wiz->pma_cmn_refclk_int_mode)) { @@ -1042,6 +1083,11 @@ static int j721e_wiz_bind_clocks(struct wiz *wiz) } } + rc = device_bind(dev, wiz_clk_drv, "phy-en-refclk", + NULL, dev_ofnode(dev), NULL); + if (rc) + dev_err(dev, "cannot bind driver for clock phy-en-refclk\n"); + return 0; } -- 2.51.2

