Re: FDT DMA controller interface extension
Yuri Honegger <[email protected]> Sun, 25 Jan 2026 15:20:01 +0100
| Newsgroups | gmane.os.netbsd.ports.arm |
|---|---|
| Message-ID | <[email protected]> |
> Hi everyone,
>
> Recently, I've been writing a DMA controller for the i.MX23. The i.MX23 DMA
> controller works by passing the hardware a pointer to a DMA command chain stored
> in memory. A DMA command looks roughly like this:
>
> struct dma_command {
> void *next; /* you can chain commands */
> uint32_t control;
> void *buffer; /* memory buffer to transfer to/from */
> uint32_t pio_words[3];
> };
>
> The i.MX23 DMA controller supports so-called "Programmable IO Words", short PIO.
> These PIO words get written to the hardware configuration register of the
> peripheral we are interacting over DMA before transferring data.
>
> Due to some peculiarities of the i.MX23 hardware, you basically need to use PIO
> for the SD card driver if you don't want to write a polling driver.
>
> The issue is that the FDT DMA controller interface (sys/dev/fdt/fdt_dma.h)
> doesn't provide a way to pass PIO data from a driver to the DMA controller.
> Therefore, I suggest to extend the fdtbus_dma_req struct with some optional
> parameters to specify PIO operations.
>
> Here is my suggested diff. It solves the problem in the most straightforward way
> that works for the i.MX23.
>
> Is it fine like this? I’m a bit afraid of ballooning the fdtbus_dma_req struct even more.
> Already right now most options are only supported by 1-2 controllers due to the wide
> variety in DMA controllers.
>
> Thanks,
> Yuri
Hi,
With the help of Nick and Jared, we’ve created an updated patch. It should be less
i.MX23-specific by using a pointer+size approach.
Yuri
fdt_dma_v2.diff
(application/octet-stream, 729 B)
diff --git a/sys/dev/fdt/fdt_dma.h b/sys/dev/fdt/fdt_dma.h
index a876bc62d67f..147aa187f0ac 100644
--- a/sys/dev/fdt/fdt_dma.h
+++ b/sys/dev/fdt/fdt_dma.h
@@ -41,7 +41,8 @@ struct fdtbus_dma {
enum fdtbus_dma_dir {
FDT_DMA_READ, /* device -> memory */
- FDT_DMA_WRITE /* memory -> device */
+ FDT_DMA_WRITE, /* memory -> device */
+ FDT_DMA_NO_XFER /* dma operation without data transfer */
};
struct fdtbus_dma_opt {
@@ -56,6 +57,9 @@ struct fdtbus_dma_req {
bus_dma_segment_t *dreq_segs; /* Memory */
int dreq_nsegs;
+ void *dreq_data; /* Controller-specific ancillary data */
+ int dreq_datalen; /* Size of dreq_data */
+
bus_addr_t dreq_dev_phys; /* Device */
int dreq_sel; /* Device selector */