cpufreq: frequency scaling spec in DT node
From: viresh.kumar@linaro.org (Viresh Kumar)
Date: 2017-07-11 10:25:14
Also in:
linux-pm
On 11-07-17, 11:27, Mason wrote:
On 29/06/2017 16:34, Viresh Kumar wrote:quoted
On 29-06-17, 13:41, Mason wrote:quoted
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?
quoted
quoted
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