diff mbox series

[v7,03/12] dmaengine: doc: Add sections for per descriptor metadata support

Message ID 20191209094332.4047-4-peter.ujfalusi@ti.com (mailing list archive)
State New, archived
Headers show
Series dmaengine/soc: Add Texas Instruments UDMA support | expand

Commit Message

Peter Ujfalusi Dec. 9, 2019, 9:43 a.m. UTC
Update the provider and client documentation with details about the
metadata support.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Reviewed-by: Tero Kristo <t-kristo@ti.com>
---
 Documentation/driver-api/dmaengine/client.rst | 75 +++++++++++++++++++
 .../driver-api/dmaengine/provider.rst         | 46 ++++++++++++
 2 files changed, 121 insertions(+)

Comments

Vinod Koul Dec. 20, 2019, 8:28 a.m. UTC | #1
Hi Peter,

On 09-12-19, 11:43, Peter Ujfalusi wrote:

> +  Optional: per descriptor metadata
> +  ---------------------------------
> +  DMAengine provides two ways for metadata support.
> +
> +  DESC_METADATA_CLIENT
> +
> +    The metadata buffer is allocated/provided by the client driver and it is
> +    attached to the descriptor.
> +
> +  .. code-block:: c
> +
> +     int dmaengine_desc_attach_metadata(struct dma_async_tx_descriptor *desc,
> +				   void *data, size_t len);
> +
> +  DESC_METADATA_ENGINE
> +
> +    The metadata buffer is allocated/managed by the DMA driver. The client

and when would it be freed?

> +    driver can ask for the pointer, maximum size and the currently used size of
> +    the metadata and can directly update or read it.
> +
> +  .. code-block:: c
> +
> +     void *dmaengine_desc_get_metadata_ptr(struct dma_async_tx_descriptor *desc,
> +		size_t *payload_len, size_t *max_len);
> +
> +     int dmaengine_desc_set_metadata_len(struct dma_async_tx_descriptor *desc,
> +		size_t payload_len);
> +
> +  Client drivers can query if a given mode is supported with:
> +
> +  .. code-block:: c
> +
> +     bool dmaengine_is_metadata_mode_supported(struct dma_chan *chan,
> +		enum dma_desc_metadata_mode mode);
> +
> +  Depending on the used mode client drivers must follow different flow.
> +
> +  DESC_METADATA_CLIENT
> +
> +    - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
> +      1. prepare the descriptor (dmaengine_prep_*)
> +         construct the metadata in the client's buffer
> +      2. use dmaengine_desc_attach_metadata() to attach the buffer to the
> +         descriptor
> +      3. submit the transfer

This is simpler, txn finished the metadata would be freed up right?
> +    - DMA_DEV_TO_MEM:
> +      1. prepare the descriptor (dmaengine_prep_*)
> +      2. use dmaengine_desc_attach_metadata() to attach the buffer to the
> +         descriptor
> +      3. submit the transfer
> +      4. when the transfer is completed, the metadata should be available in the
> +         attached buffer

and when and how would driver free that up :)

> +
> +  DESC_METADATA_ENGINE
> +
> +    - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
> +      1. prepare the descriptor (dmaengine_prep_*)
> +      2. use dmaengine_desc_get_metadata_ptr() to get the pointer to the
> +         engine's metadata area
> +      3. update the metadata at the pointer
> +      4. use dmaengine_desc_set_metadata_len()  to tell the DMA engine the
> +         amount of data the client has placed into the metadata buffer
> +      5. submit the transfer
> +    - DMA_DEV_TO_MEM:
> +      1. prepare the descriptor (dmaengine_prep_*)
> +      2. submit the transfer
> +      3. on transfer completion, use dmaengine_desc_get_metadata_ptr() to get the
> +         pointer to the engine's metadata area
> +      4. Read out the metadata from the pointer
> +
> +  .. note::
> +
> +     Mixed use of DESC_METADATA_CLIENT / DESC_METADATA_ENGINE is not allowed,
> +     client drivers must use either of the modes per descriptor.

We should check that if not done already!
Peter Ujfalusi Dec. 20, 2019, 9:52 a.m. UTC | #2
Hi Vinod,

On 20/12/2019 10.28, Vinod Koul wrote:
> Hi Peter,
> 
> On 09-12-19, 11:43, Peter Ujfalusi wrote:
> 
>> +  Optional: per descriptor metadata
>> +  ---------------------------------
>> +  DMAengine provides two ways for metadata support.
>> +
>> +  DESC_METADATA_CLIENT
>> +
>> +    The metadata buffer is allocated/provided by the client driver and it is
>> +    attached to the descriptor.
>> +
>> +  .. code-block:: c
>> +
>> +     int dmaengine_desc_attach_metadata(struct dma_async_tx_descriptor *desc,
>> +				   void *data, size_t len);
>> +
>> +  DESC_METADATA_ENGINE
>> +
>> +    The metadata buffer is allocated/managed by the DMA driver. The client
> 
> and when would it be freed?

It is not defined as it could be driver dependent, but afaik we have
defined (which I'm not sure why it is not here or in the code) that in
DESC_METADATA_ENGINE case the metadata pointer is valid for the client
between the time it got the desc (via prep call) and the execution of
the completion callback.
Iow, DESC_METADATA_ENGINE does not make any sense if the client want to
receive metadata back and does not provide a callback.

I will extend the documentation and comment in the code to reflect this.

>> +    driver can ask for the pointer, maximum size and the currently used size of
>> +    the metadata and can directly update or read it.
>> +
>> +  .. code-block:: c
>> +
>> +     void *dmaengine_desc_get_metadata_ptr(struct dma_async_tx_descriptor *desc,
>> +		size_t *payload_len, size_t *max_len);
>> +
>> +     int dmaengine_desc_set_metadata_len(struct dma_async_tx_descriptor *desc,
>> +		size_t payload_len);
>> +
>> +  Client drivers can query if a given mode is supported with:
>> +
>> +  .. code-block:: c
>> +
>> +     bool dmaengine_is_metadata_mode_supported(struct dma_chan *chan,
>> +		enum dma_desc_metadata_mode mode);
>> +
>> +  Depending on the used mode client drivers must follow different flow.
>> +
>> +  DESC_METADATA_CLIENT
>> +
>> +    - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
>> +      1. prepare the descriptor (dmaengine_prep_*)
>> +         construct the metadata in the client's buffer
>> +      2. use dmaengine_desc_attach_metadata() to attach the buffer to the
>> +         descriptor
>> +      3. submit the transfer
> 
> This is simpler, txn finished the metadata would be freed up right?

It is up to the client driver what it does with the provided buffer. As
for what the DMA driver does is not documented as it is not relevant and
can be different by different HW or SW implementation.

>> +    - DMA_DEV_TO_MEM:
>> +      1. prepare the descriptor (dmaengine_prep_*)
>> +      2. use dmaengine_desc_attach_metadata() to attach the buffer to the
>> +         descriptor
>> +      3. submit the transfer
>> +      4. when the transfer is completed, the metadata should be available in the
>> +         attached buffer
> 
> and when and how would driver free that up :)

It is up to the client, it manages the buffer. It can reuse it and
attach it to another descriptor or free it up or pass it to other
layers, return it to other layer.

>> +
>> +  DESC_METADATA_ENGINE
>> +
>> +    - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
>> +      1. prepare the descriptor (dmaengine_prep_*)
>> +      2. use dmaengine_desc_get_metadata_ptr() to get the pointer to the
>> +         engine's metadata area
>> +      3. update the metadata at the pointer
>> +      4. use dmaengine_desc_set_metadata_len()  to tell the DMA engine the
>> +         amount of data the client has placed into the metadata buffer
>> +      5. submit the transfer
>> +    - DMA_DEV_TO_MEM:
>> +      1. prepare the descriptor (dmaengine_prep_*)
>> +      2. submit the transfer
>> +      3. on transfer completion, use dmaengine_desc_get_metadata_ptr() to get the
>> +         pointer to the engine's metadata area
>> +      4. Read out the metadata from the pointer
>> +
>> +  .. note::
>> +
>> +     Mixed use of DESC_METADATA_CLIENT / DESC_METADATA_ENGINE is not allowed,
>> +     client drivers must use either of the modes per descriptor.
> 
> We should check that if not done already!

Yes, we check it.


- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
Vinod Koul Dec. 20, 2019, 10:14 a.m. UTC | #3
On 20-12-19, 11:52, Peter Ujfalusi wrote:
> Hi Vinod,
> 
> On 20/12/2019 10.28, Vinod Koul wrote:
> > Hi Peter,
> > 
> > On 09-12-19, 11:43, Peter Ujfalusi wrote:
> > 
> >> +  Optional: per descriptor metadata
> >> +  ---------------------------------
> >> +  DMAengine provides two ways for metadata support.
> >> +
> >> +  DESC_METADATA_CLIENT
> >> +
> >> +    The metadata buffer is allocated/provided by the client driver and it is
> >> +    attached to the descriptor.
> >> +
> >> +  .. code-block:: c
> >> +
> >> +     int dmaengine_desc_attach_metadata(struct dma_async_tx_descriptor *desc,
> >> +				   void *data, size_t len);
> >> +
> >> +  DESC_METADATA_ENGINE
> >> +
> >> +    The metadata buffer is allocated/managed by the DMA driver. The client
> > 
> > and when would it be freed?
> 
> It is not defined as it could be driver dependent, but afaik we have
> defined (which I'm not sure why it is not here or in the code) that in
> DESC_METADATA_ENGINE case the metadata pointer is valid for the client
> between the time it got the desc (via prep call) and the execution of
> the completion callback.
> Iow, DESC_METADATA_ENGINE does not make any sense if the client want to
> receive metadata back and does not provide a callback.

Make sense and once callback completes driver can free it up!
> 
> I will extend the documentation and comment in the code to reflect this.

makes sense, thanks!

> 
> >> +    driver can ask for the pointer, maximum size and the currently used size of
> >> +    the metadata and can directly update or read it.
> >> +
> >> +  .. code-block:: c
> >> +
> >> +     void *dmaengine_desc_get_metadata_ptr(struct dma_async_tx_descriptor *desc,
> >> +		size_t *payload_len, size_t *max_len);
> >> +
> >> +     int dmaengine_desc_set_metadata_len(struct dma_async_tx_descriptor *desc,
> >> +		size_t payload_len);
> >> +
> >> +  Client drivers can query if a given mode is supported with:
> >> +
> >> +  .. code-block:: c
> >> +
> >> +     bool dmaengine_is_metadata_mode_supported(struct dma_chan *chan,
> >> +		enum dma_desc_metadata_mode mode);
> >> +
> >> +  Depending on the used mode client drivers must follow different flow.
> >> +
> >> +  DESC_METADATA_CLIENT
> >> +
> >> +    - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
> >> +      1. prepare the descriptor (dmaengine_prep_*)
> >> +         construct the metadata in the client's buffer
> >> +      2. use dmaengine_desc_attach_metadata() to attach the buffer to the
> >> +         descriptor
> >> +      3. submit the transfer
> > 
> > This is simpler, txn finished the metadata would be freed up right?
> 
> It is up to the client driver what it does with the provided buffer. As
> for what the DMA driver does is not documented as it is not relevant and
> can be different by different HW or SW implementation.

yeah lets document that and the fact the dmaengine driver cant touch it
after the callback
diff mbox series

Patch

diff --git a/Documentation/driver-api/dmaengine/client.rst b/Documentation/driver-api/dmaengine/client.rst
index 45953f171500..41309c176df4 100644
--- a/Documentation/driver-api/dmaengine/client.rst
+++ b/Documentation/driver-api/dmaengine/client.rst
@@ -151,6 +151,81 @@  The details of these operations are:
      Note that callbacks will always be invoked from the DMA
      engines tasklet, never from interrupt context.
 
+  Optional: per descriptor metadata
+  ---------------------------------
+  DMAengine provides two ways for metadata support.
+
+  DESC_METADATA_CLIENT
+
+    The metadata buffer is allocated/provided by the client driver and it is
+    attached to the descriptor.
+
+  .. code-block:: c
+
+     int dmaengine_desc_attach_metadata(struct dma_async_tx_descriptor *desc,
+				   void *data, size_t len);
+
+  DESC_METADATA_ENGINE
+
+    The metadata buffer is allocated/managed by the DMA driver. The client
+    driver can ask for the pointer, maximum size and the currently used size of
+    the metadata and can directly update or read it.
+
+  .. code-block:: c
+
+     void *dmaengine_desc_get_metadata_ptr(struct dma_async_tx_descriptor *desc,
+		size_t *payload_len, size_t *max_len);
+
+     int dmaengine_desc_set_metadata_len(struct dma_async_tx_descriptor *desc,
+		size_t payload_len);
+
+  Client drivers can query if a given mode is supported with:
+
+  .. code-block:: c
+
+     bool dmaengine_is_metadata_mode_supported(struct dma_chan *chan,
+		enum dma_desc_metadata_mode mode);
+
+  Depending on the used mode client drivers must follow different flow.
+
+  DESC_METADATA_CLIENT
+
+    - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
+      1. prepare the descriptor (dmaengine_prep_*)
+         construct the metadata in the client's buffer
+      2. use dmaengine_desc_attach_metadata() to attach the buffer to the
+         descriptor
+      3. submit the transfer
+    - DMA_DEV_TO_MEM:
+      1. prepare the descriptor (dmaengine_prep_*)
+      2. use dmaengine_desc_attach_metadata() to attach the buffer to the
+         descriptor
+      3. submit the transfer
+      4. when the transfer is completed, the metadata should be available in the
+         attached buffer
+
+  DESC_METADATA_ENGINE
+
+    - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM:
+      1. prepare the descriptor (dmaengine_prep_*)
+      2. use dmaengine_desc_get_metadata_ptr() to get the pointer to the
+         engine's metadata area
+      3. update the metadata at the pointer
+      4. use dmaengine_desc_set_metadata_len()  to tell the DMA engine the
+         amount of data the client has placed into the metadata buffer
+      5. submit the transfer
+    - DMA_DEV_TO_MEM:
+      1. prepare the descriptor (dmaengine_prep_*)
+      2. submit the transfer
+      3. on transfer completion, use dmaengine_desc_get_metadata_ptr() to get the
+         pointer to the engine's metadata area
+      4. Read out the metadata from the pointer
+
+  .. note::
+
+     Mixed use of DESC_METADATA_CLIENT / DESC_METADATA_ENGINE is not allowed,
+     client drivers must use either of the modes per descriptor.
+
 4. Submit the transaction
 
    Once the descriptor has been prepared and the callback information
diff --git a/Documentation/driver-api/dmaengine/provider.rst b/Documentation/driver-api/dmaengine/provider.rst
index dfc4486b5743..da557c21c619 100644
--- a/Documentation/driver-api/dmaengine/provider.rst
+++ b/Documentation/driver-api/dmaengine/provider.rst
@@ -247,6 +247,52 @@  after each transfer. In case of a ring buffer, they may loop
 (DMA_CYCLIC). Addresses pointing to a device's register (e.g. a FIFO)
 are typically fixed.
 
+Per descriptor metadata support
+-------------------------------
+Some data movement architecture (DMA controller and peripherals) uses metadata
+associated with a transaction. The DMA controller role is to transfer the
+payload and the metadata alongside.
+The metadata itself is not used by the DMA engine itself, but it contains
+parameters, keys, vectors, etc for peripheral or from the peripheral.
+
+The DMAengine framework provides a generic ways to facilitate the metadata for
+descriptors. Depending on the architecture the DMA driver can implement either
+or both of the methods and it is up to the client driver to choose which one
+to use.
+
+- DESC_METADATA_CLIENT
+
+  The metadata buffer is allocated/provided by the client driver and it is
+  attached (via the dmaengine_desc_attach_metadata() helper to the descriptor.
+
+  From the DMA driver the following is expected for this mode:
+  - DMA_MEM_TO_DEV / DEV_MEM_TO_MEM
+    The data from the provided metadata buffer should be prepared for the DMA
+    controller to be sent alongside of the payload data. Either by copying to a
+    hardware descriptor, or highly coupled packet.
+  - DMA_DEV_TO_MEM
+    On transfer completion the DMA driver must copy the metadata to the client
+    provided metadata buffer.
+
+- DESC_METADATA_ENGINE
+
+  The metadata buffer is allocated/managed by the DMA driver. The client driver
+  can ask for the pointer, maximum size and the currently used size of the
+  metadata and can directly update or read it. dmaengine_desc_get_metadata_ptr()
+  and dmaengine_desc_set_metadata_len() is provided as helper functions.
+
+  From the DMA driver the following is expected for this mode:
+  - get_metadata_ptr
+    Should return a pointer for the metadata buffer, the maximum size of the
+    metadata buffer and the currently used / valid (if any) bytes in the buffer.
+  - set_metadata_len
+    It is called by the clients after it have placed the metadata to the buffer
+    to let the DMA driver know the number of valid bytes provided.
+
+  Note: since the client will ask for the metadata pointer in the completion
+  callback (in DMA_DEV_TO_MEM case) the DMA driver must ensure that the
+  descriptor is not freed up prior the callback is called.
+
 Device operations
 -----------------