On Wed, 13 Sep 2017, David Wu wrote: > The clk_saradc is dividing from the 24M, clk_saradc=24MHz/(saradc_div_con+1). > Saradc integer divider control register is 10-bits width. > > Signed-off-by: David Wu <david.wu at rock-chips.com> Reviewed-by: Philipp Tomsich <philipp.tomsich at theobroma-systems.com> See below for comments. > --- > drivers/clk/rockchip/clk_rk3328.c | 37 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > > diff --git a/drivers/clk/rockchip/clk_rk3328.c b/drivers/clk/rockchip/clk_rk3328.c > index c3a6650..e1ae7b2 100644 > --- a/drivers/clk/rockchip/clk_rk3328.c > +++ b/drivers/clk/rockchip/clk_rk3328.c > @@ -115,6 +115,7 @@ enum { > /* CLKSEL_CON23 */ > CLK_SARADC_DIV_CON_SHIFT = 0, > CLK_SARADC_DIV_CON_MASK = 0x3ff << CLK_SARADC_DIV_CON_SHIFT, Can we use GENMASK here? > + CLK_SARADC_DIV_CON_WIDTH = 10, > > /* CLKSEL_CON24 */ > CLK_PWM_PLL_SEL_CPLL = 0, > @@ -180,6 +181,11 @@ enum { > #define PLL_DIV_MIN 16 > #define PLL_DIV_MAX 3200 > > +static inline u32 extract_bits(u32 val, unsigned width, unsigned shift) > +{ > + return (val >> shift) & ((1 << width) - 1); Can we use the functions from bitfield.h, please? > +} > + > /* > * How to calculate the PLL(from TRM V0.3 Part 1 Page 63): > * Formulas also embedded within the Fractional PLL Verilog model: > @@ -478,6 +484,31 @@ static ulong rk3328_pwm_set_clk(struct rk3328_cru *cru, uint hz) > return DIV_TO_RATE(GPLL_HZ, div); > } > > +static ulong rk3328_saradc_get_clk(struct rk3328_cru *cru) > +{ > + u32 div, val; > + > + val = readl(&cru->clksel_con[23]); > + div = extract_bits(val, CLK_SARADC_DIV_CON_WIDTH, > + CLK_SARADC_DIV_CON_SHIFT); > + > + return DIV_TO_RATE(OSC_HZ, div); > +} > + > +static ulong rk3328_saradc_set_clk(struct rk3328_cru *cru, uint hz) > +{ > + int src_clk_div; > + > + src_clk_div = DIV_ROUND_UP(OSC_HZ, hz) - 1; > + assert(src_clk_div < 128); > + > + rk_clrsetreg(&cru->clksel_con[23], > + CLK_SARADC_DIV_CON_MASK, > + src_clk_div << CLK_SARADC_DIV_CON_SHIFT); > + > + return rk3328_saradc_get_clk(cru); > +} > + > static ulong rk3328_clk_get_rate(struct clk *clk) > { > struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); > @@ -501,6 +532,9 @@ static ulong rk3328_clk_get_rate(struct clk *clk) > case SCLK_PWM: > rate = rk3328_pwm_get_clk(priv->cru); > break; > + case SCLK_SARADC: > + rate = rk3328_saradc_get_clk(priv->cru); > + break; > default: > return -ENOENT; > } > @@ -531,6 +565,9 @@ static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate) > case SCLK_PWM: > ret = rk3328_pwm_set_clk(priv->cru, rate); > break; > + case SCLK_SARADC: > + ret = rk3328_saradc_set_clk(priv->cru, rate); > + break; > default: > return -ENOENT; > } >