settings 0.8
[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.2 (7. 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 pwr=/sys/power
29
30 echo ondemand > $cfr/scaling_governor
31 if test -f $cfd/avoid_frequencies -a -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     avoid=`cat $cfd/avoid_frequencies`
75     freqs=
76     for f in 0 $allfreq; do
77         popvsel $vsel
78         poprate $rate
79         case " $avoid " in *" $f "*) ;;
80         *) freqs="$freqs$((f/1000)):$curvsel,$currate " ;;
81         esac
82     done
83     if test $cmd = show; then
84         echo "current kernel configuration:"
85         echo "current frequency:" $((`cat $cfr/scaling_cur_freq`/1000))
86         echo -n "supported frequencies: "
87         for f in $allfreq; do echo -n "$((f/1000)) "; done
88         echo
89         echo "min. frequency:" $minfreq
90         echo "max. frequency:" $maxfreq
91         echo -n "avoid frequencies: "
92         for f in $avoid; do echo -n "$((f/1000)) "; done
93         echo
94         echo "active frequencies: $freqs"
95         echo "SmartReflex" "VDD1=`cat $pwr/sr_vdd1_autocomp`, VDD2=`cat $pwr/sr_vdd2_autocomp`"
96         echo -n "ondemand: ignore nice load=" `cat $cfd/ignore_nice_load` 
97         echo -n ", up threshold=" `cat $cfd/up_threshold`
98         echo ", sampling rate=" `cat $cfd/sampling_rate`
99     else
100         test $cmd = save && arg=$1
101         if test -z "$arg"; then
102             echo "filename argument is mssing"
103             exit 1
104         fi
105         if test `basename $arg` = $arg; then
106             u=/home/user/.kernel
107             arg=$u/$arg
108             if test ! -d $u; then
109                 mkdir -p $u
110                 chown user.users $u
111             fi
112             touch $arg
113             chown user.users $arg
114         fi
115         rm -f $arg
116         echo "saving to $arg"
117         echo "# kernel configuration file generated by $0" > $arg
118         echo "MINFREQ=$minfreq" >> $arg
119         echo "MAXFREQ=$maxfreq" >> $arg
120         echo "FREQS=\"$freqs\"" >> $arg
121         echo "SMARTREFLEX_VDD1=`cat $pwr/sr_vdd1_autocomp`" >> $arg
122         echo "SMARTREFLEX_VDD2=`cat $pwr/sr_vdd2_autocomp`" >> $arg
123         echo "IGNORE_NICE_LOAD=`cat $cfd/ignore_nice_load`" >> $arg
124         echo "UP_THRESHOLD=`cat $cfd/up_threshold`" >> $arg
125         echo "SAMPLING_RATE=`cat $cfd/sampling_rate`" >> $arg
126     fi
127     ;;
128 load|loaddef)
129     test $cmd = loaddef || arg=$1
130     if test -z "$arg"; then
131         arg=/etc/default/kernel-power
132         test -f $arg || arg=/usr/share/kernel-power-settings/default
133     fi
134     if test `basename $arg` = $arg; then # not absolute
135         for p in . /home/user/.kernel /usr/share/kernel-power-settings; do
136             test -f $p/$arg && arg=$p/$arg && break
137         done
138     fi
139     if test ! -f "$arg"; then
140         echo "file not found $arg"
141         exit 1
142     fi
143     echo "loading $arg"
144     source $arg
145     if test -n "$VDD1_OPPS_VSEL" -o -n "$DSP_OPPS_RATE"; then
146         echo "warning: old configuration format detected. please save in the new format."
147         if test -n "$MAX_FREQ"; then
148             test $MAX_FREQ = 600000 && MAX_FREQ=599000
149             echo $MAX_FREQ > $cfr/scaling_max_freq
150         fi
151         test -n "$MIN_FREQ" && echo $MIN_FREQ > $cfr/scaling_min_freq
152         test -n "$MAX_FREQ" && echo $MAX_FREQ > $cfr/scaling_max_freq
153         test -n "$VDD1_OPPS_VSEL" && echo $VDD1_OPPS_VSEL > $pwr/vdd1_opps_vsel
154         test -n "$DSP_OPPS_RATE" && echo $DSP_OPPS_RATE > $pwr/dsp_opps_rate
155         test -n "$SMARTREFLEX_VDD1" && echo $SMARTREFLEX_VDD1 > $pwr/sr_vdd1_autocomp
156         test -n "$SMARTREFLEX_VDD2" && echo $SMARTREFLEX_VDD2 > $pwr/sr_vdd2_autocomp
157         test -n "$IGNORE_NICE_LOAD" && echo $IGNORE_NICE_LOAD > $cfd/ignore_nice_load
158         test -n "$UP_THRESHOLD" && echo $UP_THRESHOLD > $cfd/up_threshold
159         test -n "$SAMPLING_RATE" && echo $SAMPLING_RATE > $cfd/sampling_rate
160         exit 1
161     fi
162     active=
163     minfreq=
164     maxfreq=
165     for f in $FREQS; do
166         freq=`echo $f | cut -d: -f1`
167         f=`echo $f | cut -d: -f2`
168         volt=`echo $f | cut -d, -f1`
169         dsp=`echo $f | cut -d, -f2`
170         if test ! $freq = 0; then
171             test -z "$minfreq" -o "$freq" -lt "$minfreq" && minfreq=$freq
172             test -z "$maxfreq" -o "$freq" -gt "$maxfreq" && maxfreq=$freq
173             freq=$((freq*1000))
174             case " $allfreq " in *" $freq "*) ;;
175             *)  echo warning: $freq not supported; continue ;;
176             esac
177             active="$active $freq"
178         fi
179         test -z "$volt" && test -z "$dsp" && continue
180         tvsel=
181         trate=
182         for fr in 0 $allfreq; do
183             if test $fr = $freq; then
184                 popvsel $vsel
185                 poprate $rate
186                 test -z "$volt" && volt=$curvsel
187                 test -z "$dsp" && dsp=$currate
188                 tvsel="$tvsel $volt $vsel"
189                 trate="$trate $dsp $rate"
190                 break
191             fi
192             popvsel $vsel
193             tvsel="$tvsel $curvsel"
194             poprate $rate
195             trate="$trate $currate"
196         done
197         vsel=$tvsel
198         rate=$trate
199     done
200     test -n "$MINFREQ" && minfreq=$MINFREQ
201     test -n "$MAXFREQ" && maxfreq=$MAXFREQ
202     test "$minfreq" -gt 100000 && minfreq=$((minfreq/1000))
203     test "$maxfreq" -gt 100000 && maxfreq=$((maxfreq/1000))
204     avoid=
205     for f in $allfreq; do
206         if test "$f" -lt $((minfreq*1000)); then
207             avoid="$avoid $f"
208             continue
209         fi
210         case " $active " in *" $f "*) ;;
211         *) avoid="$avoid $f" ;;
212         esac
213     done
214     echo $avoid > $cfd/avoid_frequencies
215     echo $vsel > $pwr/vdd1_opps_vsel
216     echo $rate > $pwr/dsp_opps_rate
217     test $maxfreq = 600 && maxfreq=599
218     echo $((maxfreq*1000)) > $cfr/scaling_max_freq
219     echo $((minfreq*1000)) > $cfr/scaling_min_freq
220     echo $((maxfreq*1000)) > $cfr/scaling_max_freq
221     test -n "$SMARTREFLEX_VDD1" && echo $SMARTREFLEX_VDD1 > $pwr/sr_vdd1_autocomp
222     test -n "$SMARTREFLEX_VDD2" && echo $SMARTREFLEX_VDD2 > $pwr/sr_vdd2_autocomp
223     test -n "$IGNORE_NICE_LOAD" && echo $IGNORE_NICE_LOAD > $cfd/ignore_nice_load
224     test -n "$UP_THRESHOLD" && echo $UP_THRESHOLD > $cfd/up_threshold
225     test -n "$SAMPLING_RATE" && echo $SAMPLING_RATE > $cfd/sampling_rate
226     echo "successfully loaded."
227     ;;
228 default)
229     arg=$1
230     if test -z "$arg"; then
231         echo "filename missing"
232         exit 1
233     fi
234     if test `basename $arg` = $arg; then # not absolute
235         for p in . /home/user/.kernel /usr/share/kernel-power-settings; do
236             test -f $p/$arg && arg=$p/$arg && break
237         done
238     fi
239     def=/etc/default/kernel-power
240     rm -f $def
241     case $arg in 
242     /usr/share/kernel-power-settings/*) ln -s $arg $def ;;
243     *) cp $arg $def ;;
244     esac
245     echo "defaults set to $arg"
246     ;;
247 limits)
248     minfreq=$1
249     maxfreq=$2
250     if test "x$minfreq" = x -o "x$maxfreq" = x; then
251         echo "frequency limit arguments missing"
252         exit 1
253     fi
254     test "x$minfreq" = "x-" && minfreq=$((`cat $cfr/scaling_min_freq`/1000))
255     test "x$maxfreq" = "x-" && maxfreq=$((`cat $cfr/scaling_max_freq`/1000))
256     limits="$minfreq,$maxfreq"
257     minfreq=$((minfreq*1000))
258     maxfreq=$((maxfreq*1000))
259     case " $allfreq " in *" $minfreq "*) ;;
260     *) echo "invalid lower limit $1"; exit 1; ;;
261     esac
262     case " $allfreq " in *" $maxfreq "*) ;;
263     *) echo "invalid upper limit $2"; exit 1; ;;
264     esac
265     if test $minfreq -gt $maxfreq; then
266         echo "minimum must not be greater than maximum: $limits"
267         exit 1
268     fi
269     test $maxfreq = 600000 && maxfreq=599000
270     echo $maxfreq > $cfr/scaling_max_freq
271     echo $minfreq > $cfr/scaling_min_freq
272     echo $maxfreq > $cfr/scaling_max_freq
273     echo "the limits were set to [$limits]"
274     ;;
275 lock)
276     arg=$1
277     altfreq=
278     for f in $allfreq; do
279         test "$f" = "$arg" && continue
280         altfreq=$f
281         break
282     done
283     vsel=
284     dsp=
285     freq=$((arg*1000))
286     ifreq=
287     i=1
288     avoid=
289     for f in $allfreq; do
290         i=$((i+1))
291         if test $f = $freq; then
292             ifreq=$i
293             break
294         fi
295         avoid="$avoid $f"
296     done
297     if test -z "ifreq"; then
298         echo invalid frequency $freq
299         exit 1
300     fi
301     echo userspace > $cfr/scaling_governor 
302     echo $altfreq > $cfr/scaling_setspeed # temporarily set alternative frequencies
303     volt=$2
304     if test -n "$volt"; then
305         i=0
306         vsel=
307         for v in `cat $pwr/vdd1_opps_vsel`; do
308             i=$((i+1))
309             test $i = $ifreq && v=$volt
310             vsel="$vsel $v"
311         done
312         echo $vsel > $pwr/vdd1_opps_vsel
313     fi
314     dsp=$3
315     if test -n "$dsp"; then
316         i=0
317         dsp=
318         for r in `cat $pwr/dsp_opps_rate`; do
319             i=$((i+1))
320             test $i = $ifreq && r=$dsp
321             dsp="$dsp $r"
322         done
323         echo $dsp > $pwr/dsp_opps_rate
324     fi
325     echo locking frequency $freq
326     echo ondemand > $cfr/scaling_governor 
327     echo $avoid > $cfd/avoid_frequencies # avoid all other freqs
328     maxfreq=$freq
329     test $maxfreq = 600000 && maxfreq=599000
330     # min after max? kernel docs are wrong?
331     echo $maxfreq > $cfr/scaling_max_freq
332     echo $freq > $cfr/scaling_min_freq
333     echo $maxfreq > $cfr/scaling_max_freq
334     ;;
335 esac
336 exit 0