Jump to content

HDMI0 fails to link at low pixel clocks (hdptx phy lane can't ready) — workaround via patched EDID


Go to solution Solved by TrueLine Timing,

Recommended Posts

Posted

Board: Orange Pi 5 Pro (RK3588S)
OS: Armbian, kernel 6.1.115-vendor-rk35xx
Display: Generic 7" HDMI panel, 1024x600 native (SKU MPI7002, "7inch HDMI Display-C")

 

Symptom

 

HDMI0 (the HDMI 2.1 port, using the new hdptx combo PHY via dwhdmi-rockchip) reliably fails to link-train at this panel's native timing (1024x600@59.82Hz, pixel clock 50.25MHz):

 

dwhdmi-rockchip fde80000.hdmi: use tmds mode
rockchip-vop2: Update mode to 1024x600p60 ... dclk: 50250000
rockchip-hdptx-phy-hdmi fed60000.hdmiphy: hdptx phy pll locked!
rockchip-hdptx-phy-hdmi fed60000.hdmiphy: hdptx phy lane can't ready!
phy phy-fed60000.hdmiphy.7: phy poweron failed --> -22
dwhdmi-rockchip fde80000.hdmi: dw_hdmi_qp_setup hdmi set operation mode failed

100% reproducible across 6+ reboots. Ruled out with real hardware tests (not the actual cause):

 

 

  • Bad cable (same HDMI 2.1 8K UHD cable works fine on the board's other HDMI port)
  • Monitor power sequencing (fails identically whether the monitor is powered from the Pi's own USB or an independent wall adapter)
  • Shared PHY contention (fails identically with only one monitor connected, nothing else)

 

What actually works

 

The same physical port locks fine at a higher pixel clock — confirmed with the standard 720p60 timing (1280x720@60, dclk 74.25MHz):
rockchip-vop2: Update mode to 1280x720p60 ... dclk: 74250000
dwhdmi-rockchip fde80000.hdmi: final tmdsclk = 74250000
rockchip-hdptx-phy-hdmi fed60000.hdmiphy: hdptx phy lane locked!

So this looks specific to low pixel clocks on this PHY, not a broken port. This matches ongoing upstream work on phy-rockchip-samsung-hdptx (patch series through v6, August 2026) fixing PLL/clock-ratio edge cases — this vendor kernel predates those fixes.

 

(Side note: the board's second HDMI port, which shows up as DP-1/DP0 in dmesg since it's actually the SoC's native DP output through an on-board Lontium LT8711UXD DP-to-HDMI bridge chip, is not a working alternative for this panel either — Armbian's kernel has no driver/devicetree node for that bridge chip at all, so DP link training "succeeds" at the protocol level but no usable HDMI signal ever reaches the display.)

 

Workaround: EDID override with increased blanking

 

Instead of switching resolutions (with visible upscaling artifacts), I kept the monitor's native 1024x600 active area but patched its EDID to advertise a higher pixel clock via more blanking (1024x600, htotal 1650, vtotal 750, dclk 74.25MHz — reusing the same clock that's confirmed to work at 720p60), then loaded it via drm.edid_firmware=.

 

Confirmed working end-to-end from cold boot:
[drm] Got external EDID base block and 1 extension from "edid/monitor7_1024x600_ib.bin" for connector "HDMI-A-1"
Update mode to 1024x600p60 ... dclk: 74250000
hdptx phy lane locked!

 

Full write-up (EDID byte-level patching script, initramfs hook gotcha, etc.) here: [link a deploy/edid/README.md en tu repo, si quieres que sea público]

 

Posting in case anyone else hits the same low-clock failure on this PHY, and in case it's a useful data point for whoever's working on the phy-rockchip-samsung-hdptx patches.

  • Werner changed the title to HDMI0 fails to link at low pixel clocks (hdptx phy lane can't ready) — workaround via patched EDID
Posted

Thanks for the detailed write-up — the 50.25 vs 74.25 MHz contrast is exactly the kind of data point the hdptx work needs. We've seen the same pattern on EM3588 (RK3588, dual HDMI 2.1, vendor 6.1): the PHY locks without complaint at standard clocks but gets flaky below ~75 MHz on some panels, which lines up with what the upstream phy-rockchip-samsung-hdptx series has been chasing around PLL and clock-ratio edge cases. The vendor kernel here clearly predates those fixes.
Your EDID approach is also the practical answer for industrial displays. Most of the low-resolution panels we run into in signage and access-control products (1024x600, 800x480) sit right in that fragile clock range, and inflating blanking to reuse a known-good dclk keeps the native active area untouched — much cleaner than letting the scaler upscale. The initramfs gotcha you hit is worth repeating too: the connector asks for EDID well before the rootfs is up, so the override has to live in initramfs or it silently misses.

  • Solution
Posted

@Boardcon_yang thanks for confirming this on the EM3588 — the ~75MHz threshold
you're seeing lines up exactly with what I found: 50.25MHz never locks, 74.25MHz
(the 720p60 clock) locks every time on the same port and cable. Good to know
it's not specific to the Orange Pi 5 Pro or to this particular panel.

 

Also, apologies: the "[link a deploy/edid/README.md ...]" line at the end of my
first post was a leftover placeholder (the repo is private), and I can no
longer edit the post.

 

Here are the full steps instead, so this is self-contained:

 

1) Validate the timing live first (stop getty@tty1 so modetest can take DRM master):

   sudo systemctl stop getty@tty1
   sudo modetest -M rockchip -s <connector_id>:1024,1210,1278,1650,600,625,650,750-60

   -> dmesg should show "hdptx phy lane locked!" and the panel should show an image.

   Timing used (same 1024x600 active area, more blanking, 74.25MHz = the 720p60 clock):
     H: active 1024, front porch 186, sync 68, back porch 372 -> htotal 1650
     V: active 600,  front porch 25,  sync 25, back porch 100 -> vtotal 750
     74,250,000 / (1650 x 750) = 60.0 Hz

2) Patch the EDID: dump the panel's real EDID (modetest -M rockchip -c, EDID blob
   property of the connector), rewrite only the first Detailed Timing Descriptor
   (bytes 54-71) with the timing above, keep the physical size bytes (66-71)
   untouched, and recompute the checksum (byte 127).

3) The initramfs gotcha (as you said, the connector asks for the EDID before the
   rootfs is up): update-initramfs does NOT pick up loose files in
   /lib/firmware/edid/ — it only packs firmware referenced by kernel modules.
   Without this you get "Direct firmware load for edid/<file>.bin failed with error -2".

   /etc/initramfs-tools/hooks/edid-firmware (chmod +x):

   #!/bin/sh
   PREREQ=""
   prereqs() { echo "$PREREQ"; }
   case "$1" in
       prereqs) prereqs; exit 0 ;;
   esac
   . /usr/share/initramfs-tools/hook-functions
   copy_file firmware /lib/firmware/edid/monitor7_1024x600_ib.bin

   sudo update-initramfs -u
   lsinitramfs /boot/initrd.img-$(uname -r) | grep edid   # must list the file

4) /boot/armbianEnv.txt, extraargs:

   video=HDMI-A-1:1024x600@60 drm.edid_firmware=HDMI-A-1:edid/monitor7_1024x600_ib.bin

   Note: use drm.edid_firmware= — the old drm_kms_helper.edid_firmware= is
   deprecated on this kernel and silently loads nothing (only a warning).

 

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
×
×
  • Create New...

Important Information

Terms of Use - Privacy Policy - Guidelines