Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
7e506a5
refactor(rockchip-rga): move the RGA2 encoder under a backend module …
JosephJoshua Jun 22, 2026
761bdbe
feat(rockchip-rga): add the RgaError driver core error type
JosephJoshua Jun 22, 2026
3ba5836
feat(rockchip-rga): add typed Copy and Fill operations with checked v…
JosephJoshua Jun 22, 2026
8254c9e
feat(rockchip-rga): add the RgaDmaBuffer contiguous DMA wrapper
JosephJoshua Jun 22, 2026
0105622
feat(rockchip-rga): add the RgaBackend trait and RgaStatus
JosephJoshua Jun 22, 2026
596d35f
feat(rockchip-rga): encode RGA2 MMU-off copy and fill with golden tests
JosephJoshua Jun 22, 2026
34f3f92
feat(rockchip-rga): add the RGA2 MMIO backend with submit, poll, ack,…
JosephJoshua Jun 22, 2026
ce4502a
feat(rockchip-rga): add an unsupported RGA3 backend skeleton
JosephJoshua Jun 22, 2026
6fda988
feat(rockchip-rga): add the RgaCore state machine with backend select…
JosephJoshua Jun 22, 2026
ea1bc53
feat(rockchip-rga): add an OS independent RGA2 fill, copy, and CRC32 …
JosephJoshua Jun 22, 2026
f7785ea
feat(ax-driver): probe RGA with BindingInfo IRQ and power the core do…
JosephJoshua Jun 22, 2026
76e7ba3
feat(starry): add an rga selftest boot hook over serial
JosephJoshua Jun 22, 2026
7f6cf50
docs(rockchip-rga): document the RGA2 submission path
JosephJoshua Jun 22, 2026
5dd4700
test(rockchip-rga): enroll the crate in the host std test whitelist
JosephJoshua Jun 22, 2026
f5c9a72
test(starry): add the OrangePi 5 Plus RGA2 selftest board case
JosephJoshua Jun 22, 2026
adabead
refactor(rockchip-rga): drop the dry run encoder and keep the MMU-off…
JosephJoshua Jun 22, 2026
aad4440
docs(ax-driver): add a SAFETY note on the RGA iomap
JosephJoshua Jun 22, 2026
24d509a
fix(rockchip-rga): correct the RGA2 interrupt status bits, soft reset…
JosephJoshua Jun 23, 2026
c26aaaf
fix(rockchip-rga): correct the RGA2 MMU enable bits and source mask s…
JosephJoshua Jun 23, 2026
2bb82cb
docs(rockchip-rga): document RGA2 CMD_BASE raw addressing
JosephJoshua Jun 23, 2026
35ef8ba
feat(rockchip-rga): add RgaBufferBacking for owned and imported buffers
JosephJoshua Jun 23, 2026
3afd250
feat(starry): define the dma-heap and dma-buf uapi with compile time …
JosephJoshua Jun 23, 2026
229f38b
feat(starry): add the DmaBufObject contiguous allocator
JosephJoshua Jun 23, 2026
cacd971
feat(starry): add the DmaBufFile dma-buf fd with anchored mmap and sync
JosephJoshua Jun 23, 2026
a92d8a8
feat(starry): implement the DMA_HEAP_IOCTL_ALLOC handler
JosephJoshua Jun 23, 2026
fcbb176
feat(starry): register the system and cma dma-heap device nodes
JosephJoshua Jun 23, 2026
dad9ef1
test(starry): add a userspace dma-heap alloc, mmap, lifetime, and syn…
JosephJoshua Jun 23, 2026
879ef78
feat(starry): add an imported dma-buf RGA2 fill selftest case
JosephJoshua Jun 23, 2026
70857d9
feat(rockchip-rga): add YUV formats, Rect, CscStandard, and the UV pl…
JosephJoshua Jun 23, 2026
b5e67dc
feat(rockchip-rga): add the general Blit operation with crop, scale, …
JosephJoshua Jun 23, 2026
dbb5bd7
feat(rockchip-rga): emit RGA2 format codes and CSC and scale register…
JosephJoshua Jun 23, 2026
0140b95
feat(rockchip-rga): encode blit scale factors, sub rect offsets, CSC,…
JosephJoshua Jun 23, 2026
15c1c16
feat(rockchip-rga): add resize and CSC capability flags with letterbo…
JosephJoshua Jun 23, 2026
eff2a14
feat(starry): add a board RGA2 blit resize selftest case
JosephJoshua Jun 23, 2026
35ae868
fix(rockchip-rga): encode ABGR distinctly and add upscale and cropped…
JosephJoshua Jun 23, 2026
c9a300e
style(starry): rustfmt the blit resize selftest block
JosephJoshua Jun 23, 2026
ff48849
feat(rockchip-rga): add librga_abi rga_req mirrors and RK_FORMAT mapping
JosephJoshua Jun 23, 2026
028ce01
feat(rockchip-rga): translate librga rga_req into RgaOperation
JosephJoshua Jun 23, 2026
bf85645
feat(starry): add the /dev/rga node with RGA_BLIT_SYNC submission
JosephJoshua Jun 23, 2026
829f650
test(starry): add a /dev/rga QEMU graceful no device ABI test
JosephJoshua Jun 23, 2026
c3b1ad3
fix(starry): gate rga selftest board success on an end of suite sentinel
JosephJoshua Jun 23, 2026
7458abf
style(rockchip-rga): clear clippy warnings in the librga_abi tests
JosephJoshua Jun 23, 2026
f2de0a7
feat(rockchip-soc): add RGA2 CRU clock gate entries
JosephJoshua Jun 23, 2026
6cb7982
fix(ax-driver): ungate RGA2 clocks before MMIO and defer the RGA3 probe
JosephJoshua Jun 23, 2026
c70bd0e
docs(ax-driver): document that rdrive probes every RGA core
JosephJoshua Jun 23, 2026
c124c8a
feat(rockchip-rga): program SYS_CTRL master mode and dump engine stat…
JosephJoshua Jun 23, 2026
a558f08
feat(ax-driver): deassert RGA2 soft resets before MMIO
JosephJoshua Jun 23, 2026
f254b55
feat(starry): dump RGA2 engine state on a selftest timeout
JosephJoshua Jun 23, 2026
0720148
fix(rockchip-rga): arm the RGA2 completion interrupt enable so the do…
JosephJoshua Jun 23, 2026
e6436a3
fix(rockchip-rga): correct RGA2 fill color, mode control, and scale e…
JosephJoshua Jun 24, 2026
fb21bdc
refactor(rockchip-rga): poll the done flag and capture diagnostics in…
JosephJoshua Jun 24, 2026
f705d92
feat(starry): emit RGA2 verify diagnostics on completed but incorrect…
JosephJoshua Jun 24, 2026
f9dd703
fix(rockchip-rga): pin the RGA2 fill SRC1 format to the destination f…
JosephJoshua Jun 24, 2026
47d7a55
test(starry): add a distinct fill probe and pixel dump to the selftest
JosephJoshua Jun 24, 2026
bbb8483
fix(rockchip-rga): emit RGA2 set_pat_info words for color fill
JosephJoshua Jun 24, 2026
f849f91
test(starry): add a poison sentinel fill probe and bitblt fill fallback
JosephJoshua Jun 24, 2026
b52cc25
test(starry): add the rga selftest board app case
JosephJoshua Jun 24, 2026
897bf24
test(rockchip-rga): prove an equal size Blit encodes identically to Copy
JosephJoshua Jun 24, 2026
4f3472f
fix(starry): clean DMA destinations before RGA writes and classify ev…
JosephJoshua Jun 24, 2026
3cdcbbe
fix(starry): sync dma-buf coherency on the /dev/rga submit path
JosephJoshua Jun 24, 2026
f9cbda8
fix(rockchip-rga): match the librga ABI mirrors to the MultiRGA v1.3.…
JosephJoshua Jun 24, 2026
ad8be27
feat(starry): implement the RGA_IOC_IMPORT_BUFFER and RELEASE_BUFFER …
JosephJoshua Jun 24, 2026
b383f93
feat(rockchip-rga): add packed YUYV 4:2:2 format support
JosephJoshua Jun 24, 2026
189ed27
test(rockchip-rga): add letterbox golden tests for the fill and blit …
JosephJoshua Jun 24, 2026
a48e9d6
fix(starry): restore DMA coherency and correct the batch handle API a…
JosephJoshua Jun 24, 2026
b89e89d
fix(rockchip-rga): reject packed YUV as a blit destination
JosephJoshua Jun 24, 2026
ce1258f
feat(starry): isolate RGA handles per task and use try_lock on the rd…
JosephJoshua Jun 24, 2026
082316a
feat(starry): add version query and REQUEST_SUBMIT ioctls for modern …
JosephJoshua Jun 25, 2026
69501b6
test(starry): exercise the /dev/rga handle path in QEMU
JosephJoshua Jun 25, 2026
3d9839e
fix(rockchip-rga): accept librga identity rotation blits and reject u…
JosephJoshua Jun 26, 2026
54653f6
feat(rockchip-rga): add a YUYV to RGB CSC selftest for the librga imc…
JosephJoshua Jun 26, 2026
210c4cc
feat(starry): report the RK3588 RGA2 version, select the RGA2 core, a…
JosephJoshua Jun 26, 2026
a2a8120
style(starry): remove the dead DmaBufObject is_empty method
JosephJoshua Jun 26, 2026
499aab5
fix(starry): use DeviceDma::new_legacy in the dma-heap allocator
JosephJoshua Jun 26, 2026
1602393
fix(rga): collapse the execute_blit parse failure diagnostic to one w…
JosephJoshua Jun 26, 2026
da8a9b6
fix(rga): resolve clippy warnings across the rga and dma-heap feature…
JosephJoshua Jun 26, 2026
f29743b
test(rga): add a per-case build config for the rga selftest board case
JosephJoshua Jun 26, 2026
ee32a51
fix(rga): place rga_req handle_flag at offset 360 to match librga
JosephJoshua Jun 26, 2026
ac9061d
test(starry): re-home RGA2 selftest from kernel boot hook to userspace
JosephJoshua Jun 29, 2026
76a19ce
fix(starry): report O_RDWR open flags for dma-buf fds
JosephJoshua Jun 29, 2026
7f71181
fix(rockchip-rga): derive the NV12 chroma base for single-fd semiplan…
JosephJoshua Jun 29, 2026
dde4552
test(starry): drop the rga-blit-hw hardware case from the test-suit
JosephJoshua Jun 30, 2026
c0a37f0
fix(starry): roll back /dev/rga handle/request on write-back fault
JosephJoshua Jun 30, 2026
02662b4
Merge upstream/dev; reconcile RGA onto the shared dmaheap + FDT clock…
JosephJoshua Jul 14, 2026
07a7535
test(starry): drop the RGA qemu ABI tests from the Starry test-suit
JosephJoshua Jul 14, 2026
2a0ed7b
style(starry): keep pseudofs/dev module decls sorted (rustfmt)
JosephJoshua Jul 14, 2026
89b9b85
fix(starry): key /dev/rga handles by process (tgid), not thread id
JosephJoshua Jul 15, 2026
21d17ec
fix(starry): reclaim /dev/rga state only on the last open-description…
JosephJoshua Jul 16, 2026
8f03d3a
test(starry): add /dev/rga open-file-description lifecycle regressions
JosephJoshua Jul 16, 2026
d39b67b
fix(starry): give /dev/rga a per-open session and align ioctls to the…
JosephJoshua Jul 16, 2026
2a5c142
test(starry): add a fork lifecycle regression to the /dev/rga qemu case
JosephJoshua Jul 16, 2026
42cf45d
fix(starry): bound-check imported dma-bufs against plane extents befo…
JosephJoshua Jul 20, 2026
3c2ce4d
test(starry): regress small-buffer + large-geometry RGA rejection
JosephJoshua Jul 20, 2026
99b06a6
Merge branch 'dev' into feat/rk3588-rga-driver
ZR233 Jul 20, 2026
324c7fc
Merge remote-tracking branch 'upstream/dev' into rga-pr-clean
JosephJoshua Jul 20, 2026
58c1ab7
fix(rockchip-rga): use per-format vertical chroma subsampling for sem…
JosephJoshua Jul 20, 2026
7abc8df
fix(rockchip-rga): satisfy clippy chunks_exact_to_as_chunks under --a…
JosephJoshua Jul 20, 2026
7ae3043
fix(starry): serialize concurrent /dev/rga blits instead of reporting…
JosephJoshua Jul 21, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion drivers/ax-driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ serial = [
"dep:some-serial",
]
rknpu = ["rockchip-pm", "rockchip-soc", "dep:rockchip-npu"]
rga = ["dep:rockchip-rga"]
rga = ["rockchip-pm", "rockchip-soc", "dep:rockchip-rga"]
jpeg = ["rockchip-pm", "rockchip-soc", "dep:rockchip-jpeg"]
jpu-selftest = ["jpeg"]
rockchip-sdhci = [
Expand Down
116 changes: 98 additions & 18 deletions drivers/ax-driver/src/rga.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
use alloc::vec::Vec;

use log::info;
use log::{info, warn};
use rdrive::{
probe::OnProbeError,
register::{FdtInfo, ProbeFdt},
};
use rockchip_rga::{RgaCoreConfig, RgaCoreResource, RockchipRga};
use rockchip_pm::{PowerDomain, RockchipPM};
use rockchip_rga::{RgaCoreConfig, RgaCoreResource, RgaVersion, RockchipRga};

use crate::mmio::iomap;

crate::model_register!(
name: "Rockchip RGA",
level: ProbeLevel::PostKernel,
priority: ProbePriority::DEFAULT,
// Match all three RGA cores. rdrive probes each matching FDT node independently (its probed
// set is keyed per node, not per driver), so every core gets its own probe() call; PR-1
// brings up RGA2 and defers the RGA3 cores in probe().
probe_kinds: &[
ProbeKind::Fdt {
compatibles: &[
Expand All @@ -30,30 +34,119 @@ fn probe(probe: ProbeFdt<'_>) -> Result<(), OnProbeError> {
let config = detect_core_config(&info)
.ok_or_else(|| OnProbeError::other("unsupported Rockchip RGA compatible string"))?;

// PR-1 brings up RGA2 only. RGA3's clock tree / reset / real version-register offset are
// unverified and deferred to a later phase, so skip the RGA3 cores here (they still each get a
// probe() call now that rdrive probes every matching node). Skipping before any MMIO avoids
// the synchronous external abort an unclocked/unverified RGA3 version-read would raise.
if config.version == RgaVersion::Rga3 {
info!(
"RGA3 core (index {}) probe deferred in PR-1; skipping (RGA2-only bring-up)",
config.core_index
);
return Ok(());
}

// Bring the RGA2 core onto the bus BEFORE any MMIO: RgaCore::new reads the version register
// at base+0x28, which raises a synchronous external abort if the bus-interface clocks are
// still gated (U-Boot leaves the RGA clocks off at handoff). Power the domain, then ungate
// aclk/hclk/clk. If the clocks cannot be established, skip the core rather than fault the
// kernel on the version read.
enable_power(config);
if let Err(e) = enable_rga2_clocks(&info) {
warn!("RGA2 clock bring-up failed ({e}); skipping core to avoid an MMIO abort");
return Ok(());
}
deassert_rga2_resets(&info);

let irq = crate::binding_info_from_fdt(&info)?.irq_num();

let mut resources = Vec::new();
for reg in info.node.regs() {
let start_raw = reg.address as usize;
let size_raw = reg.size.unwrap_or(0x1000) as usize;
let (start, size, offset) = page_aligned_region(start_raw, size_raw);
// SAFETY: `start`/`size` are a page-aligned MMIO window from the FDT `reg`; iomap maps it and `offset` is within it.
let base = unsafe { iomap(start, size)?.add(offset) };

resources.push(RgaCoreResource {
base,
size: size_raw,
irq: decode_fdt_irq(&info.interrupts()),
irq,
config,
});
}

let dma = axklib::dma::device_with_mask(u32::MAX as u64);
let rga = RockchipRga::new(&resources, dma);
let core_count = rga.core_count();
let version = rga.cores().first().map(|c| c.version());
plat_dev.register(rga);
info!("RGA registered: cores={core_count} version={version:?}");
Ok(())
}

info!("RGA registered successfully, cores={core_count}");
fn enable_power(config: RgaCoreConfig) {
// RK3588 power-domain IDs (from rockchip-pm rk3588 variant): RGA30=22, RGA31=30, RGA2/VDPU=21.
let domain = match config.version {
RgaVersion::Rga3 => {
if config.core_index == 0 {
PowerDomain(22) // RGA30
} else {
PowerDomain(30) // RGA31
}
}
RgaVersion::Rga2 => PowerDomain(21), // RGA2/VDPU
};
match rdrive::get_one::<RockchipPM>() {
Some(pm) => match pm.lock() {
Ok(mut pm) => {
if let Err(e) = pm.power_domain_on(domain) {
warn!("RGA power_domain_on({domain:?}) failed: {e:?}");
}
}
Err(e) => warn!("RGA: RockchipPM lock failed: {e:?}"),
},
None => warn!("RGA: RockchipPM not found; assuming domain already powered"),
}
// Bus clocks are ungated in enable_rga2_clocks() and the soft-resets are deasserted in
// deassert_rga2_resets(), both before any MMIO. The version read succeeds without the reset
// deassert (it only needs the APB/hclk interface), but the 2D engine needs the AXI/core
// domains out of any residual reset to actually execute a submitted op.
}

/// Ungate the RGA2 core's CRU bus clocks (hclk, aclk, clk) named by the node's `clocks` DT
/// property. U-Boot leaves the RGA clocks gated at handoff, so this is the load-bearing step that
/// makes the version-register read at base+0x28 succeed (otherwise it aborts on a gated bus). The
/// clock phandles resolve to the RK3588 BSP rk3588-cru.h ids (HCLK/ACLK_RGA2, CLK_RGA2_CORE) whose
/// gate positions (CLKGATE_CON45 bits 7/8/9) live in the rockchip-soc CRU gate table.
fn enable_rga2_clocks(info: &FdtInfo<'_>) -> Result<(), OnProbeError> {
for clock in &info.clock_lines()? {
clock.enable()?;
}
Ok(())
}

/// Deassert the RGA2 CRU soft-resets named by the node's `resets` DT property so the AXI/core
/// domains are out of any residual reset before the engine runs. Best-effort and idempotent,
/// mirroring the JPEG decoder bring-up; symmetric with the RGA2 clock gates at CLKGATE_CON45.
fn deassert_rga2_resets(info: &FdtInfo<'_>) {
let resets = match info.reset_lines() {
Ok(resets) => resets,
Err(e) => {
warn!("RGA2 reset_lines() failed (continuing): {e}");
return;
}
};
for reset in &resets {
if let Err(e) = reset.deassert() {
warn!(
"RGA2 reset deassert {:?} ({:#x}) failed (continuing): {e}",
reset.name(),
reset.id().raw()
);
}
}
}

fn detect_core_config(info: &FdtInfo<'_>) -> Option<RgaCoreConfig> {
for compatible in info.node.as_node().compatibles() {
match compatible {
Expand All @@ -73,16 +166,3 @@ fn page_aligned_region(start_raw: usize, size_raw: usize) -> (usize, usize, usiz
let end = (start_raw + size_raw + page_size - 1) & !(page_size - 1);
(start, end - start, offset)
}

fn decode_fdt_irq(interrupts: &[rdrive::probe::fdt::InterruptRef]) -> Option<usize> {
let interrupt = interrupts.first()?;
match interrupt.specifier.as_slice() {
[irq] => Some(*irq as usize),
[kind, irq, ..] => match *kind {
0 => Some(*irq as usize + 32),
1 => Some(*irq as usize + 16),
_ => Some(*irq as usize),
},
_ => None,
}
}
46 changes: 46 additions & 0 deletions drivers/gpu/rockchip-rga/src/backend/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//! Generation-specific RGA hardware backends behind one trait (spec §20.1).
pub mod rga2;
pub mod rga3;

use crate::{RgaHardwareVersion, RgaVersion, error::Result, operation::RgaOperation};

/// Hardware completion status, polled out of hard-IRQ context in PR-1.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum RgaStatus {
Busy,
Done,
Error,
}

/// One-shot snapshot of an RGA core's engine state, captured on a timeout so a board run can
/// localize whether the engine never started, errored, or completed on a different bit.
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct RgaDiag {
pub int: u32,
pub sys_ctrl: u32,
pub cmd_ctrl: u32,
pub cmd_base: u32,
pub status: u32,
pub version: u32,
pub cmd_phys: u64,
}

/// A generation-specific RGA core controller. Owns its MMIO region and DMA context.
pub trait RgaBackend: Send {
fn generation(&self) -> RgaVersion;
fn read_version(&self) -> RgaHardwareVersion;
/// Returns Ok(()) if this backend can execute `op`, else `RgaError::Unsupported`.
fn supports(&self, op: &RgaOperation) -> Result<()>;
/// Program registers/command for a validated `op` and start the engine (non-blocking).
fn submit(&mut self, op: &RgaOperation) -> Result<()>;
/// Poll hardware completion (non-blocking).
fn poll(&self) -> RgaStatus;
/// Acknowledge/clear the interrupt/status after a completed or errored job.
fn ack(&mut self);
/// Reset the core for recovery (timeout/fatal error).
fn reset(&mut self) -> Result<()>;
/// Read-only engine-state snapshot for diagnostics (default zeroed for backends without MMIO).
fn diag(&self) -> RgaDiag {
RgaDiag::default()
}
}
Loading