raspberrypi / firmware

This repository contains pre-compiled binaries of the current Raspberry Pi kernel and modules, userspace libraries, and bootloader/GPU firmware.
5.18k stars 1.68k forks source link

Feature request: add option to disable GPU frequency scaling #1308

Open edo1 opened 4 years ago

edo1 commented 4 years ago

I need stable core clock frequency because SPI bus is used. I use my PRi in headless mode, so GPU performance doesn't matter to me. And I prefer to keep GPU power consumption as low as possible. I want to use max (non-overcocked) CPU frequency. At least with performance governor RPi boots faster. And idle temperature difference between 600MHz and 1400MHz is only 0.5-1℃ on 3B+.

There is my current config, it works on RPi 3B+:

gpu_freq=250
force_turbo=1

I dislike explicit frequency setting, I'm unsure if it is compatible with RPi 4 and future models.

What about new option? Something like gpu_turbo=0 would be fine.

pelwell commented 4 years ago

On a Pi with onboard Bluetooth, enable_uart=1 is another way to stop the core frequency from changing.

edo1 commented 4 years ago

I tried it, it doesn't work to me

# for src in arm core h264 isp v3d uart pwm emmc pixel vec hdmi dpi ; do   echo -e "$src:\t$(vcgencmd measure_clock $src)" ; done
arm:    frequency(45)=600000000
core:   frequency(1)=250000000
h264:   frequency(28)=0
isp:    frequency(42)=250000000
v3d:    frequency(43)=250000000
uart:   frequency(22)=47999000
pwm:    frequency(25)=0
emmc:   frequency(47)=200000000
pixel:  frequency(29)=148500000
vec:    frequency(10)=0
hdmi:   frequency(9)=163682000
dpi:    frequency(4)=0
# echo performance > /sys/devices/system/cpu/cpufreq/policy0/scaling_governor 
# for src in arm core h264 isp v3d uart pwm emmc pixel vec hdmi dpi ; do   echo -e "$src:\t$(vcgencmd measure_clock $src)" ; done
arm:    frequency(45)=1400000000
core:   frequency(1)=400000000
h264:   frequency(28)=300000000
isp:    frequency(42)=300000000
v3d:    frequency(43)=300000000
uart:   frequency(22)=48000000
pwm:    frequency(25)=0
emmc:   frequency(47)=200000000
pixel:  frequency(29)=148500000
vec:    frequency(10)=0
hdmi:   frequency(9)=163683000
dpi:    frequency(4)=0

And I'm unsure if enable_uart=1 is compatible with dtoverlay=disable-bt (I need ttyAMA0 because ttyS0 lacks MARK/SPACE parity support).

pelwell commented 4 years ago

You are correct - the two are incompatible. disable-bt effectively turns a BT Pi into a non-BT Pi, at which point the clock-fixing is disabled.

Although I'm not yet convinced about the choice of name, I think this would be a useful addition - particularly now that Pi 4 uses different clock speeds.

edo1 commented 4 years ago

English is not my native language, I completely rely on your choice of name.

pelwell commented 4 years ago

@popcornmix To be maximally useful we need two options - one to fix the core clock at the highest supported frequency, and one to fix it at the lowest. How about fixed_core=1 for the lower bound and fixed_core=2 for the higher, the default being 0?

pelwell commented 4 years ago

In relation to https://github.com/raspberrypi/linux/issues/3381, there should also be a way of setting the value from Device Tree.

amahoneyLIT commented 4 years ago

just want to confirm - is there currently a way to disable GPU scaling on the RPi 4? I am also looking for optimal settings for SPI usage, also disabled bluetooth and using uarts

referring to https://www.raspberrypi.org/documentation/configuration/config-txt/overclocking.md

gpu_freq # sets core_freq, h264_freq, isp_freq, and v3d_freq together. 
         # defaults to 500, 600 is the only other accepted value. 

gpu_freq_min # defaults to 500

core_freq      # For Pi 4B the default value is 500, 600 is the only other accepted value
core_freq_min  # The default value is 250. On Pi 4B the default is 275 when hdmi_enable_4kp60 is set

So correct me if I'm wrong, we'll currently have to do core_freq=500 and core_freq_min=500, and this issue is requesting being able to do core_freq=250 and core_freq_min=250, which is currently not allowed according to the values of 500 or 600 being required for core_freq even though the documentation suggests core_freq_min defaults to 250 and is allowed

Appreciate any input, thanks!

pelwell commented 4 years ago

For an unchanging core clock, the absolute max/min values chosen for the core frequency don't matter - only that they are the same. Choose the absolute values appropriately for the platform and the workload - 500 on the Pi 4 is likely to be fine:

core_freq=500
core_freq_min=500
amahoneyLIT commented 4 years ago

I see. I tried this

force_turbo=1
core_freq=250
core_freq_min=250

and confirmed that vcgencmd measure_clock core showed 250MHz under load/idle conditions

I'm confused why the documentation states for core_freq that

For Pi 4B the default value is 500, 600 is the only other accepted value

https://www.raspberrypi.org/documentation/configuration/config-txt/overclocking.md

amahoneyLIT commented 4 years ago

@edo1 think that

force_turbo=1
gpu_freq=250
gpu_freq_min=250

does the trick to keep arm clock at 1500MHz and everything else at lowest 250MHz on the RPi 4

JamesH65 commented 4 years ago

I see. I tried this

force_turbo=1
core_freq=250
core_freq_min=250

and confirmed that vcgencmd measure_clock core showed 250MHz under load/idle conditions

I'm confused why the documentation states for core_freq that

For Pi 4B the default value is 500, 600 is the only other accepted value

https://www.raspberrypi.org/documentation/configuration/config-txt/overclocking.md

That page is currently under review.

amahoneyLIT commented 4 years ago

@JamesH65 thanks for pointing that out. I've added this note to the PR

edo1 commented 4 years ago

What about

gpu_freq=min
gpu_mem=min

?

pelwell commented 4 years ago

Those settings are declared to be integers, with standard integer parsing code, so that scheme won't work without some hackery.

edo1 commented 4 years ago

ok, gpu_minimal=on :)

sherifeid commented 4 years ago

hi there, I tried force_turbo=1 and fixing core/gpu frequencies as above, still SPI frequency keeps jumping around, is there any workaround to keep SPI frequency constant? I have an application that's sensitive to frequency changes

sherifeid commented 4 years ago

guys this is so painful, @pelwell is there a simple way to disable SPI frequency change, rpi 3 SPI frequency is constant, rpi 4 keeps scaling down by 1/2, 1/4, 1/8 multipliers very randomly and causes all kinds of problems with the attached device, here's what I have in my /boot/config.txt

force_turbo=1
core_freq_min=500
core_freq=500
gpu_freq=500
gpu_freq_min=500
v3d_freq=500
v3d_freq_min=500
h264_freq=500
h264_freq_min=500
isp_freq=500
isp_freq_min=500
temp_limit=100
temp_soft_limit=100

I even tried different values for gpu_freq/gpu_freq_min ranging from 100 to 500, no effect at all all other frequencies are stable except GPU

pelwell commented 4 years ago

Those settings have to be on separate lines. Setting force_turbo=1 should be sufficient on its own, provided you aren't thermal throttling or undervolting.

Another way is to add enable_uart=1 on a BT-enabled Pi, as you long as you aren't already using dtoverlay=miniuart-bt. That technique will choose a suitable fixed frequency for the core clock without affecting the ARM clock.

But yes, there should be an easier way - I'm thinking core_freq=0, as it's easy to remember, platform-independent and could never be mistaken for a real clock frequency.

sherifeid commented 4 years ago

Thanks @pelwell , the settings are on different lines (displayed problem in comment), I already had enable_uart=1

I'm trying some experiments (comment out enable_uart), also changing frequencies to zero like your suggestion, I will update with my findings, I do have the latest eeprom (beta) flashed

pi@zrpi-b5:~ $ sudo rpi-eeprom-update
BCM2711 detected
Dedicated VL805 EEPROM detected
BOOTLOADER: up-to-date
CURRENT: Thu 16 Jul 15:15:46 UTC 2020 (1594912546)
 LATEST: Thu 16 Jul 15:15:46 UTC 2020 (1594912546)
 FW DIR: /lib/firmware/raspberrypi/bootloader/beta
VL805: up-to-date
CURRENT: 000138a1
 LATEST: 000138a1
#enable_uart=1
force_turbo=1
core_freq_min=0
core_freq=0
gpu_freq=0
gpu_freq_min=0
v3d_freq=500
v3d_freq_min=500
h264_freq=500
h264_freq_min=500
isp_freq=500
isp_freq_min=500
temp_limit=100
temp_soft_limit=100
pelwell commented 4 years ago

I must not have been clear enough in what I said - the cpu_freq=0 comment was suggesting a way it might be implemented in future, but that doesn't work now.

There was a problem recently where the frequency lock wasn't being honoured - I suggest you use sudo rpi-update (not something that is normally recommended) to get the latest firmware, then comment out all of your frequency settings, leaving only enable_uart=1. You can confirm whether or not this is working by running this sequence in a new terminal window:

$ sleep 1 && vcgencmd measure_clock core
$ while true; do true; done &
$ sleep 1 && vcgencmd measure_clock core
$ kill %1

The frequency(1) value should be the same in the first (idle) and second (busy) cases.

pelwell commented 4 years ago

On second thoughts - leave the rpi-update until after you've edited your config.txt as advised and run the measure_clock test. If you see the same frequency in both cases then there is no reason to update.

sherifeid commented 4 years ago

I do have a question, what clock source does the SPI block take, gpu or core? I always run the core speed test and frequency doesn't change, gpu frequency on the other hand keeps changing

pelwell commented 4 years ago

SPI, like I2C, is run from the core clock, hence vcgencmd measure_clock core.

sherifeid commented 4 years ago

@pelwell , I'm sorry I didn't clarify, I'm using a RPi 4 according to the post here https://github.com/raspberrypi/linux/issues/3381#issuecomment-567536640 SPI clock is controlled by VPU, which I'm assuming is different from CPU clock, maybe my whole should've been in a different issue?

pelwell commented 4 years ago

I know it's a Pi 4, otherwise you wouldn't have an EEPROM version. My comments still apply. The core clock is also known as the VPU clock, as it is the main processor clock for the VideoCore processor. vcgencmd measure_clock core measures that clock - vcgencmd measure_clock arm does the same thing for the ARM processor clocks. The SPI clock is generated using a divisor from the core clock - the divisor is controlled by the ARM, and the core clock is controlled by the VPU.

sherifeid commented 4 years ago

I'd like to report back on the findings, after rpi-update the kernel updated from 4.19.118-v7l+ to 5.4.51-v7l+. I tried with only enable_uart=1 and removing all frequency settings, the core frequency was not stable. After inserting back all frequency settings the core frequency (and in turn SPI) is much more stable, I didn't detect an event of clock scaling. Definitely the way to go for me, the power consumption is a little higher (it trigger some under voltage events which I fixed by a more stable 5V regulator) thanks @pelwell for your help

guymcswain commented 4 years ago

@popcornmix To be maximally useful we need two options - one to fix the core clock at the highest supported frequency, and one to fix it at the lowest. How about fixed_core=1 for the lower bound and fixed_core=2 for the higher, the default being 0?

Is there an estimate for when this feature will be implemented? I'm maintaining the pigpio library and it would be really useful to have - fixed_core=1.

Bump @popcornmix

edo1 commented 2 years ago

Does disable_auto_turbo option make GPU frequency fixed?

popcornmix commented 2 years ago

It stops "auto" boosts, caused by running gpu jobs that require higher clocks (high resolution/framerate hardware video decode, encode, deinterlace). The core clock will still change as arm frequency changes (i.e. when busy/idle through cpufreq driver). And it will change when necessary (e.g. it is boosted when using a 4kp60 HDMI mode).