Skip to content

Undervolting janice

mkaluza edited this page Nov 1, 2014 · 13 revisions

Apps needed:

Scripts:

Scripts

It's good to place them in /system/xbin. Remember to do chmod 755 script_name on them.

freq_jump.sh

It's the script I use to check system stability when changing frequecies. When run without parameters, it'll check every possible combination of available frequencies between scaling_min_freq and scaling_max_freq. But that takes a while... So if it's given a frequency (in kHz, as used by cpufreq) parameter, it'll only check switching to and from that frequency to all others - it's quite fast.

mali_top

I use it to check gpu load and freq

opptop

The script shows all opp requirements and their current value, so we can see what's keeping APE/DDR frequency high

CPU

All operations here assume that we are using a root shell. The first thing that should be changed is governor to userspace

echo userspace > /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor

and set frequency to a desired value (i.e. 800 MHz)

echo 800000 > /sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed

Also, all voltage changes should be done when StabilityTest (or any other app that generates high cpu load) is running.

Using LiveOPP

I'll use 800MHz as an example. All XXXXX stuff is to be replaced with actual values

Do cd /sys/kernel/liveopp and then find the arm_stepXX file for the freqency you want to manipulate:

grep 800000 arm_step*

  • currently it's arm_step07. To change the voltage, do

echo varm=0xXX > arm_stepXX

It doesn't apply the change - it will be applied next time this frequency is entered. freq_jump.sh script is useful for that - do

freq_jump.sh 800000

and it'll check all possible combinations of frequency changes to and from 800MHz. When lowest stable voltage is found that way, there is a fair chance it'll be stable in the long run (but not always) - set this value with init.d scripts, reboot and use the phone for some time.

Never change more than one frequency at a time! If the phone gets unstable, you won't know which one is wrong. Change one and use the phone for a few days.

GPU

Undervolting GPU is easier/faster

  1. Set mali_boost_high idx to desired value and start some app that will load a gpu - preferably a game,
  2. Check with mali_top that gpu load is constantly 100% and that frequency is correct (mali_boost is working),
  3. Use the register method described below to lower the voltage in 0x0e register until the phone crashes (decrease one step at a time every 10s or more),
  4. Choose a voltage 1-3 steps higher than the one, that crashed the phone,
  5. Use init.d scripts to store it in mali_dvfs_config and enjoy.

Extreme undervolting

Intro

From my observations it seems that the most critical point is frequency change - cpu can work on lower voltage (if set directly via register) when it's already at some frequency than when it switches to it (via liveOPP). Work is in progress to modify LiveOPP so that it can use these lower voltages while maintaining stability.

Setting voltage via register

There is a sysfs interface that gives direct access to prcmu registers:

cd /sys/kernel/debug/ab8500

To access cpu voltage we need to select right register bank (AB8500_REGU_CTRL2) which is 0x04:

echo 0x04 > register-bank

Then we have to select the right register. There are two registers used for CPU voltage - for ARM_MAX_OPP (f>=1000MHz) and ARM_100_OPP (1000MHz>f>=800MHz) register 0x0b is used, and for lower freqs register 0x0c, so be sure to use the right one for current frequency

echo 0x0b > register-address

After that we can do cat register-value to read current voltage or echo 0xXX > register-value to set current voltage.

This way we can get the lowest voltage our cpu/gpu is stable at when not changing frequency. Changing voltage this way is immediate! There's no need to use liveopp/cpufreq - when value is written, it's set right away.

Summary

cd /sys/kernel/debug/ab8500
echo 0x04 > register-bank

Registers

  • CPU >= 800MHz 0x0c
  • CPU < 800MHZ 0x0b
  • GPU full speed 0x0e
  • GPU half speed 0x0f

Undervolting

WARNING values obtained this way are not usable in liveopp - they will hang the phone for sure. Currently this is only an experiment to show that the cpu can run at much lower voltage than the minimum achievable with liveopp. However, this low voltage is not usable when using frequency scaling. Code to use it is being written here https://github.com/mkaluza/Samsung_STE_Kernel/tree/liveopp_uv.

Of course do it with stability test running and governor set to userspace. When bank and address are set, just lower the voltage until the phone crashes. After a reboot, set the voltage again the same way, but two a value +2 higher than the last one that caused the crash and leave the phone for some time - if it doesn't reboot after 20+ minutes, it should be fine.

Script extreme_uv.sh from folder linked at the top may be helpful.

Results

My results for janice (values at which the phone hangs - stable voltages are/should be around +2 more):

  • 100,200 - 0x05
  • 300 - 0x0a
  • 400-600 0x0f
  • 700 - 0x14
  • 800 - 0x1a
  • 900 - 0x1f
  • 1000 - 0x24

Finding maximum freq for given voltage.

Use pll register

cd /sys/kernel/prcmu

To read pll reg, do

echo 0x88 > prcmu_rreg
cat prcmu_rreg

The value is 0xAABBCCDD

  • AA - divide freq by 2 (for ARM_50_OPP) - its a flag - either 00 or 01
  • BB - divisor
  • CC - unknown - is always 01
  • DD - multiplier

current frequency is calculated as 38400KHz * DD / BB and optionally halved if AA == 01

to set new freq do

echo 0x88 0xAABB01DD > prcmu_wreg

current freq can be checked with

cat /sys/kernel/liveopp/arm_pllclk

Those changes (and voltage settings via register) are immediate, there's no need to switch frequencies for liveopp to work

Warning Value obtained this way may be too high for liveopp - when changing frequencies, either voltage has to be higher, or frequency lower, otherwise system will crash