megi's PinePhone Development Log RSS

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:

If you have this issue, and you're using my kernel v5.13 or later, which includes HPD change logging patches, you will:

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

  1. Dump your monitor's EDID binary data on some other Linux computer using cat /sys/class/drm/card-[connector_name]/edid > edid.bin
  2. 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
  3. 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.