The XDMAC supports memset transfers, both over contiguous areas, and over
discontiguous areas through a LLI.
The current memset operation only supports contiguous memset for now, add some
support for it. Scatter-gathered memset will come eventually.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Now that we can have ICGs set for both the source and destination (using
the icg field of struct data_chunk) or for only the source or the
destination (using the dst_icg or src_icg respectively), and that these
fields can be ignored depending on other parameters (src_inc, src_sgl,
etc.), the logic to get the actual ICG value can be quite tricky.
The XDMAC driver was already implementing it, but since we will need it in
other drivers, we can move it to the main header file.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Rework slave configuration part in order to more report wrong errors
about the configuration.
Only maxburst and addr width values are checked when doing the slave
configuration. The validity of the channel configuration is done at
prepare time.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Cc: stable@vger.kernel.org # 4.0 and later
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Using _bh variant for spin locks causes this kind of warning:
Starting logging: ------------[ cut here ]------------
WARNING: CPU: 0 PID: 3 at /ssd_drive/linux/kernel/softirq.c:151
__local_bh_enable_ip+0xe8/0xf4()
Modules linked in:
CPU: 0 PID: 3 Comm: ksoftirqd/0 Not tainted 4.1.0-rc2+ #94
Hardware name: Atmel SAMA5
[<c0013c04>] (unwind_backtrace) from [<c00118a4>] (show_stack+0x10/0x14)
[<c00118a4>] (show_stack) from [<c001bbcc>]
(warn_slowpath_common+0x80/0xac)
[<c001bbcc>] (warn_slowpath_common) from [<c001bc14>]
(warn_slowpath_null+0x1c/0x24)
[<c001bc14>] (warn_slowpath_null) from [<c001e28c>]
(__local_bh_enable_ip+0xe8/0xf4)
[<c001e28c>] (__local_bh_enable_ip) from [<c01fdbd0>]
(at_xdmac_device_terminate_all+0xf4/0x100)
[<c01fdbd0>] (at_xdmac_device_terminate_all) from [<c02221a4>]
(atmel_complete_tx_dma+0x34/0xf4)
[<c02221a4>] (atmel_complete_tx_dma) from [<c01fe4ac>]
(at_xdmac_tasklet+0x14c/0x1ac)
[<c01fe4ac>] (at_xdmac_tasklet) from [<c001de58>]
(tasklet_action+0x68/0xb4)
[<c001de58>] (tasklet_action) from [<c001dfdc>]
(__do_softirq+0xfc/0x238)
[<c001dfdc>] (__do_softirq) from [<c001e140>] (run_ksoftirqd+0x28/0x34)
[<c001e140>] (run_ksoftirqd) from [<c0033a3c>]
(smpboot_thread_fn+0x138/0x18c)
[<c0033a3c>] (smpboot_thread_fn) from [<c0030e7c>] (kthread+0xdc/0xf0)
[<c0030e7c>] (kthread) from [<c000f480>] (ret_from_fork+0x14/0x34)
---[ end trace b57b14a99c1d8812 ]---
It comes from the fact that devices can called some code from the DMA
controller with irq disabled. _bh variant is not intended to be used in
this case since it can enable irqs. Switch to irqsave/irqrestore variant to
avoid this situation.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Cc: stable@vger.kernel.org # 4.0 and later
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
The XDMAC supports interleaved tranfers through its flexible descriptor
configuration.
Add support for that kind of transfers to the dmaengine driver.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
So far, we were setting the NDE bit in our descriptors through some logic to
try to see if we were the last descriptor in the chain.
However, that was turning out to be rather complex to get right, while this
information is also available when we actually chain a new descriptor after an
already existing one.
Simplify this by never setting NDE unless when we actually chain a descriptor.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
The code has some logic to compute the burst width according to the alignment
of the address we're using.
Move that in a function of its own to reduce code duplication.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
The XDMAC DMA controller uses a concept of views to be able to handle
descriptors of different sizes.
So far, only the views 1 and 2 were handled by the driver. Unfortunately, we
need some of the configuration fields found in the view 3 in order to support
memset and interleaved transfers.
Add the definition for the view 3 registers, and the needed code to handle view
3 descriptors.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
When simplificating the channel configuration, the cyclic case has been
forgotten. It leads to use bad configuration causing many bugs.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
When using FIFO, we need to support differents data width in a single
transfer. For example, serial device which usually uses 1-byte data
width will use 4-bytes data width when using the FIFO. If the transfer
size is not aligned on 4-bytes then the end of the transfer will be
performed with 1-byte data-width. For that reason,
at_xdmac_prep_slave_sg() now builds linked list descriptors using view 2
instead of view 1 so each of them can update the DWIDTH field into the
Channel Configuration Register.
Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
This patch simplifies the channel configuration register management.
Relying on a "software snapshot" of the configuration is not safe and
too complex.
Multiple dwidths will be introduced for slave transfers. In this case,
it becomes quite difficult to have an accurate snapshot of the channel
configuration register in the way it is done. Using the channel
configuration available in the lli descriptor simplifies this stuff.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
When suspending the device, read the channel configuration directly from
the register instead of relying on a software snapshot, it will be
safer.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
This platform_driver does not need to set an owner, it will be populated by the
driver core.
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Now that the generic slave caps code can make use of the device assigned
capabilities, instead of relying on a callback to be implemented.
Make use of this code.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
The dmaengine header abbreviates destination as at least two different strings.
Make a coherent use of a single one.
Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>
Acked-by: Mark Brown <broonie@kernel.org>
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Acked-by: Stephen Warren <swarren@wwwdotorg.org>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
same issue as commit 7f5ae3553685:
"Without DMA_PRIVATE the driver is not able to allocate more than one channel.
Since it uses dma_get_any_slave_channel that calls private_candidate, the
second allocation fails at
/* some channels are already publicly allocated */
"
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Lock taken when entering the function but unlock missing before it
returns.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
The total size of the transfer was wrong in at_xdmac_prep_slave_sg()
resulting in bad computation of the transfer residue by
at_xdmac_tx_status().
Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
According to the Atmel eXtended DMA controller datasheet, requesting a
DMA transfer flush for a channel is only revelant when this transfer is
source peripheral synchronized.
So we have to check this condition before requesting a channel flush by
writing the channel bit into the Global channel SoftWare Flush (GSWF)
register then waiting for flush to complete by monitoring the end of
Flush Interrupt Status (FIS) bit in the Channel Interrupt Status (CIS)
register.
Indeed, for non source peripheral synchronized transfer, writing the
channel bit into the GSWF register does nothing. Especially, the FIS bit
is never set into the CIS register. The former code looped forever
waiting for this bit to be set.
Signed-off-by: Cyrille Pitchen <cyrille.pitchen@atmel.com>
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Remove chancnt affectation since it is done in dma_async_device_regiser.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
_relaxed version of readl and writel are not implemented on all
architecture so COMPILE_TEST has to be removed in order to not cause
some build failures.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
As documented in printk-formats.txt the dma_addr_t should be printed with
%pad specfiers. This way it works on all archs.
make.cross ARCH=s390
All warnings:
drivers/dma/at_xdmac.c: In function 'at_xdmac_prep_slave_sg':
>> drivers/dma/at_xdmac.c:621:3: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'dma_addr_t' [-Wformat=]
dev_dbg(chan2dev(chan),
^
>> drivers/dma/at_xdmac.c:621:3: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=]
>> drivers/dma/at_xdmac.c:628:4: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=]
dev_dbg(chan2dev(chan),
^
drivers/dma/at_xdmac.c: In function 'at_xdmac_prep_dma_cyclic':
>> drivers/dma/at_xdmac.c:663:2: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'dma_addr_t' [-Wformat=]
dev_dbg(chan2dev(chan), "%s: buf_addr=0x%08x, buf_len=%d, period_len=%d, dir=%s, flags=0x%lx\n",
^
>> drivers/dma/at_xdmac.c:690:3: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=]
dev_dbg(chan2dev(chan),
^
>> drivers/dma/at_xdmac.c:709:3: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'dma_addr_t' [-Wformat=]
dev_dbg(chan2dev(chan),
^
>> drivers/dma/at_xdmac.c:709:3: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=]
>> drivers/dma/at_xdmac.c:716:4: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=]
dev_dbg(chan2dev(chan),
>> drivers/dma/at_xdmac.c:731:2: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=]
dev_dbg(chan2dev(chan),
^
drivers/dma/at_xdmac.c: In function 'at_xdmac_prep_dma_memcpy':
>> drivers/dma/at_xdmac.c:765:2: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'dma_addr_t' [-Wformat=]
dev_dbg(chan2dev(chan), "%s: src=0x%08x, dest=0x%08x, len=%d, flags=0x%lx\n",
^
>> drivers/dma/at_xdmac.c:765:2: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=]
dev_dbg(chan2dev(chan), "%s: remaining_size=%u\n", __func__, remaining_size);
^
>> drivers/dma/at_xdmac.c:845:3: warning: format '%x' expects argument of type 'unsigned int', but argument 5 has type 'dma_addr_t' [-Wformat=]
dev_dbg(chan2dev(chan),
^
>> drivers/dma/at_xdmac.c:845:3: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=]
>> drivers/dma/at_xdmac.c:852:4: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=]
dev_dbg(chan2dev(chan),
^
drivers/dma/at_xdmac.c: In function 'at_xdmac_tx_status':
>> drivers/dma/at_xdmac.c:929:2: warning: format '%x' expects argument of type 'unsigned int', but argument 6 has type 'dma_addr_t' [-Wformat=]
dev_dbg(chan2dev(chan),
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
As documented in printk-formats.txt the size_t should be printed with
%zu/%zd specfiers. This way it works on all archs.
make.cross ARCH=avr32
All warnings:
drivers/dma/at_xdmac.c: In function 'at_xdmac_prep_dma_cyclic':
>> drivers/dma/at_xdmac.c:663: warning: format '%d' expects type 'int', but argument 6 has type 'size_t'
>> drivers/dma/at_xdmac.c:663: warning: format '%d' expects type 'int', but argument 7 has type 'size_t'
drivers/dma/at_xdmac.c: In function 'at_xdmac_prep_dma_memcpy':
>> drivers/dma/at_xdmac.c:765: warning: format '%d' expects type 'int', but argument 7 has type 'size_t'
>> drivers/dma/at_xdmac.c:794: warning: format '%u' expects type 'unsigned int', but argument 5 has type 'size_t'
>> drivers/dma/at_xdmac.c:815: warning: format '%u' expects type 'unsigned int', but argument 5 has type 'size_t'
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
This driver uses read_relaxed and writel_relaxed to read, write to IO
memory. the config defines COMPILE_TEST so gets compiled on different archs.
This causes issue as few archs like x86 etc don't define it.
So use readl/writel which is defined in all archs
Reported-by: kbuild test robot <fengguang.wu@intel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>
New atmel DMA controller known as XDMAC, introduced with SAMA5D4
devices.
Signed-off-by: Ludovic Desroches <ludovic.desroches@atmel.com>
Acked-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Signed-off-by: Vinod Koul <vinod.koul@intel.com>