set-cpu-freq 3.7 KB

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