[AMD Lucienne/Ryzen] HDMI not detected — HP laptops — HPD failure + deep color fix

External display via HDMI is not detected on HP laptops with AMD Lucienne (Ryzen 4xxx/5xxx APUs) and possibly other AMD-based laptops. The TV may show “signal detected” (due to +5V on the HDMI power pin) but the system never sees the display — the kernel reports the HDMI-A-1 connector as disconnected with 0 bytes of EDID.

When the connector is force-enabled, the display may work but shows severe artifacts and constant blinking because amdgpu negotiates 16 bpc (48-bit) deep color over the HDMI link, exceeding cable bandwidth.

Cause

Two separate issues:

1. HPD (Hot-Plug Detect) GPIO failure — On certain laptop implementations (commonly HP with AMD Lucienne/DCN 2.1), the amdgpu driver never receives the HPD signal. The HDMI +5V pin is always active (so the TV thinks something is connected), but the HPD line is never asserted or read by the driver. Without an HPD event, amdgpu never probes DDC, never reads the EDID, and never marks the connector as connected.

2. Deep color overload — The TV’s EDID advertises 36/48-bit deep color capability. When amdgpu honors this, it drives 48-bit color at 1080p60, which exceeds what the HDMI cable/port can carry → sparkle artifacts and blinking.

Workaround (proven fix)

Step 1 — Capture TV’s EDID from the DDC bus

sudo dnf install -y i2c-tools

Find the HDMI DDC bus:

ls -la /sys/class/drm/card1-HDMI-A-1/ddc/
# → /sys/devices/.../i2c-3 (yours may differ)

Capture the full EDID (256 bytes):

sudo python3 -c "
import os, fcntl, time
f = os.open('/dev/i2c-3', os.O_RDWR)
fcntl.ioctl(f, 0x0703, 0x50)  # I2C_SLAVE
os.write(f, bytes([0x00]))
time.sleep(0.02)
block0 = os.read(f, 128)
os.write(f, bytes([128])) if block0[126] else None
time.sleep(0.02)
block1 = os.read(f, 128) if block0[126] else b''
os.close(f)
with open('/tmp/tv-edid.bin', 'wb') as out:
    out.write(block0 + block1)
print(f'Captured {len(block0 + block1)} bytes')
"

Step 2 — Optionally remove deep color (to prevent artifacts)

python3 -c "
with open('/tmp/tv-edid.bin', 'rb') as f:
    edid = bytearray(f.read())
if edid[173] & 0xF0:
    edid[173] &= 0x0F
    edid[255] = (256 - (sum(edid[128:255]) % 256)) % 256
    with open('/tmp/tv-edid.bin', 'wb') as f:
        f.write(edid)
    print('Deep color flags removed from EDID')
"

Step 3 — Deploy to initramfs and kernel cmdline

sudo mkdir -p /lib/firmware/edid
sudo cp /tmp/tv-edid.bin /lib/firmware/edid/tv-edid.bin
sudo chmod 644 /lib/firmware/edid/tv-edid.bin
echo 'install_items+=" /lib/firmware/edid/tv-edid.bin "' | sudo tee /etc/dracut.conf.d/edid.conf
sudo dracut --regenerate-all --force
sudo grubby --update-kernel=ALL --args="drm.edid_firmware=HDMI-A-1:edid/tv-edid.bin video=HDMI-A-1:e"
sudo sed -i 's/^GRUB_CMDLINE_LINUX="/GRUB_CMDLINE_LINUX="drm.edid_firmware=HDMI-A-1:edid\/tv-edid.bin video=HDMI-A-1:e /' /etc/default/grub
sudo reboot

Step 4 — Verify

cat /sys/class/drm/card1-HDMI-A-1/status       # should say "connected"
dmesg | grep -i 'tv-edid'                       # should show no errors

How it works

  • drm.edid_firmware=HDMI-A-1:edid/tv-edid.bin — feeds the captured EDID at boot, bypassing the broken HPD. Forces the connector to connected with correct display capabilities.
  • video=HDMI-A-1:e — extra insurance that the connector is force-enabled.
  • EDID in initramfs — required because firmware loading happens before /lib/firmware is available from the root filesystem.
  • Patched EDID — removing DC_36bit/DC_30bit/DC_Y444 flags prevents deep color negotiation entirely.

Hi @stjone , is this report AI-generated? It contains very deep technical details, but no links to actual bug reports. Where did you learn the technical details from? Have you reported this to the amdgpu driver developers, or is there an existing bug report for your issue already?

The instructions seem extremely specific to your setup, i.e. your laptop + display/TV combination. Do you have any pointers showing that this is a more general issue?