From cf0b23abaf3f603a53aaf413caa1bed29864525e Mon Sep 17 00:00:00 2001 From: Shunhua Lan Date: Mon, 6 Nov 2023 11:59:11 +0800 Subject: [PATCH] misc: rk628: cru: add sclk_hdmirx_aud api config Signed-off-by: Shunhua Lan Change-Id: I7ec66204a4e2e4724b644f796ce7f4ee4f26b23e --- drivers/misc/rk628/rk628_cru.c | 40 ++++++++++++++++++++++++++++++++++ drivers/misc/rk628/rk628_cru.h | 4 ++++ 2 files changed, 44 insertions(+) diff --git a/drivers/misc/rk628/rk628_cru.c b/drivers/misc/rk628/rk628_cru.c index 0c335a33bd27..f9744222e5dc 100644 --- a/drivers/misc/rk628/rk628_cru.c +++ b/drivers/misc/rk628/rk628_cru.c @@ -400,6 +400,40 @@ static unsigned long rk628_cru_clk_set_rate_sclk_uart(struct rk628 *rk628, return rate; } +static unsigned long rk628_cru_clk_set_rate_sclk_hdmirx_aud(struct rk628 *rk628, unsigned long rate) +{ + u64 parent_rate; + u8 div; + + parent_rate = rk628_cru_clk_set_rate_pll(rk628, CGU_CLK_APLL, rate*4); + div = DIV_ROUND_CLOSEST_ULL(parent_rate, rate); + rate = parent_rate / div; + rk628_i2c_write(rk628, CRU_CLKSEL_CON05, + 0x3fc0 << 16 | ((div - 1) << 6) | + CLK_HDMIRX_AUD_SEL(2)); + return rate; +} + +static unsigned long rk628_cru_clk_get_rate_sclk_hdmirx_aud(struct rk628 *rk628) +{ + unsigned long rate; + u64 parent_rate; + u8 div; + u32 val; + + rk628_i2c_read(rk628, CRU_CLKSEL_CON05, &val); + div = ((val&0x3fc0) >> 6) + 1; + val &= CLK_HDMIRX_AUD_SEL_MASK; + if (val == 0) + parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_CPLL); + else if (val == (1 << 14)) + parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_GPLL); + else + parent_rate = rk628_cru_clk_get_rate_pll(rk628, CGU_CLK_APLL); + rate = parent_rate / div; + return rate; +} + static unsigned long rk628_cru_clk_get_rate_bt1120_dec_parent(struct rk628 *rk628) { @@ -453,6 +487,9 @@ int rk628_cru_clk_set_rate(struct rk628 *rk628, unsigned int id, case CGU_BT1120DEC: rk628_cru_clk_set_rate_bt1120_dec(rk628, rate); break; + case CGU_CLK_HDMIRX_AUD: + rk628_cru_clk_set_rate_sclk_hdmirx_aud(rk628, rate); + break; default: return -EINVAL; } @@ -479,6 +516,9 @@ unsigned long rk628_cru_clk_get_rate(struct rk628 *rk628, unsigned int id) case CGU_CLK_IMODET: rate = rk628_cru_clk_get_rate_clk_imodet(rk628); break; + case CGU_CLK_HDMIRX_AUD: + rate = rk628_cru_clk_get_rate_sclk_hdmirx_aud(rk628); + break; default: return 0; } diff --git a/drivers/misc/rk628/rk628_cru.h b/drivers/misc/rk628/rk628_cru.h index e84d73176da3..4f9ba6cea4b9 100644 --- a/drivers/misc/rk628/rk628_cru.h +++ b/drivers/misc/rk628/rk628_cru.h @@ -77,6 +77,10 @@ #define CLK_BT1120DEC_DIV(x) HIWORD_UPDATE(x, 4, 0) #define CRU_CLKSEL_CON03 CRU_REG(0x008c) #define CRU_CLKSEL_CON04 CRU_REG(0x0090) +#define CLK_HDMIRX_AUD_DIV_MASK GENMASK(13, 6) +#define CLK_HDMIRX_AUD_DIV(x) HIWORD_UPDATE(x, 13, 6) +#define CLK_HDMIRX_AUD_SEL_MASK GENMASK(15, 14) +#define CLK_HDMIRX_AUD_SEL(x) HIWORD_UPDATE(x, 15, 14) #define CRU_CLKSEL_CON05 CRU_REG(0x0094) #define CLK_IMODET_SEL_MASK BIT(5) #define CLK_IMODET_SEL_SHIFT 5