rockchip: clk: clk_rk3576: Add support for RK3576 GMAC 25MHz clock output

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@flipper.net>
Reviewed-by: Quentin Schulz <quentin.schulz@cherry.de>
Reviewed-by: Kever Yang <kever.yang@rock-chips.com>
This commit is contained in:
Alexey Charkov
2026-06-10 00:19:05 +08:00
committed by Kever
parent 924f87b995
commit 957941943b
2 changed files with 64 additions and 0 deletions
@@ -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,
+50
View File
@@ -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;
}
@@ -2016,6 +2062,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:
@@ -2197,6 +2245,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: