This commit introduces a different interface to submit transfers, using
DMA descriptors.
The structure of the DMA descriptor is as follows:
struct dma_desc {
u32 flags,
u32 id,
u64 dest_addr,
u64 src_addr,
u64 next_sg_addr,
u32 y_len,
u32 x_len,
u32 src_stride,
u32 dst_stride,
};
The 'flags' field currently offers two control bits:
- bit 0: if set, the transfer will complete after this last descriptor
is processed, and the DMA core will go back to idle state; if cleared,
the next DMA descriptor pointed to by 'next_sg_addr' will be loaded.
- bit 1: if set, an end-of-transfer interrupt will be raised after the
memory segment pointed to by this descriptor has been transferred.
The 'id' field corresponds to an identifier of the descriptor.
The 'dest_addr' and 'src_addr' contain the destination and source
addresses to use for the transfer, respectively.
The 'x_len' field contains the number of bytes to transfer,
minus one.
The 'y_len', 'src_stride' and 'dst_stride' fields are only useful for
2D transfers, and should be set to zero if 2D transfers are not
required.
To start a transfer, the address of the first DMA descriptor must be
written to register 0x47c and the HWDESC bit of CONTROL register must
be set. The Scatter-Gather transfer is queued similarly to the simple
transfers, by writing 1 in TRANSFER_SUBMIT.
The Scatter-Gather interface has a dedicated AXI-MM bus configured for
read transfers, with its own dedicated clock, which can be asynchronous.
The Scatter-Gather reset is generated by the reset manager to reset the
logic after completing any pending transactions on the bus.
When the Scatter-Gather is enabled during runtime, the legacy cyclic
functionality of the DMA is disabled.
Signed-off-by: Ionut Podgoreanu <ionut.podgoreanu@analog.com>
New improvements for the ADI DMAC IP:
1)The capability to manually overwrite the DMA_AXI_ADDR_WIDTH(from GUI or from tcl)
2)DMA_AXI_ADDR_WIDTH attribute is now visible in the Vivado GUI:
-"Auto mode": Automatically calculated by the core tcl files based on the existing attached address segments.
-"Manual mode": Specify the desired dma_width between 32-64 bits.
3)Added two new debug registers that return higher part of the current source/destination address.
Signed-off-by: Filip Gherman <Filip.Gherman@analog.com>
In some cases, the Vivado version can contain other characters than just
numbers. One such example is after applying the patch of AR# 71948,
which makes `version -short` return something like `2018.3_AR71948`.
This patch changes the version check to ignore anything after the first
two components of the version.
Current implementation does not supports updated versions of Vivado
e.g. 2017.4.1 or 2018.2.1
This fix ignores the update number from the version checking.
FPGAs support different widths for the read and write port of the block
SRAM cells. The DMAC can make use of this feature when the source and
destination interface have a different width to up-size/down-size the data
bus.
Using memory cells with asymmetric port width consumes the same amount of
SRAM cells, but allows to bypass the re-size blocks inside the DMAC that
are otherwise used for up- and down-sizing. This reduces overall resource
usage and can improve timing.
If the ratio between the destination and source port is too larger to be
handled by SRAM alone the SRAM block will be configured to do partial up-
or down-sizing and a resize block will be inserted to take care of the
remaining up-/down-sizing. E.g. if a 256-bit interface is connected to a
32-bit interface the SRAM will be used to do an initial resizing of 256 bit
to 64 bit and a resize block will be used to do the remaining resizing from
64 bit to 32 bit.
Currently this feature is disabled for Intel FPGAs since Quartus does not
properly infer a block RAM with different read and write port widths from
the current ad_asym_mem module. Once that has been resolved support for
asymmetric memories can also be enabled in the DMAC.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The round function from tcl is a rounding to nearest. Using it in address
width calculation produces incorrect values.
e.g.
round(log(0xAF000000)/log(2)) will produce 31 instead of 32
The fix is to replace the rounding function with ceiling that guarantees
rounding up.
The MAX_BYTES_PER_BURST option allows to configure the maximum bytes that
are part of a burst. This can be an arbitrary value.
At the same time there is a limit of how many bytes can be supported by the
memory buses. A AXI3 interface supports a maximum of 16 beats per burst
and a AXI4 interface supports a maximum of 256 beats per burst.
At the moment the it is possible to specify a MAX_BYTES_PER_BURST value
that exceeds what can be supported by the AXI memory-mapped bus. If that is
the case undefined behavior will occur and the DMAC will function
incorrectly.
To avoid this make sure that the MAX_BYTES_PER_BURST value does not exceed
the maximum that can be supported by the interfaces.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
When a mapping has multiple address segments we need to consider all of
them to calculate the required address width.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The address width needs to be large enough to be able to address the
largest possible address. This means the in addition to the address segment
range the specified offset also needs to be considered to calculate the
address width.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Currently the AXI address width of the DMA is always 32-bit. But not all
address spaces are so large that they require 32-bit to address all memory.
Extract the size of the address space that the DMA is connected too and
configure reduce the address size to the minimum required to address the
full address space.
This slightly reduces utilization.
If no mapped address space can be found the default of 32 bits is used for
the address.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Add validation values for the different configuration parameters. This
enables the tools to check whether the configured value is valid and avoids
accidental misconfiguration.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Configure the maximum burst size as well as the maximum number of active
requests on the AXI master interfaces according to the core configuration.
This allows connected slaves to know what kind of requests to expect and
allows them to configure themselves accordingly.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
The axi_dmac core generates requests which are both AXI3 and AXI4
compliant. This means it is possible to connect it to both a AXI3 or AXI4
slave port without needing a AXI protocol converter. Unfortunately it is
not possible to declare a port as both AXI3 and AXI4 compliant, so the core
has the C_DMA_AXI_PROTCOL_SRC and C_DMA_AXI_PROTOCOL_DEST parameters, which
allow to configure the protocol type of the corresponding AXI master
interface. Currently the default is always AXI4.
But when being used on ZYNQ it is most likely that the AXI master interface
of the DMAC core ends up being connected to the AXI3, so change the default
to AXI3 if the core is instantiated in a ZYNQ design.
The default can still be overwritten by explicitly setting the
configuration property.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Add support for querying the clock domains of the clock pins for the
axi_dmac controller. This allows the core to automatically figure out
whether its different parts run in different clock domains or not and setup
the configuration parameters accordingly.
Being able to auto-detect those configuration parameters makes the core
easier to use and also avoids accidental misconfiguration.
It is still possible to automatically overwrite the configuration
parameters by hand if necessary.
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>