From a7d429b7255f771a8775f84f9895eb194d6ed97a Mon Sep 17 00:00:00 2001 From: Algea Cao Date: Tue, 17 Oct 2023 20:29:12 +0800 Subject: [PATCH] misc: rk628: cru: Add rk628f APLL Signed-off-by: Algea Cao Change-Id: Ib7237bfbd83012fa0d1d5290bc69e59beaf0f04c --- drivers/misc/rk628/rk628_cru.c | 29 +++++++++++++++++++++++++---- drivers/misc/rk628/rk628_cru.h | 5 +++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/drivers/misc/rk628/rk628_cru.c b/drivers/misc/rk628/rk628_cru.c index da448508ed28..0c335a33bd27 100644 --- a/drivers/misc/rk628/rk628_cru.c +++ b/drivers/misc/rk628/rk628_cru.c @@ -5,6 +5,7 @@ * Author: Wyon Bi */ +#include "asm-generic/errno-base.h" #include "rk628.h" #include "rk628_cru.h" @@ -65,6 +66,9 @@ static unsigned long rk628_cru_clk_get_rate_pll(struct rk628 *rk628, u64 foutvco, foutpostdiv; u32 offset, val; + if (id == CGU_CLK_APLL && rk628->version < RK628F_VERSION) + return 0; + rk628_i2c_read(rk628, CRU_MODE_CON00, &val); if (id == CGU_CLK_CPLL) { val &= CLK_CPLL_MODE_MASK; @@ -73,13 +77,20 @@ static unsigned long rk628_cru_clk_get_rate_pll(struct rk628 *rk628, return parent_rate; offset = 0x00; - } else { + } else if (id == CGU_CLK_GPLL) { val &= CLK_GPLL_MODE_MASK; val >>= CLK_GPLL_MODE_SHIFT; if (val == CLK_GPLL_MODE_OSC) return parent_rate; offset = 0x20; + } else { + val &= CLK_APLL_MODE_MASK; + val >>= CLK_APLL_MODE_SHIFT; + if (val == CLK_APLL_MODE_OSC) + return parent_rate; + + offset = 0x40; } rk628_i2c_read(rk628, offset + CRU_CPLL_CON0, &con0); @@ -140,8 +151,10 @@ static unsigned long rk628_cru_clk_set_rate_pll(struct rk628 *rk628, if (id == CGU_CLK_CPLL) offset = 0x00; - else + else if (id == CGU_CLK_GPLL) offset = 0x20; + else + offset = 0x40; rk628_i2c_write(rk628, offset + CRU_CPLL_CON1, PLL_PD(1)); @@ -419,7 +432,11 @@ static unsigned long rk628_cru_clk_set_rate_bt1120_dec(struct rk628 *rk628, int rk628_cru_clk_set_rate(struct rk628 *rk628, unsigned int id, unsigned long rate) { + if (id == CGU_CLK_APLL && rk628->version < RK628F_VERSION) + return -EINVAL; + switch (id) { + case CGU_CLK_APLL: case CGU_CLK_CPLL: case CGU_CLK_GPLL: rk628_cru_clk_set_rate_pll(rk628, id, rate); @@ -437,7 +454,7 @@ int rk628_cru_clk_set_rate(struct rk628 *rk628, unsigned int id, rk628_cru_clk_set_rate_bt1120_dec(rk628, rate); break; default: - return -1; + return -EINVAL; } return 0; @@ -447,7 +464,11 @@ unsigned long rk628_cru_clk_get_rate(struct rk628 *rk628, unsigned int id) { unsigned long rate; + if (id == CGU_CLK_APLL && rk628->version < RK628F_VERSION) + return 0; + switch (id) { + case CGU_CLK_APLL: case CGU_CLK_CPLL: case CGU_CLK_GPLL: rate = rk628_cru_clk_get_rate_pll(rk628, id); @@ -472,7 +493,7 @@ void rk628_cru_init(struct rk628 *rk628) rk628_i2c_read(rk628, GRF_SYSTEM_STATUS0, &val); mcu_mode = (val & I2C_ONLY_FLAG) ? 0 : 1; - if (mcu_mode) + if (mcu_mode || rk628->version >= RK628F_VERSION) return; rk628_i2c_write(rk628, CRU_GPLL_CON0, 0xffff701d); diff --git a/drivers/misc/rk628/rk628_cru.h b/drivers/misc/rk628/rk628_cru.h index 0684d7c0d53c..e84d73176da3 100644 --- a/drivers/misc/rk628/rk628_cru.h +++ b/drivers/misc/rk628/rk628_cru.h @@ -47,6 +47,10 @@ #define CRU_GPLL_CON3 CRU_REG(0x002c) #define CRU_GPLL_CON4 CRU_REG(0x0030) #define CRU_MODE_CON00 CRU_REG(0x0060) +#define CLK_APLL_MODE_MASK BIT(4) +#define CLK_APLL_MODE_SHIFT 4 +#define CLK_APLL_MODE_GPLL 1 +#define CLK_APLL_MODE_OSC 0 #define CLK_GPLL_MODE_MASK BIT(2) #define CLK_GPLL_MODE_SHIFT 2 #define CLK_GPLL_MODE_GPLL 1 @@ -152,6 +156,7 @@ #define CGU_I2S_MCLKOUT 36 #define CGU_BT1120DEC 37 #define CGU_SCLK_UART 38 +#define CGU_CLK_APLL 39 unsigned long rk628_cru_clk_get_rate(struct rk628 *rk628, unsigned int id); int rk628_cru_clk_set_rate(struct rk628 *rk628, unsigned int id,