microSD reads on am335x cost about 90% of the single core, almost all of it in interrupt context, because ti_sdhci is PIO only:
19.47 MB/s busy 93.8% (sys 3.7% intr 89.6% idle 6.2%)
SD_CAPA advertises SDMA, but the MMCHS OCP master interface is not implemented on this SoC: SD_CON[20] DMA_MnS is documented as "not available on this device" (AM335x TRM SPRUH73Q 18.5.1.5). The controller can only ever be a DMA slave, and sdhci(4) implements SDMA, which is bus mastering by definition. Clearing SDHCI_QUIRK_BROKEN_DMA makes the first data transfer time out and loses the storage path entirely.
Use the platform hooks sdhci(4) already provides platform_will_handle, platform_start_transfer, platform_finish_transfer with EDMA3 driving the controller's SDTXEVT/SDRXEVT slave request lines. bcm2835_sdhci(4) is the existing precedent for the same shape: a controller that cannot master, paired with a separate SoC DMA engine.
Note the quirk deliberately stays set. It only clears SDHCI_HAVE_DMA, which governs sdhci(4) programming a system address and letting the controller master the bus. The offload attaches on a different path: sdhci(4) reaches the platform hooks from its PIO handler, so EDMA3 replaces the byte copy rather than SDHCI DMA. The controller never masters anything, and the data phase never touches the CPU.
Two hardware details shape the implementation. SD_CMD[0] DE must be set by the same register write that issues the command (18.3.5.1); ti_sdhci already defers the transfer mode and writes command and mode together, so that write is the arming point. And with DE set the controller reports only command complete and transfer complete — one interrupt per transfer rather than per block.
The caller's buffer is mapped and each physically contiguous run described by its own PaRAM set, linked into a chain the channel controller walks unaided, so there is no copy. PaRAM sets 0-63 belong to the channels, so chains are built from spare sets above those. Transfers that cannot be mapped in place fall back to a bounce buffer; that is 12.5% of data phases, all of them buffers starting on a cache line but not a block boundary, so a block straddles two segments and one request moves exactly one block.
Reading 150MB from microSD at 1000MHz, three trials each:
PIO 19.2-19.6 MB/s busy 92.6% intr 89.2% idle 7.4% EDMA3, mapped 18.9-19.0 MB/s busy 6.0% intr 2.2% idle 94.0%
Just under 98% of the throughput the CPU achieves by hand, for a fifteenth of the CPU time and a fortieth of the time in interrupt context.
Derived from the AM335x TRM (SPRUH73Q) and from BSD licensed FreeBSD source: sdhci.c, sdhci_if.m, bcm2835_sdhci.c and the pre-existing ti_edma3.c. No GPL licensed source was consulted.
Depends on D59124.