* [PATCH/RFC 3/3 v2] ARM: mach-shmobile: implement parent clock
@ 2010-10-29 12:42 Guennadi Liakhovetski
2010-10-30 11:50 ` [PATCH/RFC 3/3 v2] ARM: mach-shmobile: implement parent clock optimization Paul Mundt
0 siblings, 1 reply; 2+ messages in thread
From: Guennadi Liakhovetski @ 2010-10-29 12:42 UTC (permalink / raw)
To: linux-fbdev
This new function allows to select a parent frequency, which provides the
best matching child clock rate.
Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
---
Paul, something like this? I know, this is against an "old" kernel, only
compile tested so far, so, this is even more of an RFC than the previous
version, just to ask your opinion, if this is the direction you were
thinking about. Unfortunately, I don't think re-using
clk_rate_round_helper() would be wise here, but we can discuss that too.
Thanks
Guennadi
diff --git a/drivers/sh/clk.c b/drivers/sh/clk.c
index 5d84ada..412620b 100644
--- a/drivers/sh/clk.c
+++ b/drivers/sh/clk.c
@@ -390,6 +390,79 @@ long clk_round_rate(struct clk *clk, unsigned long rate)
}
EXPORT_SYMBOL_GPL(clk_round_rate);
+long clk_round_parent(struct clk *clk, unsigned long target,
+ unsigned long *best_freq, unsigned long *parent_freq,
+ unsigned int div_min, unsigned int div_max)
+{
+ struct cpufreq_frequency_table *freq, *best = NULL;
+ unsigned long error = ULONG_MAX, freq_high, freq_low, div;
+ struct clk *parent = clk_get_parent(clk);
+
+ if (!parent) {
+ *parent_freq = 0;
+ *best_freq = clk_round_rate(clk, target);
+ return abs(target - *best_freq);
+ }
+
+ for (freq = parent->freq_table; freq->frequency != CPUFREQ_TABLE_END;
+ freq++) {
+ if (freq->frequency = CPUFREQ_ENTRY_INVALID)
+ continue;
+
+ if (unlikely(freq->frequency <= target * div_min)) {
+ unsigned long freq_max = (freq->frequency + div_min / 2) / div_min;
+ if (error > target - freq_max) {
+ error = target - freq_max;
+ best = freq;
+ if (best_freq)
+ *best_freq = freq_max;
+ }
+ if (!error)
+ break;
+ continue;
+ }
+
+ if (unlikely(freq->frequency >= target * div_max)) {
+ unsigned long freq_min = (freq->frequency + div_max / 2) / div_max;
+ if (error > target - freq_min) {
+ error = freq_min - target;
+ best = freq;
+ if (best_freq)
+ *best_freq = freq_min;
+ }
+ if (!error)
+ break;
+ continue;
+ }
+
+
+ div = freq->frequency / target;
+ freq_high = freq->frequency / div;
+ freq_low = freq->frequency / (div + 1);
+ if (freq_high - target < error) {
+ error = freq_high - target;
+ best = freq;
+ if (best_freq)
+ *best_freq = freq_high;
+ }
+ if (target - freq_low < error) {
+ error = target - freq_low;
+ best = freq;
+ if (best_freq)
+ *best_freq = freq_low;
+ }
+ pr_debug("%u / %lu = %lu, / %lu = %lu, best %lu, parent %u\n",
+ freq->frequency, div, freq_high, div + 1, freq_low,
+ *best_freq, best->frequency);
+ if (!error)
+ break;
+ }
+ if (parent_freq)
+ *parent_freq = best->frequency;
+ return error;
+}
+EXPORT_SYMBOL_GPL(clk_round_parent);
+
#ifdef CONFIG_PM
static int clks_sysdev_suspend(struct sys_device *dev, pm_message_t state)
{
diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h
index 875ce50..d370057 100644
--- a/include/linux/sh_clk.h
+++ b/include/linux/sh_clk.h
@@ -111,6 +111,10 @@ int clk_rate_table_find(struct clk *clk,
struct cpufreq_frequency_table *freq_table,
unsigned long rate);
+long clk_round_parent(struct clk *clk, unsigned long target,
+ unsigned long *best_freq, unsigned long *parent_freq,
+ unsigned int div_min, unsigned int div_max);
+
#define SH_CLK_MSTP32(_parent, _enable_reg, _enable_bit, _flags) \
{ \
.parent = _parent, \
^ permalink raw reply related [flat|nested] 2+ messages in thread
* Re: [PATCH/RFC 3/3 v2] ARM: mach-shmobile: implement parent clock optimization
2010-10-29 12:42 [PATCH/RFC 3/3 v2] ARM: mach-shmobile: implement parent clock Guennadi Liakhovetski
@ 2010-10-30 11:50 ` Paul Mundt
0 siblings, 0 replies; 2+ messages in thread
From: Paul Mundt @ 2010-10-30 11:50 UTC (permalink / raw)
To: linux-fbdev
On Fri, Oct 29, 2010 at 02:42:16PM +0200, Guennadi Liakhovetski wrote:
> This new function allows to select a parent frequency, which provides the
> best matching child clock rate.
>
> Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
> ---
>
> Paul, something like this? I know, this is against an "old" kernel, only
> compile tested so far, so, this is even more of an RFC than the previous
> version, just to ask your opinion, if this is the direction you were
> thinking about. Unfortunately, I don't think re-using
> clk_rate_round_helper() would be wise here, but we can discuss that too.
>
Yes, that basically looks like what I had in mind.
Re-using clk_rate_round_helper() probably won't help here since it's
doing sufficiently different things anyways.
If this ends up working for you then please test it and respin it against
a current kernel. This can go upstream pretty easily by itself.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2010-10-30 11:50 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-10-29 12:42 [PATCH/RFC 3/3 v2] ARM: mach-shmobile: implement parent clock Guennadi Liakhovetski
2010-10-30 11:50 ` [PATCH/RFC 3/3 v2] ARM: mach-shmobile: implement parent clock optimization Paul Mundt
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).