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 https://megous.com/dl/tmp/c6502c5610bfcc28.png
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: https://megous.com/dl/tmp/c085a50ccd387257.png),
I see this instead: https://megous.com/dl/tmp/9feeb09553ce976c.png
(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: https://megous.com/dl/tmp/c9a286427ce66d80.png
(pixels seem less lazy only because this also removed my 60 Hz fix, so the
display is running at 43 Hz in this capture https://megous.com/dl/tmp/8f4b586e2c945bc6.png
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.