[PATCH] rockchip: clk: clk_rk3576: Add support for RK3576 GMAC 25MHz clock output
Alexey Charkov
alchark at flipper.net
Mon May 4 15:45:08 CEST 2026
Rockchip RK3576 SoC has two built-in GMACs which connect to external PHYs
via RGMII interface. The RGMII link can be clocked by either the PHY or
the SoC. When the SoC is the master, as is the case on the RK3576 EVB1,
the output clock needs to be configured in the CRU.
Add the respective logic for getting and setting the RGMII reference clock
output for both GMAC0 and GMAC1.
Signed-off-by: Alexey Charkov <alchark at flipper.net>
---
arch/arm/include/asm/arch-rockchip/cru_rk3576.h | 14 +++++++
drivers/clk/rockchip/clk_rk3576.c | 50 +++++++++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3576.h b/arch/arm/include/asm/arch-rockchip/cru_rk3576.h
index c51750beff28..fb77fbd7307a 100644
--- a/arch/arm/include/asm/arch-rockchip/cru_rk3576.h
+++ b/arch/arm/include/asm/arch-rockchip/cru_rk3576.h
@@ -222,6 +222,20 @@ enum {
REF_CLK0_OUT_PLL_DIV_SHIFT = 0,
REF_CLK0_OUT_PLL_DIV_MASK = 0xff << REF_CLK0_OUT_PLL_DIV_SHIFT,
+ /* CRU_CLK_SEL36_CON */
+ CLK_REFCLKO25M_GMAC0_DIV_SHIFT = 0,
+ CLK_REFCLKO25M_GMAC0_DIV_MASK = 0x7f << CLK_REFCLKO25M_GMAC0_DIV_SHIFT,
+ CLK_REFCLKO25M_GMAC0_SEL_SHIFT = 7,
+ CLK_REFCLKO25M_GMAC0_SEL_MASK = 1 << CLK_REFCLKO25M_GMAC0_SEL_SHIFT,
+ CLK_REFCLKO25M_GMAC0_SEL_GPLL = 0,
+ CLK_REFCLKO25M_GMAC0_SEL_CPLL = 1,
+ CLK_REFCLKO25M_GMAC1_DIV_SHIFT = 8,
+ CLK_REFCLKO25M_GMAC1_DIV_MASK = 0x7f << CLK_REFCLKO25M_GMAC1_DIV_SHIFT,
+ CLK_REFCLKO25M_GMAC1_SEL_SHIFT = 15,
+ CLK_REFCLKO25M_GMAC1_SEL_MASK = 1 << CLK_REFCLKO25M_GMAC1_SEL_SHIFT,
+ CLK_REFCLKO25M_GMAC1_SEL_GPLL = 0,
+ CLK_REFCLKO25M_GMAC1_SEL_CPLL = 1,
+
/* CRU_CLK_SEL55_CON */
ACLK_BUS_ROOT_SEL_SHIFT = 9,
ACLK_BUS_ROOT_SEL_MASK = 1 << ACLK_BUS_ROOT_SEL_SHIFT,
diff --git a/drivers/clk/rockchip/clk_rk3576.c b/drivers/clk/rockchip/clk_rk3576.c
index 1026af27ca13..5168196b14e8 100644
--- a/drivers/clk/rockchip/clk_rk3576.c
+++ b/drivers/clk/rockchip/clk_rk3576.c
@@ -1549,6 +1549,24 @@ static ulong rk3576_gmac_get_clk(struct rk3576_clk_priv *priv, ulong clk_id)
con = readl(&cru->clksel_con[31]);
div = (con & CLK_GMAC1_125M_DIV_MASK) >> CLK_GMAC1_125M_DIV_SHIFT;
return DIV_TO_RATE(priv->cpll_hz, div);
+ case REFCLKO25M_GMAC0_OUT:
+ con = readl(&cru->clksel_con[36]);
+ div = (con & CLK_REFCLKO25M_GMAC0_DIV_MASK) >> CLK_REFCLKO25M_GMAC0_DIV_SHIFT;
+ src = (con & CLK_REFCLKO25M_GMAC0_SEL_MASK) >> CLK_REFCLKO25M_GMAC0_SEL_SHIFT;
+ if (src == CLK_REFCLKO25M_GMAC0_SEL_CPLL)
+ p_rate = priv->cpll_hz;
+ else
+ p_rate = priv->gpll_hz;
+ return DIV_TO_RATE(p_rate, div);
+ case REFCLKO25M_GMAC1_OUT:
+ con = readl(&cru->clksel_con[36]);
+ div = (con & CLK_REFCLKO25M_GMAC1_DIV_MASK) >> CLK_REFCLKO25M_GMAC1_DIV_SHIFT;
+ src = (con & CLK_REFCLKO25M_GMAC1_SEL_MASK) >> CLK_REFCLKO25M_GMAC1_SEL_SHIFT;
+ if (src == CLK_REFCLKO25M_GMAC1_SEL_CPLL)
+ p_rate = priv->cpll_hz;
+ else
+ p_rate = priv->gpll_hz;
+ return DIV_TO_RATE(p_rate, div);
default:
return -ENOENT;
}
@@ -1608,6 +1626,34 @@ static ulong rk3576_gmac_set_clk(struct rk3576_clk_priv *priv,
CLK_GMAC1_125M_DIV_MASK,
(div - 1) << CLK_GMAC1_125M_DIV_SHIFT);
break;
+ case REFCLKO25M_GMAC0_OUT:
+ if (!(priv->gpll_hz % rate)) {
+ src = CLK_REFCLKO25M_GMAC0_SEL_GPLL;
+ div = priv->gpll_hz / rate;
+ } else {
+ src = CLK_REFCLKO25M_GMAC0_SEL_CPLL;
+ div = priv->cpll_hz / rate;
+ }
+ rk_clrsetreg(&cru->clksel_con[36],
+ CLK_REFCLKO25M_GMAC0_SEL_MASK |
+ CLK_REFCLKO25M_GMAC0_DIV_MASK,
+ src << CLK_REFCLKO25M_GMAC0_SEL_SHIFT |
+ (div - 1) << CLK_REFCLKO25M_GMAC0_DIV_SHIFT);
+ break;
+ case REFCLKO25M_GMAC1_OUT:
+ if (!(priv->gpll_hz % rate)) {
+ src = CLK_REFCLKO25M_GMAC1_SEL_GPLL;
+ div = priv->gpll_hz / rate;
+ } else {
+ src = CLK_REFCLKO25M_GMAC1_SEL_CPLL;
+ div = priv->cpll_hz / rate;
+ }
+ rk_clrsetreg(&cru->clksel_con[36],
+ CLK_REFCLKO25M_GMAC1_SEL_MASK |
+ CLK_REFCLKO25M_GMAC1_DIV_MASK,
+ src << CLK_REFCLKO25M_GMAC1_SEL_SHIFT |
+ (div - 1) << CLK_REFCLKO25M_GMAC1_DIV_SHIFT);
+ break;
default:
return -ENOENT;
}
@@ -2014,6 +2060,8 @@ static ulong rk3576_clk_get_rate(struct clk *clk)
case CLK_GMAC1_PTP_REF:
case CLK_GMAC0_125M_SRC:
case CLK_GMAC1_125M_SRC:
+ case REFCLKO25M_GMAC0_OUT:
+ case REFCLKO25M_GMAC1_OUT:
rate = rk3576_gmac_get_clk(priv, clk->id);
break;
case CLK_UART_FRAC_0:
@@ -2193,6 +2241,8 @@ static ulong rk3576_clk_set_rate(struct clk *clk, ulong rate)
case CLK_GMAC1_PTP_REF:
case CLK_GMAC0_125M_SRC:
case CLK_GMAC1_125M_SRC:
+ case REFCLKO25M_GMAC0_OUT:
+ case REFCLKO25M_GMAC1_OUT:
ret = rk3576_gmac_set_clk(priv, clk->id, rate);
break;
case CLK_UART_FRAC_0:
---
base-commit: bb0f3eebb3c196d9b6efbbd1e5aa9b16abbb9ad6
change-id: 20260504-rk3576-rgmii-refclk-45d18a47be33
Best regards,
--
Alexey Charkov <alchark at flipper.net>
More information about the U-Boot
mailing list