From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754898AbbCXSxB (ORCPT ); Tue, 24 Mar 2015 14:53:01 -0400 Received: from bear.ext.ti.com ([192.94.94.41]:56190 "EHLO bear.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752625AbbCXSw7 (ORCPT ); Tue, 24 Mar 2015 14:52:59 -0400 Message-ID: <5511B28E.5040800@ti.com> Date: Tue, 24 Mar 2015 20:53:02 +0200 From: Tero Kristo User-Agent: Mozilla/5.0 (X11; Linux i686; rv:31.0) Gecko/20100101 Thunderbird/31.5.0 MIME-Version: 1.0 To: Tony Lindgren CC: Mike Turquette , Stephen Boyd , , , Brian Hutchinson , Matthijs van Duin Subject: Re: [PATCH 2/3] clk: ti: Implement FAPLL set_rate for the synthesizer References: <1427063726-4248-1-git-send-email-tony@atomide.com> <1427063726-4248-3-git-send-email-tony@atomide.com> <5510143A.8090404@ti.com> <20150323155242.GX31346@atomide.com> <20150324163734.GY31346@atomide.com> In-Reply-To: <20150324163734.GY31346@atomide.com> Content-Type: text/plain; charset="utf-8"; format=flowed Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 03/24/2015 06:37 PM, Tony Lindgren wrote: > * Tony Lindgren [150323 08:58]: >> * Tero Kristo [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 > 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 > Cc: Matthijs van Duin > Cc: Tero Kristo > Signed-off-by: Tony Lindgren > > --- a/drivers/clk/ti/fapll.c > +++ b/drivers/clk/ti/fapll.c > @@ -12,6 +12,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -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, >