Why AXI DMA Fails with OCM on Kria K26 SoC

Summary

The goal was to configure an AXI DMA controller on a Kria K26 SoC to use physical OCM memory as a DMA target. While the example works for DRAM, mapping OCM memory into the DMA pipeline fails due to unrecognized DMA buffer allocation logic in the driver.

Root Cause

  • Invalid DMA buffer registration: The AXI DMA driver’s axidma_register_buffer API expects memory regions compatible with DMA, but OCM lacks required attributes (e.g., DMA coherence, cache alignment).
  • Driver limitations: The axidma_dma_get_external function uses dma_buf_get internally, which may not recognize OCM memory as a valid DMA buffer even if mapped via /dev/mem.
  • Missing device tree configuration: OCM memory might not be exposed to the DMA subsystem as a shareable DMA pool or coherent memory region.

Why This Happens in Real Systems

  • Memory attribute mismatch: DMA operations require memory regions with explicit DMA support (e.g., dma_memory properties in DT, cache attributes). OCM may lack these unless explicitly configured.
  • Legacy driver design: The libaxidma framework might prioritize simplicity over advanced memory targeting, relying on standard DMA buffers from DRAM.
  • Hardware constraints: OCM access via AXI DMA may require specific alignment or synchronization mechanisms not handled by the example.

Real-World Impact

  • Performance bottlenecks: Using OCM instead of DRAM could reduce throughput due to slower OCM access latencies.
  • Design flexibility loss: Forcing DMA to use OCM may complicate scenarios requiring dynamic memory allocation.
  • Maintenance overhead: A custom driver would be needed to bypass library limitations, increasing code complexity.

Example or Code (if necessary and relevant)

// Incomplete OCM mapping code (attempted by user)
unsigned int bram_size = OCM_SIZE;  
off_t bram_pbase = OCM_BASE;  
bram64_vptr = (u64 *)mmap(NULL, bram_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, Bram_pbase);  

// AXI DMA registration (failing call)  
rc = axidma_register_buffer(axidma_dev, rx_fd, rx_address, rx_size);

This code fails because axidma_register_buffer does not validate OCM memory as a valid DMA target.

How Senior Engineers Fix It

  • Modify device tree: Add dma-memory properties to OCM memory region to signal DMA compatibility.
  • Replace with custom DMA API: Implement a driver that directly configures the AXI DMA controller to target OCM without relying on libaxidma.
  • Use coherent memory: Allocate memory via dma_alloc_coherent instead of manual /dev/mem mmapping for guaranteed DMA support.

Why Juniors Miss It

  • Overlooking DMA memory requirements: Juniors may treat all mapped memory as equally valid for DMA, ignoring hardware-specific constraints.
  • Relying on abstracted APIs: They might assume axidma_register_buffer handles all memory types without verifying underlying implementation.
  • Ignoring device tree impact: Juniors often miss how DT overrides affect driver behavior, especially for niche memory regions like OCM.

Leave a Comment