megi's PinePhone Development Log RSS


2023–04–15: Pinephone Backlight Testing

I bought a very fast visible light sensitive PIN photodiode, to verify my backlight PWM change/fix for Pinephone Pro.

The diode has rise/fall times of 30ns, so it's infinitely faster than the photoresistor I was using before to do rought verification, and it's much faster than needed for these backlight/display test. :)

I hooked up the diode to the scope, loaded it, and made some measurements with diode staring directly to the phone's display.

Pinephone Pro

Pinephone Pro had the backlight PWM frequency set to 1 kHz since initial release. I noticed this recently, and I made a change to 20 kHz and updated the brightness → duty cycle translation curve to avoid too small duty cycle at low brightness, which the backlight controller doesn't support. Pinephone Pro supports 51 brightness levels now, so I selected a few and measured them with my above described setup.

I link many images of scope captures below. You can interpret them as middle line (0 V) being completely dark, and 150 mV being about the max brightness the display can produce.

Pre fix 1 kHz PWM frequency:

Massive ripple, the display is basically blinking all the time going down to being completely dark every 1 ms. DC-DC boost convertor that's driving the backlight LED is pretty much shutting down every 1 ms.

Terrible horrible. And you probably didn't notice, unless you've tried to move the pencil before the screen very fast left and right and saw the pencil itself blinking, instead of fading into a blur. :)

With my change to 20 kHz PWM:

So mostly flat as per theory. :) Only a slight ripple is visible for brihtness 38, but it's tiny.

The boost DC-DC backluight LED driver has internal RC low pass filter on the PWM/EN pin, and 1 kHz is well below its cutoff frequency, so it was not filtering the 1 kHz PWM signal away pretty much at all. The filtered signal internally sets the reference current for the LEDs, so if this is not smoothed out, the LED current will not be smooth either and correpsondingly the LEDs will blink all the time, except at max brightness.

Both settings at 0 brightness for completeness.

Original Pinephone

Of course I counldn't forget to test the original Pinephone, too, with the same setup. This makes the measurements somewhat comparable with Pinephone Pro.

Flat as a table. Not even a hint of a ripple.

Pixel update speed

Given that measured voltage somewhat linearly corresponds to brightness, we can also measure another thing about a LCD display itself. And that is the transition speed of a pixel from being fully transparent to being fully opaque (or white to black update in other words).

So I've set up my DRM framerate testing app to instead of outputing white picture all the time to swap white and black framebuffers each VSYNC.

This produces a 30 Hz repeating pattern of display brightness changes:

As you can see the changes are not immediate, but follow a logarithmic progression. It also looks like that the pixel update doesn't finish before the next VSYNC swap comes, so I slowed down the swaps, to see complete settling of the changes:

The result seems to be that the pixel opacity transition between the extremes settles in just about one VSYNC cycle (it takes slightly logner, I think).

Interesting, eh? Nothing in nature is immediate. (Except for quantum mechaincs, I guess.) :)

And the same for original Pinephone's display:

The pixels are a bit laid back in the OG Pinephone's LCD, don't you think?

And another exciting bug discovered, due to this testing

Original Pinephone's A64 SoC's display driver code was always quite a bit unreliable, having various issues with DRM plane changes, with occasional corrupted frame, with spontaneous output loss, etc.

I've tried to address these issues over the years, and I thought I finally had somehting that works perfectly. But nope, lol. The test app that swaps black and white frames as fast as possible revealed that there are still some quite obvious issues in the driver, that are not normally visible when the displayed image doesn't change much.

The driver basically skips frame updates at some pretty weird, random interval. So if I zoom out the scope to see larger time interval of the expected, perfectly even, blinking pattern (Pinephone Pro:, I see this instead: (yes, pixels are really that lazy on OG PP)

The driver is skipping frame updates A LOT. Many times a second.

What is interesting though is that the driver is completing DRM atomic flips and reporting them to userspace at perfect 60 Hz! So the hardware is reporting a display scanout success to the driver, even when the update does not actually happen. (Or it happens for a wrong framebuffer.)

Just to be sure, I've removed all my changes from sun4i DRM driver, and the result is not very encouraging. It's even worse than with my fixes: (pixels seem less lazy only because this also removed my 60 Hz fix, so the display is running at 43 Hz in this capture giving those small liquid buddies more time to shift around)

Go wonder.

These frame skips are almost certainly one of those remaining things that still make original Pinephone feel not so smooth when scrolling or when watching movies.

That's something to fix. I'm reasonably sure this will be due to misuse of DE2 vsync interrupt for making register swaps for the next scanout. (There's a another special interrupt in DE2 that's meant to report that registers are ready to be swapped, which is not used by the mainline driver)

Regardless, now that this is very easy to replicate, it should be possible to experiment with sun4i-drm driver changes and find a fix rather quickly.