3d033d9ba9fe98450a98773e67eef0c87c3b1bb6
[kernel-power] / kernel-power-settings / kernel-config
1 #!/bin/sh
2 # kernel configuration script for power user kernel
3 # (c) Copyright 2010 by Thomas Tanner <maemo@tannerlab.com>
4 # licensed under GPLv3
5 # version 0.3 (16. May 2010)
6
7 if test $# -eq 0; then
8     echo "$0 command [options]"
9     echo "commands:"
10     echo "  show        - show current settings"
11     echo "  load <file> - load settings from file"
12     echo "  save <file> - save settings to file (abs. path or filename in /home/user/.kernel)"
13     echo "  default [<file>] - set file or the current settings as default settings"
14     echo "  limits min max - set the frequency limits ('-' keeps the current setting)"
15     echo "  lock freq [volt] [dsp] - lock CPU at frequency with specific settings"
16     echo "  unlock       - unlock CPU frequency"
17     echo "filenames: absolute path or filename in search path or none=defaults"
18     echo "search path: .,/home/user/.kernel,/usr/share/kernel-power-settings/"
19     exit 1
20 fi
21 if test "`id -u`" -ne 0; then
22     sudo $0 $* # run as root
23     exit $?
24 fi
25
26 cfr=/sys/devices/system/cpu/cpu0/cpufreq
27 cfd=$cfr/ondemand
28 cfc=$cfr/conservative
29 pwr=/sys/power
30
31 if test -f $pwr/vdd1_opps_vsel -a -f $pwr/dsp_opps_rate; then :
32 else
33     echo This kernel version `uname -r` is not supported
34     echo Please make sure that kernel-power is installed and running.
35     echo If you have just installed the kernel, you need to shutdown and boot to activate it.
36     echo To reinstall the power user kernel run:
37     echo \'apt-get install --reinstall kernel-power kernel-power-flasher\'
38     exit 1
39 fi
40
41 allfreq=
42 for f in `cat $cfr/scaling_available_frequencies`; do
43     allfreq="$f $allfreq"
44 done
45 vsel=`cat $pwr/vdd1_opps_vsel` 
46 rate=`cat $pwr/dsp_opps_rate` 
47
48 cmd=$1
49 test "$cmd" = setdefault && cmd=default # old name
50 case " show load save default limits lock unlock " in
51 *" $cmd "*) ;;
52 *)  echo "invalid command $cmd";  exit 1 ;;
53 esac
54 arg=
55 shift
56 if test "$cmd" = unlock; then
57     echo 'unlocking frequency. reset to defaults'
58     cmd=loaddef
59 fi
60 if test "$cmd" = default && test $# -eq 0; then
61     echo 'saving current settings as defaults'
62     arg=/etc/default/kernel-power
63     cmd=savedef
64 fi
65
66 popvsel() { curvsel=$1; shift; vsel="$*"; }
67 poprate() { currate=$1; shift; rate="$*"; }
68
69 case $cmd in
70 show|save|savedef)
71     minfreq=$((`cat $cfr/scaling_min_freq`/1000))
72     maxfreq=$((`cat $cfr/scaling_max_freq`/1000))
73     test $maxfreq = 599 && maxfreq=600
74     gov=`cat $cfr/scaling_governor`
75     avoid=
76     test $gov = ondemand && avoid=`cat $cfd/avoid_frequencies`
77     freqs=
78     for f in $allfreq; do
79         popvsel $vsel
80         poprate $rate
81         case " $avoid " in *" $f "*) ;;
82         *) freqs="$freqs$((f/1000)):$curvsel,$currate " ;;
83         esac
84     done
85     if test $cmd = show; then
86         echo "current kernel configuration:"
87         echo "current frequency:" $((`cat $cfr/scaling_cur_freq`/1000))
88         echo -n "supported frequencies: "
89         for f in $allfreq; do echo -n "$((f/1000)) "; done
90         echo
91         echo "min. frequency:" $minfreq
92         echo "max. frequency:" $maxfreq
93         echo -n "avoid frequencies: "
94         for f in $avoid; do echo -n "$((f/1000)) "; done
95         echo
96         echo "active frequencies: $freqs"
97         echo "SmartReflex" "VDD1=`cat $pwr/sr_vdd1_autocomp`, VDD2=`cat $pwr/sr_vdd2_autocomp`"
98         echo -n "governor $gov:"
99         if test $gov = ondemand; then
100             echo -n " ignore nice load=" `cat $cfd/ignore_nice_load` 
101             echo -n ", up threshold=" `cat $cfd/up_threshold`
102             echo -n ", sampling rate=" `cat $cfd/sampling_rate`
103             echo ", powersave bias=" `cat $cfd/powersave_bias`
104         else
105             echo
106         fi
107     else
108         test $cmd = save && arg=$1
109         if test -z "$arg"; then
110             echo "filename argument is mssing"
111             exit 1
112         fi
113         if test `basename $arg` = $arg; then
114             u=/home/user/.kernel
115             arg=$u/$arg
116             if test ! -d $u; then
117                 mkdir -p $u
118                 chown user.users $u
119             fi
120             touch $arg
121             chown user.users $arg
122         fi
123         rm -f $arg
124         echo "saving to $arg"
125         echo "# kernel configuration file generated by $0" > $arg
126         echo "MINFREQ=$minfreq" >> $arg
127         echo "MAXFREQ=$maxfreq" >> $arg
128         echo "FREQS=\"$freqs\"" >> $arg
129         echo "SMARTREFLEX_VDD1=`cat $pwr/sr_vdd1_autocomp`" >> $arg
130         echo "SMARTREFLEX_VDD2=`cat $pwr/sr_vdd2_autocomp`" >> $arg
131         echo "GOVERNOR=$gov" >> $arg
132         if test $gov = ondemand; then
133             echo "IGNORE_NICE_LOAD=`cat $cfd/ignore_nice_load`" >> $arg
134             echo "UP_THRESHOLD=`cat $cfd/up_threshold`" >> $arg
135             echo "SAMPLING_RATE=`cat $cfd/sampling_rate`" >> $arg
136             echo "POWERSAVE_BIAS=`cat $cfd/powersave_bias`" >> $arg
137         fi
138     fi
139     ;;
140 load|loaddef)
141     test $cmd = loaddef || arg=$1
142     if test -z "$arg"; then
143         arg=/etc/default/kernel-power
144         test -f $arg || arg=/usr/share/kernel-power-settings/default
145     fi
146     if test `basename $arg` = $arg; then # not absolute
147         for p in . /home/user/.kernel /usr/share/kernel-power-settings; do
148             test -f $p/$arg && arg=$p/$arg && break
149         done
150     fi
151     if test ! -f "$arg"; then
152         echo "file not found $arg"
153         exit 1
154     fi
155     echo "loading $arg"
156     source $arg
157     if test -n "$VDD1_OPPS_VSEL" -o -n "$DSP_OPPS_RATE"; then
158         echo "warning: old configuration format detected. please save in the new format."
159         if test -n "$MAX_FREQ"; then
160             test $MAX_FREQ = 600000 && MAX_FREQ=599000
161             echo $MAX_FREQ > $cfr/scaling_max_freq
162         fi
163         test -n "$MIN_FREQ" && echo $MIN_FREQ > $cfr/scaling_min_freq
164         test -n "$MAX_FREQ" && echo $MAX_FREQ > $cfr/scaling_max_freq
165         test -n "$VDD1_OPPS_VSEL" && echo $VDD1_OPPS_VSEL > $pwr/vdd1_opps_vsel
166         test -n "$DSP_OPPS_RATE" && echo $DSP_OPPS_RATE > $pwr/dsp_opps_rate
167         test -n "$SMARTREFLEX_VDD1" && echo $SMARTREFLEX_VDD1 > $pwr/sr_vdd1_autocomp
168         test -n "$SMARTREFLEX_VDD2" && echo $SMARTREFLEX_VDD2 > $pwr/sr_vdd2_autocomp
169         test -n "$IGNORE_NICE_LOAD" && echo $IGNORE_NICE_LOAD > $cfd/ignore_nice_load
170         test -n "$UP_THRESHOLD" && echo $UP_THRESHOLD > $cfd/up_threshold
171         test -n "$SAMPLING_RATE" && echo $SAMPLING_RATE > $cfd/sampling_rate
172         exit 1
173     fi
174     active=
175     minfreq=
176     maxfreq=
177     for f in $FREQS; do
178         freq=`echo $f | cut -d: -f1`
179         f=`echo $f | cut -d: -f2`
180         volt=`echo $f | cut -d, -f1`
181         dsp=`echo $f | cut -d, -f2`
182         if test ! $freq = 0; then
183             test -z "$minfreq" -o "$freq" -lt "$minfreq" && minfreq=$freq
184             test -z "$maxfreq" -o "$freq" -gt "$maxfreq" && maxfreq=$freq
185             freq=$((freq*1000))
186             case " $allfreq " in *" $freq "*) ;;
187             *)  echo warning: $freq not supported; continue ;;
188             esac
189             active="$active $freq"
190         fi
191         test -z "$volt" && test -z "$dsp" && continue
192         tvsel=
193         trate=
194         for fr in $allfreq; do
195             if test $fr = $freq; then
196                 popvsel $vsel
197                 poprate $rate
198                 test -z "$volt" && volt=$curvsel
199                 test -z "$dsp" && dsp=$currate
200                 tvsel="$tvsel $volt $vsel"
201                 trate="$trate $dsp $rate"
202                 break
203             fi
204             popvsel $vsel
205             tvsel="$tvsel $curvsel"
206             poprate $rate
207             trate="$trate $currate"
208         done
209         vsel=$tvsel
210         rate=$trate
211     done
212     test -z "$GOVERNOR" && GOVERNOR=ondemand
213     test -n "$MINFREQ" && minfreq=$MINFREQ
214     test -n "$MAXFREQ" && maxfreq=$MAXFREQ
215     test "$minfreq" -gt 100000 && minfreq=$((minfreq/1000))
216     test "$maxfreq" -gt 100000 && maxfreq=$((maxfreq/1000))
217     avoid=
218     for f in $allfreq; do
219         if test "$f" -lt $((minfreq*1000)); then
220             avoid="$avoid $f"
221             continue
222         fi
223         case " $active " in *" $f "*) ;;
224         *) avoid="$avoid $f" ;;
225         esac
226     done
227     echo $GOVERNOR > $cfr/scaling_governor
228     if test $GOVERNOR = ondemand; then
229         echo $avoid > $cfd/avoid_frequencies
230         test -n "$IGNORE_NICE_LOAD" && echo $IGNORE_NICE_LOAD > $cfd/ignore_nice_load
231         test -n "$UP_THRESHOLD" && echo $UP_THRESHOLD > $cfd/up_threshold
232         test -n "$SAMPLING_RATE" && echo $SAMPLING_RATE > $cfd/sampling_rate
233         test -n "$POWERSAVE_BIAS" && echo $POWERSAVE_BIAS > $cfd/powersave_bias
234     fi
235     echo $vsel > $pwr/vdd1_opps_vsel
236     echo $rate > $pwr/dsp_opps_rate
237     test $maxfreq = 600 && maxfreq=599
238     echo $((maxfreq*1000)) > $cfr/scaling_max_freq
239     echo $((minfreq*1000)) > $cfr/scaling_min_freq
240     echo $((maxfreq*1000)) > $cfr/scaling_max_freq
241     test -n "$SMARTREFLEX_VDD1" && echo $SMARTREFLEX_VDD1 > $pwr/sr_vdd1_autocomp
242     test -n "$SMARTREFLEX_VDD2" && echo $SMARTREFLEX_VDD2 > $pwr/sr_vdd2_autocomp
243     echo "successfully loaded."
244     ;;
245 default)
246     arg=$1
247     if test -z "$arg"; then
248         echo "filename missing"
249         exit 1
250     fi
251     if test `basename $arg` = $arg; then # not absolute
252         for p in . /home/user/.kernel /usr/share/kernel-power-settings; do
253             test -f $p/$arg && arg=$p/$arg && break
254         done
255     fi
256     def=/etc/default/kernel-power
257     rm -f $def
258     case $arg in 
259     /usr/share/kernel-power-settings/*) ln -s $arg $def ;;
260     *) cp $arg $def ;;
261     esac
262     echo "defaults set to $arg"
263     ;;
264 limits)
265     minfreq=$1
266     maxfreq=$2
267     if test "x$minfreq" = x -o "x$maxfreq" = x; then
268         echo "frequency limit arguments missing"
269         exit 1
270     fi
271     test "x$minfreq" = "x-" && minfreq=$((`cat $cfr/scaling_min_freq`/1000))
272     test "x$maxfreq" = "x-" && maxfreq=$((`cat $cfr/scaling_max_freq`/1000))
273     limits="$minfreq,$maxfreq"
274     minfreq=$((minfreq*1000))
275     maxfreq=$((maxfreq*1000))
276     case " $allfreq " in *" $minfreq "*) ;;
277     *) echo "invalid lower limit $1"; exit 1; ;;
278     esac
279     case " $allfreq " in *" $maxfreq "*) ;;
280     *) echo "invalid upper limit $2"; exit 1; ;;
281     esac
282     if test $minfreq -gt $maxfreq; then
283         echo "minimum must not be greater than maximum: $limits"
284         exit 1
285     fi
286     test $maxfreq = 600000 && maxfreq=599000
287     echo $maxfreq > $cfr/scaling_max_freq
288     echo $minfreq > $cfr/scaling_min_freq
289     echo $maxfreq > $cfr/scaling_max_freq
290     echo "the limits were set to [$limits]"
291     ;;
292 lock)
293     arg=$1
294     altfreq=
295     for f in $allfreq; do
296         test "$f" = "$arg" && continue
297         altfreq=$f
298         break
299     done
300     vsel=
301     dsp=
302     freq=$((arg*1000))
303     ifreq=
304     i=1
305     avoid=
306     for f in $allfreq; do
307         i=$((i+1))
308         if test $f = $freq; then
309             ifreq=$i
310             break
311         fi
312         avoid="$avoid $f"
313     done
314     if test -z "ifreq"; then
315         echo invalid frequency $freq
316         exit 1
317     fi
318     echo userspace > $cfr/scaling_governor 
319     echo $altfreq > $cfr/scaling_setspeed # temporarily set alternative frequencies
320     volt=$2
321     if test -n "$volt"; then
322         i=0
323         vsel=
324         for v in `cat $pwr/vdd1_opps_vsel`; do
325             i=$((i+1))
326             test $i = $ifreq && v=$volt
327             vsel="$vsel $v"
328         done
329         echo $vsel > $pwr/vdd1_opps_vsel
330     fi
331     dsp=$3
332     if test -n "$dsp"; then
333         i=0
334         dsp=
335         for r in `cat $pwr/dsp_opps_rate`; do
336             i=$((i+1))
337             test $i = $ifreq && r=$dsp
338             dsp="$dsp $r"
339         done
340         echo $dsp > $pwr/dsp_opps_rate
341     fi
342     echo locking frequency $freq
343     echo ondemand > $cfr/scaling_governor 
344     echo $avoid > $cfd/avoid_frequencies # avoid all other freqs
345     maxfreq=$freq
346     test $maxfreq = 600000 && maxfreq=599000
347     # min after max? kernel docs are wrong?
348     echo $maxfreq > $cfr/scaling_max_freq
349     echo $freq > $cfr/scaling_min_freq
350     echo $maxfreq > $cfr/scaling_max_freq
351     ;;
352 esac
353 exit 0