Page MenuHomeFreeBSD

DMA abstraction layer xDMA
ClosedPublic

Authored by br on Apr 5 2018, 1:06 PM.
Tags
None
Referenced Files
F106054057: D14971.id41125.diff
Tue, Dec 24, 2:35 PM
F106042466: D14971.diff
Tue, Dec 24, 9:11 AM
Unknown Object (File)
Fri, Dec 20, 11:00 AM
Unknown Object (File)
Tue, Dec 10, 5:04 AM
Unknown Object (File)
Sat, Dec 7, 5:06 AM
Unknown Object (File)
Oct 10 2024, 1:17 AM
Unknown Object (File)
Sep 26 2024, 4:43 PM
Unknown Object (File)
Sep 25 2024, 1:41 PM
Subscribers

Details

Summary

Generic interface operation flow:

/* Get xDMA controller */
sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");

/* Allocate virtual channel */
sc->xchan_tx = xdma_channel_alloc(sc->xdma_tx, caps);

/* Setup transfer status callback. */
xdma_setup_intr(sc->xchan_tx, my_tx_intr, sc, &sc->ih_tx);

/* Request a transfer */
ret = xdma_request(sc->xchan_tx, &req);

/* Free the channel */
xdma_channel_free(sc->xdma_tx);

/* Free the controller */
xdma_put(sc->xdma_tx);

Less generic (scatter-gather application based on xDMA interface) operation flow:

/* Get xDMA controller */
sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");

/* Allocate virtual channel */
sc->xchan_tx = xdma_channel_alloc(sc->xdma_tx, caps);
int
atse_xdma_tx_intr(void *arg, xdma_transfer_status_t *status)
{
    for (;;) {
            err = xdma_dequeue_mbuf(sc->xchan_tx, &m, &st);
            if (err != 0) {
                    break;
            }
    }
}

/* Setup interrupt handler. */
xdma_setup_intr(sc->xchan_tx, atse_xdma_tx_intr, sc, &sc->ih_tx);

/* Prepare SG transfer */
xdma_prep_sg(sc->xchan_tx, TX_QUEUE_SIZE, ...);
/* Enqueue (multiple) mbufs to receive */
m = m_getcl();
xdma_enqueue_mbuf(sc->xchan_rx, &m, 0, 4, 4, XDMA_DEV_TO_MEM);
m = m_getcl();
xdma_enqueue_mbuf(sc->xchan_rx, &m, 0, 4, 4, XDMA_DEV_TO_MEM);
...
xdma_queue_submit(sc->xchan_rx);
/* Enqueue mbuf to transmit */
xdma_enqueue_mbuf(sc->xchan_tx, &m, 0, 4, 4, XDMA_MEM_TO_DEV);
xdma_queue_submit(sc->xchan_tx);

DMA engine driver interface. These functions have to be implemented in DMA engine driver

/* Allocate real hardware channel */
int
msgdma_channel_alloc(device_t dev, struct xdma_channel *xchan) 
{

}

/* Request a transfer */
static int
pdma_channel_request(device_t dev, struct xdma_channel *xchan, struct xdma_request *req)
{

}

/* Free the channel */
static int
msgdma_channel_free(device_t dev, struct xdma_channel *xchan)
{

}

/* Start/stop DMA operation */
static int
msgdma_channel_control(device_t dev, xdma_channel_t *xchan, int cmd)
{

}

Scatter-gather DMA engine driver interface. These functions have to be implemented in DMA engine driver

/* Prepare a channel for SG transfer */
softdma_channel_prep_sg(device_t dev, struct xdma_channel *xchan)
{
...
}

/* Submit sg list */
softdma_channel_submit_sg(device_t dev, struct xdma_channel *xchan,
    struct xdma_sglist *sg, uint32_t sg_n) 
{
...
}

/* Provide the amount of free entries for requests. */
softdma_channel_capacity(device_t dev, xdma_channel_t *xchan,
    uint32_t *capacity)
{
...
}
Test Plan

Tested with:

  • Ingenic mips32 Audio Interface Controller (AIC) with Ingenic PDMA® engine (cyclic transfer).
  • atse(4) device with Altera SoftDMA® and Altera mSGDMA® engines.
  • Cadence QSPI device with ARM PrimeCell® DMA engine.

Diff Detail

Repository
rS FreeBSD src repository - subversion
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

br edited the test plan for this revision. (Show Details)
br edited the test plan for this revision. (Show Details)
This revision was not accepted when it landed; it landed in state Needs Review.Apr 12 2018, 3:36 PM
Closed by commit rS332435: Tune xDMA interface slightly: (authored by br). · Explain Why
This revision was automatically updated to reflect the committed changes.