# Device profile: Xiaomi 24129PN74C, Snapdragon 8 Elite (SM8750, "sun"), # Adreno 830v2, adb serial 35d0befa. # # One of the two devices the disaggregation campaign is measured on (the other is # devices/oppo-mali.env). It exists so that the pinning and thermal protocol the campaign # actually runs is written down in the repository instead of living in one operator's shell # history, and so that a `--device` argument names something reviewable. # # ============================== DEVICE-VERIFIED ============================== # Read off the device on 2026-09-07 and confirmed against one pinned window: pins written, # 8 concurrent busy loops as load, scaling_cur_freq / gpuclk sampled 7 times over 30 s, every # sample equal to the pin, then unpinned and every node confirmed back at its stock value. # Evidence is in ../REPORT.md. # # READ THIS BEFORE USING IT WITH bench.sh / session.sh # ---------------------------------------------------- # bench.sh's pin_freqs()/unpin_freqs() are MediaTek-only: they write /proc/ppm/policy/* and # /proc/gpufreq/gpufreq_opp_freq. NEITHER PATH EXISTS ON THIS DEVICE, and `su -c 'echo ... > # /proc/...'` against a missing path fails without a non-zero exit - which is the exact silent # failure the PROFILE_VERIFIED guard was built to prevent. PROFILE_VERIFIED=1 below certifies # THE NODES AND THE PINS IN THIS FILE, not that bench.sh can drive them. # # So until bench.sh grows a PIN_STYLE switch, drive the pin out of band: # tools/device_bench/pin_device.sh 35d0befa pin # before the run # tools/device_bench/bench.sh --device --backend X --no-pin # tools/device_bench/pin_device.sh 35d0befa check # AFTER, exits non-zero on drift # tools/device_bench/pin_device.sh 35d0befa unpin # `--no-pin` is what keeps bench.sh from writing MediaTek paths into the void and labelling the # result pinned; pin_device.sh check is what replaces the pin-integrity fields it would have # sampled. (bench.sh's read_temp and its GPU-busy sampling ARE portable - they only read # /sys/class/thermal and $GPU_UTIL_NODE - so those fields stay meaningful.) # ============================================================================= PROFILE_VERIFIED=1 PIN_STYLE=qualcomm-kgsl DEVICE_SERIAL=35d0befa # --- CPU ------------------------------------------------------------------------------------- # SM8750 is a 2+6 part with NO true little cluster: # policy0 = cpus 0-5, 384000..3532800 kHz (6x performance) <- the protocol's "little" # policy6 = cpus 6-7, 1017600..4320000 kHz (2x prime) <- the protocol's "big" # The campaign's targets (big 1.96 GHz / little 1.55 GHz) are both EXACT members of # scaling_available_frequencies here, so no rounding is involved: # policy6 avail: ... 1689600 [1958400] 2246400 ... # policy0 avail: ... 1363200 [1555200] 1785600 ... # Pin method: scaling_min_freq = scaling_max_freq = target, leaving the stock `walt` governor # in place. Verified to hold: 30 s under load, zero drift, and the walt governor has no say # once min == max. A `performance` governor is offered but is not needed and would have to be # restored by name, so the min/max clamp is the lighter touch. # Restore: write the stock min/max back (see CPU_*_STOCK_* below). Order matters on policy0 - # its stock min (556800) is BELOW its pinned value, so lower the max first, then the min, or # the min write is clamped against the still-pinned max. CPU_BIG_POLICY=policy6 CPU_BIG_FREQ=1958400 CPU_LITTLE_POLICY=policy0 CPU_LITTLE_FREQ=1555200 # Stock values sampled 2026-09-07, for the restore path. Governor is `walt` on both policies # and is never written, so it needs no restore. CPU_BIG_STOCK_MIN=1017600 CPU_BIG_STOCK_MAX=2841600 CPU_LITTLE_STOCK_MIN=556800 CPU_LITTLE_STOCK_MAX=2745600 # --- GPU ------------------------------------------------------------------------------------- # Adreno pins through the kgsl pwrlevel knobs, not /proc/gpufreq. 14 pwrlevels, index 0 fastest: # [0] 1100 MHz ... [12] 222 MHz [13] 160 MHz # Stock range is min_pwrlevel=12 / max_pwrlevel=0, and the devfreq governor (msm-adreno-tz) # holds its own max_freq at 1050000000 - i.e. stock DVFS never reaches level 0. Writing # echo 0 > /sys/class/kgsl/kgsl-3d0/min_pwrlevel # echo 0 > /sys/class/kgsl/kgsl-3d0/max_pwrlevel # collapses the range onto level 0 and DOES unlock the 1100 MHz step: gpuclk read 1100000000 # immediately and for the whole 30 s window. Prefer this over the devfreq min_freq/max_freq # pair, which cannot express the top step. GPU_PIN_PWRLEVEL=0 GPU_PIN_KHZ=1100000 # UNIT TRAP, do not delete: bench.sh reports `gpu_cur_khz` from $GPU_CURFREQ_NODE via # `awk '{print $NF}'`. On MediaTek that node yields kHz; kgsl's gpuclk yields Hz. So on this # device the field bench.sh calls gpu_cur_khz is actually Hz, and the value to compare it # against is GPU_PIN_HZ, not GPU_PIN_KHZ. GPU_PIN_KHZ is carried only to keep the schema # identical across profiles. GPU_PIN_HZ=1100000000 GPU_CURFREQ_UNIT=hz GPU_STOCK_MIN_PWRLEVEL=12 GPU_STOCK_MAX_PWRLEVEL=0 # NOT gpubusy. `cat gpubusy` prints " " and bench.sh takes $1, which # would record raw busy cycles as a percentage. gpu_busy_percentage prints "26 %", whose $1 is # the percentage bench.sh means. GPU_UTIL_NODE=/sys/class/kgsl/kgsl-3d0/gpu_busy_percentage GPU_CURFREQ_NODE=/sys/class/kgsl/kgsl-3d0/gpuclk # --- Thermal --------------------------------------------------------------------------------- # 84 thermal zones; `cpuss-0-0` (thermal_zone13) is the CPU-subsystem sensor for the 6-core # cluster that carries most of the load, and was the hottest of the candidates under the load # test (47.1 -> 52.1 C while gpuss/quiet_therm stayed near 30 C). Type strings are unique on # this device, so bench.sh's match-first-zone-by-type loop resolves it unambiguously. # 40 C is reachable at rest: it idles at 34.7 C. THERMAL_ZONE_TYPE=cpuss-0-0 THERMAL_START_MAX_MC=40000 # Xiaomi has no fan; bench.sh's `settings put global fan_mode 3` is an Odin Lite line and is a # harmless no-op here.