1#!/bin/bash
2
3# defines
4FREQ=0 #percent
5SERVICES=(perfd thermal-engine mpdecision)
6DIR="/sys/devices/system/cpu"
7
8
9###################### SETUP ######################
10
11# helper functions
12fileexists() {
13  [ `adb shell "[ -f $1 ] && echo 1 || echo 0" | tr -d '\r'` -eq 1 ]
14}
15getprop() {
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}
22setprop() {
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
31if [[ $# -eq 1 ]]; then
32  FREQ=$1
33fi
34
35# switch to root
36if [[ "`adb shell id | tr -d '\r' | awk -F'[()]' '{print $2}'`" != "root" ]]; then
37  adb root
38  adb wait-for-device
39fi
40
41# device name
42echo Device: `adb shell getprop ro.product.model`
43echo
44
45# collect all cores
46cores=`adb shell ls /sys/devices/system/cpu/ | grep cpu[0-9].* | tr -d '\r'`
47
48# disable GPU
49adb shell setprop debug.rs.default-CPU-driver 1
50
51
52###################### CONFIGURE ######################
53
54# freeze system
55for service in ${SERVICES[@]}; do
56  adb shell stop $service
57done
58
59# set frequencies
60declare -A selectedFreq
61for 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
89done
90
91
92# keep trying until the frequencies are properly set
93while 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
147done
148
149# display
150for core in $cores; do
151  echo "$core successfully set to ${selectedFreq[$core]}"
152done
153
154
155