megi's PinePhone Development Log RSS

Surgenons in Gaza Surgeons in Gaza

2023–05–23: Boot time power consumption tracing

Power consumption changes rapidly during boot. One microsecond it can be 700 mW and a few microseconds later it can be 3000 mW.

So that I can observe these changes precisely and attribute them to code being executed in the bootloader (levinboot in this case), I had to create a test steup that measures the voltage drop on a shunt resistor placed in the VBUS path and taps into phone's serial console at the same time. Pinephone has serial console conveniently routed to the audio jack output, so this was easily doable.

Pinephone (Pro) precise power consumption tracing setup

This way I can precisely attribute bootloader actions to power consumption changes down to 100's of nanoseconds.

(I decided to measure at the battery terminals instead of VBUS/Type-C port to avoid having to deal with the VBUS input current limit. VBUS current can be calculated by multiplying the battery current by 4.3 / 5. So 500 mA from battery equals 430 mA from Type-C port.)

The output from the entire boot looks something like this:

Pinephone Pro boot power consumption trace (power up to Linux) – yellow: battery current @ 332 mA/div / fixed voltage 4.3 V – magenta: UART TX showing only the levinboot trace, because I forgot to enable Linux serial console. (Yes levinboot really takes just ~300 ms to boot Linux here)

Peak current from the battery during boot is almost 2A @ 4.3V. (8.6 W)

Walkthrough of the powerup process

Let's walk through the whole powerup process together.

The power button is pressed, and PMIC starts going throug initial regulator powerup in a sequence defined in the datasheet.

PMIC regulator startup order according to the datasheet
PMIC regulator startup timing according to the datasheet

The datasheet says that regulators are powered up in sequence separated by 66 x tCK32k, which means 66 periods of 32 kHz clock, which equals to 2.1ms.

This matches with the first activity we see on the scope:

PMIC starting up reuqired regulators. Each current peak represents one DC-DC regulator being started.

The biggest peak by far is the VCC3V3_SYS power rail being enabled, which is not surprising, since a lot of things are powered by it inside Pinephone Pro.

UART TX signal going high coincides with VDD_LOG being enabled. This power rail drives the internal logic in the SoC, thus the name. Apparently it also powers the UART controller.

After power up sequence is complete, PMIC will wait for voltages to stabilize and release NRESPWRON signal after Ton6 (82 ms):

NRESPWRON timing specification

We can see this time interval on the scope as a period of stable current after the power up sequence finished:

Calmness while NRESPWRON is held low, keeping the SoC in reset

Power consumption is 465 mW, calculated as 4.3 V * 108 mA. BTW, 1 mV on the yellow trace's scale means 1 mA.

So just about after the predefined set of regulators needed for startup is enabled, the power consumption is already higher than what can be achieved in deep sleep. (Even when the SoC is held in reset state and is doing nothing.)

Next period of time is RK3399 boot ROM (BROM) doing some initialization that ultimately results in it reading a SRAM stage of levinboot from my microSD card. The moment BROM passes execution to levinboot, is the moment when the first activity is seen at the UART TX, because levinboot immediately announces itself by printing its version to serial console.

Levinboot saying Hi!

This period of BROM activity, prior to levinboot saying hello, lasts 365 ms and can be split into two parts:

Curious 257 ms of BROM activity that only happens on power-on, but not after system reset
108 ms of BROM activity that always happens on power-on or system reset

Both of these periods of activity are easily identified by their power consumption profile.

Reset power profile, for reference. (Sorry for the compressed scale) Levinboot is here seen detecting a soft reset and issuing a hard reset.

The zoomed in part in detail:

Detail of BROM loading levinboot 2× after soft reset (2× 108 ms of identical activity). Sorry again for vertical scale. :)

Maybe someone knows what's BROM up to in those post-powerup 257 ms of activity. I don't. This is the only unaccounted for time of activity during boot.

In any case, during the whole period of BROM activity before the bootloader is jumped to (regardless of whether it's levinboot or U-Boot), the phone is seen consuming maximum of 1.3 W. This is well inside the bounds of the default 450 mA input current limit on VBUS, which in worst case of 4.5 V VBUS is ~2W.

No problem here.

Next up, the levinboot runs and loads the kernel. DRAM initialization and training happens in the first 80 ms or so, after which there's a period of loading data from eMMC and jump to TF-A/kernel.

Detail of levinboot doing its thing.

The power consumption is ~2.1W right before the bootloader starts accessing eMMC to load the payload (kernel, etc.). This is so so within the input current limit.

Power consumption in the bootloader unfortunately peaks to 2.8–3W during the eMMC access time, and this is where the PMIC power cycles when the battery is fully discharged.

This matches my experience with levinboot failing to boot without battery, during the eMMC load stage, before I patched it to raise the limit in early DRAM stage.

The same issue of course happens in U-Boot, for the same reason.

Suspend / resume power traces for the curious

Deep sleep transitions are interesting, too. It's possible to use them to discern contributions of various parts of the sleep transition sequence to power savings.

I'll leave them to you with just one observation, because I haven't looked very closely at them. A whole 66% of power savings seems to be attributable to just the one last thing TF-A does during the transition to deep sleep. Amazing, right?

Detail of Pinephone Pro kernel going to deep sleep
Detail of the detail of Pinephone Pro kernel going to deep sleep. Marvel at that size of the last drop!

Wakeup looks quite different. Not at all just the sleep transition reverse, as one might expect. There's some story in there, too.

Detail of Pinephone Pro kernel waking up from deep sleep

Power consumption tracing and the future optimizations

Power consumption tracing can show us a lot of interesting things and can be used creatively to identify opportunities to save more power at runtime.

I can envision adding a 100 ms delay and a printk before each driver's suspend function, and record the suspend to idle power trace. From the trace it will be possible to see contributions of each device that's being suspended to the power consumption of the phone, without tediously going through each device by hand and figuring out ways to disable them manually.

I'll simply go through a trace, and find a printk that results in the biggest drop in current. :)

Given the large difference between idle and s2idle power consumption, this can be used to identify devices that consume the most at runtime, and are best candidates for implementing runtime power management.

Stay tuned for some DRAM power savings on Pinephone Pro in the next post!