On 07/01/14 21:12, Viresh Kumar wrote:
On 1 July 2014 22:02, Viresh Kumar viresh.kumar@linaro.org wrote:
V1: https://lkml.org/lkml/2014/6/25/152
Stephen Boyd sent few patches some time back around a new cpufreq driver for Qualcomm's Krait SoC: https://lkml.org/lkml/2014/6/24/918.
Krait couldn't use existing cpufreq-cpu0 driver as it doesn't have support for SoC's with multiple clusters or SoC's which don't share clock line across all CPUs.
This patchset is all about extending support beyond CPU0. It can be used for platforms like Krait or ARM big LITTLE architecture now.
First two patches add helper routine for of and clk layer, which would be used by later patches.
Third one adds space for driver specific data in 'struct cpufreq_policy' and later ones migrate cpufreq-cpu0 to cpufreq-generic, i.e. can be used for SoCs which don't share clock lines across all CPUs.
@Stephen: I haven't added your Tested-by as there were few modifications since the time you tested it last.
Pushed here: Rebased over v3.16-rc3: git://git.linaro.org/people/viresh.kumar/linux.git cpufreq/cpu0-krait-v2
Hi Stephen,
As suggested by you I have updated patch
7/14: cpufreq: cpu0: OPPs can be populated at runtime 12/14: cpufreq: cpu0: Extend support beyond CPU0
and dropped 2/14: clk: Create of_clk_shared_by_cpus()
Please see if they look fine and work for you.
git://git.linaro.org/people/viresh.kumar/linux.git cpufreq/cpu0-krait-v3
I gave it a spin. It works so you can have my
Tested-by: Stephen Boyd sboyd@codeaurora.org
I'm still concerned about the patch where we figure out if the clocks are shared. I worry about a configuration where there are different clocks for on/off (i.e. gates) that are per-cpu but they all source from the same divider or something that is per-cluster. In DT this may be described as different clock provider outputs for the gates and in the cpu node we would have different clock specifiers but in reality all the CPUs in that cluster are affected by the same frequency scaling.
In this case we'll need to get help from the clock framework to determine that those gates clocks don't have any .set_rate() callback so they can't actually change rate independently, and then walk up the tree to their parents to see if they have a common ancestor that does change rates. That's where it becomes useful to have a clock framework API for this, like clk_shares_rate(struct clk *clk, struct clk *peer) or something that can hide all this from cpufreq. Here's what I think it would look like (totally untested/uncompiled):
static struct clk *find_rate_changer(struct clk *clk) {
if (!clk) return NULL;
do { /* Rate could change by changing parents */ if (clk->num_parents > 1) return clk;
/* Rate could change by calling clk_set_rate() */ if (clk->ops->set_rate) return clk;
/* * This is odd, clk_set_rate() doesn't propagate * and this clock can't change rate or parents * so we must be at the root and the clock we * started at can't change rates. Just return the * root so that we can see if the other clock shares * the same root although CPUfreq should never care. */ if (!(clk->flags & CLK_SET_RATE_PARENT)) return clk; } while ((clk = clk->parent))
return NULL; }
bool clk_shares_rate(struct clk *clk, struct clk *peer) { struct clk *p1, *p2;
p1 = find_rate_changer(clk); p2 = find_rate_changer(peer)
return p1 == p2; }