2023–05–25:
DRAM frequency scaling on Pinephone Pro saves 0.5W of power!
I've tried to enable DRAM frequency scaling several times already on
Pinephone Pro. I was stopped by a few issues:
- Frequency scaling doesn't work with upstream TF-A, Rockchcip's prebuilt
version from 3 years ago is needed for that.
- Rockchip's blob doesn't work with Levinboot.
- Mainline U-Boot would not run with Rockchip's TF-A blob until recently,
when the support for using it was added to mainline.
So this is a great time to revisit U-Boot and DRAM frequency scaling on
RK3399.
I've put together a DT patch for Linux to enable the DMC driver needed so
that kernel can decide when to change DRAM frequency and so that it can talk to
TF-A which performs the actual change.
I've also downloaded and integrated Rokchcip's blobs and configured U-Boot
to use them. Two blobs are needed for DMC to work:
- Rockchip's DRAM init binary (equivalent of U-Boot's TPL)
- Rockchip's TF-A build that takes info from the former and allows DRAM
frequency changes
These two files from rkbin
repository:
- rk3399_ddr_933MHz_v1.30.bin – DRAM init
- rk3399_bl31_v1.36.elf – TF-A
When all is enabled and working, you get this as a result:
- much slower boot (just the DRAM init blob itself delays boot by 3s doing
some training)
- much slower TF-A startup
- working DMC driver that you can use to manually or automatically change DRAM
frequency at runtime
- no change in system sleep power consumption
- RAM being able to run at higher than mainline U-Boot's 800 MHz frequency
(it can run up to 933MHz)
- and the most awesome part:
Yes, that's about 0.5W in power savings when idling, 30% reduction in the
current state of art on Pinephone Pro!
With the DMC driver you also get a few new nice toggles and controls
in sysfs:
The difference between lowest and highest frequency is about 600 mW.
Suspend to idle curiosity
Suspend to idle (s2idle) power consumption is now 860mW. What is interesting
is that after some use the power consumption in idle will hover around 1.1W and
after s2idle cycle it will hover around 1W. There's some bug weighing about
0.1W in there somewhere in runtime PM implementation of some driver that system
sleep callbacks fix during s2idle cycle. Very curious and probably some low
hanging fruit.
U-Boot changes
The changes to U-Boot are minimal. You just need the latest U-Boot master and
a specific configuration for Pinephone Pro that utilizes the above mentioned
blobs. (This is not a great news for Tow-Boot users, because that seems stuck on
2021.10 release of
U-Boot)
Also now that Tow-Boot doesn't sees much activity
even in the development branch, and everyone has it pre-installed in SPI instead
of distros taking care of the bootloader in their distro images, you're pretty
much stuck having to build your own U-Boot and configuring it properly if you
want these power savings in exchange for some morally impure code in the
boot path.
I can provide my U-Boot master builds for Pinephone Pro with FOSS or
Rockchip blobs, but I don't care or know about UEFI, SPI boot and other things
used by Tow-Boot, so this would only work when installed on a microSD card.
Building U-Boot and installing it on a microSD card is quite simple:
# get the blobs from the repository linked to above and set appropriate
# environment variables so that U-Boot makefile will find and use them
export BL31=rkbin/bin/rk33/rk3399_bl31_v1.36.elf
export ROCKCHIP_TPL=rkbin/bin/rk33/rk3399_ddr_933MHz_v1.30.bin
# configure U-Boot
make pinephone-pro-rk3399_defconfig
# build U-Boot
make -j
# as a result you'll get u-boot-rockchip.bin that you can flash to the
# microSD card at offset of 64 blocks (32768 bytes)
#
# the card needs to be partitioned such that this will not overwrite any
# filesystem (this should not matter if you load the OS from eMMC, then
# you can just use an empty microSD card and you don't even need to
# partition it)
dd if=u-boot-rockchip.bin of=/dev/sdhcarddevice seek=64
Use this U-Boot branch: https://xff.cz/git/u-boot/log/?h=ppp
You'll need to erase any bootloader from eMMC and SPI so that BROM boots via
your now bootloader stored on the microSD card.
Linux changes
Linux needs a simple DT patch. The problem with that is that when you run
such kernel on a system that doesn't use rockchip's blobs, your system will
lock up on the first DRAM frequency change attempt by the driver.
So you need to match the kernel to the partly non-free bootloader build.
The Linux patch is: https://megous.com/dl/tmp/0001-arm64-dts-rockchip-rk3399-pinephone-pro-Enable-DMC.patch
It applies on top of my orange-pi-6.3 branch on top of which it was tested. It
will probably also work fine just with mainline Linux.
Summary
It would be amazing if it didn't require rockchip's blobs to work, but it
brings idle power consumption quite close to original Pinephone, so it's well
worth trying if you daily drive Pinephone Pro.