Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
S
Simple PCIe FMC carrier SPEC
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
50
Issues
50
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
Simple PCIe FMC carrier SPEC
Commits
32659261
Commit
32659261
authored
Jul 02, 2020
by
Federico Vaga
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
doc: add DMA chapter
Signed-off-by:
Federico Vaga
<
federico.vaga@cern.ch
>
parent
7f6fb421
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
53 additions
and
0 deletions
+53
-0
sw-driver.rst
doc/sw-driver.rst
+53
-0
No files found.
doc/sw-driver.rst
View file @
32659261
...
...
@@ -237,3 +237,56 @@ attributes. Here we focus only on those.
and ``close(2)`` to request and release a DMA engine channel. Then,
the user can use ``lseek(2)`` to set the offset in the DDR, and
``read(2)``/``write(2)`` to start the DMA transfer.
DMA
---
On SPEC-Based designs the DMA engine is implemented in HDL. This means
that you can't perform a DMA transfer without a *spec-base* device
on the FPGA.
The SPEC driver(s) implements the dmaengine API for the HDL DMA
engine. To request a dmaengine channel the user must provide a filter
function. The SPEC driver assigns to the application driver a
IORESOURCE_DMA which value is ``dma_device->dev_id << 16 |
channel_number``. Therefore, the user can use the following filter
function.::
static bool filter_function(struct dma_chan *dchan, void *arg)
{
struct dma_device *ddev = dchan->device;
int dev_id = (*((int *)arg) >> 16) & 0xFFFF;
int chan_id = *((int *)arg) & 0xFFFF;
return ddev->dev_id == dev_id && dchan->chan_id == chan_id;
}
void function(void)
{
struct resource *r;
int dma_dev_id;
dma_cap_mask_t dma_mask;
/* ... */
r = platform_get_resource(pdev, IORESOURCE_DMA, TDC_DMA);
dma_dev_id = r->start;
dma_cap_zero(dma_mask);
dma_cap_set(DMA_SLAVE, dma_mask);
dma_cap_set(DMA_PRIVATE, dma_mask);
dchan = dma_request_channel(dma_mask, filter_function,
dma_dev_id);
/* ... */
}
You can get the maximum transfer size by calling ``dma_get_max_seg_size()``.::
dma_get_max_seg_size(dchan->device->dev);
.. warning::
The HDL DMA engine implementation does not support very well
``DMA_MEM_TO_DEV`` transfers. To overcome some bugs users must
split their transfers in 4KiB chunks.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment