cpufreq: frequency scaling spec in DT node

Viresh Kumar viresh.kumar at linaro.org
Tue Jul 11 03:25:14 PDT 2017


On 11-07-17, 11:27, Mason wrote:
> On 29/06/2017 16:34, Viresh Kumar wrote:
> 
> > On 29-06-17, 13:41, Mason wrote:
> > 
> >> I was trying to "emulate" the behavior of the ondemand governor.
> >> Based on your reaction, I got it wrong...
> >> Here is the actual issue:
> >>
> >> I'm on SoC B, where nominal/max freq is expected to be 1206 MHz.
> >> So the OPPs in the DT are:
> >> operating-points = <1206000 0 603000 0 402000 0 241200 0 134000 0>;
> >> *But* FW changed the max freq behind my back, to 1215 MHz.

What does this line mean really? Where is this frequency changed ? In the OPP
table in DT?

> >>
> >> Here is what happens when I execute:
> >> echo ondemand >scaling_governor
> >> sleep 2
> >> cpuburn-a9 & cpuburn-a9 & cpuburn-a9 & cpuburn-a9
> >> ### cpuburn-a9 spins in a tight infinite loop,
> >> ### hitting all FUs to raise the CPU temperature
> >>
> >> # cpufreq_test.sh
> >> [   69.933874] set_target: index=4
> >> [   69.944799] set_target: index=2
> >> [   69.947988] clk_divider_set_rate: rate=303750000 parent_rate=1215000000 div=4
> >> [   69.955542] set_target: index=4
> >> [   69.958801] clk_divider_set_rate: rate=607500000 parent_rate=1215000000 div=2
> >> [   69.984789] set_target: index=0
> >> [   69.987980] clk_divider_set_rate: rate=121500000 parent_rate=1215000000 div=10
> >> [   71.947597] set_target: index=4
> >> [   71.950996] clk_divider_set_rate: rate=607500000 parent_rate=1215000000 div=2
> >>
> >> As you can see, the divider remains stuck at 2, so the SoC
> >> is actually running only at 607.5 MHz (instead of 1215 MHz).
> >>
> >> If I fix the OPPs in DT to:
> >> operating-points = <1215000 0 607500 0 405000 0 243000 0 135000 0>;
> >> Then I get the expected behavior:
> >>
> >> $ cpufreq_test.sh 
> >> [   32.717930] set_target: index=1
> >> [   32.721131] clk_divider_set_rate: rate=243000000 parent_rate=1215000000 div=5
> >> [   32.731326] set_target: index=4
> >> [   32.734521] clk_divider_set_rate: rate=1215000000 parent_rate=1215000000 div=1
> >> [   32.754556] set_target: index=0
> >> [   32.757738] clk_divider_set_rate: rate=135000000 parent_rate=1215000000 div=9
> >> [   32.765864] set_target: index=4
> >> [   32.769217] clk_divider_set_rate: rate=1215000000 parent_rate=1215000000 div=1
> >> [   33.438811] set_target: index=0
> >> [   33.442001] clk_divider_set_rate: rate=135000000 parent_rate=1215000000 div=9
> >> [   33.450249] set_target: index=4
> >> [   33.453470] clk_divider_set_rate: rate=1215000000 parent_rate=1215000000 div=1
> >> [   33.477888] set_target: index=0
> >> [   33.481067] clk_divider_set_rate: rate=135000000 parent_rate=1215000000 div=9
> >> [   34.714786] set_target: index=4
> >> [   34.718237] clk_divider_set_rate: rate=1215000000 parent_rate=1215000000 div=1
> >>
> >> Divider settles at 1 (full speed) to provide maximum
> >> performance for the user-space processes.
> > 
> > I am not sure how such behavior will happen just because we changed
> > the max OPP (actually increased it). You need to dig in a bit to see
> > why this happens, as I can't agree to your numbers for now.
> 
> I had a closer look.
> 
> static int _div_round(...)
> {
> 	if (flags & CLK_DIVIDER_ROUND_CLOSEST)
> 		return _div_round_closest(table, parent_rate, rate, flags);
> 
> 	return _div_round_up(table, parent_rate, rate, flags);
> }
> 
> This flag was /not/ set for the CPU divider clock.

i.e. _div_round_up() was getting called ? And you failed to explain why do you
think this results in that awkward behavior.

> But setting it breaks in dev_pm_opp_set_rate()
> 
> [    9.201681] set_target: index=4
> [    9.204870] dev_pm_opp_set_rate: target_freq=1206000000 freq=1215000000 old_freq=243000000

I have some assumptions on how you are printing this line and will present my
analysis based on that.

cpufreq core asked for a freq of 1206 (why?, DT should have had 1215 as max),
but clk framework rounded it up to 1215 (this should happen without the
CLK_DIVIDER_ROUND_CLOSEST flag as well).

> [    9.213647] cpu cpu0: dev_pm_opp_set_rate: failed to find OPP for freq 1215000000 (-34)

Now we failed because DT didn't had the max set to 1215, why ?

> I'll experiment with the other solution of creating the OPP table
> at init.

Sorry, I haven't got a convincing answer to why you see the problem you are
seeing.

-- 
viresh



More information about the linux-arm-kernel mailing list