[PATCH net-next 3/3] net: stmmac: dwmac-rk: Enable RGMII 25M refout clock

Gavin Gao attinagaoxu at gmail.com
Sun Jul 26 19:10:47 PDT 2026


Boards can set clock_in_out = "output" to request a MAC-provided clock,
but dwmac-rk currently does not enable the optional 25 MHz RGMII
reference output clock. The common clock framework may therefore disable
the clock as unused.

Request the optional clk_mac_25m_refout clock in RGMII output mode, set
it to 25 MHz, and keep it enabled while the MAC clocks are enabled.

Signed-off-by: Gavin Gao <attinagaoxu at gmail.com>
---
 .../net/ethernet/stmicro/stmmac/dwmac-rk.c    | 33 ++++++++++++++++++-
 1 file changed, 32 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
index 643578266dfc..5e7e5e8f8d62 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
+++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-rk.c
@@ -81,6 +81,7 @@ struct rk_priv_data {
 	struct clk_bulk_data *clks;
 	int num_clks;
 	struct clk *clk_phy;
+	struct clk *clk_mac_25m_refout;
 
 	struct reset_control *phy_reset;
 
@@ -1419,6 +1420,24 @@ static int rk_gmac_clk_init(struct plat_stmmacenet_data *plat)
 		clk_set_rate(bsp_priv->clk_phy, 50000000);
 	}
 
+	if (!bsp_priv->clock_input && phy_interface_mode_is_rgmii(phy_iface)) {
+		bsp_priv->clk_mac_25m_refout =
+			devm_clk_get_optional(dev, "clk_mac_25m_refout");
+		if (IS_ERR(bsp_priv->clk_mac_25m_refout)) {
+			ret = PTR_ERR(bsp_priv->clk_mac_25m_refout);
+			return dev_err_probe(dev, ret,
+					     "Cannot get 25M refout clock\n");
+		}
+
+		if (bsp_priv->clk_mac_25m_refout) {
+			ret = clk_set_rate(bsp_priv->clk_mac_25m_refout,
+					   25000000);
+			if (ret)
+				return dev_err_probe(dev, ret,
+						     "Cannot set 25M refout clock rate\n");
+		}
+	}
+
 	return 0;
 }
 
@@ -1433,9 +1452,13 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
 			if (ret)
 				return ret;
 
+			ret = clk_prepare_enable(bsp_priv->clk_mac_25m_refout);
+			if (ret)
+				goto err_disable_clks;
+
 			ret = clk_prepare_enable(bsp_priv->clk_phy);
 			if (ret)
-				return ret;
+				goto err_disable_25m_refout;
 
 			if (bsp_priv->ops && bsp_priv->ops->set_clock_selection)
 				bsp_priv->ops->set_clock_selection(bsp_priv,
@@ -1454,12 +1477,20 @@ static int gmac_clk_enable(struct rk_priv_data *bsp_priv, bool enable)
 			clk_bulk_disable_unprepare(bsp_priv->num_clks,
 						   bsp_priv->clks);
 			clk_disable_unprepare(bsp_priv->clk_phy);
+			clk_disable_unprepare(bsp_priv->clk_mac_25m_refout);
 
 			bsp_priv->clk_enabled = false;
 		}
 	}
 
 	return 0;
+
+err_disable_25m_refout:
+	clk_disable_unprepare(bsp_priv->clk_mac_25m_refout);
+err_disable_clks:
+	clk_bulk_disable_unprepare(bsp_priv->num_clks, bsp_priv->clks);
+
+	return ret;
 }
 
 static int phy_power_on(struct rk_priv_data *bsp_priv, bool enable)
-- 
2.55.0



More information about the Linux-rockchip mailing list