diff --git a/skeleton/SYSTEM/tg5040/bin/cpufreq.sh b/skeleton/SYSTEM/tg5040/bin/cpufreq.sh new file mode 100755 index 000000000..731941713 --- /dev/null +++ b/skeleton/SYSTEM/tg5040/bin/cpufreq.sh @@ -0,0 +1,197 @@ +#!/bin/sh +# +# cpufreq.sh - CPU governor and frequency control for Allwinner A133p (Tina Linux) +# + +CPU_BASE="/sys/devices/system/cpu" +AVAIL_GOVS="$CPU_BASE/cpu0/cpufreq/scaling_available_governors" +AVAIL_FREQS="$CPU_BASE/cpu0/cpufreq/scaling_available_frequencies" + +# Default fallback governor +DEFAULT_GOV="schedutil" + +# Helpers +set_for_all_cpus() { + local file=$1 + local value=$2 + for cpu in $CPU_BASE/cpu[0-9]*; do + if [ -w "$cpu/cpufreq/$file" ]; then + echo "$value" > "$cpu/cpufreq/$file" 2>/dev/null + fi + done +} + +get_max_freq() { + cat $AVAIL_FREQS 2>/dev/null | awk '{print $NF}' +} +get_min_freq() { + cat $AVAIL_FREQS 2>/dev/null | awk '{print $1}' +} + +has_governor() { + grep -qw "$1" "$AVAIL_GOVS" 2>/dev/null +} + +reset_cpufreq() { + echo "Resetting CPU frequency policy to defaults" + + # Ensure all cores are online + for cpu in $CPU_BASE/cpu[0-9]*; do + if [ -w "$cpu/online" ]; then + echo 1 > "$cpu/online" 2>/dev/null + fi + done + + # Reset frequency limits + for cpu in $CPU_BASE/cpu[0-9]*; do + min=$(cat $cpu/cpufreq/cpuinfo_min_freq 2>/dev/null) + max=$(cat $cpu/cpufreq/cpuinfo_max_freq 2>/dev/null) + [ -w "$cpu/cpufreq/scaling_min_freq" ] && echo "$min" > "$cpu/cpufreq/scaling_min_freq" + [ -w "$cpu/cpufreq/scaling_max_freq" ] && echo "$max" > "$cpu/cpufreq/scaling_max_freq" + done + + # Reset governor + if has_governor "$DEFAULT_GOV"; then + echo "Governor reset to $DEFAULT_GOV" + set_for_all_cpus scaling_governor "$DEFAULT_GOV" + else + echo "Governor $DEFAULT_GOV not available, falling back to performance" + set_for_all_cpus scaling_governor "performance" + fi +} + +detect_profile() { + gov=$(cat $CPU_BASE/cpu0/cpufreq/scaling_governor 2>/dev/null) + cur=$(cat $CPU_BASE/cpu0/cpufreq/scaling_cur_freq 2>/dev/null) + min=$(cat $CPU_BASE/cpu0/cpufreq/cpuinfo_min_freq 2>/dev/null) + max=$(cat $CPU_BASE/cpu0/cpufreq/cpuinfo_max_freq 2>/dev/null) + + case "$gov" in + performance) echo "performance" ;; + powersave) echo "powersave" ;; + ondemand) echo "ondemand" ;; + schedutil) echo "schedutil" ;; + interactive) echo "interactive" ;; + conservative)echo "conservative" ;; + userspace) + if [ "$cur" = "$max" ]; then + echo "userspace (max freq)" + elif [ "$cur" = "$min" ]; then + echo "userspace (min freq)" + else + echo "userspace (custom freq: $cur)" + fi + ;; + *) echo "unknown governor: $gov" ;; + esac +} + +show_status() { + echo "=== CPU Frequency/Governor Status ===" + echo "Available governors: $(cat $AVAIL_GOVS 2>/dev/null)" + echo "Available freqs: $(cat $AVAIL_FREQS 2>/dev/null)" + echo "Active profile: $(detect_profile)" + for cpu in $CPU_BASE/cpu[0-9]*; do + online="1" + [ -r "$cpu/online" ] && online=$(cat "$cpu/online") + gov=$(cat $cpu/cpufreq/scaling_governor 2>/dev/null) + cur=$(cat $cpu/cpufreq/scaling_cur_freq 2>/dev/null) + smin=$(cat $cpu/cpufreq/scaling_min_freq 2>/dev/null) + smax=$(cat $cpu/cpufreq/scaling_max_freq 2>/dev/null) + min=$(cat $cpu/cpufreq/cpuinfo_min_freq 2>/dev/null) + max=$(cat $cpu/cpufreq/cpuinfo_max_freq 2>/dev/null) + echo "$(basename $cpu): online=$online governor=$gov cur=${cur}" + echo " scaling_min=${smin} scaling_max=${smax} (hardware min=${min} max=${max})" + done +} + +list_profiles() { + echo "Supported profiles on this system:" + for gov in $(cat $AVAIL_GOVS 2>/dev/null); do + echo " $gov" + done + echo "Special modes:" + echo " reset (restore defaults: $DEFAULT_GOV)" + echo " status (show current info)" + echo " list (list supported governors)" + echo " freq (set specific frequency, requires -f , userspace governor)" +} + +usage() { + echo "Usage: $0 -p [-f ]" + echo "Profiles:" + echo " performance - max speed" + echo " powersave - min speed" + echo " ondemand - ondemand governor" + echo " schedutil - schedutil governor (if supported)" + echo " interactive - interactive governor (if supported)" + echo " conservative - conservative governor (if supported)" + echo " reset - restore defaults (all cores online, default min/max, default governor)" + echo " status - show current governor, freq, active profile, and CPU online status" + echo " list - list supported governors" + echo " freq - set exact frequency (requires -f , userspace governor)" + exit 1 +} + +PROFILE="" +FREQ="" + +while getopts "p:f:" opt; do + case $opt in + p) PROFILE="$OPTARG" ;; + f) FREQ="$OPTARG" ;; + *) usage ;; + esac +done + +[ -z "$PROFILE" ] && usage + +case "$PROFILE" in + performance) + if has_governor performance; then + set_for_all_cpus scaling_governor performance + set_for_all_cpus scaling_setspeed "$(get_max_freq)" + fi + ;; + powersave) + if has_governor powersave; then + set_for_all_cpus scaling_governor powersave + set_for_all_cpus scaling_setspeed "$(get_min_freq)" + fi + ;; + ondemand|schedutil|interactive|conservative) + if has_governor "$PROFILE"; then + set_for_all_cpus scaling_governor "$PROFILE" + else + echo "Governor $PROFILE not supported, falling back to $DEFAULT_GOV" + reset_cpufreq + fi + ;; + reset) + reset_cpufreq + ;; + status) + show_status + ;; + list) + list_profiles + ;; + freq) + if [ -z "$FREQ" ]; then + echo "Error: freq profile requires -f " + exit 1 + fi + if has_governor userspace; then + echo "Setting userspace governor at $FREQ Hz" + set_for_all_cpus scaling_governor userspace + set_for_all_cpus scaling_setspeed "$FREQ" + else + echo "userspace governor not supported!" + exit 1 + fi + ;; + *) + echo "Unknown profile: $PROFILE" + usage + ;; +esac diff --git a/skeleton/SYSTEM/tg5040/bin/poweroff_next b/skeleton/SYSTEM/tg5040/bin/poweroff_next index 75bd7e8aa..098f72f3a 100755 --- a/skeleton/SYSTEM/tg5040/bin/poweroff_next +++ b/skeleton/SYSTEM/tg5040/bin/poweroff_next @@ -1,4 +1,5 @@ #!/bin/sh +# https://github.com/Ninoh-FOX/ADB-shell-trimui/blob/master/Apps/poweroff/poweroff # Function to terminate all non-essential processes task_killer() { diff --git a/skeleton/SYSTEM/tg5040/bin/reboot_next b/skeleton/SYSTEM/tg5040/bin/reboot_next index 4abd2b41c..da69500be 100755 --- a/skeleton/SYSTEM/tg5040/bin/reboot_next +++ b/skeleton/SYSTEM/tg5040/bin/reboot_next @@ -1,4 +1,5 @@ #!/bin/sh +# Adapted from https://github.com/Ninoh-FOX/ADB-shell-trimui/blob/master/Apps/poweroff/poweroff # Function to terminate all non-essential processes task_killer() { diff --git a/skeleton/SYSTEM/tg5040/paks/MinUI.pak/launch.sh b/skeleton/SYSTEM/tg5040/paks/MinUI.pak/launch.sh index 0534b102e..a1eba2769 100755 --- a/skeleton/SYSTEM/tg5040/paks/MinUI.pak/launch.sh +++ b/skeleton/SYSTEM/tg5040/paks/MinUI.pak/launch.sh @@ -13,15 +13,6 @@ ####################################### -if [ -f "/tmp/poweroff" ]; then - poweroff_next - exit 0 -fi -if [ -f "/tmp/reboot" ]; then - reboot_next - exit 0 -fi - export PLATFORM="tg5040" export SDCARD_PATH="/mnt/SDCARD" export BIOS_PATH="$SDCARD_PATH/Bios" @@ -99,20 +90,12 @@ if [ "$TRIMUI_MODEL" = "Trimui Brick" ]; then echo 0 > /sys/class/led_anim/max_scale_lr echo 0 > /sys/class/led_anim/max_scale_f1f2 fi - # start stock gpio input daemon trimui_inputd & -echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -CPU_PATH=/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed -CPU_SPEED_PERF=2000000 -echo $CPU_SPEED_PERF > $CPU_PATH - keymon.elf & # &> $SDCARD_PATH/keymon.txt & batmon.elf & # &> $SDCARD_PATH/batmon.txt & -#killall MtpDaemon # I dont think we need to micro manage this one - # BT handling # on by default, disable based on systemval setting bluetoothon=$(nextval.elf bluetooth | sed -n 's/.*"bluetooth": \([0-9]*\).*/\1/p') @@ -124,7 +107,6 @@ if [ "$bluetoothon" -eq 0 ]; then /etc/bluetooth/bt_init.sh stop > /dev/null 2>&1 & else /etc/bluetooth/bt_init.sh start > /dev/null 2>&1 & - #bt_daemon -s & fi # wifi handling @@ -135,7 +117,6 @@ if [ "$wifion" -eq 0 ]; then /etc/wifi/wifi_init.sh stop > /dev/null 2>&1 & else /etc/wifi/wifi_init.sh start > /dev/null 2>&1 & - #wifi_daemon -s & fi ####################################### @@ -153,21 +134,25 @@ EXEC_PATH="/tmp/nextui_exec" NEXT_PATH="/tmp/next" touch "$EXEC_PATH" && sync while [ -f $EXEC_PATH ]; do + # boost CPU to speed up transition to main UI + cpufreq.sh -p reset nextui.elf &> $LOGS_PATH/nextui.txt - echo $CPU_SPEED_PERF > $CPU_PATH if [ -f $NEXT_PATH ]; then + # at this point main UI exited, boost CPU to speed up transition to new app + cpufreq.sh -p reset CMD=`cat $NEXT_PATH` eval $CMD rm -f $NEXT_PATH - echo $CPU_SPEED_PERF > $CPU_PATH fi if [ -f "/tmp/poweroff" ]; then + cpufreq.sh -p reset poweroff_next exit 0 fi if [ -f "/tmp/reboot" ]; then + cpufreq.sh -p reset reboot_next exit 0 fi diff --git a/workspace/all/common/api.c b/workspace/all/common/api.c index 716e26aa2..6a5fbd4d3 100644 --- a/workspace/all/common/api.c +++ b/workspace/all/common/api.c @@ -3728,10 +3728,10 @@ void PWR_powerOff(int reboot) GFX_blitMessage(font.large, msg, gfx.screen, &(SDL_Rect){0, 0, gfx.screen->w, gfx.screen->h}); //, NULL); GFX_flip(gfx.screen); - system("killall -STOP keymon.elf"); - system("killall -STOP batmon.elf"); - system("killall -STOP wifi_daemon"); - system("killall -STOP bt_daemon"); + system("killall -TERM keymon.elf"); + system("killall -TERM batmon.elf"); + system("killall -TERM wifi_daemon"); + system("killall -TERM bt_daemon"); PWR_updateFrequency(-1, false); @@ -3759,9 +3759,6 @@ static void PWR_enterSleep(void) } system("killall -STOP keymon.elf"); system("killall -STOP batmon.elf"); - // this is currently handled in wifi_init.sh from suspend script, doing this double or at same time causes problems - // system("killall -STOP wifi_daemon"); - system("killall -STOP bt_daemon"); PWR_updateFrequency(-1, false); @@ -3780,9 +3777,6 @@ static void PWR_exitSleep(void) system("killall -CONT keymon.elf"); system("killall -CONT batmon.elf"); - // this is currently handled in wifi_init.sh from suspend script, doing this double or at same time causes problems - // system("killall -CONT wifi_daemon"); - system("killall -CONT bt_daemon"); if (GetHDMI()) { diff --git a/workspace/all/common/api.h b/workspace/all/common/api.h index 34b2ae2e8..5156a8bff 100644 --- a/workspace/all/common/api.h +++ b/workspace/all/common/api.h @@ -487,6 +487,7 @@ enum { CPU_SPEED_POWERSAVE, CPU_SPEED_NORMAL, CPU_SPEED_PERFORMANCE, + CPU_SPEED_ADAPTIVE, }; #define CPU_SWITCH_DELAY_MS 500 #define PWR_setCPUSpeed PLAT_setCPUSpeed diff --git a/workspace/all/minarch/minarch.c b/workspace/all/minarch/minarch.c index 2f7d6f58e..a2911937d 100644 --- a/workspace/all/minarch/minarch.c +++ b/workspace/all/minarch/minarch.c @@ -4915,8 +4915,8 @@ void Menu_beforeSleep() { RTC_write(); State_autosave(); putFile(AUTO_RESUME_PATH, game.path + strlen(SDCARD_PATH)); - - PWR_setCPUSpeed(CPU_SPEED_MENU); + + PWR_setCPUSpeed(CPU_SPEED_ADAPTIVE); } void Menu_afterSleep() { unlink(AUTO_RESUME_PATH); diff --git a/workspace/all/nextui/nextui.c b/workspace/all/nextui/nextui.c index 530a3b980..0d6295e99 100644 --- a/workspace/all/nextui/nextui.c +++ b/workspace/all/nextui/nextui.c @@ -2152,6 +2152,7 @@ int main (int argc, char *argv[]) { int was_online = PLAT_isOnline(); int had_bt = PLAT_btIsConnected(); + PWR_setCPUSpeed(CPU_SPEED_MENU); pthread_t cpucheckthread; pthread_create(&cpucheckthread, NULL, PLAT_cpu_monitor, NULL); diff --git a/workspace/tg5040/install/boot.sh b/workspace/tg5040/install/boot.sh index 2b448d7ba..0ddac0d9a 100755 --- a/workspace/tg5040/install/boot.sh +++ b/workspace/tg5040/install/boot.sh @@ -7,10 +7,8 @@ UPDATE_PATH="$SDCARD_PATH/MinUI.zip" PAKZ_PATH="$SDCARD_PATH/*.pakz" SYSTEM_PATH="$SDCARD_PATH/.system" -echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor -CPU_PATH=/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed -CPU_SPEED_PERF=2000000 -echo $CPU_SPEED_PERF > $CPU_PATH +# we cant rely on cpufreq.sh being present, so set manually +echo schedutil > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ##Remove Old Led Daemon if [ -f "/etc/LedControl" ]; then diff --git a/workspace/tg5040/platform/platform.c b/workspace/tg5040/platform/platform.c index 9ff20abc1..1b347fc16 100644 --- a/workspace/tg5040/platform/platform.c +++ b/workspace/tg5040/platform/platform.c @@ -2427,9 +2427,9 @@ void *PLAT_cpu_monitor(void *arg) { double prev_real_time = get_time_sec(); double prev_cpu_time = get_process_cpu_time_sec(); - const int cpu_frequencies[] = {408,450,500,550, 600,650,700,750, 800,850,900,950, 1000,1050,1100,1150, 1200,1250,1300,1350, 1400,1450,1500,1550, 1600,1650,1700,1750, 1800,1850,1900,1950, 2000}; + const int cpu_frequencies[] = {408,600,816,1008,1200,1416,1608,1800,2000}; const int num_freqs = sizeof(cpu_frequencies) / sizeof(cpu_frequencies[0]); - int current_index = 5; + int current_index = 1; double cpu_usage_history[ROLLING_WINDOW] = {0}; double cpu_speed_history[ROLLING_WINDOW] = {0}; @@ -2531,16 +2531,10 @@ void *PLAT_cpu_monitor(void *arg) { } -#define GOVERNOR_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed" +#define GOVERNOR_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_governor" +#define CLOCKSPEED_PATH "/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed" void PLAT_setCustomCPUSpeed(int speed) { - FILE *fp = fopen(GOVERNOR_PATH, "w"); - if (fp == NULL) { - perror("Failed to open scaling_setspeed"); - return; - } - - fprintf(fp, "%d\n", speed); - fclose(fp); + putInt(CLOCKSPEED_PATH, speed); } void PLAT_setCPUSpeed(int speed) { int freq = 0; @@ -2549,8 +2543,16 @@ void PLAT_setCPUSpeed(int speed) { case CPU_SPEED_POWERSAVE: freq = 1200000; currentcpuspeed = 1200; break; case CPU_SPEED_NORMAL: freq = 1608000; currentcpuspeed = 1600; break; case CPU_SPEED_PERFORMANCE: freq = 2000000; currentcpuspeed = 2000; break; + case CPU_SPEED_ADAPTIVE: freq = -1; break; + } + // ensure we are on the correct governor + if(freq > 0) { + putFile(GOVERNOR_PATH, "userspace"); + PLAT_setCustomCPUSpeed(freq); + } + else { + putFile(GOVERNOR_PATH, "schedutil"); } - putInt(GOVERNOR_PATH, freq); } #define MAX_STRENGTH 0xFFFF