evidence · 8.4 KiB

kernel-vblank-latch.md

Committed at docs/evidence/card-shell/bottom-band-flicker/kernel-vblank-latch.md. This is what grounds the requirements that cite it.

Open raw source

Kernel finding: the VO’s shadow-register commit is not synchronized to scanout

Branch fix/drm-vblank-latch-and-idle-redraws, based on origin/master (fed8fdb2). Follows the board diagnostic in docs/evidence/card-shell/bottom-band-flicker/board-diagnostic.md, whose result (installed as 3f1dlarv…, log at /tmp/claude-1000/.../scratchpad/bottom-strip.log, 74,513 lines, real finger gestures recorded in scratchpad/flick4.mkv) is the evidence this fix is grounded in:

What the driver source shows

drivers/gpu/drm/canaan/ (pinned ruyisdk/linux-xuantie-kernel @ 7d4e1f444f461dbe3833bd99a4640e7b6c2cd529, nix/kernel-src.nix):

Conclusion: the driver has the plumbing for a real double-buffered, vblank-synchronized commit (VO_REG_LOAD_CTL as a distinct “go” step, kept separate from the individual register writes, and a working vblank IRQ already wired into DRM’s own event/vblank-counter machinery) — it just never connects the two. VO_REG_LOAD_CTL fires synchronously at commit time instead of at the interrupt. Whether the underlying VO hardware additionally has its own internal shadow-latch behavior on that bit is a question this source reading cannot answer (no datasheet is grounding here, per .skills/k230-spec-change/SKILL.md) — but the software gives the bit no chance to matter either way, since it is written at an arbitrary point in the current frame’s scan rather than during the blanking window the driver’s own IRQ line (VO_DISP_IRQ1_CTL, computed from vtotal in canaan_vo_set_timing()) is positioned at.

This is also consistent with the separately-established, unrelated docs/evidence/flicker-after-headroom-revert.md finding that this panel’s own TE line is never consumed (a free-running host/panel phase). That is a display/panel-side gap this change does not touch; the fix below is scoped to making the VO’s own commit timing correct, which is a necessary condition for correctness regardless of what the panel side turns out to need later.

The fix

nix/patches/canaan-drm-defer-reg-load-to-vblank.patch (see nix/kernel.nix for where it’s added to the pinned kernel’s patch list):

This is the smallest change that makes the existing plumbing do what its own naming and structure already imply it should: apply the shadow registers only inside the interrupt the driver author positioned at the blanking window, and never anywhere else. It cannot make the existing behavior worse (the write still happens, at most one frame period later, and only ever exactly once per armed commit); if the VO hardware’s own internal latching already made this bit’s timing irrelevant, this change is inert. If it did not — which the board symptom (torn/flickering band specifically on late-render frames) is most consistent with — this removes the race.

What this does not claim

Verification performed (host only; no board access)