From: Tony Lindgren <tony@atomide.com>
To: Tero Kristo <t-kristo@ti.com>
Cc: Mike Turquette <mturquette@linaro.org>,
Stephen Boyd <sboyd@codeaurora.org>,
linux-kernel@vger.kernel.org, linux-omap@vger.kernel.org,
Brian Hutchinson <b.hutchman@gmail.com>,
Matthijs van Duin <matthijsvanduin@gmail.com>
Subject: Re: [PATCH 2/3] clk: ti: Implement FAPLL set_rate for the synthesizer
Date: Tue, 24 Mar 2015 09:37:35 -0700 [thread overview]
Message-ID: <20150324163734.GY31346@atomide.com> (raw)
In-Reply-To: <20150323155242.GX31346@atomide.com>
* 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.
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,
next prev parent reply other threads:[~2015-03-24 16:37 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-03-22 22:35 [PATCH 0/3] Implement set_rate for FAPLL on dm816x Tony Lindgren
2015-03-22 22:35 ` [PATCH 1/3] clk: ti: Fix FAPLL recalc_rate for rounding errors Tony Lindgren
2015-03-22 22:35 ` [PATCH 2/3] clk: ti: Implement FAPLL set_rate for the synthesizer Tony Lindgren
2015-03-23 13:25 ` Tero Kristo
2015-03-23 15:52 ` Tony Lindgren
2015-03-24 16:37 ` Tony Lindgren [this message]
2015-03-24 18:53 ` Tero Kristo
2015-03-22 22:35 ` [PATCH 3/3] clk: ti: Implement FAPLL set_rate for the PLL Tony Lindgren
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20150324163734.GY31346@atomide.com \
--to=tony@atomide.com \
--cc=b.hutchman@gmail.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-omap@vger.kernel.org \
--cc=matthijsvanduin@gmail.com \
--cc=mturquette@linaro.org \
--cc=sboyd@codeaurora.org \
--cc=t-kristo@ti.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).