Messages in this thread | | | Date | Tue, 24 Mar 2015 20:53:02 +0200 | From | Tero Kristo <> | Subject | Re: [PATCH 2/3] clk: ti: Implement FAPLL set_rate for the synthesizer |
| |
On 03/24/2015 06:37 PM, Tony Lindgren wrote: > * Tony Lindgren <tony@atomide.com> [150323 08:58]: >> * Tero Kristo <t-kristo@ti.com> [150323 06:25]: >>> >>> This code is generating these compile time warnings for me: >>> >>> CC drivers/clk/ti/fapll.o >>> drivers/clk/ti/fapll.c: In function ‘ti_fapll_synth_set_rate’: >>> drivers/clk/ti/fapll.c:394:5: warning: ‘synth_int_div’ may be used >>> uninitialized in this function [-Wuninitialized] >>> drivers/clk/ti/fapll.c:373:18: note: ‘synth_int_div’ was declared here >>> drivers/clk/ti/fapll.c:400:23: warning: ‘synth_frac_div’ may be used >>> uninitialized in this function [-Wuninitialized] >>> drivers/clk/ti/fapll.c:373:33: note: ‘synth_frac_div’ was declared here >> >> Oops thanks will check. I did move this into a separate function >> to make it more readable, probably happened at that point. > > Updated version of this patch below, let me know if you want the > whole set reposted.
Yes this is fine, all patches queued for 4.1, thanks!
-Tero
> > Regards, > > Tony > > 8< ------------------- > From: Tony Lindgren <tony@atomide.com> > Date: Mon, 16 Mar 2015 18:04:20 -0700 > Subject: [PATCH] clk: ti: Implement FAPLL set_rate for the synthesizer > > We can pretty much get any rate out of the FAPLL because of the fractional > divider. Let's first try just adjusting the post divider, and if that is > not enough, then reprogram both the fractional divider and the post divider. > > Let's also add a define for the fixed SYNTH_PHASE_K instead of using 8. > > Cc: Brian Hutchinson <b.hutchman@gmail.com> > Cc: Matthijs van Duin <matthijsvanduin@gmail.com> > Cc: Tero Kristo <t-kristo@ti.com> > Signed-off-by: Tony Lindgren <tony@atomide.com> > > --- a/drivers/clk/ti/fapll.c > +++ b/drivers/clk/ti/fapll.c > @@ -12,6 +12,7 @@ > #include <linux/clk-provider.h> > #include <linux/delay.h> > #include <linux/err.h> > +#include <linux/math64.h> > #include <linux/of.h> > #include <linux/of_address.h> > #include <linux/clk/ti.h> > @@ -47,6 +48,8 @@ > /* Synthesizer frequency register */ > #define SYNTH_LDFREQ BIT(31) > > +#define SYNTH_PHASE_K 8 > +#define SYNTH_MAX_INT_DIV 0xf > #define SYNTH_MAX_DIV_M 0xff > > struct fapll_data { > @@ -204,7 +207,7 @@ static unsigned long ti_fapll_synth_recalc_rate(struct clk_hw *hw, > /* > * Synth frequency integer and fractional divider. > * Note that the phase output K is 8, so the result needs > - * to be multiplied by 8. > + * to be multiplied by SYNTH_PHASE_K. > */ > if (synth->freq) { > u32 v, synth_int_div, synth_frac_div, synth_div_freq; > @@ -215,7 +218,7 @@ static unsigned long ti_fapll_synth_recalc_rate(struct clk_hw *hw, > synth_div_freq = (synth_int_div * 10000000) + synth_frac_div; > rate *= 10000000; > do_div(rate, synth_div_freq); > - rate *= 8; > + rate *= SYNTH_PHASE_K; > } > > /* Synth post-divider M */ > @@ -224,11 +227,138 @@ static unsigned long ti_fapll_synth_recalc_rate(struct clk_hw *hw, > return DIV_ROUND_UP_ULL(rate, synth_div_m); > } > > +static unsigned long ti_fapll_synth_get_frac_rate(struct clk_hw *hw, > + unsigned long parent_rate) > +{ > + struct fapll_synth *synth = to_synth(hw); > + unsigned long current_rate, frac_rate; > + u32 post_div_m; > + > + current_rate = ti_fapll_synth_recalc_rate(hw, parent_rate); > + post_div_m = readl_relaxed(synth->div) & SYNTH_MAX_DIV_M; > + frac_rate = current_rate * post_div_m; > + > + return frac_rate; > +} > + > +static u32 ti_fapll_synth_set_frac_rate(struct fapll_synth *synth, > + unsigned long rate, > + unsigned long parent_rate) > +{ > + u32 post_div_m, synth_int_div = 0, synth_frac_div = 0, v; > + > + post_div_m = DIV_ROUND_UP_ULL((u64)parent_rate * SYNTH_PHASE_K, rate); > + post_div_m = post_div_m / SYNTH_MAX_INT_DIV; > + if (post_div_m > SYNTH_MAX_DIV_M) > + return -EINVAL; > + if (!post_div_m) > + post_div_m = 1; > + > + for (; post_div_m < SYNTH_MAX_DIV_M; post_div_m++) { > + synth_int_div = DIV_ROUND_UP_ULL((u64)parent_rate * > + SYNTH_PHASE_K * > + 10000000, > + rate * post_div_m); > + synth_frac_div = synth_int_div % 10000000; > + synth_int_div /= 10000000; > + > + if (synth_int_div <= SYNTH_MAX_INT_DIV) > + break; > + } > + > + if (synth_int_div > SYNTH_MAX_INT_DIV) > + return -EINVAL; > + > + v = readl_relaxed(synth->freq); > + v &= ~0x1fffffff; > + v |= (synth_int_div & SYNTH_MAX_INT_DIV) << 24; > + v |= (synth_frac_div & 0xffffff); > + v |= SYNTH_LDFREQ; > + writel_relaxed(v, synth->freq); > + > + return post_div_m; > +} > + > +static long ti_fapll_synth_round_rate(struct clk_hw *hw, unsigned long rate, > + unsigned long *parent_rate) > +{ > + struct fapll_synth *synth = to_synth(hw); > + struct fapll_data *fd = synth->fd; > + unsigned long r; > + > + if (ti_fapll_clock_is_bypass(fd) || !synth->div || !rate) > + return -EINVAL; > + > + /* Only post divider m available with no fractional divider? */ > + if (!synth->freq) { > + unsigned long frac_rate; > + u32 synth_post_div_m; > + > + frac_rate = ti_fapll_synth_get_frac_rate(hw, *parent_rate); > + synth_post_div_m = DIV_ROUND_UP(frac_rate, rate); > + r = DIV_ROUND_UP(frac_rate, synth_post_div_m); > + goto out; > + } > + > + r = *parent_rate * SYNTH_PHASE_K; > + if (rate > r) > + goto out; > + > + r = DIV_ROUND_UP_ULL(r, SYNTH_MAX_INT_DIV * SYNTH_MAX_DIV_M); > + if (rate < r) > + goto out; > + > + r = rate; > +out: > + return r; > +} > + > +static int ti_fapll_synth_set_rate(struct clk_hw *hw, unsigned long rate, > + unsigned long parent_rate) > +{ > + struct fapll_synth *synth = to_synth(hw); > + struct fapll_data *fd = synth->fd; > + unsigned long frac_rate, post_rate = 0; > + u32 post_div_m = 0, v; > + > + if (ti_fapll_clock_is_bypass(fd) || !synth->div || !rate) > + return -EINVAL; > + > + /* Produce the rate with just post divider M? */ > + frac_rate = ti_fapll_synth_get_frac_rate(hw, parent_rate); > + if (frac_rate < rate) { > + if (!synth->freq) > + return -EINVAL; > + } else { > + post_div_m = DIV_ROUND_UP(frac_rate, rate); > + if (post_div_m && (post_div_m <= SYNTH_MAX_DIV_M)) > + post_rate = DIV_ROUND_UP(frac_rate, post_div_m); > + if (!synth->freq && !post_rate) > + return -EINVAL; > + } > + > + /* Need to recalculate the fractional divider? */ > + if ((post_rate != rate) && synth->freq) > + post_div_m = ti_fapll_synth_set_frac_rate(synth, > + rate, > + parent_rate); > + > + v = readl_relaxed(synth->div); > + v &= ~SYNTH_MAX_DIV_M; > + v |= post_div_m; > + v |= SYNTH_LDMDIV1; > + writel_relaxed(v, synth->div); > + > + return 0; > +} > + > static struct clk_ops ti_fapll_synt_ops = { > .enable = ti_fapll_synth_enable, > .disable = ti_fapll_synth_disable, > .is_enabled = ti_fapll_synth_is_enabled, > .recalc_rate = ti_fapll_synth_recalc_rate, > + .round_rate = ti_fapll_synth_round_rate, > + .set_rate = ti_fapll_synth_set_rate, > }; > > static struct clk * __init ti_fapll_synth_setup(struct fapll_data *fd, >
| |