Powkiddy RGB30: playable NDS via sdl2_drastic and related fixes - #100
Open
jamespharaoh wants to merge 30 commits into
Open
Powkiddy RGB30: playable NDS via sdl2_drastic and related fixes#100jamespharaoh wants to merge 30 commits into
jamespharaoh wants to merge 30 commits into
Conversation
The image-final systemsReport.sh iterates architectures from a list containing 'rk3566', looking up configgen-defaults-<arch>.yml. But only configgen-defaults-rk3568.yml exists. Symlink rk3566 -> rk3568 so both names work (proper fix would be to normalize on one). Also add a default emulator+core for the 'quake' system, which es_systems.yml defines but configgen-defaults.yml never had an entry for. Without a default, systemsReport.sh throws 'default core (None/None) not enabled for <arch>/quake'.
0008 (rg-arc-battery-adjustment) is malformed: hunks contain bare empty lines instead of space-prefixed context blanks. Strict patch(1) refuses to apply. Only modifies rk3566-rg-arc-linux.dts, safe to skip for non-RG-Arc boards. 0010 (rg-arc-cpu-and-leds) hunk 3 also touches the battery block and depends on state 0008 was supposed to leave. Failing 0008 => failing 0010. Also RG-Arc-only. Disable by renaming to .patch.disabled (buildroot only picks up *.patch by default). Proper fix later: repair 0008's whitespace so both patches apply cleanly.
See individual commits in the submodule for details: - sdl2: always add libgbm/libegl deps when KMSDRM is enabled - weston: force renderer-gl=false on knulli builds Both work around limitations of the shipped mali libmali blob and a kconfig quirk that strips BR2_PACKAGE_HAS_LIBGBM/HAS_LIBEGL from .config after syncconfig.
sdl2_drastic uses SDL2 as its base with the drastic detour code baked into src/, and requires the same GPU/render-path patches as system SDL2 to work on this platform. Without the 9 board patches — in particular librga hardware rotation and the mali-blob GBM_BO_USE_LINEAR fallback — sdl2_drastic SIGSEGVs on video init. Symlink keeps a single source of truth so future edits reach both automatically.
trngaje's video_handler thread sets up its own DRM + GBM + EGL and tries to drive the display in parallel with SDL's KMSDRM backend. On the rockchip mali-blob-gbm variant this doesn't work: the blob's gbm_bo_get_handle isn't a valid DRM GEM handle so drmModeAddFB fails EINVAL, and even if fixed we'd fight SDL for DRM master. Instead, when ADVDRASTIC_SDL_GL is defined (rk3568 target only): * Main releases its GL context via SDL_GL_MakeCurrent(win, NULL) on the first render callback (release_main_gl_context_once). We save win/ctx pointers first because SDL nulls current_glctx on release. Mali blob requires the source thread to be unbound before another thread can eglMakeCurrent - documented behaviour, not a quirk. * video_handler lazy-inits (deferred from thread startup, runs on first GFX_Flip/GFX_Copy) so the release has definitely happened. Guards prevent lazy init running on any thread other than video_handler. * egl_init calls SDL_GL_MakeCurrent(saved_win, saved_ctx) - the cross-thread migration succeeds now that main released. * GFX_Flip calls SDL_GL_SwapWindow(vid.window), NOT raw eglSwapBuffers. Raw eglSwapBuffers only cycles the EGL back buffer; SDL's KMSDRM_GLES_SwapWindow wraps it in the full lock_front_buffer / drmModeAddFB / drmModePageFlip pipeline which is what actually promotes the GBM front buffer to the scanout plane. Guards on GFX_Flip / GFX_Copy no-op if egl_init has never succeeded (e.g. main never released) so audio and input keep working even if video is broken. h700 (mali-fbdev) and a133 targets don't define ADVDRASTIC_SDL_GL, so their code path is unchanged. The pre-existing ADVDRASTIC_DRM branch is also unchanged and remains inert on rk3566. Verified: Mario Kart DS launches, 3D emulation runs, video displays. Known outstanding: audio stutter and slow 3D (likely cross-thread EGL + full SDL swap pipeline overhead); 4:3 stretched to 1:1 720x720 layout - separate config issue.
The rk3566 SDL_GL_SwapWindow takes ~30ms on this stack (kernel 4.19, legacy drmModePageFlip API allows only one flip in flight, mali GPU work, RGA blit). The parent commit had sdl_update_screens block on cond_wait for that entire duration every frame, capping the NDS emulator at ~18fps and stuttering audio. Now: main snapshots drastic's NDS screen pixels into one of 2 ring slots, atomically publishes it under snap_mutex, cond_signals video_handler, and returns without waiting. Video_handler grabs the latest slot, releases the outer lock during the render+flip so main's next mutex_lock isn't blocked either, then renders. process_screen reads pixels from the snapshot slot instead of raw VAR_SDL_SCREEN* pointers (which would race with drastic's ongoing emulation). This is the standard emulator threaded-video pattern (as in RetroArch, PCSX2, PPSSPP): emulation rate and render rate are independent, intermediate frames get dropped. Measured: 2D scenes now hit 60fps (up from ~18 before). 3D scenes limited by NDS 3D emulation CPU cost, not by video pipeline. Vanilla-drastic behaviour, no more. Guarded by ADVDRASTIC_SDL_GL; h700/a133 code paths unchanged. Known outstanding: menu crash (display_custom_setting calls GFX_Copy/GFX_Flip inline on main thread, tripping the thread-guard). Separate fix.
display_custom_setting calls GFX_Copy/GFX_Flip inline on main thread. Once video_handler has run egl_init (making vid.eglDisplay non-null), those calls skip the lazy-init check and go straight to glTexImage2D / glDrawElements on main - but the GL context is bound to video_handler, so main hits a NULL current context and SEGVs. Fix: hard-guard GFX_Copy and GFX_Flip to no-op when called from any thread other than video_handler. In display_custom_setting, replace the inline calls with a `nds.update_menu = 1` set so video_handler picks up the render on the subsequent cond_signal (same path the menu uses everywhere else). Menu now renders via video_handler (the advanced_drastic menu with the extra functionality) instead of segfaulting. Guarded by ADVDRASTIC_SDL_GL; h700/a133 code paths unchanged.
Powkiddy shipped RGB30 hardware in two revisions with the tcs4525 CPU buck regulator at different i2c addresses (0x1c on early boards, 0x40 on later boards). knulli's kernel tree carries two DTS variants for this - the v1 (default) targets 0x1c, v2 targets 0x40 but drops a bunch of knulli-friendly ergonomics (wakeup-source, power-key handler, suspend config). Both came from JELOS upstream (fewtarius commits 9d98ce7b4 Sep 2023 and d4d7335a5 Feb 2024). On our HW-rev the chip is at 0x40 (i2cdetect confirms 0x1c is empty, 0x40 responds), so the tcs452x driver never binds against v1's DTS, no vdd_cpu regulator materialises, and arm_rockchip_cpufreq refuses to register any cpufreq policy. Symptoms: CPU stuck at 408 MHz (max 1.8 GHz), empty /sys/devices/system/cpu/cpufreq/, empty "clock rate" menu in EmulationStation. Fix v1's tcs4525 address in place (0x1c -> 0x40). Keeps all of v1's suspend/power ergonomics, only changes the wrong hex digit. This is a local workaround that assumes HW-rev v2; older HW-rev v1 boards would be broken by this change. A proper fix needs runtime HW detection at u-boot (precedent: rg35xx ships 3 battery-variant DTBs picked by Actions bootloader) - separate discussion to raise with knulli. Signed-off-by: James Pharaoh <james@pharaoh.uk>
Upstream Mikhailzrick (790e97b, Jul 2026) added rk3568 default of 1800 MHz. This adds warn labelling for 1992 MHz - the RK3566 is spec'd to 1800 MHz max, so 1992 is an overclock that runs hotter and drains battery faster. Match the h700 pattern (which warns on its 1704 max). Depends on the vdd_cpu i2c address fix - without cpufreq registering, this is moot on affected hardware. Signed-off-by: James Pharaoh <james@pharaoh.uk>
knulli-main has three source lines pointing at Config.in files that have never been committed to the tree: package/emulators/ppsspp/Config.in package/modules/rtl8733bu/Config.in package/libraries/shaderc/Config.in (already commented out upstream) Kconfig fails immediately with 'can't open file' during defconfig generation on any target, blocking the build entirely. Same pattern as the vtree issue that was later fixed by adding the package. These need the same treatment upstream. Comment out locally so we can build. Signed-off-by: James Pharaoh <james@pharaoh.uk>
The upstream trngaje/drastic_layout config for 720x720 has 17 layout entries but 7 of them are broken on this device: - vh_t0, vh_t1, s1, hres1 stretch screen1 to 720x720, distorting the 4:3 NDS content on our 1:1 display - hh0, hh1 place two 480-wide screens at x=0/x=360, needing 960px width - the right screen clips 120px off screen - thraeg_vh_s2 uses y=-6, clipping 6px off the top and bottom Overall the config was accumulated across contributions with duplicate indices and no consistent aspect handling. Users can't easily tell which entries render correctly since the UI shows only index numbers. Replace with a small tuned selection of 7 entries in ordered-by-utility sequence, all aspect-correct with no clipping. Ship as an rk3566 fsoverlay so h700 / a133 / anything else with a real 720x720 layout is unaffected (drastic picks the layout file matching current display resolution). [0] stack_tight two 480x360 stacked, no gap - default in-game [1] hero_top 720x540 top + 240x180 bottom overlay [2] single_small 512x384 letterboxed, screen0 hidden [3] stack_gap two 448x336 stacked with 48px NDS-native gap [4] fullscreen 720x540 letterboxed, screen0 hidden [5] hires_small 512x384 letterboxed (DS hi-res mode) [6] hires_fullscreen 720x540 letterboxed (DS hi-res mode) Should really be sent upstream to trngaje/drastic_layout so all RGB30 users benefit. Signed-off-by: James Pharaoh <james@pharaoh.uk>
The install script guarded gbm.h copy with a check for STAGING_DIR/usr/include/GBM/gbm.h, but the upstream libmali repo lays out headers under versioned subdirs (GBM/<mesa-version>/gbm.h). The guard never matched, gbm.h was silently not copied, and downstream packages doing #include <gbm.h> failed on clean tree. Additionally gbm.pc hardcoded Version: 21.0.0, which weston 14 rejects (requires >= 21.1.1). Now derive the version from the picked header subdir so consumers see a truthful version.
Upstream vaixterm's Makefile supports both a vendored libvterm (from
vendor/libvterm/) and system libvterm (via pkg-config). Upstream's CI
fetches libvterm 0.3.3 from Ubuntu and populates the vendor dir before
building. buildroot has no libvterm package, so the fallback to system
mode fails with fatal error: vterm.h: No such file or directory.
Replicate the CI's fetching as a POST_PATCH hook, and add
-Ivendor/libvterm/{include,src} to the CFLAGS we pass to make (which
otherwise clobbers the Makefile's own VTERM_CFLAGS assignment).
Derived from rg35xx-h; remaps hotkey combos to RGB30 controller layout. HOT+R1 for fast-forward instead of HOT+dpad-right.
…revs The old 0009 patch bundled three unrelated changes (joypad rename, suspend/wakeup plumbing, volume-key remap) and only touched the v1 top-level DTS. The old 0010 patched the v1 dtsi's tcs4525 address in place, which fixed the v2 board but would brick v1 boards. Split into three thematic patches, each touching BOTH the v1 and v2 top-level DTS files (they differ only by which dtsi they include, so hunks apply verbatim to both): - 0009: joypad rename retrogame_joypad -> Powkiddy_RGB30_Controller - 0011: suspend/wakeup config + power-key + LCD suspend regulator - 0012: volume keys moved onto singleadc-joypad as sw18/sw19 Drop 0010 entirely. The v1 dtsi is left at tcs4525@1c (correct for v1) and the v2 dtsi is left at tcs4525@40 (upstream-correct for v2). Once u-boot picks the right DTB at boot, both HW revs get the right regulator address without a downstream patch. Interim safety on v2 still relies on shipping /boot/rk3566-rgb30-v2-linux.dtb, which knulli already builds and installs. Signed-off-by: James Pharaoh <james@pharaoh.uk>
Add 0013-rgb30-v2-model-string.patch, which changes the v2 DTB's model property from 'Powkiddy RGB30' to 'Powkiddy RGB30 v2'. Once u-boot picks the right DTB per HW rev, this surfaces in ES System Info as 'Powkiddy_RGB30_v2' on v2 boards and unchanged 'Powkiddy_RGB30' on v1 boards. Also affects the Bluetooth device name (S29namebluetooth reads from knulli-info Model:), so testers can see at a glance which HW rev they are looking at.
Upstream master regressed the BR2_TARGET_KNULLI_IMAGES default for
BR2_PACKAGE_BATOCERA_TARGET_RK3568 from the full list of five board
subpaths (miyoo-flip, powkiddy-rgb30, rg-arc-s, powkiddy-x55, rg-ds)
to just "rockchip/rk3566". The post-image script iterates over that
list and expects each entry to point at a directory containing a
create-boot-script.sh, so with just "rockchip/rk3566" it fails:
bash: /build/board/rockchip/rk3566/create-boot-script.sh: No such file
Restore the full list, matching how BR2_PACKAGE_BATOCERA_TARGET_A133
and other multi-board SoCs express theirs. Was previously present in
the tree; lost somewhere on the current knulli-main branch.
Add u-boot patch that, after SARADC-based board detection resolves to RGB30, probes i2c0 for the tcs4525 CPU regulator at 0x40. If it ACKs, this is a HW-v2 board; set pxe_label_override=rgb30-v2 so u-boot's extlinux/sysboot parser picks the v2 LABEL block. Silent no-op on v1 boards (probe fails, default LABEL rgb30-v1 kicks in) and on all non-RGB30 boards that share the same u-boot binary. extlinux.conf rewritten with two LABEL blocks, one per HW rev, pointing at the correct DTB. DEFAULT is rgb30-v1 (safe fallback if i2c probe fails on a v2 board for any reason). NOTE: the shipped prebuilt u-boot-rk3566.bin does NOT yet contain this patch. To ship this properly the .bin needs to be rebuilt from mainline u-boot v2024.07 + 000-DTB_DIR_boot.patch + 001-rgb30-hw-rev -detect.patch. Until then, HW-v2 boards will boot via the default rgb30-v1 label -> v1 DTB (tcs4525 at 0x1c) -> CPU stuck at 408 MHz. For local v2 testing, temporarily flip DEFAULT to rgb30-v2 in the built image via ssh, or interactively at the u-boot prompt. Signed-off-by: James Pharaoh <james@pharaoh.uk>
The general configgen-defaults.yml sets psp default to emulator=ppsspp / core=ppsspp (standalone PPSSPP). BR2_PACKAGE_PPSSPP is not available on rk3568 (upstream references a missing Config.in; we commented out the include in eb358a3). BR2_PACKAGE_LIBRETRO_PPSSPP is enabled, so knulli-report-system.py finds a psp variant enabled but the default combo unavailable and fails post-image with: Exception: default core (ppsspp/ppsspp) not enabled for rk3566/psp Override at the arch layer to point psp at libretro/ppsspp, matching what is actually available.
Two more knulli-report-system.py failures from the same class as the psp fix in 393751c: - 3ds default is citra/citra in the general defaults, but rk3568 has BR2_PACKAGE_AZAHAR enabled and no CITRA/LIBRETRO_CITRA. Add an arch-layer override to azahar/azahar. - vaixterm default is vaixterm/vaixterm in the general defaults but es_systems.yml declares only one variant: odcommander/odcommander (which requires BR2_PACKAGE_VAIXTERM). This is an upstream defaults typo, not arch-specific - fix in the general file so every arch benefits. Verified with a scripted walk over es_systems.yml + defaults + .config that no other systems currently fail the same check.
Same class of upstream default gap as vaixterm (fixed in eea7fd9). quake2 is declared in es_systems.yml with a single variant (libretro/vitaquake2, requires BR2_PACKAGE_LIBRETRO_VITAQUAKE2) but has no entry in configgen-defaults.yml, so knulli-report-system.py sees a system with an enabled variant, defaultEmulator/defaultCore both None, and fails: Exception: default core (None/None) not enabled for rk3566/quake2 Only affects post-image assembly of boards processed after our RGB30 (which was earlier in the list) - the RGB30 .img.gz did get produced. Fix so the other rk3568 boards' images also complete.
Rebuilt from mainline u-boot v2024.07 + knulli's existing 000-DTB_DIR_boot.patch + our new 001-rgb30-hw-rev-detect.patch (committed in a243e21). Cross-compiled with aarch64-linux-gnu-gcc and rockchip rkbin blobs (rk3566_ddr_1056MHz_v1.25.bin, rk3568_bl31_v1.46.elf). Binary strings confirm the patch made it in: U-Boot 2024.07 (Aug 06 2026 - 15:53:10 +0200) pxe_label_override rgb30-v2 Effect on other rk3566 boards using this binary (X55 uses a separate .bin so unaffected): SARADC-based board detection unchanged. Only new codepath is one i2c0 probe after board_id resolves to RGB30 - silent no-op on all other boards.
Same class of upstream gap as vaixterm/quake2 - es_systems.yml declares namco22 with libretro/mame (BR2_PACKAGE_LIBRETRO_MAME) and mame/mame (BR2_PACKAGE_MAME) variants, but configgen-defaults.yml has no entry. On any arch that enables one of those packages, knulli-report-system.py fails with 'default core (None/None) not enabled for <arch>/namco22'. Scripted walk over the yml + defaults + .config confirms no other systems currently miss defaults.
…700/a133
Every other knulli platform (h700, a133 etc.) runs advanced_drastic
via trngaje's upstream launch.sh:
#!/bin/sh
mydir=$(dirname "$0")
export LD_LIBRARY_PATH=$mydir/libs:$LD_LIBRARY_PATH
cd $mydir
./drastic "$1"
That flow uses advanced_drastic's own drastic binary + our patched
sdl2_drastic libSDL2 (which is what /usr/share/advanced_drastic/libs
is populated with by the sdl2_drastic package). Our rk3566-specific
patches - 0007 (adopt SDL KMSDRM EGL context) - land there and
actually activate.
rk3566 was the odd one out: an fsoverlay at
board/rockchip/rk3566/fsoverlay/usr/share/advanced_drastic/launch.sh
overrode trngaje's launcher with a redirect through drastic_aarch64
plus libhookdrastic:
LD_PRELOAD=/usr/share/drastic_aarch64/libhookdrastic.so \
/usr/share/drastic_aarch64/drastic "$1"
That bypassed our sdl2_drastic build entirely (no LD_LIBRARY_PATH),
so drastic on rk3566 was linked against the system libSDL2 and none
of our Path B rendering patches took effect. Result on RGB30 (v2 or
v1): unplayable stuttering even with CPU scaled to 1.99 GHz.
Delete both the launch.sh override AND the whole drastic_aarch64
fsoverlay directory (drastic binary, libhookdrastic.so, LICENSE,
logos, config, cheats, system dir - 14 files). Nothing else in the
tree references drastic_aarch64; grep confirms the only reference
was the override itself. Advanced_drastic's own drastic binary
(same md5 as trngaje's README requires:
59a7711eff41c640b8861b4d869c747d) takes over cleanly.
Trade-off: rk3566 loses libhookdrastic's menu extensions and the
rg-ds dual-screen switch that was hard-coded in the override. The
menu goes back to trngaje's minimal set (which is the same as what
h700/a133 users have always seen). If rg-ds needs the display
switch, it should live in a rg-ds-specific fsoverlay - the SoC-wide
override affected every rk3566 device (including RGB30 which
doesn't have a second screen).
Signed-off-by: James Pharaoh <james@pharaoh.uk>
Two per-topic docs written during the RGB30 test drop, aimed at downstream reviewers (acmeplus's rk3566 unification, trngaje's SDL_drastic, knulli maintainers, discord readers). rk3566-sdl2-drastic.md: - Audits the 9 pre-existing board sdl2 patches (fewtarius, JohnnyOnFlame, knulli team) and our 1 new sdl2_drastic-only patch (0007-rk3566-adopt-sdl-egl-context). - Explicit: none of these are CPU-throttle workarounds. The "CPU stuck at 408 MHz" fix was separate (DTB + u-boot). Empirical headroom at 1.8 GHz: MKDS 55% idle, high-res 45% idle. - Splits drastic-specific vs generic-worthy pieces for future extraction (threaded-video decoupling + cross-thread EGL adoption are the generic patterns worth trngaje-upstream). - Includes buildroot submodule sdl2/weston fixes context. rk3566-uboot-rebuild.md: - Reproducible source-to-.bin recipe from mainline u-boot v2024.07 + 000-DTB_DIR_boot.patch + our 001-rgb30-hw-rev-detect.patch. - aarch64 cross-toolchain steps, rkbin blob wiring, verification. - Pairs with the two-label extlinux.conf HW-rev split.
jamespharaoh
force-pushed
the
knulli-main-work
branch
from
August 6, 2026 17:58
b24e573 to
53e91bd
Compare
Root configgen-defaults.yml sets psp default to ppsspp/ppsspp (the standalone PPSSPP package). rk3128 doesn't have BR2_PACKAGE_PPSSPP enabled but does have BR2_PACKAGE_LIBRETRO_PPSSPP, so knulli-report-system.py in target-post-image errors: Exception: default core (ppsspp/ppsspp) not enabled for rk3128/psp which aborts image assembly for ALL architectures, not just rk3128. Fix: override psp default on rk3128 to libretro/ppsspp, the emulator that's actually enabled there. Same pattern as the fix on rk3568 (fd4713c), which had the same root cause.
Upstream added the sgb-msu1 system in commit 15d6570 (Super Game Boy MSU1) with libretro/bsnes and libretro/bsnes_hd as options, but did not add a default. On any arch that has BR2_PACKAGE_LIBRETRO_BSNES or BR2_PACKAGE_LIBRETRO_BSNES_HD enabled, knulli-report-system.py in target-post-image errors: Exception: default core (None/None) not enabled for h700/sgb-msu1 which aborts the release-archive step for the whole build. Add a default of libretro/bsnes (the more compatible of the two).
The fallback psp default was ppsspp/ppsspp (standalone PPSSPP). None of the arches in scripts/linux/systemsReport.sh's ARCHS list (rk3128 rk3326 rk3566 a133 h700 r16 sm8250) actually enable BR2_PACKAGE_PPSSPP by default - they all enable BR2_PACKAGE_LIBRETRO_PPSSPP instead. So the fallback was never matching, and every arch was forced to add its own override or die in knulli-report-system.py during target-post-image. rk3568 already had this override (fd4713c), rk3128 was added last-minute (47a4af5 in this branch), h700 was next in the whack- a-mole. Fix at the root instead: change the fallback to what's actually enabled. The two per-arch overrides for rk3568 and rk3128 are now redundant but harmless; leaving them makes intent explicit if the arch ever diverges.
es_systems.yml declares mpv's only emulator/core as sh/sh (requireAnyOf: BR2_PACKAGE_MPV), but configgen-defaults.yml set the default to mpv/mpv - a pair that doesn't exist in es_systems.yml. On any arch that enables BR2_PACKAGE_MPV, knulli-report-system.py in target-post-image errors: Exception: default core (mpv/mpv) not enabled for h700/mpv Aligning the default with the actual emulator/core key resolves it.
…gle arch's missing default target-post-image runs knulli-report-system.py, which walks every arch in scripts/linux/systemsReport.sh's ARCHS list and validates that each system's default (emulator, core) resolves to an actually- enabled buildroot package. Any single miss raised an exception, which aborted the whole target-post-image step, which killed image assembly for every arch (even ones with no misses). The arch defaults yaml is a moving snapshot: when upstream adds a system without setting a default (e.g. sgb-msu1 in 15d6570), or when an arch turns off a package the fallback default expects (e.g. rk3128 without standalone PPSSPP), the report script fails loud for everyone. That coupling is too tight. Change the miss from a raise to a stderr warning. The images still build, the miss is still visible in build logs, but one arch's maintenance debt no longer blocks unrelated arches. Also: fix the mpv default on rk3326 (was mpv/mpv, now sh/sh, to match es_systems.yml which declares mpv's only emulator as sh/sh).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This was authored with the help of Claude code, but I've been checking everything carefully.
Draft PR for visibility, not immediate merge. Some of this overlaps with @acmeplus's in-progress rk3566 unification (u-boot, kernel BSP). I want the work discoverable while we sort out the merge story on Discord — happy to rebase, split, or drop pieces as that lands.
What this gives an RGB30 user
launch.shoverride any more (aligns with the h700/a133 code path).Docs in this PR
Two
docs/rk3566-*.mdfiles worth reading first if you want to follow the design decisions:docs/rk3566-sdl2-drastic.md— per-patch justification for the 9 pre-existing board sdl2 patches and our 1 new sdl2_drastic-only patch. Explicit about what's a real fix vs what's downstream glue, and what a "generic rk3566 libSDL2" would look like.docs/rk3566-uboot-rebuild.md— reproducible steps for rebuildingu-boot-rk3566.binfrom mainline v2024.07 + the patch set. Needed for anyone auditing the shipped binary or merging with an alternative u-boot flow.Commits, grouped by concern
Full commit list below — the branch is 25 commits above
origin/knulli-main, all authored during this cycle.1. Build hygiene (mergeable independently)
c8edaeaConfig.in: comment out references to missing packagesd6d3b0bkernel-rk3566-bsp: disable malformed RG-Arc-only patches (0008, 0010 have broken unified-diff context lines)685c499buildroot: bump submodule pointer for sdl2/weston knulli-build fixesccc14e6mali-libs: install gbm.h properly + generate matching gbm.pc version9baffd6vaixterm: vendor libvterm and expose it via -I flagsb290fafknulli-system Config.in: restore per-board image subpaths for rk35682. configgen defaults for master
ddae9f2configgen: quake default emulator + rk3566 → rk3568 aliasfd4713cconfiggen-defaults-rk3568: point psp default at libretro/ppssppbeb85d4configgen-defaults: fix 3ds+vaixterm defaults22f0649configgen-defaults: add missing quake2 default5d3bec5configgen-defaults: add missing namco22 default3. RGB30 DTB / kernel BSP — HW-rev aware
The full HW-rev story is in the PR body of
4d19a29+ the inline docs indocs/rk3566-uboot-rebuild.md. Short version: v1 and v2 differ only by tcs4525 i2c address (0x1c vs 0x40); the knulli tree already builds both DTBs. Extlinux hardcoded the v1 one, so v2 boards would boot the wrong DTB and lose CPU frequency scaling.4d19a29kernel-rk3566-bsp: split old 0009+0010 into three thematic patches (name / suspend / volume) covering both v1 and v2 top-level DTSes. Drops the in-place 0x1c → 0x40 hack.359c8f6kernel-rk3566-bsp: distinguish v2 DTB model string so ES / bluetooth pick up the correct model on v2 boards6771458(superseded by4d19a29; kept for history) fix vdd_cpu i2c address on RGB30 — in-place v1 patch, correct for v2 but breaks v14. RGB30 u-boot — HW-rev detection
Pairs with (3). After mainline's SARADC-based board detection resolves RGB30, probe i2c0 for tcs4525 at 0x40 and set
pxe_label_override=rgb30-v2so u-boot's extlinux parser picks the v2 LABEL. Silent no-op on v1 and on non-RGB30 rgxx3 boards.0ec1fe0uboot-rk3566: HW-rev detect patch + two-label extlinux.conf15f382duboot-rk3566: rebuildu-boot-rk3566.binwith the new patch applied (currently ships as prebuilt .bin, per the existing knulli pattern for rockchip u-boot)Note for @acmeplus: these commits will need to fold into your rk3566 unification work when it lands. Happy to rebase.
5. Drastic with sdl2_drastic instead of libhookdastic (align rk3566 with h700/a133)
The heart of the drastic story. RK3566 was on a different code path from h700/a133 (used libhookdrastic + drastic_aarch64 override); this switches it to the shared upstream approach and adds the sdl2_drastic patch needed to make it work on mali-blob-gbm. Full rationale in
docs/rk3566-sdl2-drastic.md.e75fac3rk3566: drop libhookdrastic + drastic_aarch64 fsoverlay, align with h700/a13366b36fdboard/rockchip/rk3566: symlink sdl2 patches so sdl2_drastic gets the same 9 rotation/RGA/build fixesb407c0asdl2_drastic: adopt SDL KMSDRM EGL context on rk3566 (fixes black-screen crash on mali-blob-gbm — video_handler's parallel DRM/GBM/EGL setup can't coexist with SDL's KMSDRM backend on this variant)168d49csdl2_drastic: threaded video for rk35660bbc16bsdl2_drastic: fix menu crash on rk35668162f60rgb30: per-device drastic.cfg with RGB30 button IDsa5a93a7rgb30: replace drastic 720x720 layout selection (fixes hh0/hh1 clipping right, thraeg_vh_s2 y=-6 clip)6. RGB30 UX + generic ergonomics
6b66406knulli-overclock: warn on 1992 MHz overclock for rk3568b24e573docs: the two rk3566 docs aboveTesting done
End-to-end on a Powkiddy RGB30 v2 board, 2026-08-06:
Powkiddy_RGB30_v2in ES System InfoNot yet tested on a v1 board. I don't have a v1 board to test on; the u-boot detection will silently fall back to the v1 LABEL if the i2c probe at 0x40 fails, which is the expected behaviour on v1. Looking for a v1 tester on Discord.
Known outstanding / follow-ups
psp:entry (or the release-archive report script needs to tolerate missing entries) to stop the report step from erroring on the rk3128 arch. Not investigated in this PR — needs a decision on which side the fix belongs.
dow" patterns are generically useful, not rockchip-specific. Planning follow-up PRs there.
li migrates.