Message ID | 1505299969-13329-1-git-send-email-david.wu@rock-chips.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
> 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@rock-chips.com> > --- > drivers/clk/rockchip/clk_rk3328.c | 37 +++++++++++++++++++++++++++++++++++++ > 1 file changed, 37 insertions(+) > Acked-by: Philipp Tomsich <philipp.tomsich@theobroma-systems.com>
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@rock-chips.com> Reviewed-by: Philipp Tomsich <philipp.tomsich@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; > } >
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, + 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); +} + /* * 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; }
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@rock-chips.com> --- drivers/clk/rockchip/clk_rk3328.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+)