1 #!/bin/bash 2 3 # defines 4 FREQ=0 #percent 5 SERVICES=(perfd thermal-engine mpdecision) 6 DIR="/sys/devices/system/cpu" 7 8 9 ###################### SETUP ###################### 10 11 # helper functions 12 fileexists() { 13 [ `adb shell "[ -f $1 ] && echo 1 || echo 0" | tr -d '\r'` -eq 1 ] 14 } 15 getprop() { 16 if fileexists $1; then 17 echo `adb shell cat $1 | tr -d '\r'` 18 else 19 echo "FILE $1 NOT FOUND" 20 fi 21 } 22 setprop() { 23 if fileexists $1; then 24 adb shell "echo -n $2 > $1" 25 else 26 echo "FILE $1 NOT FOUND" 27 fi 28 } 29 30 # use passed in percent frequency 31 if [[ $# -eq 1 ]]; then 32 FREQ=$1 33 fi 34 35 # switch to root 36 if [[ "`adb shell id | tr -d '\r' | awk -F'[()]' '{print $2}'`" != "root" ]]; then 37 adb root 38 adb wait-for-device 39 fi 40 41 # device name 42 echo Device: `adb shell getprop ro.product.model` 43 echo 44 45 # collect all cores 46 cores=`adb shell ls /sys/devices/system/cpu/ | grep cpu[0-9].* | tr -d '\r'` 47 48 # disable GPU 49 adb shell setprop debug.rs.default-CPU-driver 1 50 51 52 ###################### CONFIGURE ###################### 53 54 # freeze system 55 for service in ${SERVICES[@]}; do 56 adb shell stop $service 57 done 58 59 # set frequencies 60 declare -A selectedFreq 61 for core in $cores; do 62 63 # turn on core if possible 64 if fileexists $DIR/$core/online; then 65 adb shell "echo -n 1 > $DIR/$core/online" 66 fi 67 68 # get available frequencies in sorted order 69 if fileexists $DIR/$core/cpufreq/scaling_available_frequencies; then 70 frequencies=(`getprop $DIR/$core/cpufreq/scaling_available_frequencies`) 71 elif fileexists $DIR/$core/cpufreq/stats/time_in_state; then 72 frequencies=(`adb shell cat $DIR/$core/cpufreq/stats/time_in_state | cut -f1 -d " " | tr -d '\r'`) 73 fi 74 frequencies=(`printf "%s\n" "${frequencies[@]}" | sort -n`) 75 76 # find target frequency based on frequency percentage 77 minFreq=${frequencies[0]} 78 maxFreq=${frequencies[-1]} 79 targetFreq=$(( FREQ * ( maxFreq - minFreq ) / 100 + minFreq )) 80 81 # find closest frequency 82 freq=`printf "%d\n" "${frequencies[@]}" | awk -v c=${frequencies[0]} -v t=$targetFreq 'BEGIN{d=$0-t;if(d<0)d=-d;l=d}{d=$0-t;if(d<0)d=-d;if(d<l){l=d;c=$0}}END{print c}'` 83 selectedFreq[$core]=$freq 84 85 # set frequency 86 adb shell "echo -n $freq > $DIR/$core/cpufreq/scaling_min_freq" 87 adb shell "echo -n $freq > $DIR/$core/cpufreq/scaling_max_freq" 88 89 done 90 91 92 # keep trying until the frequencies are properly set 93 while true; do 94 95 # check to see if frequencies are correct 96 CORRECT=true 97 for core in $cores; do 98 if fileexists $DIR/$core/online && [ `getprop $DIR/$core/online` -eq 0 ]; then 99 echo "$core is offline" 100 CORRECT=false 101 else 102 if fileexists $DIR/$core/cpufreq/scaling_cur_freq; then 103 frequency=`getprop $DIR/$core/cpufreq/scaling_cur_freq` 104 if [ $frequency != ${selectedFreq[$core]} ]; then 105 echo "$core: $frequency != ${selectedFreq[$core]}" 106 CORRECT=false 107 fi 108 else 109 echo "$core is offline" 110 CORRECT=false 111 fi 112 fi 113 done 114 115 # finished 116 if [ $CORRECT == "true" ]; then 117 break 118 fi 119 120 # display 121 echo "Frequencies not properly set. Trying again..." 122 123 # unfreeze system 124 for service in ${SERVICES[@]}; do 125 adb shell start $service 126 done 127 128 # wait for changes to be made 129 sleep 1 130 131 # freeze system 132 for service in ${SERVICES[@]}; do 133 adb shell stop $service 134 done 135 136 # try resetting the values (only really needed for Nexus 7 for some reason) 137 for core in $cores; do 138 if fileexists $DIR/$core/online; then 139 adb shell "echo -n 1 > $DIR/$core/online" 140 fi 141 adb shell "echo -n $freq > $DIR/$core/cpufreq/scaling_min_freq" 142 adb shell "echo -n $freq > $DIR/$core/cpufreq/scaling_max_freq" 143 done 144 145 sleep 1 146 147 done 148 149 # display 150 for core in $cores; do 151 echo "$core successfully set to ${selectedFreq[$core]}" 152 done 153 154 155