-#!/bin/sh
-# kernel configuration script for power user kernel
-# (c) Copyright 2010 by Thomas Tanner <maemo@tannerlab.com>
-# licensed under GPLv3
-# version 0.3 (16. May 2010)
-
-if test $# -eq 0; then
- echo "$0 command [options]"
- echo "commands:"
- echo " show - show current settings"
- echo " load <file> - load settings from file"
- echo " save <file> - save settings to file (abs. path or filename in /home/user/.kernel)"
- echo " default [<file>] - set file or the current settings as default settings"
- echo " limits min max - set the frequency limits ('-' keeps the current setting)"
- echo " lock freq [volt] [dsp] - lock CPU at frequency with specific settings"
- echo " unlock - unlock CPU frequency"
- echo "filenames: absolute path or filename in search path or none=defaults"
- echo "search path: .,/home/user/.kernel,/usr/share/kernel-power-settings/"
- exit 1
-fi
-if test "`id -u`" -ne 0; then
- sudo $0 $* # run as root
- exit $?
-fi
-
-cfr=/sys/devices/system/cpu/cpu0/cpufreq
-cfd=$cfr/ondemand
-cfc=$cfr/conservative
-pwr=/sys/power
-
-if test -f $pwr/vdd1_opps_vsel -a -f $pwr/dsp_opps_rate; then :
-else
- echo This kernel version `uname -r` is not supported
- echo Please make sure that kernel-power is installed and running.
- echo If you have just installed the kernel, you need to shutdown and boot to activate it.
- echo To reinstall the power user kernel run:
- echo \'apt-get install --reinstall kernel-power kernel-power-flasher\'
- exit 1
-fi
-
-allfreq=
-for f in `cat $cfr/scaling_available_frequencies`; do
- allfreq="$f $allfreq"
-done
-vsel=`cat $pwr/vdd1_opps_vsel`
-rate=`cat $pwr/dsp_opps_rate`
-
-cmd=$1
-test "$cmd" = setdefault && cmd=default # old name
-case " show load save default limits lock unlock " in
-*" $cmd "*) ;;
-*) echo "invalid command $cmd"; exit 1 ;;
-esac
-arg=
-shift
-if test "$cmd" = unlock; then
- echo 'unlocking frequency. reset to defaults'
- cmd=loaddef
-fi
-if test "$cmd" = default && test $# -eq 0; then
- echo 'saving current settings as defaults'
- arg=/etc/default/kernel-power
- cmd=savedef
-fi
-
-popvsel() { curvsel=$1; shift; vsel="$*"; }
-poprate() { currate=$1; shift; rate="$*"; }
-
-case $cmd in
-show|save|savedef)
- minfreq=$((`cat $cfr/scaling_min_freq`/1000))
- maxfreq=$((`cat $cfr/scaling_max_freq`/1000))
- test $maxfreq = 599 && maxfreq=600
- gov=`cat $cfr/scaling_governor`
- avoid=
- test $gov = ondemand && avoid=`cat $cfd/avoid_frequencies`
- freqs=
- for f in 0 $allfreq; do
- popvsel $vsel
- poprate $rate
- case " $avoid " in *" $f "*) ;;
- *) freqs="$freqs$((f/1000)):$curvsel,$currate " ;;
- esac
- done
- if test $cmd = show; then
- echo "current kernel configuration:"
- echo "current frequency:" $((`cat $cfr/scaling_cur_freq`/1000))
- echo -n "supported frequencies: "
- for f in $allfreq; do echo -n "$((f/1000)) "; done
- echo
- echo "min. frequency:" $minfreq
- echo "max. frequency:" $maxfreq
- echo -n "avoid frequencies: "
- for f in $avoid; do echo -n "$((f/1000)) "; done
- echo
- echo "active frequencies: $freqs"
- echo "SmartReflex" "VDD1=`cat $pwr/sr_vdd1_autocomp`, VDD2=`cat $pwr/sr_vdd2_autocomp`"
- echo -n "governor $gov:"
- if test $gov = ondemand; then
- echo -n " ignore nice load=" `cat $cfd/ignore_nice_load`
- echo -n ", up threshold=" `cat $cfd/up_threshold`
- echo -n ", sampling rate=" `cat $cfd/sampling_rate`
- echo ", powersave bias=" `cat $cfd/powersave_bias`
- else
- echo
- fi
- else
- test $cmd = save && arg=$1
- if test -z "$arg"; then
- echo "filename argument is mssing"
- exit 1
- fi
- if test `basename $arg` = $arg; then
- u=/home/user/.kernel
- arg=$u/$arg
- if test ! -d $u; then
- mkdir -p $u
- chown user.users $u
- fi
- touch $arg
- chown user.users $arg
- fi
- rm -f $arg
- echo "saving to $arg"
- echo "# kernel configuration file generated by $0" > $arg
- echo "MINFREQ=$minfreq" >> $arg
- echo "MAXFREQ=$maxfreq" >> $arg
- echo "FREQS=\"$freqs\"" >> $arg
- echo "SMARTREFLEX_VDD1=`cat $pwr/sr_vdd1_autocomp`" >> $arg
- echo "SMARTREFLEX_VDD2=`cat $pwr/sr_vdd2_autocomp`" >> $arg
- echo "GOVERNOR=$gov" >> $arg
- if test $gov = ondemand; then
- echo "IGNORE_NICE_LOAD=`cat $cfd/ignore_nice_load`" >> $arg
- echo "UP_THRESHOLD=`cat $cfd/up_threshold`" >> $arg
- echo "SAMPLING_RATE=`cat $cfd/sampling_rate`" >> $arg
- echo "POWERSAVE_BIAS=`cat $cfd/powersave_bias`" >> $arg
- fi
- fi
- ;;
-load|loaddef)
- test $cmd = loaddef || arg=$1
- if test -z "$arg"; then
- arg=/etc/default/kernel-power
- test -f $arg || arg=/usr/share/kernel-power-settings/default
- fi
- if test `basename $arg` = $arg; then # not absolute
- for p in . /home/user/.kernel /usr/share/kernel-power-settings; do
- test -f $p/$arg && arg=$p/$arg && break
- done
- fi
- if test ! -f "$arg"; then
- echo "file not found $arg"
- exit 1
- fi
- echo "loading $arg"
- source $arg
- if test -n "$VDD1_OPPS_VSEL" -o -n "$DSP_OPPS_RATE"; then
- echo "warning: old configuration format detected. please save in the new format."
- if test -n "$MAX_FREQ"; then
- test $MAX_FREQ = 600000 && MAX_FREQ=599000
- echo $MAX_FREQ > $cfr/scaling_max_freq
- fi
- test -n "$MIN_FREQ" && echo $MIN_FREQ > $cfr/scaling_min_freq
- test -n "$MAX_FREQ" && echo $MAX_FREQ > $cfr/scaling_max_freq
- test -n "$VDD1_OPPS_VSEL" && echo $VDD1_OPPS_VSEL > $pwr/vdd1_opps_vsel
- test -n "$DSP_OPPS_RATE" && echo $DSP_OPPS_RATE > $pwr/dsp_opps_rate
- test -n "$SMARTREFLEX_VDD1" && echo $SMARTREFLEX_VDD1 > $pwr/sr_vdd1_autocomp
- test -n "$SMARTREFLEX_VDD2" && echo $SMARTREFLEX_VDD2 > $pwr/sr_vdd2_autocomp
- test -n "$IGNORE_NICE_LOAD" && echo $IGNORE_NICE_LOAD > $cfd/ignore_nice_load
- test -n "$UP_THRESHOLD" && echo $UP_THRESHOLD > $cfd/up_threshold
- test -n "$SAMPLING_RATE" && echo $SAMPLING_RATE > $cfd/sampling_rate
- exit 1
- fi
- active=
- minfreq=
- maxfreq=
- for f in $FREQS; do
- freq=`echo $f | cut -d: -f1`
- f=`echo $f | cut -d: -f2`
- volt=`echo $f | cut -d, -f1`
- dsp=`echo $f | cut -d, -f2`
- if test ! $freq = 0; then
- test -z "$minfreq" -o "$freq" -lt "$minfreq" && minfreq=$freq
- test -z "$maxfreq" -o "$freq" -gt "$maxfreq" && maxfreq=$freq
- freq=$((freq*1000))
- case " $allfreq " in *" $freq "*) ;;
- *) echo warning: $freq not supported; continue ;;
- esac
- active="$active $freq"
- fi
- test -z "$volt" && test -z "$dsp" && continue
- tvsel=
- trate=
- for fr in 0 $allfreq; do
- if test $fr = $freq; then
- popvsel $vsel
- poprate $rate
- test -z "$volt" && volt=$curvsel
- test -z "$dsp" && dsp=$currate
- tvsel="$tvsel $volt $vsel"
- trate="$trate $dsp $rate"
- break
- fi
- popvsel $vsel
- tvsel="$tvsel $curvsel"
- poprate $rate
- trate="$trate $currate"
- done
- vsel=$tvsel
- rate=$trate
- done
- test -z "$GOVERNOR" && GOVERNOR=ondemand
- test -n "$MINFREQ" && minfreq=$MINFREQ
- test -n "$MAXFREQ" && maxfreq=$MAXFREQ
- test "$minfreq" -gt 100000 && minfreq=$((minfreq/1000))
- test "$maxfreq" -gt 100000 && maxfreq=$((maxfreq/1000))
- avoid=
- for f in $allfreq; do
- if test "$f" -lt $((minfreq*1000)); then
- avoid="$avoid $f"
- continue
- fi
- case " $active " in *" $f "*) ;;
- *) avoid="$avoid $f" ;;
- esac
- done
- echo $GOVERNOR > $cfr/scaling_governor
- if test $GOVERNOR = ondemand; then
- echo $avoid > $cfd/avoid_frequencies
- test -n "$IGNORE_NICE_LOAD" && echo $IGNORE_NICE_LOAD > $cfd/ignore_nice_load
- test -n "$UP_THRESHOLD" && echo $UP_THRESHOLD > $cfd/up_threshold
- test -n "$SAMPLING_RATE" && echo $SAMPLING_RATE > $cfd/sampling_rate
- test -n "$POWERSAVE_BIAS" && echo $POWERSAVE_BIAS > $cfd/powersave_bias
- fi
- echo $vsel > $pwr/vdd1_opps_vsel
- echo $rate > $pwr/dsp_opps_rate
- test $maxfreq = 600 && maxfreq=599
- echo $((maxfreq*1000)) > $cfr/scaling_max_freq
- echo $((minfreq*1000)) > $cfr/scaling_min_freq
- echo $((maxfreq*1000)) > $cfr/scaling_max_freq
- test -n "$SMARTREFLEX_VDD1" && echo $SMARTREFLEX_VDD1 > $pwr/sr_vdd1_autocomp
- test -n "$SMARTREFLEX_VDD2" && echo $SMARTREFLEX_VDD2 > $pwr/sr_vdd2_autocomp
- echo "successfully loaded."
- ;;
-default)
- arg=$1
- if test -z "$arg"; then
- echo "filename missing"
- exit 1
- fi
- if test `basename $arg` = $arg; then # not absolute
- for p in . /home/user/.kernel /usr/share/kernel-power-settings; do
- test -f $p/$arg && arg=$p/$arg && break
- done
- fi
- def=/etc/default/kernel-power
- rm -f $def
- case $arg in
- /usr/share/kernel-power-settings/*) ln -s $arg $def ;;
- *) cp $arg $def ;;
- esac
- echo "defaults set to $arg"
- ;;
-limits)
- minfreq=$1
- maxfreq=$2
- if test "x$minfreq" = x -o "x$maxfreq" = x; then
- echo "frequency limit arguments missing"
- exit 1
- fi
- test "x$minfreq" = "x-" && minfreq=$((`cat $cfr/scaling_min_freq`/1000))
- test "x$maxfreq" = "x-" && maxfreq=$((`cat $cfr/scaling_max_freq`/1000))
- limits="$minfreq,$maxfreq"
- minfreq=$((minfreq*1000))
- maxfreq=$((maxfreq*1000))
- case " $allfreq " in *" $minfreq "*) ;;
- *) echo "invalid lower limit $1"; exit 1; ;;
- esac
- case " $allfreq " in *" $maxfreq "*) ;;
- *) echo "invalid upper limit $2"; exit 1; ;;
- esac
- if test $minfreq -gt $maxfreq; then
- echo "minimum must not be greater than maximum: $limits"
- exit 1
- fi
- test $maxfreq = 600000 && maxfreq=599000
- echo $maxfreq > $cfr/scaling_max_freq
- echo $minfreq > $cfr/scaling_min_freq
- echo $maxfreq > $cfr/scaling_max_freq
- echo "the limits were set to [$limits]"
- ;;
-lock)
- arg=$1
- altfreq=
- for f in $allfreq; do
- test "$f" = "$arg" && continue
- altfreq=$f
- break
- done
- vsel=
- dsp=
- freq=$((arg*1000))
- ifreq=
- i=1
- avoid=
- for f in $allfreq; do
- i=$((i+1))
- if test $f = $freq; then
- ifreq=$i
- break
- fi
- avoid="$avoid $f"
- done
- if test -z "ifreq"; then
- echo invalid frequency $freq
- exit 1
- fi
- echo userspace > $cfr/scaling_governor
- echo $altfreq > $cfr/scaling_setspeed # temporarily set alternative frequencies
- volt=$2
- if test -n "$volt"; then
- i=0
- vsel=
- for v in `cat $pwr/vdd1_opps_vsel`; do
- i=$((i+1))
- test $i = $ifreq && v=$volt
- vsel="$vsel $v"
- done
- echo $vsel > $pwr/vdd1_opps_vsel
- fi
- dsp=$3
- if test -n "$dsp"; then
- i=0
- dsp=
- for r in `cat $pwr/dsp_opps_rate`; do
- i=$((i+1))
- test $i = $ifreq && r=$dsp
- dsp="$dsp $r"
- done
- echo $dsp > $pwr/dsp_opps_rate
- fi
- echo locking frequency $freq
- echo ondemand > $cfr/scaling_governor
- echo $avoid > $cfd/avoid_frequencies # avoid all other freqs
- maxfreq=$freq
- test $maxfreq = 600000 && maxfreq=599000
- # min after max? kernel docs are wrong?
- echo $maxfreq > $cfr/scaling_max_freq
- echo $freq > $cfr/scaling_min_freq
- echo $maxfreq > $cfr/scaling_max_freq
- ;;
-esac
-exit 0