According to the documentation https://www.raspberrypi.org/documentation/hardware/raspberrypi/frequency-management.md On Raspberry Pi 4 Model B, firmware from late November 2019 onwards implements Dynamic Voltage and Frequency Scaling. I have the latest firmware on my Raspberry Pi 4 Model B
Given below is the output from vcgencmd.
pi@raspberrypi:~ $ vcgencmd version
Mar 26 2021 16:34:17 Copyright (c) 2012 Broadcom version edf2e9c318863999c97c50cdb74eee235ede3af5 (clean) (release) (start_x)
I ran a test with the following python code to change the frequency to each of the available frequencies and checked the voltage and frequency through the command
watch -n1 "vcgencmd measure_clock arm && vcgencmd measure_volts core"
While the frequency changes as per the frequency set by the script, the voltage remains the same all the time.
Script to change frequency and governors.
import time
import os
import subprocess
NUM_CORE = 4
SLEEP_TIME = 30
#Sets Frequency of the available cores to freq
def set_freq(freq, num_core):
set_freq_part1 = 'sudo sh -c "echo '
set_freq_part2 = ' > /sys/devices/system/cpu/cpu'
set_freq_part3 = '/cpufreq/scaling_setspeed"'
get_freq_part1 = 'sudo cat /sys/devices/system/cpu/cpu'
get_freq_part2 = '/cpufreq/cpuinfo_cur_freq'
for core in range(num_core):
set_freq = set_freq_part1 + str(freq) + set_freq_part2 + str(core) + set_freq_part3
# print(set_freq)
os.system(set_freq)
print("Core {} Frequency successfully set to ...".format(core))
get_freq = get_freq_part1 + str(core) + get_freq_part2
os.system(get_freq)
def set_gov_userspace(num_core):
set_gov_part1 = 'sudo sh -c "echo userspace > /sys/devices/system/cpu/cpu'
set_gov_part2 = '/cpufreq/scaling_governor"'
for core in range(num_core):
set_gov = set_gov_part1 + str(core) + set_gov_part2
os.system(set_gov)
# Sets the governor to the specified governor gov
def set_gov(gov, num_core):
set_gov_part1 = 'sudo sh -c "echo ' + gov
set_gov_part2 = ' > /sys/devices/system/cpu/cpu'
set_gov_part3 = '/cpufreq/scaling_governor"'
for core in range(num_core):
set_gov = set_gov_part1 + set_gov_part2 + str(core) + set_gov_part3
os.system(set_gov)
set_gov_userspace(NUM_CORE)
get_freq_str = "sudo cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_available_frequencies"
# result = os.system(get_freq_str, shell=True)
result = subprocess.check_output(get_freq_str, shell=True)
#convert byte stream to string
result = result.decode("utf-8")
print("cpu0 scaling_available_frequencies ...")
# print(result)
freq_list = result.split()
print(freq_list)
print("\n")
for freq in freq_list:
set_freq(freq, NUM_CORE)
# print(f"Sleeping for {SLEEP_TIME} seconds")
print(f"Sleeping for {SLEEP_TIME} seconds")
time.sleep(SLEEP_TIME)
print("\n")
for gov in ("conservative", "ondemand", "powersave", "performance", "schedutil"):
print("Setting Gov to :", gov)
set_gov(gov, NUM_CORE)
print(f"Sleeping for {SLEEP_TIME} seconds")
# print("Sleeping for 10 seconds")
time.sleep(SLEEP_TIME)
print("\n")