Merge tag 'dmaengine-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine

Pull dmaengine updates from Vinod Koul:
 "New Support:

   - MT6795 SoC dma controller (AngeloGioacchino Del Regno)

   - qcom-adm controller yaml binding (Christian Marangi)

   - Renesas r8a779g0 dma controller yaml binding (Geert Uytterhoeven)

   - Qualcomm SM6350 GPI dma controller (Luca Weiss)

  Updates:

   - STM32 DMA-MDMA chaining support (Amelie Delaunay)

   - make hsu driver use managed resources (Andy Shevchenko)

   - the usual round of idxd driver updates (Dave Jiang & Jerry
     Snitselaar)

   - apple dma driver iommu and pd properties and remove use
     of devres for irqs (Janne Grunau & Martin Povišer)

   - device_synchronize support for Xilinx zynqmp driver (Swati
     Agarwal)"

* tag 'dmaengine-6.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/vkoul/dmaengine: (60 commits)
  dmaengine: ioat: remove unused declarations in dma.h
  dmaengine: ti: k3-udma: Respond TX done if DMA_PREP_INTERRUPT is not requested
  dmaengine: zynqmp_dma: Add device_synchronize support
  dt-bindings: dma: add additional pbus reset to qcom,adm
  dt-bindings: dma: rework qcom,adm Documentation to yaml schema
  dt-bindings: dma: apple,admac: Add iommus and power-domains properties
  dmaengine: dw-edma: Remove runtime PM support
  dmaengine: idxd: add configuration for concurrent batch descriptor processing
  dmaengine: idxd: add configuration for concurrent work descriptor processing
  dmaengine: idxd: add WQ operation cap restriction support
  dmanegine: idxd: reformat opcap output to match bitmap_parse() input
  dmaengine: idxd: convert ats_dis to a wq flag
  dmaengine: ioat: stop mod_timer from resurrecting deleted timer in __cleanup()
  dmaengine: qcom-adm: fix wrong calling convention for prep_slave_sg
  dmaengine: qcom-adm: fix wrong sizeof config in slave_config
  dmaengine: ti: k3-psil: add additional TX threads for j721e
  dmaengine: ti: k3-psil: add additional TX threads for j7200
  dmaengine: apple-admac: Trigger shared reset
  dmaengine: apple-admac: Do not use devres for IRQs
  dmaengine: ti: edma: Remove some unused functions
  ...
This commit is contained in:
Linus Torvalds
2022-10-07 15:56:34 -07:00
47 changed files with 1851 additions and 410 deletions

View File

@@ -227,6 +227,17 @@ Contact: dmaengine@vger.kernel.org
Description: Indicate the number of retires for an enqcmds submission on a sharedwq.
A max value to set attribute is capped at 64.
What: /sys/bus/dsa/devices/wq<m>.<n>/op_config
Date: Sept 14, 2022
KernelVersion: 6.0.0
Contact: dmaengine@vger.kernel.org
Description: Shows the operation capability bits displayed in bitmap format
presented by %*pb printk() output format specifier.
The attribute can be configured when the WQ is disabled in
order to configure the WQ to accept specific bits that
correlates to the operations allowed. It's visible only
on platforms that support the capability.
What: /sys/bus/dsa/devices/engine<m>.<n>/group_id
Date: Oct 25, 2019
KernelVersion: 5.6.0
@@ -255,3 +266,27 @@ Contact: dmaengine@vger.kernel.org
Description: Indicates the number of Read Buffers reserved for the use of
engines in the group. See DSA spec v1.2 9.2.18 GRPCFG Read Buffers
Reserved.
What: /sys/bus/dsa/devices/group<m>.<n>/desc_progress_limit
Date: Sept 14, 2022
KernelVersion: 6.0.0
Contact: dmaengine@vger.kernel.org
Description: Allows control of the number of work descriptors that can be
concurrently processed by an engine in the group as a fraction
of the Maximum Work Descriptors in Progress value specified in
the ENGCAP register. The acceptable values are 0 (default),
1 (1/2 of max value), 2 (1/4 of the max value), and 3 (1/8 of
the max value). It's visible only on platforms that support
the capability.
What: /sys/bus/dsa/devices/group<m>.<n>/batch_progress_limit
Date: Sept 14, 2022
KernelVersion: 6.0.0
Contact: dmaengine@vger.kernel.org
Description: Allows control of the number of batch descriptors that can be
concurrently processed by an engine in the group as a fraction
of the Maximum Batch Descriptors in Progress value specified in
the ENGCAP register. The acceptable values are 0 (default),
1 (1/2 of max value), 2 (1/4 of the max value), and 3 (1/8 of
the max value). It's visible only on platforms that support
the capability.

View File

@@ -59,6 +59,7 @@ SoC-specific documents
stm32/stm32f429-overview
stm32/stm32mp13-overview
stm32/stm32mp157-overview
stm32/stm32-dma-mdma-chaining
sunxi

View File

@@ -0,0 +1,415 @@
.. SPDX-License-Identifier: GPL-2.0
=======================
STM32 DMA-MDMA chaining
=======================
Introduction
------------
This document describes the STM32 DMA-MDMA chaining feature. But before going
further, let's introduce the peripherals involved.
To offload data transfers from the CPU, STM32 microprocessors (MPUs) embed
direct memory access controllers (DMA).
STM32MP1 SoCs embed both STM32 DMA and STM32 MDMA controllers. STM32 DMA
request routing capabilities are enhanced by a DMA request multiplexer
(STM32 DMAMUX).
**STM32 DMAMUX**
STM32 DMAMUX routes any DMA request from a given peripheral to any STM32 DMA
controller (STM32MP1 counts two STM32 DMA controllers) channels.
**STM32 DMA**
STM32 DMA is mainly used to implement central data buffer storage (usually in
the system SRAM) for different peripheral. It can access external RAMs but
without the ability to generate convenient burst transfer ensuring the best
load of the AXI.
**STM32 MDMA**
STM32 MDMA (Master DMA) is mainly used to manage direct data transfers between
RAM data buffers without CPU intervention. It can also be used in a
hierarchical structure that uses STM32 DMA as first level data buffer
interfaces for AHB peripherals, while the STM32 MDMA acts as a second level
DMA with better performance. As a AXI/AHB master, STM32 MDMA can take control
of the AXI/AHB bus.
Principles
----------
STM32 DMA-MDMA chaining feature relies on the strengths of STM32 DMA and
STM32 MDMA controllers.
STM32 DMA has a circular Double Buffer Mode (DBM). At each end of transaction
(when DMA data counter - DMA_SxNDTR - reaches 0), the memory pointers
(configured with DMA_SxSM0AR and DMA_SxM1AR) are swapped and the DMA data
counter is automatically reloaded. This allows the SW or the STM32 MDMA to
process one memory area while the second memory area is being filled/used by
the STM32 DMA transfer.
With STM32 MDMA linked-list mode, a single request initiates the data array
(collection of nodes) to be transferred until the linked-list pointer for the
channel is null. The channel transfer complete of the last node is the end of
transfer, unless first and last nodes are linked to each other, in such a
case, the linked-list loops on to create a circular MDMA transfer.
STM32 MDMA has direct connections with STM32 DMA. This enables autonomous
communication and synchronization between peripherals, thus saving CPU
resources and bus congestion. Transfer Complete signal of STM32 DMA channel
can triggers STM32 MDMA transfer. STM32 MDMA can clear the request generated
by the STM32 DMA by writing to its Interrupt Clear register (whose address is
stored in MDMA_CxMAR, and bit mask in MDMA_CxMDR).
.. table:: STM32 MDMA interconnect table with STM32 DMA
+--------------+----------------+-----------+------------+
| STM32 DMAMUX | STM32 DMA | STM32 DMA | STM32 MDMA |
| channels | channels | Transfer | request |
| | | complete | |
| | | signal | |
+==============+================+===========+============+
| Channel *0* | DMA1 channel 0 | dma1_tcf0 | *0x00* |
+--------------+----------------+-----------+------------+
| Channel *1* | DMA1 channel 1 | dma1_tcf1 | *0x01* |
+--------------+----------------+-----------+------------+
| Channel *2* | DMA1 channel 2 | dma1_tcf2 | *0x02* |
+--------------+----------------+-----------+------------+
| Channel *3* | DMA1 channel 3 | dma1_tcf3 | *0x03* |
+--------------+----------------+-----------+------------+
| Channel *4* | DMA1 channel 4 | dma1_tcf4 | *0x04* |
+--------------+----------------+-----------+------------+
| Channel *5* | DMA1 channel 5 | dma1_tcf5 | *0x05* |
+--------------+----------------+-----------+------------+
| Channel *6* | DMA1 channel 6 | dma1_tcf6 | *0x06* |
+--------------+----------------+-----------+------------+
| Channel *7* | DMA1 channel 7 | dma1_tcf7 | *0x07* |
+--------------+----------------+-----------+------------+
| Channel *8* | DMA2 channel 0 | dma2_tcf0 | *0x08* |
+--------------+----------------+-----------+------------+
| Channel *9* | DMA2 channel 1 | dma2_tcf1 | *0x09* |
+--------------+----------------+-----------+------------+
| Channel *10* | DMA2 channel 2 | dma2_tcf2 | *0x0A* |
+--------------+----------------+-----------+------------+
| Channel *11* | DMA2 channel 3 | dma2_tcf3 | *0x0B* |
+--------------+----------------+-----------+------------+
| Channel *12* | DMA2 channel 4 | dma2_tcf4 | *0x0C* |
+--------------+----------------+-----------+------------+
| Channel *13* | DMA2 channel 5 | dma2_tcf5 | *0x0D* |
+--------------+----------------+-----------+------------+
| Channel *14* | DMA2 channel 6 | dma2_tcf6 | *0x0E* |
+--------------+----------------+-----------+------------+
| Channel *15* | DMA2 channel 7 | dma2_tcf7 | *0x0F* |
+--------------+----------------+-----------+------------+
STM32 DMA-MDMA chaining feature then uses a SRAM buffer. STM32MP1 SoCs embed
three fast access static internal RAMs of various size, used for data storage.
Due to STM32 DMA legacy (within microcontrollers), STM32 DMA performances are
bad with DDR, while they are optimal with SRAM. Hence the SRAM buffer used
between STM32 DMA and STM32 MDMA. This buffer is split in two equal periods
and STM32 DMA uses one period while STM32 MDMA uses the other period
simultaneously.
::
dma[1:2]-tcf[0:7]
.----------------.
____________ ' _________ V____________
| STM32 DMA | / __|>_ \ | STM32 MDMA |
|------------| | / \ | |------------|
| DMA_SxM0AR |<=>| | SRAM | |<=>| []-[]...[] |
| DMA_SxM1AR | | \_____/ | | |
|____________| \___<|____/ |____________|
STM32 DMA-MDMA chaining uses (struct dma_slave_config).peripheral_config to
exchange the parameters needed to configure MDMA. These parameters are
gathered into a u32 array with three values:
* the STM32 MDMA request (which is actually the DMAMUX channel ID),
* the address of the STM32 DMA register to clear the Transfer Complete
interrupt flag,
* the mask of the Transfer Complete interrupt flag of the STM32 DMA channel.
Device Tree updates for STM32 DMA-MDMA chaining support
-------------------------------------------------------
**1. Allocate a SRAM buffer**
SRAM device tree node is defined in SoC device tree. You can refer to it in
your board device tree to define your SRAM pool.
::
&sram {
my_foo_device_dma_pool: dma-sram@0 {
reg = <0x0 0x1000>;
};
};
Be careful of the start index, in case there are other SRAM consumers.
Define your pool size strategically: to optimise chaining, the idea is that
STM32 DMA and STM32 MDMA can work simultaneously, on each buffer of the
SRAM.
If the SRAM period is greater than the expected DMA transfer, then STM32 DMA
and STM32 MDMA will work sequentially instead of simultaneously. It is not a
functional issue but it is not optimal.
Don't forget to refer to your SRAM pool in your device node. You need to
define a new property.
::
&my_foo_device {
...
my_dma_pool = &my_foo_device_dma_pool;
};
Then get this SRAM pool in your foo driver and allocate your SRAM buffer.
**2. Allocate a STM32 DMA channel and a STM32 MDMA channel**
You need to define an extra channel in your device tree node, in addition to
the one you should already have for "classic" DMA operation.
This new channel must be taken from STM32 MDMA channels, so, the phandle of
the DMA controller to use is the MDMA controller's one.
::
&my_foo_device {
[...]
my_dma_pool = &my_foo_device_dma_pool;
dmas = <&dmamux1 ...>, // STM32 DMA channel
<&mdma1 0 0x3 0x1200000a 0 0>; // + STM32 MDMA channel
};
Concerning STM32 MDMA bindings:
1. The request line number : whatever the value here, it will be overwritten
by MDMA driver with the STM32 DMAMUX channel ID passed through
(struct dma_slave_config).peripheral_config
2. The priority level : choose Very High (0x3) so that your channel will
take priority other the other during request arbitration
3. A 32bit mask specifying the DMA channel configuration : source and
destination address increment, block transfer with 128 bytes per single
transfer
4. The 32bit value specifying the register to be used to acknowledge the
request: it will be overwritten by MDMA driver, with the DMA channel
interrupt flag clear register address passed through
(struct dma_slave_config).peripheral_config
5. The 32bit mask specifying the value to be written to acknowledge the
request: it will be overwritten by MDMA driver, with the DMA channel
Transfer Complete flag passed through
(struct dma_slave_config).peripheral_config
Driver updates for STM32 DMA-MDMA chaining support in foo driver
----------------------------------------------------------------
**0. (optional) Refactor the original sg_table if dmaengine_prep_slave_sg()**
In case of dmaengine_prep_slave_sg(), the original sg_table can't be used as
is. Two new sg_tables must be created from the original one. One for
STM32 DMA transfer (where memory address targets now the SRAM buffer instead
of DDR buffer) and one for STM32 MDMA transfer (where memory address targets
the DDR buffer).
The new sg_list items must fit SRAM period length. Here is an example for
DMA_DEV_TO_MEM:
::
/*
* Assuming sgl and nents, respectively the initial scatterlist and its
* length.
* Assuming sram_dma_buf and sram_period, respectively the memory
* allocated from the pool for DMA usage, and the length of the period,
* which is half of the sram_buf size.
*/
struct sg_table new_dma_sgt, new_mdma_sgt;
struct scatterlist *s, *_sgl;
dma_addr_t ddr_dma_buf;
u32 new_nents = 0, len;
int i;
/* Count the number of entries needed */
for_each_sg(sgl, s, nents, i)
if (sg_dma_len(s) > sram_period)
new_nents += DIV_ROUND_UP(sg_dma_len(s), sram_period);
else
new_nents++;
/* Create sg table for STM32 DMA channel */
ret = sg_alloc_table(&new_dma_sgt, new_nents, GFP_ATOMIC);
if (ret)
dev_err(dev, "DMA sg table alloc failed\n");
for_each_sg(new_dma_sgt.sgl, s, new_dma_sgt.nents, i) {
_sgl = sgl;
sg_dma_len(s) = min(sg_dma_len(_sgl), sram_period);
/* Targets the beginning = first half of the sram_buf */
s->dma_address = sram_buf;
/*
* Targets the second half of the sram_buf
* for odd indexes of the item of the sg_list
*/
if (i & 1)
s->dma_address += sram_period;
}
/* Create sg table for STM32 MDMA channel */
ret = sg_alloc_table(&new_mdma_sgt, new_nents, GFP_ATOMIC);
if (ret)
dev_err(dev, "MDMA sg_table alloc failed\n");
_sgl = sgl;
len = sg_dma_len(sgl);
ddr_dma_buf = sg_dma_address(sgl);
for_each_sg(mdma_sgt.sgl, s, mdma_sgt.nents, i) {
size_t bytes = min_t(size_t, len, sram_period);
sg_dma_len(s) = bytes;
sg_dma_address(s) = ddr_dma_buf;
len -= bytes;
if (!len && sg_next(_sgl)) {
_sgl = sg_next(_sgl);
len = sg_dma_len(_sgl);
ddr_dma_buf = sg_dma_address(_sgl);
} else {
ddr_dma_buf += bytes;
}
}
Don't forget to release these new sg_tables after getting the descriptors
with dmaengine_prep_slave_sg().
**1. Set controller specific parameters**
First, use dmaengine_slave_config() with a struct dma_slave_config to
configure STM32 DMA channel. You just have to take care of DMA addresses,
the memory address (depending on the transfer direction) must point on your
SRAM buffer, and set (struct dma_slave_config).peripheral_size != 0.
STM32 DMA driver will check (struct dma_slave_config).peripheral_size to
determine if chaining is being used or not. If it is used, then STM32 DMA
driver fills (struct dma_slave_config).peripheral_config with an array of
three u32 : the first one containing STM32 DMAMUX channel ID, the second one
the channel interrupt flag clear register address, and the third one the
channel Transfer Complete flag mask.
Then, use dmaengine_slave_config with another struct dma_slave_config to
configure STM32 MDMA channel. Take care of DMA addresses, the device address
(depending on the transfer direction) must point on your SRAM buffer, and
the memory address must point to the buffer originally used for "classic"
DMA operation. Use the previous (struct dma_slave_config).peripheral_size
and .peripheral_config that have been updated by STM32 DMA driver, to set
(struct dma_slave_config).peripheral_size and .peripheral_config of the
struct dma_slave_config to configure STM32 MDMA channel.
::
struct dma_slave_config dma_conf;
struct dma_slave_config mdma_conf;
memset(&dma_conf, 0, sizeof(dma_conf));
[...]
config.direction = DMA_DEV_TO_MEM;
config.dst_addr = sram_dma_buf; // SRAM buffer
config.peripheral_size = 1; // peripheral_size != 0 => chaining
dmaengine_slave_config(dma_chan, &dma_config);
memset(&mdma_conf, 0, sizeof(mdma_conf));
config.direction = DMA_DEV_TO_MEM;
mdma_conf.src_addr = sram_dma_buf; // SRAM buffer
mdma_conf.dst_addr = rx_dma_buf; // original memory buffer
mdma_conf.peripheral_size = dma_conf.peripheral_size; // <- dma_conf
mdma_conf.peripheral_config = dma_config.peripheral_config; // <- dma_conf
dmaengine_slave_config(mdma_chan, &mdma_conf);
**2. Get a descriptor for STM32 DMA channel transaction**
In the same way you get your descriptor for your "classic" DMA operation,
you just have to replace the original sg_list (in case of
dmaengine_prep_slave_sg()) with the new sg_list using SRAM buffer, or to
replace the original buffer address, length and period (in case of
dmaengine_prep_dma_cyclic()) with the new SRAM buffer.
**3. Get a descriptor for STM32 MDMA channel transaction**
If you previously get descriptor (for STM32 DMA) with
* dmaengine_prep_slave_sg(), then use dmaengine_prep_slave_sg() for
STM32 MDMA;
* dmaengine_prep_dma_cyclic(), then use dmaengine_prep_dma_cyclic() for
STM32 MDMA.
Use the new sg_list using SRAM buffer (in case of dmaengine_prep_slave_sg())
or, depending on the transfer direction, either the original DDR buffer (in
case of DMA_DEV_TO_MEM) or the SRAM buffer (in case of DMA_MEM_TO_DEV), the
source address being previously set with dmaengine_slave_config().
**4. Submit both transactions**
Before submitting your transactions, you may need to define on which
descriptor you want a callback to be called at the end of the transfer
(dmaengine_prep_slave_sg()) or the period (dmaengine_prep_dma_cyclic()).
Depending on the direction, set the callback on the descriptor that finishes
the overal transfer:
* DMA_DEV_TO_MEM: set the callback on the "MDMA" descriptor
* DMA_MEM_TO_DEV: set the callback on the "DMA" descriptor
Then, submit the descriptors whatever the order, with dmaengine_tx_submit().
**5. Issue pending requests (and wait for callback notification)**
As STM32 MDMA channel transfer is triggered by STM32 DMA, you must issue
STM32 MDMA channel before STM32 DMA channel.
If any, your callback will be called to warn you about the end of the overal
transfer or the period completion.
Don't forget to terminate both channels. STM32 DMA channel is configured in
cyclic Double-Buffer mode so it won't be disabled by HW, you need to terminate
it. STM32 MDMA channel will be stopped by HW in case of sg transfer, but not
in case of cyclic transfer. You can terminate it whatever the kind of transfer.
**STM32 DMA-MDMA chaining DMA_MEM_TO_DEV special case**
STM32 DMA-MDMA chaining in DMA_MEM_TO_DEV is a special case. Indeed, the
STM32 MDMA feeds the SRAM buffer with the DDR data, and the STM32 DMA reads
data from SRAM buffer. So some data (the first period) have to be copied in
SRAM buffer when the STM32 DMA starts to read.
A trick could be pausing the STM32 DMA channel (that will raise a Transfer
Complete signal, triggering the STM32 MDMA channel), but the first data read
by the STM32 DMA could be "wrong". The proper way is to prepare the first SRAM
period with dmaengine_prep_dma_memcpy(). Then this first period should be
"removed" from the sg or the cyclic transfer.
Due to this complexity, rather use the STM32 DMA-MDMA chaining for
DMA_DEV_TO_MEM and keep the "classic" DMA usage for DMA_MEM_TO_DEV, unless
you're not afraid.
Resources
---------
Application note, datasheet and reference manual are available on ST website
(STM32MP1_).
Dedicated focus on three application notes (AN5224_, AN4031_ & AN5001_)
dealing with STM32 DMAMUX, STM32 DMA and STM32 MDMA.
.. _STM32MP1: https://www.st.com/en/microcontrollers-microprocessors/stm32mp1-series.html
.. _AN5224: https://www.st.com/resource/en/application_note/an5224-stm32-dmamux-the-dma-request-router-stmicroelectronics.pdf
.. _AN4031: https://www.st.com/resource/en/application_note/dm00046011-using-the-stm32f2-stm32f4-and-stm32f7-series-dma-controller-stmicroelectronics.pdf
.. _AN5001: https://www.st.com/resource/en/application_note/an5001-stm32cube-expansion-package-for-stm32h7-series-mdma-stmicroelectronics.pdf
:Authors:
- Amelie Delaunay <amelie.delaunay@foss.st.com>

View File

@@ -49,6 +49,13 @@ properties:
in an interrupts-extended list the disconnected positions will contain
an empty phandle reference <0>.
iommus:
minItems: 1
maxItems: 2
power-domains:
maxItems: 1
required:
- compatible
- reg

View File

@@ -55,6 +55,12 @@ properties:
dma-coherent: true
iommus:
minItems: 1
maxItems: 9
description: Up to 1 IOMMU entry per DMA channel for writes and 1
IOMMU entry for reads.
power-domains:
maxItems: 1

View File

@@ -22,6 +22,7 @@ properties:
- items:
- enum:
- mediatek,mt2712-uart-dma
- mediatek,mt6795-uart-dma
- mediatek,mt8365-uart-dma
- mediatek,mt8516-uart-dma
- const: mediatek,mt6577-uart-dma

View File

@@ -0,0 +1,99 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/dma/qcom,adm.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm ADM DMA Controller
maintainers:
- Christian Marangi <ansuelsmth@gmail.com>
- Bjorn Andersson <bjorn.andersson@linaro.org>
description: |
QCOM ADM DMA controller provides DMA capabilities for
peripheral buses such as NAND and SPI.
properties:
compatible:
const: qcom,adm
reg:
maxItems: 1
interrupts:
maxItems: 1
"#dma-cells":
const: 1
clocks:
items:
- description: phandle to the core clock
- description: phandle to the iface clock
clock-names:
items:
- const: core
- const: iface
resets:
items:
- description: phandle to the clk reset
- description: phandle to the pbus reset
- description: phandle to the c0 reset
- description: phandle to the c1 reset
- description: phandle to the c2 reset
reset-names:
items:
- const: clk
- const: pbus
- const: c0
- const: c1
- const: c2
qcom,ee:
$ref: /schemas/types.yaml#/definitions/uint32
description: indicates the security domain identifier used in the secure world.
minimum: 0
maximum: 255
required:
- compatible
- reg
- interrupts
- "#dma-cells"
- clocks
- clock-names
- resets
- reset-names
- qcom,ee
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,gcc-ipq806x.h>
#include <dt-bindings/reset/qcom,gcc-ipq806x.h>
adm_dma: dma-controller@18300000 {
compatible = "qcom,adm";
reg = <0x18300000 0x100000>;
interrupts = <0 170 0>;
#dma-cells = <1>;
clocks = <&gcc ADM0_CLK>,
<&gcc ADM0_PBUS_CLK>;
clock-names = "core", "iface";
resets = <&gcc ADM0_RESET>,
<&gcc ADM0_PBUS_RESET>,
<&gcc ADM0_C0_RESET>,
<&gcc ADM0_C1_RESET>,
<&gcc ADM0_C2_RESET>;
reset-names = "clk", "pbus", "c0", "c1", "c2";
qcom,ee = <0>;
};
...

View File

@@ -8,7 +8,7 @@ title: Qualcomm Technologies Inc BAM DMA controller
maintainers:
- Andy Gross <agross@kernel.org>
- Bjorn Andersson <bjorn.andersson@linaro.org>
- Bjorn Andersson <andersson@kernel.org>
allOf:
- $ref: "dma-controller.yaml#"
@@ -20,7 +20,7 @@ properties:
- qcom,bam-v1.3.0
# MSM8974, APQ8074 and APQ8084
- qcom,bam-v1.4.0
# MSM8916
# MSM8916 and SDM845
- qcom,bam-v1.7.0
clocks:
@@ -90,8 +90,8 @@ examples:
dma-controller@f9944000 {
compatible = "qcom,bam-v1.4.0";
reg = <0xf9944000 0x15000>;
interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
reg = <0xf9944000 0x19000>;
interrupts = <GIC_SPI 239 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&gcc GCC_BLSP2_AHB_CLK>;
clock-names = "bam_clk";
#dma-cells = <1>;

View File

@@ -21,6 +21,7 @@ properties:
enum:
- qcom,sc7280-gpi-dma
- qcom,sdm845-gpi-dma
- qcom,sm6350-gpi-dma
- qcom,sm8150-gpi-dma
- qcom,sm8250-gpi-dma
- qcom,sm8350-gpi-dma

View File

@@ -1,61 +0,0 @@
QCOM ADM DMA Controller
Required properties:
- compatible: must contain "qcom,adm" for IPQ/APQ8064 and MSM8960
- reg: Address range for DMA registers
- interrupts: Should contain one interrupt shared by all channels
- #dma-cells: must be <2>. First cell denotes the channel number. Second cell
denotes CRCI (client rate control interface) flow control assignment.
- clocks: Should contain the core clock and interface clock.
- clock-names: Must contain "core" for the core clock and "iface" for the
interface clock.
- resets: Must contain an entry for each entry in reset names.
- reset-names: Must include the following entries:
- clk
- c0
- c1
- c2
- qcom,ee: indicates the security domain identifier used in the secure world.
Example:
adm_dma: dma@18300000 {
compatible = "qcom,adm";
reg = <0x18300000 0x100000>;
interrupts = <0 170 0>;
#dma-cells = <2>;
clocks = <&gcc ADM0_CLK>, <&gcc ADM0_PBUS_CLK>;
clock-names = "core", "iface";
resets = <&gcc ADM0_RESET>,
<&gcc ADM0_C0_RESET>,
<&gcc ADM0_C1_RESET>,
<&gcc ADM0_C2_RESET>;
reset-names = "clk", "c0", "c1", "c2";
qcom,ee = <0>;
};
DMA clients must use the format descripted in the dma.txt file, using a three
cell specifier for each channel.
Each dmas request consists of 3 cells:
1. phandle pointing to the DMA controller
2. channel number
3. CRCI assignment, if applicable. If no CRCI flow control is required, use 0.
The CRCI is used for flow control. It identifies the peripheral device that
is the source/destination for the transferred data.
Example:
spi4: spi@1a280000 {
spi-max-frequency = <50000000>;
pinctrl-0 = <&spi_pins>;
pinctrl-names = "default";
cs-gpios = <&qcom_pinmux 20 0>;
dmas = <&adm_dma 6 9>,
<&adm_dma 5 10>;
dma-names = "rx", "tx";
};

View File

@@ -45,6 +45,7 @@ properties:
- enum:
- renesas,dmac-r8a779a0 # R-Car V3U
- renesas,dmac-r8a779f0 # R-Car S4-8
- renesas,dmac-r8a779g0 # R-Car V4H
- const: renesas,rcar-gen4-dmac # R-Car Gen4
reg: true

View File

@@ -4,7 +4,7 @@ Required properties:
- compatible: "ti,dra7-dma-crossbar" for DRA7xx DMA crossbar
"ti,am335x-edma-crossbar" for AM335x and AM437x
- reg: Memory map for accessing module
- #dma-cells: Should be set to to match with the DMA controller's dma-cells
- #dma-cells: Should be set to match with the DMA controller's dma-cells
for ti,dra7-dma-crossbar and <3> for ti,am335x-edma-crossbar.
- dma-requests: Number of DMA requests the crossbar can receive
- dma-masters: phandle pointing to the DMA controller

View File

@@ -9157,6 +9157,7 @@ F: net/dsa/tag_hellcreek.c
HISILICON DMA DRIVER
M: Zhou Wang <wangzhou1@hisilicon.com>
M: Jie Hai <haijie1@hisilicon.com>
L: dmaengine@vger.kernel.org
S: Maintained
F: drivers/dma/hisi_dma.c

View File

@@ -180,7 +180,7 @@ config DMA_SUN6I
config DW_AXI_DMAC
tristate "Synopsys DesignWare AXI DMA support"
depends on OF || COMPILE_TEST
depends on OF
depends on HAS_IOMEM
select DMA_ENGINE
select DMA_VIRTUAL_CHANNELS

View File

@@ -2367,7 +2367,7 @@ static int pl08x_dma_init_virtual_channels(struct pl08x_driver_data *pl08x,
INIT_LIST_HEAD(&dmadev->channels);
/*
* Register as many many memcpy as we have physical channels,
* Register as many memcpy as we have physical channels,
* we won't always be able to use all but the code will have
* to cope with that situation.
*/

View File

@@ -12,8 +12,9 @@
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_dma.h>
#include <linux/interrupt.h>
#include <linux/reset.h>
#include <linux/spinlock.h>
#include <linux/interrupt.h>
#include "dmaengine.h"
@@ -95,7 +96,9 @@ struct admac_data {
struct dma_device dma;
struct device *dev;
__iomem void *base;
struct reset_control *rstc;
int irq;
int irq_index;
int nchannels;
struct admac_chan channels[];
@@ -724,18 +727,17 @@ static int admac_probe(struct platform_device *pdev)
if (irq < 0)
return dev_err_probe(&pdev->dev, irq, "no usable interrupt\n");
err = devm_request_irq(&pdev->dev, irq, admac_interrupt,
0, dev_name(&pdev->dev), ad);
if (err)
return dev_err_probe(&pdev->dev, err,
"unable to register interrupt\n");
ad->irq = irq;
ad->base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(ad->base))
return dev_err_probe(&pdev->dev, PTR_ERR(ad->base),
"unable to obtain MMIO resource\n");
ad->rstc = devm_reset_control_get_optional_shared(&pdev->dev, NULL);
if (IS_ERR(ad->rstc))
return PTR_ERR(ad->rstc);
dma = &ad->dma;
dma_cap_set(DMA_PRIVATE, dma->cap_mask);
@@ -774,17 +776,38 @@ static int admac_probe(struct platform_device *pdev)
tasklet_setup(&adchan->tasklet, admac_chan_tasklet);
}
err = dma_async_device_register(&ad->dma);
err = reset_control_reset(ad->rstc);
if (err)
return dev_err_probe(&pdev->dev, err, "failed to register DMA device\n");
return dev_err_probe(&pdev->dev, err,
"unable to trigger reset\n");
err = request_irq(irq, admac_interrupt, 0, dev_name(&pdev->dev), ad);
if (err) {
dev_err_probe(&pdev->dev, err,
"unable to register interrupt\n");
goto free_reset;
}
err = dma_async_device_register(&ad->dma);
if (err) {
dev_err_probe(&pdev->dev, err, "failed to register DMA device\n");
goto free_irq;
}
err = of_dma_controller_register(pdev->dev.of_node, admac_dma_of_xlate, ad);
if (err) {
dma_async_device_unregister(&ad->dma);
return dev_err_probe(&pdev->dev, err, "failed to register with OF\n");
dev_err_probe(&pdev->dev, err, "failed to register with OF\n");
goto free_irq;
}
return 0;
free_irq:
free_irq(ad->irq, ad);
free_reset:
reset_control_rearm(ad->rstc);
return err;
}
static int admac_remove(struct platform_device *pdev)
@@ -793,6 +816,8 @@ static int admac_remove(struct platform_device *pdev)
of_dma_controller_free(pdev->dev.of_node);
dma_async_device_unregister(&ad->dma);
free_irq(ad->irq, ad);
reset_control_rearm(ad->rstc);
return 0;
}

View File

@@ -1470,10 +1470,7 @@ at_xdmac_tx_status(struct dma_chan *chan, dma_cookie_t cookie,
bool initd;
ret = dma_cookie_status(chan, cookie, txstate);
if (ret == DMA_COMPLETE)
return ret;
if (!txstate)
if (ret == DMA_COMPLETE || !txstate)
return ret;
spin_lock_irqsave(&atchan->lock, flags);

View File

@@ -9,7 +9,6 @@
#include <linux/module.h>
#include <linux/device.h>
#include <linux/kernel.h>
#include <linux/pm_runtime.h>
#include <linux/dmaengine.h>
#include <linux/err.h>
#include <linux/interrupt.h>
@@ -682,15 +681,12 @@ static int dw_edma_alloc_chan_resources(struct dma_chan *dchan)
if (chan->status != EDMA_ST_IDLE)
return -EBUSY;
pm_runtime_get(chan->dw->chip->dev);
return 0;
}
static void dw_edma_free_chan_resources(struct dma_chan *dchan)
{
unsigned long timeout = jiffies + msecs_to_jiffies(5000);
struct dw_edma_chan *chan = dchan2dw_edma_chan(dchan);
int ret;
while (time_before(jiffies, timeout)) {
@@ -703,8 +699,6 @@ static void dw_edma_free_chan_resources(struct dma_chan *dchan)
cpu_relax();
}
pm_runtime_put(chan->dw->chip->dev);
}
static int dw_edma_channel_setup(struct dw_edma *dw, bool write,
@@ -977,9 +971,6 @@ int dw_edma_probe(struct dw_edma_chip *chip)
if (err)
goto err_irq_free;
/* Power management */
pm_runtime_enable(dev);
/* Turn debugfs on */
dw_edma_v0_core_debugfs_on(dw);
@@ -1009,9 +1000,6 @@ int dw_edma_remove(struct dw_edma_chip *chip)
for (i = (dw->nr_irqs - 1); i >= 0; i--)
free_irq(chip->ops->irq_vector(dev, i), &dw->irq[i]);
/* Power management */
pm_runtime_disable(dev);
/* Deregister eDMA device */
dma_async_device_unregister(&dw->wr_edma);
list_for_each_entry_safe(chan, _chan, &dw->wr_edma.channels,

File diff suppressed because it is too large Load Diff

View File

@@ -16,12 +16,20 @@
* port 3, and so on.
*/
#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/dmaengine.h>
#include <linux/dma-mapping.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/list.h>
#include <linux/module.h>
#include <linux/percpu-defs.h>
#include <linux/scatterlist.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/spinlock.h>
#include "hsu.h"

Some files were not shown because too many files have changed in this diff Show More