dwmmc-host 0.1.2

Synopsys DesignWare Mobile Storage Host Controller backend for sdmmc-protocol (no_std, FIFO/IDMAC)
Documentation

dwmmc-host

no_std Synopsys DesignWare Mobile Storage Host Controller (DW_mshc) backend for sdmmc-protocol.

This crate plugs the IP block known as DWC_mobile_storage / dw_mshc / dw_mmc (Linux) into the SdioHost trait so sdmmc_protocol::sdio::SdioSdmmc can drive real hardware. The same core appears in Rockchip RK33xx/RK35xx, Allwinner A-series, StarFive JH7110, and a long tail of mid-range SoCs.

This crate implements sdmmc_protocol::sdio::SdioHost for the controller while leaving MMIO mapping, SoC clocks, resets, pinmux, power rails, IRQ routing, and DMA cache policy to platform glue.

Status

  • Compiles as a no_std controller backend.
  • Intended for use through sdmmc_protocol::sdio::SdioSdmmc.
  • Board-specific clock, power, pinmux, and tuning policy must be supplied by the caller.
  • Real hardware bring-up still depends on the surrounding SoC integration.

Scope

Area Implemented
PIO read / write (FIFO)
1-bit / 4-bit / 8-bit bus
Default speed
High Speed (50 MHz)
UHS-I / HS200 clock targets
32-bit / 136-bit responses
R3 / R4 (no CRC) responses
Software reset / clock setup
Configurable FIFO offset
1.8 V signaling register path ✅ (board validation required)
DDR50 register bit path ✅ (board validation required)
IDMAC descriptor read / write
SdioHost IDMAC data path ✅ (FIFO fallback)
External-DMA data path
Controller-specific DLL/strobe/tuning windows

The SdioHost implementation tries IDMAC for 512-byte CMD17/CMD18/CMD24/CMD25 block I/O when a dma_api::DeviceDma capability is installed with DwMmc::set_dma; otherwise it uses the FIFO path. DwMmc::block_buffer_config exposes the selected queue constraints for block-device adapters.

Usage

use core::ptr::NonNull;
use sdmmc_protocol::{OperationPoll, sdio::{SdioInitScratch, SdioSdmmc}};
use dwmmc_host::DwMmc;

// SAFETY: 0xFE2B_0000 must point at a valid DW_mshc register file the
// caller has exclusive access to.
let mmio = NonNull::new(0xFE2B_0000 as *mut u8).unwrap();
let mut host = unsafe { DwMmc::new(mmio) };
host.set_reference_clock(50_000_000);
host.reset_and_init().expect("controller reset");

let mut card = SdioSdmmc::new(host);
let mut scratch = SdioInitScratch::new();
let mut request = card.submit_init(&mut scratch)?;
while let OperationPoll::Pending = card.poll_init_request(&mut request)? {
    // Runtime policy belongs here: spin, yield, wait for IRQ, or sleep/timer
    // when request.take_needs_pace() is set.
}
# Ok::<(), sdmmc_protocol::Error>(())

Construction is unsafe because the caller must guarantee that the supplied address is a valid, exclusively-owned DW_mshc register file for the lifetime of the driver.

Bring-up checklist (for real-hardware validation)

  1. Map the DW_mshc register file (e.g. RK3568 SDMMC0 at 0xFE2B_0000).
  2. Configure the platform clock so the controller has a viable reference clock before calling DwMmc::new. Most SoCs route a selectable mux through the CRU; pick a rate that divides cleanly to 400 kHz for ID mode.
  3. Pass that rate to DwMmc::set_reference_clock so the divider programmed by set_clock lands on the right frequency.
  4. host.reset_and_init()? — clears the controller / FIFO / DMA state and arms a 400 kHz ID-mode clock.
  5. Build SdioSdmmc::new(host), submit initialization with submit_init, and drive it with poll_init_request. The protocol layer will ramp the clock up via set_clock; platform/runtime code chooses whether pending work spins, yields, or waits for an IRQ.
  6. Add board-specific tuning before relying on SDR50, SDR104, DDR50, or HS200 modes.

FIFO offset

The data FIFO sits at a fixed offset that varies by IP revision / integration:

  • 0x100: very old DWC_mobile_storage builds.
  • 0x200 (default): Rockchip RK33xx/RK35xx, StarFive JH7110.
  • 0x400: some Allwinner integrations.

Use DwMmc::new_with_fifo_offset if your SoC differs from the default.

Testing

From this crate directory:

cargo fmt --check
cargo test
cargo clippy --all-features -- -D warnings

In this workspace, prefer the project xtask flow for final validation:

cargo fmt
cargo xtask clippy --package dwmmc-host

License

Licensed under the Apache License, Version 2.0.