2021–09–04:
Pinephone HDMI hot-plug-detection HW bug
I've figured out what is the cause of an issue that some Pinephone owners
experience, when using the convergence dock. It's a HW bug in the
pinephone's design of level shifting circuitry for the hot plug detect (HPD)
signal between HDMI bridge and A64 SoC.
Relevant circuit is here: https://megous.com/dl/tmp/452023169b0cce41.png
- HHPD is 3.3V input that needs at least 2.3V to detect HDMI plugin
correctly.
- ANX_HPD_OUT is 1.8V output that ANX7688 uses to notify that the HDMI cable
is plugged to the dock.
- The circuit in between (Q1300) does nothing to shift the levels. It makes
voltage levels on the HHPD pin of A64 even worse, depending on the particular
gate threshold voltage (Vth) of the Q1300 mosfet, which differs between batches
in the range of 0.4 – 1V. HHPD voltage in that circuit is approximately
max(0, Vg - Vth)
. That is 1–1.4V and not even close to
required 2.3V.
If you have this issue, and you're using my kernel v5.13 or later, which
includes HPD change logging patches, you will:
- either not see any hotplug events in dmesg after connecting the dock, (if
the voltage is too low for HHPD pin to register a logical high level
on it)
- or see a flood of messages like these https://megous.com/dl/tmp/aaf16b81b25f132e.png
(if the voltage is in the gray zone around the flipping point between high and
low levels)
NOTE: If you're using Mobian, the above may not apply to you, because Mobian
cherry-picks patches from my tree, and may not include the HPD debugging one. If
you want to help me debug kernel or hardware issues, debug with a distro that
uses my kernel tree more directly.
This may also explain why for some people HDMI works only at certain battery
charge level, because the issue depends on precise voltages and part tolerances
in the particular phone, and these may shift a bit depending on the current
voltage of the battery.
It's fixable in software. Quick workaround may be to ignore the HHPD
pin's state, and try forcing the HDMI-A-1 connector to be enabled. You may
also need to dump EDID data from your monitor and force load them on Pinephone.
How to do it is described below.
It may be enough to make it work (I haven't tried the workaround myself),
for people who experience this issue.
Proper software workaround will be a bit more involved, requiring to perform
hot plug detection in software by querying the HDMI bridge chip's status over
I2C bus, and passing it to DRM driver via a software path.
How to test with a quick
workaround
- Dump your monitor's EDID binary data on some other Linux computer
using
cat /sys/class/drm/card-[connector_name]/edid > edid.bin
- Copy
edid.bin
to your pinephone and pass it to the kernel
using cat edid.bin > /sys/kernel/debug/dri/[card_id]/HDMI-A-1/edid_override
- Force enable enable HDMI output by
echo on > /sys/kernel/debug/dri/[card_id]/HDMI-A-1/force
Now you should be able to get past the dreaded
DP state 0x03
.
You need to figure out correct values for [connector_name]
and
[card_id]
yourself by browsing the parent directories
/sys/kernel/debug/dri/
and /sys/class/drm/card
,
because these can differ netween systems.