Appendix · reference

RK3399 VOP-Lit

The display controller that scans the panel — works, except under sustained load.

The Video Output Processor (VOP) is RK3399’s display controller. It fetches framebuffers, composes planes, and drives the display interfaces (MIPI DSI, eDP, HDMI). RK3399 has two: VOP-Big and VOP-Lit. The PinePhone Pro panel is on VOP-Lit at 720×1440 @ 60 Hz.

Today the VOP is the primary open issue on the display path. First modeset is fine, day-to-day Sway works, but Hyprland output reconfig or sustained GPU load takes the modeset chain into a wedge that sometimes panics with [CRTC:33:crtc-0] flip_done timed out.

Identity

PropertyValue
BlockRK3399 VOP-Lit
MMIO base0xff8f0000
Resolution720×1440 @ 60 Hz on the PPP panel
OutputMIPI DSI → DW-MIPI-DSI bridge → HX8394 panel
DTS compatiblerockchip,rk3399-vop-lit
Linux driverdrivers/gpu/drm/rockchip/rockchip_drm_vop.c

Driver

◐ partial Local fork of the Rockchip VOP driver under the DRM subtree.

The driver has been heavily worked: full MIPI DSI bring-up ( 3462965 MIPI DSI pipeline: full driver stack, VOP outputting frames ), event-handling iterations ( c11b579 vop: fix atomic commit completion — move event to atomic_flush only , 98406a4 vop: revert atomic_begin change — keep event handling in both begin and flush , 07aca7b vop: fix event race — handle page flip event only in atomic_flush , 736d191 vop: send commit event immediately instead of arming for vblank ), the panfrost-reset deadlock workaround that dropped wait_for_vblanks ( 604bd8f rk_drm: skip wait_for_vblanks in commit_tail to prevent GPU reset deadlock ), then a TODO panic in rk_vop_plane_atomic_update and a NULL deref in rk_plane ( bc6b664 drm: fix rk_plane panic that triggered DRM atomic_helper NULL deref , 1009996 rk_plane: don't gate the window off on transient invisible state ).

Open issues

The cross-driver audit identified three structurally suspect items in the modeset path that match the wedge symptoms exactly. Two code-side fixes are now in the local overlay; the driver-side event latch is still open.

  1. drm_atomic_helper_wait_for_vblanks removed from our custom rk_drm_atomic_commit_tail. Without it, cleanup_planes runs in the same commit as commit_hw_done, leaving the next commit’s flip_done waiter unfulfilled. The original deadlock that motivated the removal predates the panfrost reset rework ( 3378d3d Queue Panfrost reset before scheduler stop , cf2dd90 Fix Panfrost reset fence signaling context ); the workaround is now over-eager.
  2. Shared-IRQ ack wrote ~0 at rk_vop.c:280, clobbering any in-flight FS_INTR that arrived between the status read and the clear write. a830a08 rk_vop: restore atomic vblank wait changed the ack to INTR_CLEAR0 = status.
  3. Double-event drain between rk_crtc_atomic_begin and rk_crtc_atomic_flush, plus a vblank_get without a balancing vblank_put. The current overlay still does not hold the event on a driver-side latch between flush and the FS_INTR vblank IRQ.

The GPU under load essay tracks the wedge. The fix path is laid out in the audit’s “rk_vop / Recommendations (priority order)” section.

Status

QuestionAnswer
Probes?Yes
First modeset?Yes — Sway and Hyprland come up
Sustained load?Wedge — modeset-lock + flip_done timeout. Re-confirmed on #145 (2026-05-04) via kldunload bwfm_sdio && kldload bwfm_sdio; not Hyprland-specific.
Output reconfig?Same wedge as above; any DRM-adjacent code path yanked while pages in flight reproduces it.

Parity verification

Two audit fixes now have code in the overlay. Verification plan: