1# 2# Copyright (C) 2018 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16 17################################################################# 18### 19### DO NOT MODIFY THIS FILE 20### This is a copy of androidx's benchmark/lockClocks.sh 21### Make changes there instead then copy here! 22### 23################################################################# 24 25# This script can be used to lock device clocks to stable levels for comparing 26# different versions of software. Since the clock levels are not necessarily 27# indicative of real world behavior, this should **never** be used to compare 28# performance between different device models. 29 30# Fun notes for maintaining this file: 31# `expr` can deal with ints > INT32_MAX, but if compares cannot. This is why we use MHz. 32# `expr` can sometimes evaluate right-to-left. This is why we use parens. 33# Everything below the initial host-check isn't bash - Android uses mksh 34# mksh allows `\n` in an echo, bash doesn't 35# can't use `awk` 36 37CPU_TARGET_FREQ_PERCENT=50 38GPU_TARGET_FREQ_PERCENT=50 39 40if [ "`command -v getprop`" == "" ]; then 41 if [ -n "`command -v adb`" ]; then 42 echo "" 43 echo "Pushing $0 and running it on device..." 44 dest=/data/local/tmp/`basename $0` 45 adb push $0 ${dest} 46 adb shell ${dest} 47 adb shell rm ${dest} 48 exit 49 else 50 echo "Could not find adb. Options are:" 51 echo " 1. Ensure adb is on your \$PATH" 52 echo " 2. Use './gradlew lockClocks'" 53 echo " 3. Manually adb push this script to your device, and run it there" 54 exit -1 55 fi 56fi 57 58# require root 59if [ "`id -u`" -ne "0" ]; then 60 echo "Not running as root, cannot lock clocks, aborting" 61 exit -1 62fi 63 64DEVICE=`getprop ro.product.device` 65MODEL=`getprop ro.product.model` 66 67# Find CPU max frequency, and lock big cores to an available frequency 68# that's >= $CPU_TARGET_FREQ_PERCENT% of max. Disable other cores. 69function_lock_cpu() { 70 CPU_BASE=/sys/devices/system/cpu 71 GOV=cpufreq/scaling_governor 72 73 # Find max CPU freq, and associated list of available freqs 74 cpuMaxFreq=0 75 cpuAvailFreqCmpr=0 76 cpuAvailFreq=0 77 enableIndices='' 78 disableIndices='' 79 cpu=0 80 while [ -f ${CPU_BASE}/cpu${cpu}/online ]; do 81 # enable core, so we can find its frequencies 82 echo 1 > ${CPU_BASE}/cpu${cpu}/online 83 84 maxFreq=`cat ${CPU_BASE}/cpu$cpu/cpufreq/cpuinfo_max_freq` 85 availFreq=`cat ${CPU_BASE}/cpu$cpu/cpufreq/scaling_available_frequencies` 86 availFreqCmpr=${availFreq// /-} 87 88 if [ ${maxFreq} -gt ${cpuMaxFreq} ]; then 89 # new highest max freq, look for cpus with same max freq and same avail freq list 90 cpuMaxFreq=${maxFreq} 91 cpuAvailFreq=${availFreq} 92 cpuAvailFreqCmpr=${availFreqCmpr} 93 94 if [ -z ${disableIndices} ]; then 95 disableIndices="$enableIndices" 96 else 97 disableIndices="$disableIndices $enableIndices" 98 fi 99 enableIndices=${cpu} 100 elif [ ${maxFreq} == ${cpuMaxFreq} ] && [ ${availFreqCmpr} == ${cpuAvailFreqCmpr} ]; then 101 enableIndices="$enableIndices $cpu" 102 else 103 disableIndices="$disableIndices $cpu" 104 fi 105 cpu=$(($cpu + 1)) 106 done 107 108 # Chose a frequency to lock to that's >= $CPU_TARGET_FREQ_PERCENT% of max 109 # (below, 100M = 1K for KHz->MHz * 100 for %) 110 TARGET_FREQ_MHZ=`expr \( ${cpuMaxFreq} \* ${CPU_TARGET_FREQ_PERCENT} \) \/ 100000` 111 chosenFreq=0 112 for freq in ${cpuAvailFreq}; do 113 freqMhz=`expr ${freq} \/ 1000` 114 if [ ${freqMhz} -ge ${TARGET_FREQ_MHZ} ]; then 115 chosenFreq=${freq} 116 break 117 fi 118 done 119 120 # enable 'big' CPUs 121 for cpu in ${enableIndices}; do 122 freq=${CPU_BASE}/cpu$cpu/cpufreq 123 124 echo 1 > ${CPU_BASE}/cpu${cpu}/online 125 echo userspace > ${CPU_BASE}/cpu${cpu}/${GOV} 126 echo ${chosenFreq} > ${freq}/scaling_max_freq 127 echo ${chosenFreq} > ${freq}/scaling_min_freq 128 echo ${chosenFreq} > ${freq}/scaling_setspeed 129 130 # validate setting the freq worked 131 obsCur=`cat ${freq}/scaling_cur_freq` 132 obsMin=`cat ${freq}/scaling_min_freq` 133 obsMax=`cat ${freq}/scaling_max_freq` 134 if [ obsCur -ne ${chosenFreq} ] || [ obsMin -ne ${chosenFreq} ] || [ obsMax -ne ${chosenFreq} ]; then 135 echo "Failed to set CPU$cpu to $chosenFreq Hz! Aborting..." 136 echo "scaling_cur_freq = $obsCur" 137 echo "scaling_min_freq = $obsMin" 138 echo "scaling_max_freq = $obsMax" 139 exit -1 140 fi 141 done 142 143 # disable other CPUs (Note: important to enable big cores first!) 144 for cpu in ${disableIndices}; do 145 echo 0 > ${CPU_BASE}/cpu${cpu}/online 146 done 147 148 echo "\nLocked CPUs ${enableIndices// /,} to $chosenFreq / $maxFreq KHz" 149 echo "Disabled CPUs ${disableIndices// /,}" 150} 151 152# If we have a Qualcomm GPU, find its max frequency, and lock to 153# an available frequency that's >= GPU_TARGET_FREQ_PERCENT% of max. 154function_lock_gpu_kgsl() { 155 if [ ! -d /sys/class/kgsl/kgsl-3d0/ ]; then 156 # not kgsl, abort 157 echo "\nCurrently don't support locking GPU clocks of $MODEL ($DEVICE)" 158 return -1 159 fi 160 if [ ${DEVICE} == "walleye" ] || [ ${DEVICE} == "taimen" ]; then 161 # Workaround crash 162 echo "\nUnable to lock GPU clocks of $MODEL ($DEVICE)" 163 return -1 164 fi 165 166 GPU_BASE=/sys/class/kgsl/kgsl-3d0 167 168 gpuMaxFreq=0 169 gpuAvailFreq=`cat $GPU_BASE/devfreq/available_frequencies` 170 for freq in ${gpuAvailFreq}; do 171 if [ ${freq} -gt ${gpuMaxFreq} ]; then 172 gpuMaxFreq=${freq} 173 fi 174 done 175 176 # (below, 100M = 1M for MHz * 100 for %) 177 TARGET_FREQ_MHZ=`expr \( ${gpuMaxFreq} \* ${GPU_TARGET_FREQ_PERCENT} \) \/ 100000000` 178 179 chosenFreq=${gpuMaxFreq} 180 index=0 181 chosenIndex=0 182 for freq in ${gpuAvailFreq}; do 183 freqMhz=`expr ${freq} \/ 1000000` 184 if [ ${freqMhz} -ge ${TARGET_FREQ_MHZ} ] && [ ${chosenFreq} -ge ${freq} ]; then 185 # note avail freq are generally in reverse order, so we don't break out of this loop 186 chosenFreq=${freq} 187 chosenIndex=${index} 188 fi 189 index=$(($index + 1)) 190 done 191 lastIndex=$(($index - 1)) 192 193 firstFreq=`echo $gpuAvailFreq | cut -d" " -f1` 194 195 if [ ${gpuMaxFreq} != ${firstFreq} ]; then 196 # pwrlevel is index of desired freq among available frequencies, from highest to lowest. 197 # If gpuAvailFreq appears to be in-order, reverse the index 198 chosenIndex=$(($lastIndex - $chosenIndex)) 199 fi 200 201 echo 0 > ${GPU_BASE}/bus_split 202 echo 1 > ${GPU_BASE}/force_clk_on 203 echo 10000 > ${GPU_BASE}/idle_timer 204 205 echo performance > ${GPU_BASE}/devfreq/governor 206 207 # NOTE: we store in min/max twice, because we don't know if we're increasing 208 # or decreasing, and it's invalid to try and set min > max, or max < min 209 echo ${chosenFreq} > ${GPU_BASE}/devfreq/min_freq 210 echo ${chosenFreq} > ${GPU_BASE}/devfreq/max_freq 211 echo ${chosenFreq} > ${GPU_BASE}/devfreq/min_freq 212 echo ${chosenFreq} > ${GPU_BASE}/devfreq/max_freq 213 echo ${chosenIndex} > ${GPU_BASE}/min_pwrlevel 214 echo ${chosenIndex} > ${GPU_BASE}/max_pwrlevel 215 echo ${chosenIndex} > ${GPU_BASE}/min_pwrlevel 216 echo ${chosenIndex} > ${GPU_BASE}/max_pwrlevel 217 218 obsCur=`cat ${GPU_BASE}/devfreq/cur_freq` 219 obsMin=`cat ${GPU_BASE}/devfreq/min_freq` 220 obsMax=`cat ${GPU_BASE}/devfreq/max_freq` 221 if [ obsCur -ne ${chosenFreq} ] || [ obsMin -ne ${chosenFreq} ] || [ obsMax -ne ${chosenFreq} ]; then 222 echo "Failed to set GPU to $chosenFreq Hz! Aborting..." 223 echo "cur_freq = $obsCur" 224 echo "min_freq = $obsMin" 225 echo "max_freq = $obsMax" 226 echo "index = $chosenIndex" 227 exit -1 228 fi 229 echo "\nLocked GPU to $chosenFreq / $gpuMaxFreq Hz" 230} 231 232# kill processes that manage thermals / scaling 233stop thermal-engine 234stop perfd 235stop vendor.thermal-engine 236stop vendor.perfd 237 238function_lock_cpu 239 240function_lock_gpu_kgsl 241 242# Memory bus - hardcoded per-device for now 243if [ ${DEVICE} == "marlin" ] || [ ${DEVICE} == "sailfish" ]; then 244 echo 13763 > /sys/class/devfreq/soc:qcom,gpubw/max_freq 245else 246 echo "\nUnable to lock memory bus of $MODEL ($DEVICE)." 247fi 248 249echo "\n$DEVICE clocks have been locked - to reset, reboot the device\n"