Skip to content

About

CeraLive RK3588 multimedia island: Rockchip MPP service (RKVENC2/RKVDEC2/JPGDEC) and multi_rga as maintained kernel source, released as a git-am series

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

rk3588-media-island

The CeraLive RK3588 multimedia island: the Rockchip MPP service and the multi_rga 2D engine driver, carried as maintained kernel source and released as a git am mailbox series.

What it holds drivers/video/rockchip/mpp/ and drivers/video/rockchip/rga3/, the UAPI headers they publish, and the integration/ patches to mainline files they need
MPP clients compiled RKVENC2, RKVDEC2, JPGDEC — those three and no others
Target kernel v7.2 (8d3ae59288f1e7d58d76558a6ee96d533bc5019f), mirrored from kernel-pin.env
Boards Radxa Rock 5B+, Orange Pi 5+
Release artifact a generated git am series, plus its .sha256 — no .deb, no kernel, no image
Versioning CalVer, YYYY.MINOR.PATCH
Status MPP + RGA OWNERSHIP INTEGRATED IN SOURCE. The complete donor/97-member replay, audited vendor backlog, mainline API port, three-core RGA ownership flip, generated series, and fail-closed RGA validation are present and CI-gated. Latest published tag v2026.9.5; both bench boards booted an image whose kernel carries it (patches_commit 6996f96b) from a production slot on 2026-09-21. See AGENTS.md KEY FACTS for what that boot does and does not prove.

Why this is a source repository and not a patch repository

CeraLive already has a patch repository for the RK3588 kernel: rk3588-kernel-patches. It carries patch text, and it is very good at it — provenance lanes, byte-parity proofs, a retirement registry, an ordinal discipline that never reuses a slot.

That model works because those patches are small, externally authored, and mostly awaiting upstream. The MPP and RGA drivers are none of those things. They are tens of thousands of lines of vendor code that CeraLive maintains, rebases, fixes, sanitizes and tests over a long horizon. Code of that size needs what code gets: review history per change, unit tests, KUnit and fuzz targets, static analysis, and a release train. A giant opaque .patch file gets none of it.

So the island is source, and the series is generated from it. That inverts the usual relationship: the mailbox series is an output artifact, like a compiled binary, and hand-editing it is a defect rather than a shortcut.

How a release becomes a kernel change

Three merges, not one. Nothing about this stack may be planned as though a driver fix were a single pull request:

island tag  ──▶  rk3588-kernel-patches `island/` lane bump
                   ──▶  image `patches_commit` bump
                          ──▶  image build  ──▶  device
  1. Island release. An owner-approved dispatch from canonical main regenerates the series from source, byte-compares it against the checked-in patches/, then atomically claims the requested tag and publishes the immutable release asset with its checksum. The workflow has no tag trigger: an existing tag is refused rather than used as release input.
  2. Consumer lane bump. rk3588-kernel-patches consumes that asset byte-preserved into its island/ lane. Provenance on an island/ member is its own variant naming the island tag, commit and asset digest — never an upstream cherry-pick stamp, because there is no upstream commit to name.
  3. Image bump. The image's single kernel_source.patches_commit pin moves to the consumer repository's new commit. That mechanism is unchanged by the island's existence; the image still sees one patch repository and one pin.

The island produces no .deb, is absent from the device image REPOS array and from fetch-debs.sh, and rides inside linux-image like every other kernel change.

Ownership: one driver per node

The Linux driver core binds one driver per platform device, and when two drivers match one node the winner is module load order — non-deterministic, and therefore not a design. Every island-owned node therefore carries exactly one compatible string, matched by exactly one driver.

Mainline rkvdec and rockchip-rga stay built alongside the island. They are not excluded by Kconfig, deliberately: keeping them built is what makes each silicon handover reversible by a device-tree change rather than a kernel rebuild, and it keeps the upstream-migration target alive in the same image.

The per-block table, and the CI lint that enforces it, are in docs/OWNERSHIP.md.

Repository layout

rk3588-media-island/
├── kernel-pin.env          # MIRROR of rk3588-kernel-patches' kernel coordinate — never edited here
├── drivers/video/rockchip/
│   ├── mpp/                # MPP service + the three compiled clients; compat shims nest at mpp/compat/
│   └── rga3/               # multi_rga
├── include/uapi/linux/     # the UAPI headers the drivers publish
├── integration/            # applied MAINLINE-file patches: hooks, providers and MPP DT
│   └── pending/            # linted, unshipped RGA3/RGA2 compatible flips
├── scripts/                # series generation, provenance and lint tooling
├── tests/
│   ├── board/              # hardware-gated drills and probes
│   ├── kunit/              # in-kernel unit tests
│   └── fuzz/               # UAPI fuzz targets
└── docs/
    ├── CI.md               # what each CI job asserts + the mutation transcripts
    ├── COMPAT.md           # shim + external-symbol inventory; ALSO the shim-lint input
    ├── KEEP-STUB.md        # deliberate no-op contracts + reopening conditions
    ├── OWNERSHIP.md        # silicon ownership table + the one-compatible rule
    ├── REFERENCES.md       # every pinned coordinate
    ├── PROVENANCE.md       # per-file import ledger
    ├── TELEMETRY.md        # tracefs/debugfs schemas + frozen proc formats
    ├── VENDOR-BACKLOG.md   # exhaustive post-donor vendor PICK/SKIP ledger
    ├── UPSTREAM-STATUS.md  # what mainline is doing; the issue-only watch
    └── BOARD-QUALIFICATION.md  # what real hardware must demonstrate

Building the modules

The island's deliverables build out of tree as two modules against the pinned kernel. CI first builds the configured vmlinux, then exposes its vmlinux.symvers as the Module.symvers external modpost consumes. A following modules_prepare generates the module linker script but not that symbol table, so both steps are required to prove the REAL-DEPENDENCY link half. CI never clones a sibling checkout — the kernel comes from the URL in kernel-pin.env.

# 1. Source the pin.
set -a && . ./kernel-pin.env && set +a

# 2. Clone the pinned kernel and verify BOTH the tag object and the peeled commit.
git clone --depth 1 --branch "$KERNEL_TAG" "$KERNEL_MIRROR" .work/linux

# 3. Apply the integration patches (mainline-file changes) and stage the island
#    directories into the tree. This is what CI's cross-compile-modules job
#    does step for step -- see docs/CI.md.

# 4. Generate the provider symbol table, then cross-build the two modules.
make -C .work/linux ARCH="$ISLAND_ARCH" CROSS_COMPILE="$ISLAND_CROSS_COMPILE" \
     vmlinux
make -C .work/linux ARCH="$ISLAND_ARCH" CROSS_COMPILE="$ISLAND_CROSS_COMPILE" \
     modules_prepare
cp .work/linux/vmlinux.symvers .work/linux/Module.symvers
make -C .work/linux ARCH="$ISLAND_ARCH" CROSS_COMPILE="$ISLAND_CROSS_COMPILE" \
     M=drivers/video/rockchip/mpp  modules
make -C .work/linux ARCH="$ISLAND_ARCH" CROSS_COMPILE="$ISLAND_CROSS_COMPILE" \
     M=drivers/video/rockchip/rga3 modules

The asserted outputs are rk_vcodec.ko and rga_multicore.ko. CI also inspects both outputs with modinfo: every maintained MPP and RGA device-tree match table must produce an OF alias, so the kernel can autoload the module from a device-tree modalias rather than requiring a manual modprobe. See docs/PROVENANCE.md for their measured version and licence identity.

The build config is arm64 defconfig plus the device image's own kernel fragment plus the island's Kconfig symbols — not a bare defconfig. Building against a configuration the device does not run proves the wrong thing.

Testing

The RGA fault seam is independently opt-in via CONFIG_ROCKCHIP_RGA_CERALIVE_TEST (DEBUG_FS-dependent, default off). Its four one-shot controls have consumed counters, KUnit coverage of maintained driver functions, and a separate fault-matrix.sh --driver island-rga --probe-rga <binary> sweep. The existing 16-row MPP sweep is unchanged. Timeout/hang suppress START, IOMMU injection directly invokes the fault callback, and reset injection changes only the debugger write result. See the fault contract for errno, placement, admission and proof limits. No production enablement or RGA board qualification is implied by these source and host tests.

The test seam also has an optional idle-window IOMMU control. It schedules one device-owned delayed callback after a selected encode completion, records the observed runtime-PM state, and cancels before resource withdrawal. The dedicated tests/board/fault-controls-probe.sh --row idle-iommu-fault probe is separate from the 16-row matrix and requires its own authorized idle campaign. Source and host tests are not a board-qualification result; see docs/FAULT-CAMPAIGN.md.

Both board drills have now run on real silicon — the matrix and the five-control sweep on a Rock 5B+ and an Orange Pi 5+ at island v2026.9.2. The idle-window row was attempted on the Rock and returned no verdict; its outcome is INCONCLUSIVE. What each campaign measured, and what it explicitly does not prove, is the campaign document's "Fault-seam contract and the 2026-09 campaigns" section.

The MPP code-quality sweep and its per-finding dispositions are recorded in docs/HARDENING-FINDINGS.md. Instrumented UML/QEMU KUnit covers production helpers; full RK3588 driver runtime coverage still needs a physical board boot. The SRAM sizing regression checks both encoder and decoder use of a shared clamp before narrowing a resource-sized span to u32.

Tier Runs where Proves
tests/kunit/ CI, no hardware MPP request boundaries and deterministic task/session recovery, plus RGA request validation and fence terminal states
tests/fuzz/ CI, no hardware the UAPI surface survives hostile input
static analysis CI, no hardware sparse findings are fatal and coccinelle inspects every selected object; smatch remains conditional on a suitable runner package
every gate's --self-test CI, no hardware each gate refuses a mutated tree AND accepts a correct one
tests/board/fault-matrix.sh a real Rock 5B+ or Orange Pi 5+ the sixteen fault rows recover the device, consume the armed one-shot exactly once, and leave a healthy session's throughput intact — via --driver island
tests/board/fault-controls-probe.sh a real Rock 5B+ or Orange Pi 5+ the five controls no matrix row consumes fire exactly once with their documented errno; --row idle-iommu-fault is the separate, explicit-only idle experiment
tests/board/soak.sh a real Rock 5B+ or Orange Pi 5+ a long media session holds its nine slope rules — RSS, slab, dma-buf objects, IOMMU mappings, fd count, thread count, fps, drops and the per-core split — or the one failing rule and the retained CSV that proves it; --self-test scores committed fixtures on a dev host and is not board proof
module contract CI, source + built modules every OF table is exported, the compiled aliases exist, and the hard-IRQ-only RKVENC2 path never uses IRQF_ONESHOT
telemetry contract CI + KUnit tracepoint call sites and ordering, debugfs counters and session snapshots, static-key definitions, and the frozen MPP formatters remain intact
tests/dt/ CI, built DTBs both supported boards carry sole island MPP compatibles and every MPP client bypasses the unavailable BSP PMU-idle request; RGA remains mainline-owned
tests/board/ a real Rock 5B+ or Orange Pi 5+ everything about silicon

The board suite is deliberately outside the kernel build. Every script is gated, takes board identity only through environment variables, and never locates credentials or references a path above this repository's root. What each drill must demonstrate before it may be ticked is docs/BOARD-QUALIFICATION.md.

The tracefs event schemas, cumulative debugfs trees, and byte-frozen procfs formats are documented in docs/TELEMETRY.md.

Phase-7 forced-IDR measurement uses tests/board/idr-latency.sh: an engine IPC requester and an offline NAL/PTS scorer, with a software-recording self-test. Its capture requirements include a complete encoder-input timeline on the requester's host clock; self-test success alone does not qualify hardware latency or DMA-BUF direct import.

The direct MPP/RGA ioctl suites compile byte-preserved handler and session functions with bounded user-copy fixtures, rather than opening real device nodes. MPP coverage includes the legacy zero-size discovery queries, their precise offset/flag boundary and checked-word pointer access; other scalar sizes and unimplemented clients retain their rejection tests. See docs/IOCTL-BOUNDARY-TESTS.md for the complete case table, reproduction commands, and the explicit hardware/uaccess limits.

The runtime-PM audit traces all eleven island nodes and every PM acquisition/error exit. Hardware devices use a 2000 ms autosuspend policy; the service and encoder CCU are software-only exceptions. RGA cancellation releases power by job ownership, and failed JPEG IRQ registration unwinds common PM setup. UML regressions exercise those paths without touching physical boards.

The RGA memory repair replaces the borrowed page-table ring with job-owned tables and prepares legacy buffers before memory-aware core selection. Explicit RGA2 work retains bounded DMA32 staging; USERPTR aliases share original-page staging. bash scripts/check-rga-memory.sh exercises the software regressions, including more live PTEs than the old ring could hold. This is source repair, not a release or board qualification; the H7/conservation causal links remain unproven. Local compilation databases and clangd flags are ignored build artifacts, not repository build inputs.

The review follow-up makes reset failure fail-stop: retain the running job's memory and power until reboot, with unload/unbind blocked. Reachable RGA2 buffers now receive execution-device mappings and DMA-address PTEs rather than borrowing RGA3 ownership. Queue admission is bounded, expired queued work cannot start, and synchronous timeout cancels queued requests rather than reporting success. The strengthened host control and new KUnit lifetime/ownership/deadline cases are documented in the same memory-repair note; staging limits remain unchanged.

The round-2 regression receipt records isolated reset-order, timeout-unit and low-USERPTR ownership mutations, each followed by a restored full KUnit pass. It adds test coverage only, including real SG construction and nonidentity DMA PTEs; it changes no production driver.

The host verification of 465598e26 records 47 executed RGA-related KUnit cases, the Coccinelle findings and triage, and the parent comparison proving the MPP hardening checker failure pre-existing. It does not waive that failing gate or claim board qualification.

The separate MPP clock-checker repair checks the actual unlocked enable/unwind helper and its wrapper's error return. Run python3 scripts/check-mpp-hardening.py for all 23 source assertions and add --self-test for the positive/negative mutation controls. The driver unwind was correct; this tooling repair changes no driver or generated series.

Versioning

CalVer, YYYY.MINOR.PATCH, matching the rest of the CeraLive stack. The tag is what the consumer repository's island/ lane names, so a tag is immutable once published: the release workflow claims it atomically and byte-compares the uploaded asset before publishing.

Licence

GPL-2.0. The inherited MPP source carries Rockchip's dual (GPL-2.0+ OR MIT) expression and the inherited RGA source carries GPL-2.0; CeraLive uses the GPL-2.0 branch of both and never independently claims MIT. CeraLive's own contributions are GPL-2.0-only. The full per-file census, and the two upstream SHAs it was taken against, are in LICENSE.md.

Contributing

Read CONTRIBUTING.md for the commit trailers, the branch and PR shape, and the testing gate. AGENTS.md is the routing layer for AI build agents and the canonical statement of this repository's anti-patterns.

About

CeraLive RK3588 multimedia island: Rockchip MPP service (RKVENC2/RKVDEC2/JPGDEC) and multi_rga as maintained kernel source, released as a git-am series

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages