31b085319da99bbed8a26963862a35fa6cfed3f9
[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.1 (2. 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, none=defaults)"
13     echo "  setdefault <file> - set file as default settings"
14     echo "  lock [freq [volt] [dsp]] - un/lock CPU at frequency with specific settings"
15     echo "filenames: absolute path or filename in search path or none=defaults"
16     echo "search path: .,/home/user/.kernel,/usr/share/kernel-power-settings/"
17     exit 1
18 fi
19 if test "`id -u`" -ne 0; then
20     sudo $0 $* # run as root
21     exit $?
22 fi
23
24 cfr=/sys/devices/system/cpu/cpu0/cpufreq
25 cfd=$cfr/ondemand
26 pwr=/sys/power/
27
28 echo ondemand > $cfr/scaling_governor
29 if test -f $cfd/avoid_frequencies -a -f $pwr/vdd1_opps_vsel -a -f $pwr/dsp_opps_rate; then :
30 else
31     echo This kernel version `uname -r` is not supported
32     exit 1
33 fi
34
35 allfreq=
36 for f in `cat $cfr/scaling_available_frequencies`; do
37     allfreq="$f $allfreq"
38 done
39 vsel=`cat $pwr/vdd1_opps_vsel` 
40 rate=`cat $pwr/dsp_opps_rate` 
41
42 cmd=$1
43 arg=
44 shift
45 if test "$cmd" = lock && test -z "$1"; then
46     echo 'unlocking frequency. reset to defaults'
47     cmd=loaddef
48     arg=
49 fi
50
51 popvsel() { curvsel=$1; shift; vsel="$*"; }
52 poprate() { currate=$1; shift; rate="$*"; }
53
54 case $cmd in
55 show|save)
56     minfreq=$((`cat $cfr/scaling_min_freq`/1000))
57     maxfreq=$((`cat $cfr/scaling_max_freq`/1000))
58     test $maxfreq = 599 && maxfreq=600
59     avoid=`cat $cfd/avoid_frequencies`
60     freqs=
61     for f in $allfreq; do
62         popvsel $vsel
63         poprate $rate
64         case " $avoid " in *" $f "*) ;;
65         *) freqs="$freqs$((f/1000)):$curvsel,$currate "
66         esac
67     done
68     if test $cmd = show; then
69         echo "current kernel configuration:"
70         echo "current frequency:" $((`cat $cfr/scaling_cur_freq`/1000))
71         echo -n "supported frequencies: "
72         for f in $allfreq; do echo -n "$((f/1000)) "; done
73         echo
74         echo "min. frequency:" $minfreq
75         echo "max. frequency:" $maxfreq
76         echo -n "avoid frequencies: "
77         for f in $avoid; do echo -n "$((f/1000)) "; done
78         echo
79         echo "active frequencies: $freqs"
80         echo "SmartReflex" "VDD1=`cat $pwr/sr_vdd1_autocomp`, VDD2=`cat $pwr/sr_vdd2_autocomp`"
81         echo -n "ondemand: ignore nice load=" `cat $cfd/ignore_nice_load` 
82         echo -n ", up threshold=" `cat $cfd/up_threshold`
83         echo ", sampling rate=" `cat $cfd/sampling_rate`
84     else
85         arg=$1
86         test -z "$arg" && arg=/etc/default/kernel-power
87         if test `basename $arg` = $arg; then
88             u=/home/user/.kernel
89             arg=$u/$arg
90             if test ! -d $u; then
91                 mkdir -p $u
92                 chown user.users $u
93             fi
94             touch $arg
95             chown user.users $arg
96         fi
97         test $arg = /etc/default/kernel-power && test -L $arg && rm -f $arg
98         echo "saving to $arg"
99         echo "# kernel configuration file generated by $0" > $arg
100         echo "MINFREQ=$minfreq" >> $arg
101         echo "MAXFREQ=$maxfreq" >> $arg
102         echo "FREQS=\"$freqs\"" >> $arg
103         echo "SMARTREFLEX_VDD1=`cat $pwr/sr_vdd1_autocomp`" >> $arg
104         echo "SMARTREFLEX_VDD2=`cat $pwr/sr_vdd2_autocomp`" >> $arg
105         echo "IGNORE_NICE_LOAD=`cat $cfd/ignore_nice_load`" >> $arg
106         echo "UP_THRESHOLD=`cat $cfd/up_threshold`" >> $arg
107         echo "SAMPLING_RATE=`cat $cfd/sampling_rate`" >> $arg
108     fi
109     ;;
110 load|loaddef)
111     test $cmd = loaddef || arg=$1
112     if test -z "$arg"; then
113         arg=/etc/default/kernel-power
114         test -f $arg || arg=/usr/share/kernel-power-settings/default
115     fi
116     if test `basename $arg` = $arg; then # not absolute
117         for p in . /home/user/.kernel /usr/share/kernel-power-settings; do
118             test -f $p/$arg && arg=$p/$arg && break
119         done
120     fi
121     if test ! -f "$arg"; then
122         echo "file not found $arg"
123         exit 1
124     fi
125     echo "loading $arg"
126     source $arg
127     if test -n "$VDD1_OPPS_VSEL" -o -n "$DSP_OPPS_RATE"; then
128         echo "warning: old configuration format detected. please save in the new format."
129         test -n "$MIN_FREQ" && echo $MIN_FREQ > $cfr/scaling_min_freq
130         test -n "$MAX_FREQ" && echo $MAX_FREQ > $cfr/scaling_max_freq
131         test -n "$VDD1_OPPS_VSEL" && echo $VDD1_OPPS_VSEL > $pwr/vdd1_opps_vsel
132         test -n "$DSP_OPPS_RATE" && echo $DSP_OPPS_RATE > $pwr/dsp_opps_rate
133         test -n "$SMARTREFLEX_VDD1" && echo $SMARTREFLEX_VDD1 > $pwr/sr_vdd1_autocomp
134         test -n "$SMARTREFLEX_VDD2" && echo $SMARTREFLEX_VDD2 > $pwr/sr_vdd2_autocomp
135         test -n "$IGNORE_NICE_LOAD" && echo $IGNORE_NICE_LOAD > $cfd/ignore_nice_load
136         test -n "$UP_THRESHOLD" && echo $UP_THRESHOLD > $cfd/up_threshold
137         test -n "$SAMPLING_RATE" && echo $SAMPLING_RATE > $cfd/sampling_rate
138         exit 1
139     fi
140     #echo $allfreq
141     #echo $vsel
142     #echo $rate
143     active=
144     minfreq=
145     maxfreq=
146     #echo $FREQS
147     for f in $FREQS; do
148         #echo processing $f
149         freq=`echo $f | cut -d: -f1`
150         f=`echo $f | cut -d: -f2`
151         volt=`echo $f | cut -d, -f1`
152         dsp=`echo $f | cut -d, -f2`
153         #echo freq $freq volt $volt dsp $dsp
154         if test ! $freq = 0; then
155             test -z "$minfreq" -o "$freq" -lt "$minfreq" && minfreq=$freq
156             test -z "$maxfreq" -o "$freq" -gt "$maxfreq" && maxfreq=$freq
157             freq=$((freq*1000))
158             case " $allfreq " in *" $freq "*) ;;
159             *)  echo warning: $freq not supported; continue ;;
160             esac
161             active="$active $freq"
162         fi
163         test -z "$volt" && test -z "$dsp" && continue
164         tvsel=
165         trate=
166         cpvsel() { tvsel="$tvsel $1"; }
167         cprate() { trate="$trate $1"; }
168         for fr in 0 $allfreq; do
169             if test $fr = $freq; then
170                 popvsel $vsel
171                 poprate $rate
172                 test -z "$volt" && volt=$curvsel
173                 test -z "$dsp" && dsp=$currate
174                 tvsel="$tvsel $volt $vsel"
175                 trate="$trate $dsp $rate"
176                 break
177             fi
178             popvsel $vsel
179             tvsel="$tvsel $curvsel"
180             poprate $rate
181             trate="$trate $currate"
182         done
183         vsel=$tvsel
184         rate=$trate
185         #echo $vsel
186     done
187     #echo vsel $vsel
188     #echo rate $rate
189     test -n "$MINFREQ" && minfreq=$MINFREQ
190     test -n "$MAXFREQ" && maxfreq=$MAXFREQ
191     test "$minfreq" -gt 100000 && minfreq=$((minfreq/1000))
192     test "$maxfreq" -gt 100000 && maxfreq=$((maxfreq/1000))
193     #echo $minfreq $maxfreq
194     avoid=
195     for f in $allfreq; do
196         if test "$f" -lt $((minfreq*1000)); then
197             avoid="$avoid $f"
198             continue
199         fi
200         case " $active " in *" $f "*) ;;
201         *) avoid="$avoid $f" ;;
202         esac
203     done
204     #echo $avoid
205     echo $avoid > $cfd/avoid_frequencies
206     echo $vsel > $pwr/vdd1_opps_vsel
207     echo $rates > $pwr/dsp_opps_rate
208     test $maxfreq = 600 && maxfreq=599
209     echo $((minfreq*1000)) > $cfr/scaling_min_freq
210     echo $((maxfreq*1000)) > $cfr/scaling_max_freq
211     test -n "$SMARTREFLEX_VDD1" && echo $SMARTREFLEX_VDD1 > $pwr/sr_vdd1_autocomp
212     test -n "$SMARTREFLEX_VDD2" && echo $SMARTREFLEX_VDD2 > $pwr/sr_vdd2_autocomp
213     test -n "$IGNORE_NICE_LOAD" && echo $IGNORE_NICE_LOAD > $cfd/ignore_nice_load
214     test -n "$UP_THRESHOLD" && echo $UP_THRESHOLD > $cfd/up_threshold
215     test -n "$SAMPLING_RATE" && echo $SAMPLING_RATE > $cfd/sampling_rate
216     echo "successfully loaded."
217     ;;
218 setdefault)
219     arg=$1
220     if test -z "$arg"; then
221         echo "filename missing"
222         exit 1
223     fi
224     if test `basename $arg` = $arg; then # not absolute
225         for p in . /home/user/.kernel /usr/share/kernel-power-settings; do
226             test -f $p/$arg && arg=$p/$arg && break
227         done
228     fi
229     def=/etc/default/kernel-power
230     rm -f $def
231     case $arg in 
232     /usr/share/kernel-power-settings/*) ln -s $arg $def ;;
233     *) cp $arg $def ;;
234     esac
235     echo "defaults set to $arg"
236     ;;
237 lock)
238     arg=$1
239     altfreq=
240     for f in $allfreq; do
241         test "$f" = "$arg" && continue
242         altfreq=$f
243         break
244     done
245     vsel=
246     dsp=
247     freq=$((arg*1000))
248     ifreq=
249     i=0
250     allfreq="0 $allfreq"
251     for f in $allfreq; do
252         i=$((i+1))
253         test $f = $freq || continue
254         ifreq=$i
255         break
256     done
257     if test -z "ifreq"; then
258         echo invalid frequency $freq
259         exit 1
260     fi
261     echo $ifreq $altfreq
262     test -f $cfd/avoid_frequencies && echo > $cfd/avoid_frequencies # enable all freqs
263     echo userspace > $cfr/scaling_governor 
264     echo $altfreq > $cfr/scaling_setspeed # temporarily set alternative frequencies
265     volt=$2
266     if test -n "$volt"; then
267         i=0
268         vsel=
269         for v in `cat $pwr/vdd1_opps_vsel`; do
270             i=$((i+1))
271             test $i = $ifreq && v=$volt
272             vsel="$vsel $v"
273         done
274         echo $vsel
275         echo $vsel > $pwr/vdd1_opps_vsel
276     fi
277     dsp=$3
278     if test -n "$dsp"; then
279         i=0
280         dsp=
281         for r in `cat $pwr/dsp_opps_rate`; do
282             i=$((i+1))
283             test $i = $ifreq && r=$dsp
284             dsp="$dsp $r"
285         done
286         echo $dsp
287         echo $dsp > $pwr/dsp_opps_rate
288     fi
289     echo locking frequency $freq
290     echo $freq > $cfr/scaling_setspeed
291     ;;
292 *)
293     echo "invalid command $cmd"
294     exit 1
295 esac
296 exit 0