version 0.6 of power-settings
[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         test -n "$MIN_FREQ" && echo $MIN_FREQ > $cfr/scaling_min_freq
148         test -n "$MAX_FREQ" && echo $MAX_FREQ > $cfr/scaling_max_freq
149         test -n "$VDD1_OPPS_VSEL" && echo $VDD1_OPPS_VSEL > $pwr/vdd1_opps_vsel
150         test -n "$DSP_OPPS_RATE" && echo $DSP_OPPS_RATE > $pwr/dsp_opps_rate
151         test -n "$SMARTREFLEX_VDD1" && echo $SMARTREFLEX_VDD1 > $pwr/sr_vdd1_autocomp
152         test -n "$SMARTREFLEX_VDD2" && echo $SMARTREFLEX_VDD2 > $pwr/sr_vdd2_autocomp
153         test -n "$IGNORE_NICE_LOAD" && echo $IGNORE_NICE_LOAD > $cfd/ignore_nice_load
154         test -n "$UP_THRESHOLD" && echo $UP_THRESHOLD > $cfd/up_threshold
155         test -n "$SAMPLING_RATE" && echo $SAMPLING_RATE > $cfd/sampling_rate
156         exit 1
157     fi
158     #echo $allfreq
159     #echo $vsel
160     #echo $rate
161     active=
162     minfreq=
163     maxfreq=
164     #echo $FREQS
165     for f in $FREQS; do
166         #echo processing $f
167         freq=`echo $f | cut -d: -f1`
168         f=`echo $f | cut -d: -f2`
169         volt=`echo $f | cut -d, -f1`
170         dsp=`echo $f | cut -d, -f2`
171         #echo freq $freq volt $volt dsp $dsp
172         if test ! $freq = 0; then
173             test -z "$minfreq" -o "$freq" -lt "$minfreq" && minfreq=$freq
174             test -z "$maxfreq" -o "$freq" -gt "$maxfreq" && maxfreq=$freq
175             freq=$((freq*1000))
176             case " $allfreq " in *" $freq "*) ;;
177             *)  echo warning: $freq not supported; continue ;;
178             esac
179             active="$active $freq"
180         fi
181         test -z "$volt" && test -z "$dsp" && continue
182         tvsel=
183         trate=
184         for fr in 0 $allfreq; do
185             if test $fr = $freq; then
186                 popvsel $vsel
187                 poprate $rate
188                 test -z "$volt" && volt=$curvsel
189                 test -z "$dsp" && dsp=$currate
190                 tvsel="$tvsel $volt $vsel"
191                 trate="$trate $dsp $rate"
192                 break
193             fi
194             popvsel $vsel
195             tvsel="$tvsel $curvsel"
196             poprate $rate
197             trate="$trate $currate"
198         done
199         vsel=$tvsel
200         rate=$trate
201         #echo $vsel
202     done
203     #echo vsel $vsel
204     #echo rate $rate
205     test -n "$MINFREQ" && minfreq=$MINFREQ
206     test -n "$MAXFREQ" && maxfreq=$MAXFREQ
207     test "$minfreq" -gt 100000 && minfreq=$((minfreq/1000))
208     test "$maxfreq" -gt 100000 && maxfreq=$((maxfreq/1000))
209     #echo $minfreq $maxfreq
210     avoid=
211     for f in $allfreq; do
212         if test "$f" -lt $((minfreq*1000)); then
213             avoid="$avoid $f"
214             continue
215         fi
216         case " $active " in *" $f "*) ;;
217         *) avoid="$avoid $f" ;;
218         esac
219     done
220     #echo $avoid
221     echo $avoid > $cfd/avoid_frequencies
222     echo $vsel > $pwr/vdd1_opps_vsel
223     echo $rate > $pwr/dsp_opps_rate
224     test $maxfreq = 600 && maxfreq=599
225     echo $((minfreq*1000)) > $cfr/scaling_min_freq
226     echo $((maxfreq*1000)) > $cfr/scaling_max_freq
227     test -n "$SMARTREFLEX_VDD1" && echo $SMARTREFLEX_VDD1 > $pwr/sr_vdd1_autocomp
228     test -n "$SMARTREFLEX_VDD2" && echo $SMARTREFLEX_VDD2 > $pwr/sr_vdd2_autocomp
229     test -n "$IGNORE_NICE_LOAD" && echo $IGNORE_NICE_LOAD > $cfd/ignore_nice_load
230     test -n "$UP_THRESHOLD" && echo $UP_THRESHOLD > $cfd/up_threshold
231     test -n "$SAMPLING_RATE" && echo $SAMPLING_RATE > $cfd/sampling_rate
232     echo "successfully loaded."
233     ;;
234 default)
235     arg=$1
236     if test -z "$arg"; then
237         echo "filename missing"
238         exit 1
239     fi
240     if test `basename $arg` = $arg; then # not absolute
241         for p in . /home/user/.kernel /usr/share/kernel-power-settings; do
242             test -f $p/$arg && arg=$p/$arg && break
243         done
244     fi
245     def=/etc/default/kernel-power
246     rm -f $def
247     case $arg in 
248     /usr/share/kernel-power-settings/*) ln -s $arg $def ;;
249     *) cp $arg $def ;;
250     esac
251     echo "defaults set to $arg"
252     ;;
253 limits)
254     minfreq=$1
255     maxfreq=$2
256     if test "x$minfreq" = x -o "x$maxfreq" = x; then
257         echo "frequency limit arguments missing"
258         exit 1
259     fi
260     test "x$minfreq" = "x-" && minfreq=$((`cat $cfr/scaling_min_freq`/1000))
261     test "x$maxfreq" = "x-" && maxfreq=$((`cat $cfr/scaling_max_freq`/1000))
262     limits="$minfreq,$maxfreq"
263     minfreq=$((minfreq*1000))
264     maxfreq=$((maxfreq*1000))
265     case " $allfreq " in *" $minfreq "*) ;;
266     *) echo "invalid lower limit $1"; exit 1; ;;
267     esac
268     case " $allfreq " in *" $maxfreq "*) ;;
269     *) echo "invalid upper limit $2"; exit 1; ;;
270     esac
271     if test $minfreq -gt $maxfreq; then
272         echo "minimum must not be greater than maximum: $limits"
273         exit 1
274     fi
275     echo $minfreq > $cfr/scaling_min_freq
276     echo $maxfreq > $cfr/scaling_max_freq
277     echo "the limits were set to [$limits]"
278     ;;
279 lock)
280     arg=$1
281     altfreq=
282     for f in $allfreq; do
283         test "$f" = "$arg" && continue
284         altfreq=$f
285         break
286     done
287     vsel=
288     dsp=
289     freq=$((arg*1000))
290     ifreq=
291     i=0
292     for f in 0 $allfreq; do
293         i=$((i+1))
294         test $f = $freq || continue
295         ifreq=$i
296         break
297     done
298     if test -z "ifreq"; then
299         echo invalid frequency $freq
300         exit 1
301     fi
302     echo $ifreq $altfreq
303     test -f $cfd/avoid_frequencies && echo > $cfd/avoid_frequencies # enable all freqs
304     echo userspace > $cfr/scaling_governor 
305     echo $altfreq > $cfr/scaling_setspeed # temporarily set alternative frequencies
306     volt=$2
307     if test -n "$volt"; then
308         i=0
309         vsel=
310         for v in `cat $pwr/vdd1_opps_vsel`; do
311             i=$((i+1))
312             test $i = $ifreq && v=$volt
313             vsel="$vsel $v"
314         done
315         echo $vsel
316         echo $vsel > $pwr/vdd1_opps_vsel
317     fi
318     dsp=$3
319     if test -n "$dsp"; then
320         i=0
321         dsp=
322         for r in `cat $pwr/dsp_opps_rate`; do
323             i=$((i+1))
324             test $i = $ifreq && r=$dsp
325             dsp="$dsp $r"
326         done
327         echo $dsp
328         echo $dsp > $pwr/dsp_opps_rate
329     fi
330     echo locking frequency $freq
331     echo $freq > $cfr/scaling_setspeed
332     ;;
333 esac
334 exit 0