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

Kever Yang kever.yang at rock-chips.com
Mon Jun 8 15:45:08 CEST 2026



> 2026年5月4日 21:45,Alexey Charkov <alchark at flipper.net> 写道:
> 
> 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>

Reviewed-by: Kever Yang <kever.yang at rock-chips.com <mailto:kever.yang at rock-chips.com>>

Thanks,
- Kever
> ---
> 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