Home | History | Annotate | Download | only in scripts
      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 
     37 CPU_TARGET_FREQ_PERCENT=50
     38 GPU_TARGET_FREQ_PERCENT=50
     39 
     40 if [ "`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
     56 fi
     57 
     58 # require root
     59 if [ "`id -u`" -ne "0" ]; then
     60     echo "Not running as root, cannot lock clocks, aborting"
     61     exit -1
     62 fi
     63 
     64 DEVICE=`getprop ro.product.device`
     65 MODEL=`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.
     69 function_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.
    154 function_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
    233 stop thermal-engine
    234 stop perfd
    235 stop vendor.thermal-engine
    236 stop vendor.perfd
    237 
    238 function_lock_cpu
    239 
    240 function_lock_gpu_kgsl
    241 
    242 # Memory bus - hardcoded per-device for now
    243 if [ ${DEVICE} == "marlin" ] || [ ${DEVICE} == "sailfish" ]; then
    244     echo 13763 > /sys/class/devfreq/soc:qcom,gpubw/max_freq
    245 else
    246     echo "\nUnable to lock memory bus of $MODEL ($DEVICE)."
    247 fi
    248 
    249 echo "\n$DEVICE clocks have been locked - to reset, reboot the device\n"