From fdd74c32209b0d4cf8167e94a5dfa8a220106984 Mon Sep 17 00:00:00 2001 From: Elaine Zhang Date: Thu, 12 Nov 2020 17:03:13 +0800 Subject: [PATCH] clk: rockchip: rk3568: support ebc clk setting/getting rate Change-Id: Iecac8e56b2b5615b54c8969767053b6282fe6fb8 Signed-off-by: Elaine Zhang --- .../include/asm/arch-rockchip/cru_rk3568.h | 11 ++++ drivers/clk/rockchip/clk_rk3568.c | 52 +++++++++++++++++++ include/dt-bindings/clock/rk3568-cru.h | 1 + 3 files changed, 64 insertions(+) diff --git a/arch/arm/include/asm/arch-rockchip/cru_rk3568.h b/arch/arm/include/asm/arch-rockchip/cru_rk3568.h index 8c0f540414..2b562f0010 100644 --- a/arch/arm/include/asm/arch-rockchip/cru_rk3568.h +++ b/arch/arm/include/asm/arch-rockchip/cru_rk3568.h @@ -349,6 +349,13 @@ enum { DCLK2_VOP_DIV_SHIFT = 0, DCLK2_VOP_DIV_MASK = 0xff << DCLK2_VOP_DIV_SHIFT, + /* CRU_CLK_SEL43_CON */ + DCLK_EBC_SEL_SHIFT = 6, + DCLK_EBC_SEL_MASK = 3 << DCLK_EBC_SEL_SHIFT, + DCLK_EBC_SEL_GPLL_400M = 0, + DCLK_EBC_SEL_CPLL_333M, + DCLK_EBC_SEL_GPLL_200M, + /* CRU_CLK_SEL50_CON */ PCLK_BUS_SEL_SHIFT = 4, PCLK_BUS_SEL_MASK = 3 << PCLK_BUS_SEL_SHIFT, @@ -429,5 +436,9 @@ enum { ACLK_TOP_HIGH_SEL_400M, ACLK_TOP_HIGH_SEL_300M, ACLK_TOP_HIGH_SEL_24M, + + /* CRU_CLK_SEL79_CON */ + CPLL_333M_DIV_SHIFT = 0, + CPLL_333M_DIV_MASK = 0x1f << CPLL_333M_DIV_SHIFT, }; #endif diff --git a/drivers/clk/rockchip/clk_rk3568.c b/drivers/clk/rockchip/clk_rk3568.c index c34bfc5dd2..e5c5a9ce45 100644 --- a/drivers/clk/rockchip/clk_rk3568.c +++ b/drivers/clk/rockchip/clk_rk3568.c @@ -1900,6 +1900,50 @@ static ulong rk3568_gmac_tx_rx_set_clk(struct rk3568_clk_priv *priv, return 0; } +static ulong rk3568_ebc_get_clk(struct rk3568_clk_priv *priv, ulong clk_id) +{ + struct rk3568_cru *cru = priv->cru; + u32 con, div, p_rate; + + con = readl(&cru->clksel_con[79]); + div = (con & CPLL_333M_DIV_MASK) >> CPLL_333M_DIV_SHIFT; + p_rate = DIV_TO_RATE(priv->cpll_hz, div); + if (clk_id == CPLL_333M) + return p_rate; + + con = readl(&cru->clksel_con[43]); + div = (con & DCLK_EBC_SEL_MASK) >> DCLK_EBC_SEL_SHIFT; + switch (div) { + case DCLK_EBC_SEL_GPLL_400M: + return 400 * MHz; + case DCLK_EBC_SEL_CPLL_333M: + return p_rate; + case DCLK_EBC_SEL_GPLL_200M: + return 200 * MHz; + default: + return -ENOENT; + } +} + +static ulong rk3568_ebc_set_clk(struct rk3568_clk_priv *priv, + ulong clk_id, ulong rate) +{ + struct rk3568_cru *cru = priv->cru; + int src_clk_div; + + src_clk_div = DIV_ROUND_UP(priv->cpll_hz, rate); + assert(src_clk_div - 1 <= 31); + rk_clrsetreg(&cru->clksel_con[79], + CPLL_333M_DIV_MASK, + (src_clk_div - 1) << CPLL_333M_DIV_SHIFT); + if (clk_id == DCLK_EBC) + rk_clrsetreg(&cru->clksel_con[43], + DCLK_EBC_SEL_MASK, + DCLK_EBC_SEL_CPLL_333M << DCLK_EBC_SEL_SHIFT); + + return rk3568_ebc_get_clk(priv, clk_id); +} + static ulong rk3568_clk_get_rate(struct clk *clk) { struct rk3568_clk_priv *priv = dev_get_priv(clk->dev); @@ -2017,6 +2061,10 @@ static ulong rk3568_clk_get_rate(struct clk *clk) case CLK_GMAC1_PTP_REF: rate = rk3568_gmac_ptp_ref_get_clk(priv, 1); break; + case CPLL_333M: + case DCLK_EBC: + rate = rk3568_ebc_get_clk(priv, clk->id); + break; case ACLK_SECURE_FLASH: case ACLK_CRYPTO_NS: case HCLK_SECURE_FLASH: @@ -2153,6 +2201,10 @@ static ulong rk3568_clk_set_rate(struct clk *clk, ulong rate) case CLK_GMAC1_PTP_REF: rate = rk3568_gmac_ptp_ref_set_clk(priv, 1, rate); break; + case CPLL_333M: + case DCLK_EBC: + rate = rk3568_ebc_set_clk(priv, clk->id, rate); + break; case ACLK_SECURE_FLASH: case ACLK_CRYPTO_NS: case HCLK_SECURE_FLASH: diff --git a/include/dt-bindings/clock/rk3568-cru.h b/include/dt-bindings/clock/rk3568-cru.h index d06f8b085d..26ec41bbbb 100644 --- a/include/dt-bindings/clock/rk3568-cru.h +++ b/include/dt-bindings/clock/rk3568-cru.h @@ -73,6 +73,7 @@ #define PLL_NPLL 6 /* cru clocks */ +#define CPLL_333M 9 #define ARMCLK 10 #define USB480M 11 #define ACLK_CORE_NIU2BUS 18