Adds true progressive 240p/288p output over composite (the 3.5mm A/V jack) on a
Raspberry Pi 4 running the mainline vc4-kms-v3d driver, and fixes a mode-selection
bug that causes video players (MPV, RetroArch, etc.) to silently fall back to
interlaced 480i/576i instead of the progressive mode the rest of the system is using.
This is not a full kernel — it's two modified source files belonging to the
vc4 module (vc4.ko), the GPU/display driver. You rebuild just that one module
against your existing installed kernel; nothing else needs to change.
A weekly GitHub Action rebuilds this
against whatever kernel version Raspberry Pi OS currently ships and publishes
it as a release, tagged kernel-<version> (e.g. kernel-6.18.34-1+rpt1),
with vc4.ko and vc4.ko.xz attached. Check the Releases page
for a build matching your exact uname -r — kernel modules only load against
the exact version they were built for, so a mismatched one simply won't load
(no harm done, just won't insmod). If nothing matches your version yet, either
wait for the next weekly run, trigger it manually from the Actions tab, or
build it yourself with the steps below.
drivers/gpu/drm/vc4/vc4_vec.c— adds a"720x480 (scaled)"/"720x576 (scaled)"mode: a normal-looking 720x480/720x576 framebuffer (so apps render into a comfortable, normal-sized canvas) that the encoder scans out as genuine progressive 240p/288p timing, matching the same horizontal line rate as the interlaced modes. Also flags this modepreferredon the connector whenever a progressive mode was requested at boot via the kernelvideo=cmdline parameter — without this, MPV (and anything else that doesn't request an explicit mode) grabs its own DRM master for playback and defaults to whatever mode is flaggedpreferred, which is the stock interlaced mode. That silent fallback is what causes "combing" / vertical jitter / a rolling artifact specifically when video starts, even though the rest of the system (menus, console) looks correct.drivers/gpu/drm/vc4/vc4_plane.c— rescales plane geometry to match the real (halved) mode instead of the doubled one advertised to the rest of KMS.
We tried that first. On this specific vc4/Pi4 combination, having a second DRM client (e.g. MPV) explicitly force a non-default mode via its own atomic commit reproducibly hard-crashes the system — silent, instant, no kernel log output at all, reproduced identically with both a custom and a completely stock mode, so it isn't specific to this patch. That's consistent with long-standing, still-unresolved instability in vc4's atomic-commit/DRM-master-handoff path (see raspberrypi#4493, #6772, #3842 for the same general area). The fix above avoids that path entirely — nothing ever needs to force a mode change from a second client.
- Raspberry Pi 4, running Raspberry Pi OS (Bookworm or Trixie) with the
vc4-kms-v3doverlay (the default). config.txt: add,composite=1to thevc4-kms-v3doverlay line —dtoverlay=vc4-kms-v3d,composite=1— this is required to even bind the VEC (composite encoder) hardware at all; without it the composite connector never appears.cmdline.txt: append a progressive mode request, e.g.video=Composite-1:720x480@60efor NTSC (drop thei— no trailing interlace flag — that's what selects progressive).- Kernel headers matching your exact running kernel (
uname -r), via the distro'slinux-headers-rpi-v8(Trixie) /raspberrypi-kernel-headers(older Bookworm) package, or the exact-matchinglinux-source-<version>package from the same apt repo, which is what these two files were built against and verified working on.
-
Get a kernel source tree that matches your exact installed kernel version. The most reliable way (Trixie/Bookworm, apt-based): install the matching
linux-source-<major>package from the same repo your kernel came from and extract it, e.g.:apt-cache policy linux-image-$(uname -r) # confirm exact version apt-get download linux-source-<major> # matching source pkg sudo dpkg -i linux-source-<major>_*.deb tar xf /usr/src/linux-source-<major>.tar.xz -C ~/A
git cloneof theraspberrypi/linuxbranch tip is not guaranteed to match your exact installed kernel — branches move ahead of what's actually shipped, and that mismatch can break the build with undefined-symbol errors unrelated to this patch (we hit exactly this once — see commit history). -
Replace the two files in your source tree with the ones in this repo:
cp drivers/gpu/drm/vc4/vc4_vec.c <your-tree>/drivers/gpu/drm/vc4/vc4_vec.c cp drivers/gpu/drm/vc4/vc4_plane.c <your-tree>/drivers/gpu/drm/vc4/vc4_plane.c -
Build just the vc4 module against your installed kernel's headers:
cd <your-tree> make -C /lib/modules/$(uname -r)/build M=$PWD/drivers/gpu/drm/vc4 modules -
Install it, and make sure your initramfs is regenerated — vc4 loads early enough (for the KMS console) that a stale initramfs can keep loading an old cached copy of the module even after you've replaced it in
/lib/modules. This bit us during testing:sudo cp drivers/gpu/drm/vc4/vc4.ko /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/vc4/vc4.ko sudo rm -f /lib/modules/$(uname -r)/kernel/drivers/gpu/drm/vc4/vc4.ko.xz # avoid ambiguity with the stock compressed module sudo depmod -a sudo update-initramfs -u -k $(uname -r) -
Edit
config.txt/cmdline.txtas described above, then reboot. -
Verify before trusting it on a real display:
modetest -c | grep -A8 Composite-1You should see a
"720x480 (scaled)"(or576) mode flaggedpreferred, userdef, driver. Then check the actual display.
Keep a copy of your stock vc4.ko.xz (or just apt install --reinstall linux-image-$(uname -r)) and re-run update-initramfs -u afterward — same
initramfs caveat applies in reverse.