Skip to content

drivercraft/rockchip-pm

Repository files navigation

Rockchip Power Management Driver (rockchip-pm)

A Rust power management driver library for Rockchip SoCs, providing basic power domain control functionality.

Features

  • 🔋 Basic Power Domain Control: Support for power domain on/off operations on RK3588
  • 🛡️ Memory Safety: Leverages Rust's type system for memory and thread safety
  • 📋 No Standard Library: #![no_std] design suitable for embedded environments
  • 🎯 Hardware Accurate: Direct register access with no abstraction overhead
  • 🔌 Name Lookup: Support for looking up power domains by name
  • 📦 Driver Framework: Built on rdif-base driver framework

Quick Start

use rockchip_pm::{RockchipPM, RkBoard, PowerDomain};
use core::ptr::NonNull;

// Initialize RK3588 PMU (base address typically from device tree)
let pmu_base = unsafe { NonNull::new_unchecked(0xfd8d8000 as *mut u8) };
let mut pm = RockchipPM::new(pmu_base, RkBoard::Rk3588);

// Control power domain by ID
let npu_domain = PowerDomain::new(8);  // NPU main domain
pm.power_domain_on(npu_domain)?;

// Look up power domain by name
if let Some(npu) = pm.get_power_dowain_by_name("npu") {
    pm.power_domain_on(npu)?;
}

// Turn off power domain
pm.power_domain_off(npu)?;

API Documentation

Core Structure

pub struct RockchipPM {
    // Private fields: board info, register interface, power domain configuration
}

Board Support

pub enum RkBoard {
    Rk3588,  // Implemented
    Rk3568,  // Not implemented (placeholder)
}

Power Domain Type

pub struct PowerDomain {
    // Power domain ID
}
impl PowerDomain {
    pub fn new(id: u32) -> Self
    pub fn id(&self) -> u32
}

Error Handling

pub enum NpuError {
    DomainNotFound,  // Power domain does not exist
    Timeout,         // Operation timeout
    HardwareError,   // Hardware error
}

pub type NpuResult<T> = Result<T, NpuError>;

Main Methods

impl RockchipPM {
    /// Create a new power manager instance
    pub fn new(base: NonNull<u8>, board: RkBoard) -> Self

    /// Look up power domain by name
    pub fn get_power_dowain_by_name(&self, name: &str) -> Option<PowerDomain>

    /// Turn on specified power domain
    pub fn power_domain_on(&mut self, domain: PowerDomain) -> NpuResult<()>

    /// Turn off specified power domain
    pub fn power_domain_off(&mut self, domain: PowerDomain) -> NpuResult<()>
}

Supported Power Domains (RK3588)

Compute Domains

  • NPU (ID: 8) - Neural Processing Unit main domain
  • NPUTOP (ID: 9) - NPU top domain
  • NPU1 (ID: 10) - NPU core 1
  • NPU2 (ID: 11) - NPU core 2

Graphics Domains

  • GPU (ID: 0) - Graphics Processing Unit
  • VOP (ID: 26) - Video Output Processor
  • VO0 (ID: 27) - Video Output 0
  • VO1 (ID: 28) - Video Output 1

Video Domains

  • VCODEC (ID: 4) - Video Codec main domain
  • VENC0 (ID: 5) - Video Encoder 0
  • VENC1 (ID: 6) - Video Encoder 1
  • RKVDEC0 (ID: 7) - Rockchip Video Decoder 0
  • RKVDEC1 (ID: 12) - Rockchip Video Decoder 1
  • AV1 (ID: 18) - AV1 Decoder
  • VDPU (ID: 2) - Video Processing Unit

Image Domains

  • VI (ID: 29) - Video Input
  • ISP1 (ID: 30) - Image Signal Processor
  • RGA30 (ID: 15) - Raster Graphics Accelerator 30
  • RGA31 (ID: 16) - Raster Graphics Accelerator 31

Bus Domains

  • PHP (ID: 17) - PHP Controller
  • GMAC (ID: 19) - Gigabit Ethernet MAC
  • PCIE (ID: 20) - PCIe Controller
  • SDIO (ID: 21) - SDIO Controller
  • USB (ID: 22) - USB Controller
  • SDMMC (ID: 23) - SD/MMC Controller

Other Domains

  • AUDIO (ID: 1) - Audio Subsystem
  • FEC (ID: 24) - Forward Error Correction
  • NVM (ID: 25) - Non-Volatile Memory
  • NVM0 (ID: 3) - NVM domain 0

Project Structure

rockchip-pm/
├── src/
│   ├── lib.rs              # Main API and RockchipPM structure
│   ├── registers/mod.rs    # Register definitions and access abstraction
│   └── variants/           # Chip-specific implementations
│       ├── mod.rs          # PowerDomain type and common structures
│       ├── _macros.rs      # Power domain definition macros
│       └── rk3588.rs       # RK3588 power domain definitions
├── tests/
│   └── test.rs             # NPU power control integration tests
├── Cargo.toml              # Project configuration and dependencies
├── build.rs                # Build script
├── rust-toolchain.toml     # Rust toolchain configuration
└── README.md               # Project documentation

Building and Testing

Requirements

  • Rust 1.75+ (nightly)
  • aarch64-unknown-none-softfloat target support

Build Steps

# Add target architecture support
rustup target add aarch64-unknown-none-softfloat

# Build library
cargo build

# Build release version
cargo build --release

# Check code
cargo check

Running Tests

The project includes 1 integration test that validates NPU power domain control:

# Run tests on development board (requires U-Boot environment)
cargo uboot

Test Coverage:

  • ✅ RK3588 NPU related power domain on/off
  • ✅ Device tree power domain parsing
  • ✅ Register access verification

Dependencies

Core Dependencies

  • rdif-base (v0.7): Device driver framework
  • tock-registers (v0.10): Type-safe register access and bit manipulation
  • mbarrier (v0.1): Memory barrier primitives for register access ordering
  • dma-api (v0.5): DMA API support
  • log (v0.4): Logging

Development Dependencies

  • bare-test (v0.7): Bare-metal testing framework

Build Dependencies

  • bare-test-macros (v0.2): Test macro definitions

Hardware Compatibility

Supported Chips

  • RK3588: ✅ Fully implemented
  • RK3568: ❌ Not implemented (marked as unimplemented!() placeholder)

Development Boards

  • RK3588 Boards:
    • Orange Pi 5/5 Plus/5B
    • Rock 5A/5B/5C
    • NanoPC-T6
    • Other boards based on RK3588/RK3588S

Memory Mapping Requirements

Before using this library, ensure:

  1. Correct PMU Base Address:
    • RK3588: Typically 0xfd8d8000 (verify from device tree)
  2. Memory Mapping Permissions: Read/write access to PMU register regions
  3. Clock Configuration: Ensure PMU clocks are properly configured

How It Works

Power On Sequence

  1. Write to power control register to enable the power domain
  2. Poll status register waiting for the domain to stabilize (up to 10000 loops)
  3. Verify that power state was successfully enabled

Power Off Sequence

  1. Write to power control register to disable the power domain
  2. Poll status register waiting for the domain to stabilize (up to 10000 loops)
  3. Verify that power state was successfully disabled

Safety Notes

⚠️ Important: This library directly manipulates hardware registers. Before use, ensure:

  • System PMU hardware is properly initialized
  • No other drivers are controlling the same power domains
  • Thorough testing before use on real hardware

License

This project is licensed under the MIT License.

Contributing

Contributions are welcome! Please submit Issues and Pull Requests.

Development Setup

# Clone the repository
git clone https://github.com/drivercraft/rockchip-pm.git
cd rockchip-pm

# Install development tools
rustup component add rustfmt clippy

# Format code
cargo fmt

# Run code checks
cargo clippy

References

  • Linux kernel drivers/soc/rockchip/pm_domains.c
  • RK3588 Technical Reference Manual
  • Rockchip Power Domain Device Tree Binding Documentation

Note: This driver is low-level system software. Ensure hardware register operations comply with chip specifications. Perform thorough testing before use in production environments.

About

power driver for rk3588

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •