Skip to content

Replace userspace CPU governor with kernel scaling governors#695

Open
pvaibhav wants to merge 1 commit intoLoveRetro:mainfrom
pvaibhav:kernel-cpu-governor
Open

Replace userspace CPU governor with kernel scaling governors#695
pvaibhav wants to merge 1 commit intoLoveRetro:mainfrom
pvaibhav:kernel-cpu-governor

Conversation

@pvaibhav
Copy link

Remove all manual CPU frequency control via the userspace governor and scaling_setspeed. Instead, three shell scripts (auto_governor.sh, powersave_governor.sh, performance_governor.sh) configure the kernel governor and frequency range dynamically at runtime.

  • auto: ondemand, min to one step below max frequency
  • powersave: conservative, min to midpoint frequency
  • performance: schedutil, min to max frequency

The minarch CPU Speed menu is reduced from four options (Powersave, Normal, Performance, Auto) to three (Auto, Performance, Powersave). Selecting a profile executes the corresponding script via an absolute path constructed from SYSTEM_PATH. The auto governor is always restored on minarch exit.

The scripts are installed in /mnt/SDCARD/.system/{tg5040,tg5050}/bin/.

The userspace PLAT_cpu_monitor frequency-scaling loop is removed from both tg5040 and tg5050 platform.c; the thread is retained for CPU usage measurement only. PLAT_setCPUSpeed and PLAT_setCustomCPUSpeed are now no-ops so existing callers (ledcontrol, bootlogo, etc.) are unaffected.

As described in #497 (comment) this PR is intended to start a discussion and testing by the community before we settle on the exact frequency governor settings for each of the 3 modes, or perhaps add more modes.

In my opinion, there should not be any need for any option except "Auto" and at best a Powersave mode → that is how for example our phones and laptops work.

For now, the biggest positive impact of this PR is significant reduction in CPU usage by the userspace governor thread and correspondingly significant reduction in core temperature of the order of 5-10°C.

Remove all manual CPU frequency control via the userspace governor and
scaling_setspeed. Instead, three shell scripts (auto_governor.sh,
powersave_governor.sh, performance_governor.sh) configure the kernel
governor and frequency range dynamically at runtime.

- auto: ondemand, min to one step below max frequency
- powersave: conservative, min to midpoint frequency
- performance: schedutil, min to max frequency

The minarch CPU Speed menu is reduced from four options (Powersave,
Normal, Performance, Auto) to three (Auto, Performance, Powersave).
Selecting a profile executes the corresponding script via an absolute
path constructed from SYSTEM_PATH. The auto governor is always restored
on minarch exit, including early-exit paths.

The userspace PLAT_cpu_monitor frequency-scaling loop is removed from
both tg5040 and tg5050 platform.c; the thread is retained for CPU usage
measurement only. PLAT_setCPUSpeed and PLAT_setCustomCPUSpeed are now
no-ops so existing callers (ledcontrol, bootlogo, etc.) are unaffected.
@frysee
Copy link
Member

frysee commented Mar 25, 2026

We should probably push this out as an alpha build, so people can give feedback.

@pvaibhav
Copy link
Author

pvaibhav commented Mar 25, 2026

Go for it. Definitely need feedback. I'm just not sure the settings I've chosen are good for a wide variety of games and cores. My own usage is limited, although I've been using it for several weeks now.

Also for tg5050, I don't have the device to test. As far as I understand it has little and big cores and the GPU can also be freq-scaled. I've copied the tg5040 scripts for tg5050 also but someone with more experience with that device should have a look.

Copy link
Author

@pvaibhav pvaibhav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some near future improvements can be made.

.default_value = 3,
.value = 3,
.count = 4,
.desc = "Select the CPU governor profile.\nAuto uses ondemand scaling, Performance\nallows max frequency, Powersave limits\nto a conservative midpoint.",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Description should be simplified and made more user-friendly.

echo ondemand > "$CPU_PATH/scaling_governor" 2>/dev/null || true
echo "$MIN_FREQ" > "$CPU_PATH/scaling_min_freq"
echo "$SECOND_MAX" > "$CPU_PATH/scaling_max_freq"
done
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to worry about special requirements for tg5050 (big core vs little core?).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could safe some power by shutting down cores, but realistically only if we get the entire cluster offline (i.e. all little or big cores).


char core_path[MAX_PATH];
char rom_path[MAX_PATH];
char rom_path[MAX_PATH];
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

irrelevant change

#define ROLLING_WINDOW 120

volatile int useAutoCpu = 1;
void *PLAT_cpu_monitor(void *arg) {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now that CPU frequency is governed by the kernel, this thread can probably be disabled entirely except when Debug HUD is turned on.

@@ -0,0 +1,11 @@
#!/bin/sh
# auto_governor.sh - ondemand governor, min freq to one step below max
for CPU_PATH in /sys/devices/system/cpu/cpu*/cpufreq; do
Copy link

@huyhoang160593 huyhoang160593 Mar 25, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

all the cpufreq dir inside each /sys/devices/system/cpu/cpu*/cpufreq is symlink to /sys/devices/system/cpu/policy0/cpufreq, they are sharing the same policy0 so we don't need to make loop here, instead just set them in one place and be done with it

@@ -0,0 +1,11 @@
#!/bin/sh
# performance_governor.sh - schedutil governor, min freq to max freq
for CPU_PATH in /sys/devices/system/cpu/cpu*/cpufreq; do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same issue, change it one is enough

@@ -0,0 +1,13 @@
#!/bin/sh
# powersave_governor.sh - conservative governor, min freq to midpoint max
for CPU_PATH in /sys/devices/system/cpu/cpu*/cpufreq; do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same issue, change it one is enough

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants