NixOS on the DevTerm A06, on a mainline kernel

I’ve been porting NixOS to the DevTerm A06. Rather than carrying the vendor
kernel, I rebased the patch set onto mainline — it now runs Linux 6.18, U-Boot
2026.07 and upstream Trusted Firmware-A, with no vendor blobs in the boot
chain. It boots and runs well enough that I’m putting it out there.

What works

Boot, display, panel orientation and backlight, keyboard and trackball, WiFi,
Bluetooth, audio, thermal sensors and throttling, CPU and GPU frequency
scaling, battery reporting, and s2idle suspend waking on the power button.
It’s stable under sustained load.

What doesn’t

deep suspend never resumes. I tested this against three separate firmware
paths — the vendor Rockchip SIP suspend patch, mainline PSCI, and Rockchip’s
own rkbin BL31 — and it fails identically in all three. Nothing wakes it,
including an RTC alarm, which points at resume itself being broken rather than
wakeup routing. s2idle works fine and wakes on the power button, so that’s
what the module selects.

DDR frequency scaling is disabled. Enabling it hangs the SoC hard under
memory load with upstream TF-A. Worth noting rk3399-gru is the only mainline
RK3399 board of 42 that enables the DMC, and it runs Chrome OS firmware where
Rockchip’s loader does the DRAM retraining. I tried Rockchip’s rkbin BL31:
it stops the hang, but scaling still fails, because the OPP table asks for
328/416/666/856 MHz while U-Boot’s open-source TPL only trains 400 and 800.
Making it work means adopting the whole proprietary boot chain — vendor DDR
blob and miniloader as well — which I chose not to do.

Both are written up in the README with what was tried, so nobody has to
rediscover it.

A device tree fix worth mentioning

The vendor device tree enables i2s0, i2s1 and i2s2, but i2s0 and i2s1
both claim GPIO4_A0. i2s0 wins, i2s1 fails to probe and logs an error on
every boot. Nothing actually references i2s1 — i2s0 drives the ES8388 codec
and i2s2 drives HDMI audio — so it’s dead weight and is simply left disabled
here.

Trying it

The installer image boots to a normal NixOS installer environment — nixos
login, empty password, sshd running — so you can get in and take it from
there:

nix build git+https://codeberg.org/cckuoescxethyomogoet/clockworkpi-a06.git#sd-image-devterm-a06-installer
sudo dd if=result/sd-image/*.img of=/dev/sdX bs=4M status=progress conv=fsync

You can build this on x86_64 or aarch64 Linux — not macOS or WSL1, since
producing a Linux SD image needs a Linux builder. You need Nix with flakes
enabled and about 15 GB free. The first build compiles the kernel and that
dominates the time, so how long it takes depends entirely on the machine: tens
of minutes on a many-core desktop, a good deal longer on something modest.

Cross-compilation from x86_64 is automatic, and deliberately not via
binfmt: emulating a kernel build would be far slower than cross-compiling it.
There’s also a NixOS module taking variant = "devterm" or "uconsole" if
you’d rather wire it into your own flake.

uConsole owners: I’d love a tester

The uConsole device tree is written and builds, but I don’t own one, so it has
never been run. The thing I’d most expect to be wrong is panel rotation — it’s
inherited from the DevTerm, and ClockworkPi’s own uConsole patch doesn’t change
it either, so there was no reference to copy from. If you have a uConsole A06
and a spare SD card, I’d be glad of a report either way.

On upstreaming

The tree is deliberately shaped to be submittable — no edits to the shared
rk3399.dtsi, supply rails taken from the schematics rather than guessed,
per-chassis compatibles, bindings that validate, and a device tree that builds
with no dtc warnings. The README lists what each piece would still need. I’m
not in a position to carry that through myself, so if anyone wants to take
pieces of it upstream, please do.

1 Like