Low-level firmware · Embedded Linux · ARM bring-up · Rockchip RK3576 — TF-A · OP-TEE · U-Boot · EDK2/UEFI · NPU
Bringing Up the RK3576 NPU on Mainline Linux
The RK3576 has a 6 TOPS NPU and the open-source rocket driver targets it. I got a full MobileNet run going — 252 hardware jobs, no hangs, no faults — and every single output byte was zero. This is roughly how the next two weeks went. Mostly it’s me being wrong a lot. The setup Radxa ROCK 4D (RK3576, 12 GiB LPDDR5) linux-next 7.1.0-rc5, rocket built into the kernel (not a module) MobileNetV1 224×224 through the Mesa Teflon TFLite delegate CPU reference: Top-1 = 653, conf ≈ 0.887 One thing kept me sane the whole time: rocket already runs this exact model perfectly on the RK3588. So nothing about the driver was fundamentally broken. The bug had to be something RK3576-specific — a value, an offset, a sequence the two chips don’t share. Whenever a theory tried to blame the whole architecture, that fact talked me down. ...
Porting OP-TEE to the RK3576
OP-TEE is the secure-world OS that runs at S-EL1, between TF-A and Linux. Getting it up on a new SoC is mostly plumbing — memory map, console, crypto, entropy — except every piece of that plumbing has a way to go silently wrong, and “silently” is the operative word here, because the first problem was literally silence. Target: Radxa Rock 4D (RK3576), firmware on SPI, kernel + an xtest initramfs off SD. The base platform support went up as OP-TEE PR #7821 — and it’s now merged into mainline OP-TEE. The OTP key-derivation half got split into its own follow-up (#7841), still in review; there’s a good reason it’s separate, and it’s below. ...
RK3576 UEFI: Teaching EDK2 to Drive HDMI, USB, and eMMC
The goal was a real UEFI firmware on the RK3576: boot the standard chain but swap U-Boot proper for EDK2, so the board comes up to a proper UEFI environment (think ESXi-on-Arm, Windows, EBBR distros). The boot chain: BootROM → U-Boot SPL (idbloader) → TF-A BL31 → EDK2 UEFI (BL33 @ 0x40800000) SPL loads a FIT image — from SPI 0x60000 or SD sector 16384 — containing BL31 and EDK2. The unbreakable rule: U-Boot proper must never end up in that FIT. Half of the early bugs were exactly that leaking back in (u-boot.bin in the FIT, raw SPL with no RKNS header, FIT entries pointing at BL31 load addresses that didn’t match the ELF’s actual segments). Once the packaging was honest, the fun started: three peripherals, three completely different failure personalities. ...
A One-Line TF-A Fix, and the Review That Came With It
This is the smallest patch I’ve ever upstreamed: it removes one line. Net diff is negative. But it’s also the first thing I sent to Trusted Firmware-A, and it got read by engineers from ST, Google, and Rockchip before it landed. So it’s a decent little story about what upstreaming actually feels like, even when the change is nearly nothing. The line I deleted In plat/rockchip/rk3576/platform.mk, one line: 1 2 3 4 5 ENABLE_PLAT_COMPAT := 0 MULTI_CONSOLE_API := 1 CTX_INCLUDE_EL2_REGS := 0 -GICV2_G0_FOR_EL3 := 1 CTX_INCLUDE_AARCH32_REGS := 0 That’s the whole patch. GICV2_G0_FOR_EL3 decides whether GICv2 Group 0 interrupts are routed to EL3. The RK3576 platform was hardcoding it to 1, and that override is both redundant and wrong: ...