Re: [PATCH 2/3] clk: ti: Implement FAPLL set_rate for the synthesizer
* Tony Lindgren t...@atomide.com [150323 08:58]: * Tero Kristo t-kri...@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 t...@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.hutch...@gmail.com Cc: Matthijs van Duin matthijsvand...@gmail.com Cc: Tero Kristo t-kri...@ti.com Signed-off-by: Tony Lindgren t...@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_M0xff 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 * 1000) + synth_frac_div; rate *= 1000; 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 * +1000, +rate * post_div_m); + synth_frac_div = synth_int_div % 1000; + synth_int_div /= 1000; + + 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 = ~0x1fff; + v |= (synth_int_div SYNTH_MAX_INT_DIV) 24; + v |= (synth_frac_div 0xff); + 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 =
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 t...@atomide.com [150323 08:58]: * Tero Kristo t-kri...@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 t...@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.hutch...@gmail.com Cc: Matthijs van Duin matthijsvand...@gmail.com Cc: Tero Kristo t-kri...@ti.com Signed-off-by: Tony Lindgren t...@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 * 1000) + synth_frac_div; rate *= 1000; 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 * +1000, +rate * post_div_m); + synth_frac_div = synth_int_div % 1000; + synth_int_div /= 1000; + + 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 = ~0x1fff; + v |= (synth_int_div SYNTH_MAX_INT_DIV) 24; + v |= (synth_frac_div 0xff); + 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, +
Re: [PATCH 2/3] clk: ti: Implement FAPLL set_rate for the synthesizer
On 03/23/2015 12:35 AM, Tony Lindgren wrote: 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.hutch...@gmail.com Cc: Matthijs van Duin matthijsvand...@gmail.com Cc: Tero Kristo t-kri...@ti.com Signed-off-by: Tony Lindgren t...@atomide.com --- drivers/clk/ti/fapll.c | 134 - 1 file changed, 132 insertions(+), 2 deletions(-) diff --git a/drivers/clk/ti/fapll.c b/drivers/clk/ti/fapll.c index 3b5e231..4064f7b 100644 --- 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 * 1000) + synth_frac_div; rate *= 1000; 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, synth_frac_div, 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 * +1000, +rate * post_div_m); + synth_frac_div = synth_int_div % 1000; + synth_int_div /= 1000; + + 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 = ~0x1fff; + v |= (synth_int_div SYNTH_MAX_INT_DIV) 24; + v |= (synth_frac_div 0xff); 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 -Tero + 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
Re: [PATCH 2/3] clk: ti: Implement FAPLL set_rate for the synthesizer
* Tero Kristo t-kri...@ti.com [150323 06:25]: On 03/23/2015 12:35 AM, Tony Lindgren wrote: +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, synth_frac_div, 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 * + 1000, + rate * post_div_m); +synth_frac_div = synth_int_div % 1000; +synth_int_div /= 1000; + +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 = ~0x1fff; +v |= (synth_int_div SYNTH_MAX_INT_DIV) 24; +v |= (synth_frac_div 0xff); 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. Regards, Tony -- To unsubscribe from this list: send the line unsubscribe linux-omap in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/3] 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.hutch...@gmail.com Cc: Matthijs van Duin matthijsvand...@gmail.com Cc: Tero Kristo t-kri...@ti.com Signed-off-by: Tony Lindgren t...@atomide.com --- drivers/clk/ti/fapll.c | 134 - 1 file changed, 132 insertions(+), 2 deletions(-) diff --git a/drivers/clk/ti/fapll.c b/drivers/clk/ti/fapll.c index 3b5e231..4064f7b 100644 --- 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_M0xff 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 * 1000) + synth_frac_div; rate *= 1000; 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, synth_frac_div, 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 * +1000, +rate * post_div_m); + synth_frac_div = synth_int_div % 1000; + synth_int_div /= 1000; + + 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 = ~0x1fff; + v |= (synth_int_div SYNTH_MAX_INT_DIV) 24; + v |= (synth_frac_div 0xff); + 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: +