Skip to content

Commit f0efe6e

Browse files
committed
fix-amd-tdp-2
Update batocera-amd-tdp
1 parent 50687d4 commit f0efe6e

File tree

3 files changed

+126
-87
lines changed

3 files changed

+126
-87
lines changed

package/batocera/core/batocera-configgen/scripts/tdp_hooks.sh

Lines changed: 95 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
# This file is part of the batocera distribution (https://batocera.org).
55
# Copyright (c) 2025+.
66
#
7-
# This program is free software: you can redistribute it and/or modify
8-
# it under the terms of the GNU General Public License as published by
7+
# This program is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU General Public License as published by
99
# the Free Software Foundation, version 3.
1010
#
11-
# You should have received a copy of the GNU General Public License
11+
# You should have received a copy of the GNU General Public License
1212
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1313
#
1414
# YOU MUST KEEP THIS HEADER AS IT IS
@@ -22,6 +22,7 @@
2222
# users can set a higher or lower manufacturer TDP accordingly.
2323

2424
log="/userdata/system/logs/amd-tdp.log"
25+
STATE_FILE="/var/run/amd-tdp.changed"
2526

2627
# Check we have a max system TDP value
2728
CPU_TDP=$(/usr/bin/batocera-settings-get system.cpu.tdp)
@@ -34,89 +35,118 @@ fi
3435

3536
# Set the final tdp value
3637
set_tdp() {
37-
echo "Game ${2} requested setting AMD Mobile Processor TDP to ${1} Watts" >> $log
38-
/usr/bin/batocera-amd-tdp $1
38+
local TDP_VALUE=$1
39+
local ROM_NAME=$2
40+
41+
echo "Game ${ROM_NAME} requested setting AMD Processor TDP to ${TDP_VALUE} Watts" >> $log
42+
43+
/usr/bin/batocera-amd-tdp "$TDP_VALUE"
3944
}
4045

4146
# Determine the new TDP value based on max TDP
4247
handle_tdp() {
43-
TDP_PERCENTAGE=$1
44-
ROM_NAME=$2
48+
local TDP_PERCENTAGE=$1
49+
local ROM_NAME=$2
50+
51+
local MAX_TDP
4552
MAX_TDP=$(/usr/bin/batocera-settings-get system.cpu.tdp)
46-
# Check if MAX_TDP is defined and non-empty
47-
if [ -n "$MAX_TDP" ]; then
48-
# round the value up or down to make bash happy
49-
TDP_VALUE=$(awk -v max_tdp="$MAX_TDP" -v tdp_percentage="$TDP_PERCENTAGE" 'BEGIN { printf("%.0f\n", max_tdp * tdp_percentage / 100) }')
50-
set_tdp "${TDP_VALUE}" "${ROM_NAME}"
51-
else
53+
54+
# Check if TDP is defined and non-empty
55+
if [ -z "$MAX_TDP" ]; then
5256
echo "A maximum TDP is not defined, cannot set TDP." >> $log
5357
exit 1
5458
fi
59+
60+
# Round the value up or down to make bash happy
61+
local TDP_VALUE
62+
TDP_VALUE=$(awk -v max_tdp="$MAX_TDP" -v tdp_percentage="$TDP_PERCENTAGE" 'BEGIN { printf("%.0f\n", max_tdp * tdp_percentage / 100) }')
63+
set_tdp "${TDP_VALUE}" "${ROM_NAME}"
5564
}
5665

57-
# Check for events
58-
EVENT=$1
59-
SYSTEM_NAME=$2
60-
ROM_PATH=$5
66+
do_game_start() {
67+
local SYSTEM_NAME="$1"
68+
local ROM_NAME="$2"
69+
local TDP_SETTING=""
70+
local RAW_GLOBAL=""
6171

62-
# Get the rom name from ROM_PATH
63-
ROM_NAME=$(basename "$ROM_PATH")
72+
# Clear previous state file if present
73+
rm -f "$STATE_FILE" 2>/dev/null
6474

65-
# Exit accordingly if the event is neither gameStart nor gameStop
66-
if [ "$EVENT" != "gameStart" ] && [ "$EVENT" != "gameStop" ]; then
67-
exit 0
68-
fi
75+
# Check for user set rom or system specific setting
76+
if [ -n "${SYSTEM_NAME}" ]; then
77+
TDP_SETTING=$(/usr/bin/batocera-settings-get "${SYSTEM_NAME}[\"${ROM_NAME}\"].tdp")
78+
[ -z "$TDP_SETTING" ] && TDP_SETTING=$(/usr/bin/batocera-settings-get "${SYSTEM_NAME}.tdp")
79+
fi
6980

70-
# Handle gameStop event
71-
if [ "$EVENT" == "gameStop" ]; then
72-
RAW_TDP_SETTING=$(/usr/bin/batocera-settings-get global.tdp)
73-
# Check if the raw setting is actually empty
74-
if [ -z "${RAW_TDP_SETTING}" ]; then
75-
# If it's empty, use the system default TDP
76-
TDP_SETTING="$(/usr/bin/batocera-settings-get system.cpu.tdp)"
77-
if [ -n "$TDP_SETTING" ]; then
78-
set_tdp "${TDP_SETTING}" "STOP"
79-
else
80-
echo "No default TDP setting defined, cannot set TDP on game stop." >> $log
81-
exit 1
81+
# If no user set system specific setting check for user set global setting
82+
if [ -z "${TDP_SETTING}" ]; then
83+
RAW_GLOBAL=$(/usr/bin/batocera-settings-get global.tdp)
84+
if [ -n "${RAW_GLOBAL}" ]; then
85+
TDP_SETTING=$(printf "%.0f" "${RAW_GLOBAL}")
8286
fi
83-
else
84-
# If it's not empty, NOW we can format it and handle it as a percentage
85-
TDP_SETTING=$(printf "%.0f" "${RAW_TDP_SETTING}")
86-
handle_tdp "${TDP_SETTING}" "STOP"
8787
fi
88-
exit 0
89-
fi
9088

91-
# Run through determining the desired TDP setting
92-
# Check for user set system specific setting
93-
if [ -n "${SYSTEM_NAME}" ]; then
94-
# Check for rom specific config
95-
TDP_SETTING=$(/usr/bin/batocera-settings-get "${SYSTEM_NAME}[\"${ROM_NAME}\"].tdp")
96-
if [ -z "${TDP_SETTING}" ]; then
97-
TDP_SETTING="$(/usr/bin/batocera-settings-get ${SYSTEM_NAME}.tdp)"
89+
# Now apply TDP percentage accordingly
90+
if [ -n "${TDP_SETTING}" ]; then
91+
handle_tdp "${TDP_SETTING}" "${ROM_NAME}"
92+
: > "$STATE_FILE"
93+
else
94+
echo "Game START, but no TDP setting defined. Leaving TDP unchanged." >> $log
95+
echo "" >> "$log"
96+
echo "*** ------------------------------------- ***" >> "$log"
97+
echo "" >> "$log"
98+
exit 0
9899
fi
99-
fi
100+
}
100101

101-
# If no user set system specific setting check for user set global setting
102-
if [ -z "${TDP_SETTING}" ]; then
103-
RAW_TDP_SETTING=$(/usr/bin/batocera-settings-get global.tdp)
104-
if [ -n "${RAW_TDP_SETTING}" ]; then
105-
TDP_SETTING=$(printf "%.0f" "${RAW_TDP_SETTING}")
102+
do_game_stop() {
103+
# Check if we actually changed anything on game start
104+
if [ ! -e "$STATE_FILE" ]; then
105+
echo "Game STOP, but no prior TDP change. Nothing to do." >> "$log"
106+
echo "" >> "$log"
107+
echo "*** ------------------------------------- ***" >> "$log"
108+
echo "" >> "$log"
109+
exit 0
106110
fi
107-
fi
108111

109-
# If no value is found after all checks, ensure tdp is default before exiting
110-
if [ -z "${TDP_SETTING}" ]; then
111-
TDP_SETTING="$(/usr/bin/batocera-settings-get-master system.cpu.tdp)"
112-
if [ -n "${TDP_SETTING}" ]; then
113-
set_tdp "${TDP_SETTING}" "${ROM_NAME}"
112+
local RAW_GLOBAL
113+
RAW_GLOBAL=$(/usr/bin/batocera-settings-get global.tdp)
114+
115+
if [ -n "${RAW_GLOBAL}" ]; then
116+
TDP_SETTING=$(printf "%.0f" "${RAW_GLOBAL}")
117+
handle_tdp "$TDP_SETTING" "STOP"
114118
else
115-
echo "No TDP setting defined, cannot set TDP." >> $log
116-
exit 1
119+
local SYSTEM_TDP
120+
SYSTEM_TDP=$(/usr/bin/batocera-settings-get system.cpu.tdp)
121+
if [ -n "$SYSTEM_TDP" ]; then
122+
set_tdp "$SYSTEM_TDP" "STOP"
123+
else
124+
echo "No default TDP setting defined, cannot set TDP on game stop." >> $log
125+
exit 1
126+
fi
117127
fi
128+
129+
rm -f "$STATE_FILE" 2>/dev/null
118130
exit 0
119-
fi
131+
}
132+
133+
# Check for events
134+
SYSTEM_NAME="$2"
135+
ROM_PATH="$5"
136+
137+
# Get the rom name from ROM_PATH
138+
ROM_NAME=$(basename "$ROM_PATH")
139+
140+
case "$1" in
141+
gameStart)
142+
do_game_start "$SYSTEM_NAME" "$ROM_NAME"
143+
;;
144+
gameStop)
145+
do_game_stop
146+
;;
147+
*)
148+
exit 0
149+
;;
150+
esac
120151

121-
# Now apply TDP percentage accordingly
122-
handle_tdp "${TDP_SETTING}" "${ROM_NAME}"
152+
exit 0

package/batocera/core/batocera-scripts/scripts/batocera-amd-tdp

Lines changed: 29 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
# This file is part of the batocera distribution (https://batocera.org).
55
# Copyright (c) 2025+.
66
#
7-
# This program is free software: you can redistribute it and/or modify
8-
# it under the terms of the GNU General Public License as published by
7+
# This program is free software: you can redistribute it and/or modify
8+
# it under the terms of the GNU General Public License as published by
99
# the Free Software Foundation, version 3.
1010
#
11-
# You should have received a copy of the GNU General Public License
11+
# You should have received a copy of the GNU General Public License
1212
# along with this program. If not, see <http://www.gnu.org/licenses/>.
1313
#
1414
# YOU MUST KEEP THIS HEADER AS IT IS
@@ -20,11 +20,6 @@
2020
log="/userdata/system/logs/amd-tdp.log"
2121
TDP_INPUT="$1"
2222

23-
# --- Helper Function ---
24-
get_firmware_max_tdp() {
25-
/usr/bin/ryzenadj -i | awk '/PPT LIMIT FAST/ {printf "%.0f\n", $6}'
26-
}
27-
2823
# --- Sanity Checks ---
2924
if [[ "$(/usr/bin/ryzenadj -i)" =~ "unsupported model" ]]; then
3025
echo "Unsupported CPU for RyzenAdj. Aborting." >> "$log"
@@ -49,21 +44,24 @@ tdp_ranges=(
4944
# Determine device's standard min/max TDP
5045
TDP_MIN=5 # Default min fallback
5146
BASE_TDP_MAX=35 # Default max fallback
47+
APPLY_TEMP_LIMIT=0 # Only set 90c for found handhelds
5248

5349
device_model=$(batocera-info | awk -F': ' '/^Model:/ {print $2; exit}')
5450

5551
if [[ -v tdp_ranges["$device_model"] ]]; then
5652
IFS=';' read -r -a info <<< "${tdp_ranges[$device_model]}"
5753
TDP_MIN=${info[1]}
5854
BASE_TDP_MAX=${info[2]}
55+
APPLY_TEMP_LIMIT=1
5956
echo "Device: ${info[0]} detected. Standard range: ${TDP_MIN}W - ${BASE_TDP_MAX}W." >> "$log"
6057
else
61-
firmware_max=$(get_firmware_max_tdp)
62-
if [[ -n "$firmware_max" && "$firmware_max" -gt 0 ]]; then
63-
BASE_TDP_MAX=$firmware_max
64-
echo "Using firmware max of ${BASE_TDP_MAX}W." >> "$log"
58+
SYSTEM_TDP=$(/usr/bin/batocera-settings-get system.cpu.tdp)
59+
if [ -n "$SYSTEM_TDP" ]; then
60+
BASE_TDP_MAX=$SYSTEM_TDP
61+
echo "Detected reported max of ${BASE_TDP_MAX}W." >> "$log"
6562
else
66-
echo "Could not read firmware. Using default max of ${BASE_TDP_MAX}W." >> "$log"
63+
echo "No system TDP defined." >> "$log"
64+
exit 1
6765
fi
6866
fi
6967

@@ -87,15 +85,26 @@ fi
8785

8886
# --- Apply Settings ---
8987
WATTS=$((TDP * 1000))
90-
SLOW_WATTS=$((WATTS * 60 / 100)) # set to 60% of TDP
88+
SLOW_WATTS=$((WATTS * 80 / 100)) # TODO: Rethink how amd tdp is applied between handhelds and everything else(if not handheld should porobably set all limits to same value)
89+
90+
if (( APPLY_TEMP_LIMIT )); then
91+
echo "Applying final TDP: ${TDP}W, Temp Limit: 90C" >> "$log"
92+
else
93+
echo "Applying final TDP: ${TDP}W" >> "$log"
94+
fi
9195

92-
echo "Applying final TDP: ${TDP}W (STAPM/Fast: ${WATTS}mW, Slow: ${SLOW_WATTS}mW, Temp Limit: 90C)" >> "$log"
96+
cmd=(/usr/bin/ryzenadj
97+
--stapm-limit="$WATTS"
98+
--fast-limit="$WATTS"
99+
--slow-limit="$SLOW_WATTS"
100+
)
101+
102+
# Only set temp limit for known handhelds
103+
if (( APPLY_TEMP_LIMIT )); then
104+
cmd+=(--tctl-temp=90)
105+
fi
93106

94-
if /usr/bin/ryzenadj \
95-
--stapm-limit="${WATTS}" \
96-
--fast-limit="${WATTS}" \
97-
--slow-limit="${SLOW_WATTS}" \
98-
--tctl-temp=90; then
107+
if "${cmd[@]}"; then
99108
echo "Successfully set TDP to ${TDP}W." >> "$log"
100109
else
101110
echo "ERROR: ryzenadj command failed. Power limits may not have been applied." >> "$log"

package/batocera/emulationstation/batocera-es-system/es_features.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@ shared:
2424
group: POWER OPTIONS
2525
prompt: RYZEN THERMAL DESIGN POWER
2626
description: Adjust the percentage of power (watts) provided to a Ryzen Mobile Series CPU based on it's default max value. Caution, setting wattage too high could damage your device.
27-
preset: slider
28-
preset_parameters: 10 120 5 100 %
27+
preset: sliderauto
28+
preset_parameters: 10 120 5 %
2929
videomode:
3030
prompt: VIDEO MODE
3131
description: Set the display's resolution. Does not affect the rendering resolution.

0 commit comments

Comments
 (0)