Re: [PATCH v6 3/6] dmaengine: Add support for repeating transactions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Laurent,

On 08/07/2020 23.19, Laurent Pinchart wrote:
> DMA engines used with displays perform 2D interleaved transfers to read
> framebuffers from memory and feed the data to the display engine. As the
> same framebuffer can be displayed for multiple frames, the DMA
> transactions need to be repeated until a new framebuffer replaces the
> current one. This feature is implemented natively by some DMA engines
> that have the ability to repeat transactions and switch to a new
> transaction at the end of a transfer without any race condition or frame
> loss.
> 
> This patch implements support for this feature in the DMA engine API. A
> new DMA_PREP_REPEAT transaction flag allows DMA clients to instruct the
> DMA channel to repeat the transaction automatically until one or more
> new transactions are issued on the channel (or until all active DMA
> transfers are explicitly terminated with the dmaengine_terminate_*()
> functions). A new DMA_REPEAT transaction type is also added for DMA
> engine drivers to report their support of the DMA_PREP_REPEAT flag.
> 
> A new DMA_PREP_LOAD_EOT transaction flag is also introduced (with a
> corresponding DMA_LOAD_EOT capability bit), as requested during the
> review of v4. The flag instructs the DMA channel that the transaction
> being queued should replace the active repeated transaction when the
> latter terminates (at End Of Transaction). Not setting the flag will
> result in the active repeated transaction to continue being repeated,
> and the new transaction being silently ignored.
> 
> The DMA_PREP_REPEAT flag is currently supported for interleaved
> transactions only. Its usage can easily be extended to cover more
> transaction types simply by adding an appropriate check in the
> corresponding dmaengine_prep_*() function.
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx>
> ---
> Changes since v5:
> 
> - Document the API in Documentation/driver-api/dmaengine/
> - Small improvements to documentation in header file

Reviewed-by: Peter Ujfalusi <peter.ujfalusi@xxxxxx>

> Changes since v4:
> 
> - Add DMA_LOAD_EOT and DMA_PREP_LOAD_EOT flags
> ---
>  Documentation/driver-api/dmaengine/client.rst |  4 +-
>  .../driver-api/dmaengine/provider.rst         | 49 +++++++++++++++++++
>  include/linux/dmaengine.h                     | 17 +++++++
>  3 files changed, 69 insertions(+), 1 deletion(-)
> 
> diff --git a/Documentation/driver-api/dmaengine/client.rst b/Documentation/driver-api/dmaengine/client.rst
> index 2104830a99ae..41938aa2bdeb 100644
> --- a/Documentation/driver-api/dmaengine/client.rst
> +++ b/Documentation/driver-api/dmaengine/client.rst
> @@ -86,7 +86,9 @@ The details of these operations are:
>    - interleaved_dma: This is common to Slave as well as M2M clients. For slave
>      address of devices' fifo could be already known to the driver.
>      Various types of operations could be expressed by setting
> -    appropriate values to the 'dma_interleaved_template' members.
> +    appropriate values to the 'dma_interleaved_template' members. Cyclic
> +    interleaved DMA transfers are also possible if supported by the channel by
> +    setting the DMA_PREP_REPEAT transfer flag.
>  
>    A non-NULL return of this transfer API represents a "descriptor" for
>    the given transaction.
> diff --git a/Documentation/driver-api/dmaengine/provider.rst b/Documentation/driver-api/dmaengine/provider.rst
> index 56e5833e8a07..f896acccdfee 100644
> --- a/Documentation/driver-api/dmaengine/provider.rst
> +++ b/Documentation/driver-api/dmaengine/provider.rst
> @@ -239,6 +239,27 @@ Currently, the types available are:
>      want to transfer a portion of uncompressed data directly to the
>      display to print it
>  
> +- DMA_REPEAT
> +
> +  - The device supports repeated transfers. A repeated transfer, indicated by
> +    the DMA_PREP_REPEAT transfer flag, is similar to a cyclic transfer in that
> +    it gets automatically repeated when it ends, but can additionally be
> +    replaced by the client.
> +
> +  - This feature is limited to interleaved transfers, this flag should thus not
> +    be set if the DMA_INTERLEAVE flag isn't set. This limitation is based on
> +    the current needs of DMA clients, support for additional transfer types
> +    should be added in the future if and when the need arises.
> +
> +- DMA_LOAD_EOT
> +
> +  - The device supports replacing repeated transfers at end of transfer (EOT)
> +    by queuing a new transfer with the DMA_PREP_LOAD_EOT flag set.
> +
> +  - Support for replacing a currently running transfer at another point (such
> +    as end of burst instead of end of transfer) will be added in the future
> +    based on DMA clients needs, if and when the need arises.
> +
>  These various types will also affect how the source and destination
>  addresses change over time.
>  
> @@ -531,6 +552,34 @@ DMA_CTRL_REUSE
>      writes for which the descriptor should be in different format from
>      normal data descriptors.
>  
> +- DMA_PREP_REPEAT
> +
> +  - If set, the transfer will be automatically repeated when it ends until a
> +    new transfer is queued on the same channel with the DMA_PREP_LOAD_EOT flag.
> +    If the next transfer to be queued on the channel does not have the
> +    DMA_PREP_LOAD_EOT flag set, the current transfer will be repeated until the
> +    client terminates all transfers.
> +
> +  - This flag is only supported if the channel reports the DMA_REPEAT
> +    capability.
> +
> +- DMA_PREP_LOAD_EOT
> +
> +  - If set, the transfer will replace the transfer currently being executed at
> +    the end of the transfer.
> +
> +  - This is the default behaviour for non-repeated transfers, specifying
> +    DMA_PREP_LOAD_EOT for non-repeated transfers will thus make no difference.
> +
> +  - When using repeated transfers, DMA clients will usually need to set the
> +    DMA_PREP_LOAD_EOT flag on all transfers, otherwise the channel will keep
> +    repeating the last repeated transfer and ignore the new transfers being
> +    queued. Failure to set DMA_PREP_LOAD_EOT will appear as if the channel was
> +    stuck on the previous transfer.
> +
> +  - This flag is only supported if the channel reports the DMA_LOAD_EOT
> +    capability.
> +
>  General Design Notes
>  ====================
>  
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index e1c03339918f..328e3aca7f51 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -61,6 +61,8 @@ enum dma_transaction_type {
>  	DMA_SLAVE,
>  	DMA_CYCLIC,
>  	DMA_INTERLEAVE,
> +	DMA_REPEAT,
> +	DMA_LOAD_EOT,
>  /* last transaction type for creation of the capabilities mask */
>  	DMA_TX_TYPE_END,
>  };
> @@ -176,6 +178,16 @@ struct dma_interleaved_template {
>   * @DMA_PREP_CMD: tell the driver that the data passed to DMA API is command
>   *  data and the descriptor should be in different format from normal
>   *  data descriptors.
> + * @DMA_PREP_REPEAT: tell the driver that the transaction shall be automatically
> + *  repeated when it ends until a transaction is issued on the same channel
> + *  with the DMA_PREP_LOAD_EOT flag set. This flag is only applicable to
> + *  interleaved transactions and is ignored for all other transaction types.
> + * @DMA_PREP_LOAD_EOT: tell the driver that the transaction shall replace any
> + *  active repeated (as indicated by DMA_PREP_REPEAT) transaction when the
> + *  repeated transaction ends. Not setting this flag when the previously queued
> + *  transaction is marked with DMA_PREP_REPEAT will cause the new transaction
> + *  to never be processed and stay in the issued queue forever. The flag is
> + *  ignored if the previous transaction is not a repeated transaction.
>   */
>  enum dma_ctrl_flags {
>  	DMA_PREP_INTERRUPT = (1 << 0),
> @@ -186,6 +198,8 @@ enum dma_ctrl_flags {
>  	DMA_PREP_FENCE = (1 << 5),
>  	DMA_CTRL_REUSE = (1 << 6),
>  	DMA_PREP_CMD = (1 << 7),
> +	DMA_PREP_REPEAT = (1 << 8),
> +	DMA_PREP_LOAD_EOT = (1 << 9),
>  };
>  
>  /**
> @@ -980,6 +994,9 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_interleaved_dma(
>  {
>  	if (!chan || !chan->device || !chan->device->device_prep_interleaved_dma)
>  		return NULL;
> +	if (flags & DMA_PREP_REPEAT &&
> +	    !test_bit(DMA_REPEAT, chan->device->cap_mask.bits))
> +		return NULL;
>  
>  	return chan->device->device_prep_interleaved_dma(chan, xt, flags);
>  }
> 

- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki





[Index of Archives]     [Linux Kernel]     [Linux ARM (vger)]     [Linux ARM MSM]     [Linux Omap]     [Linux Arm]     [Linux Tegra]     [Fedora ARM]     [Linux for Samsung SOC]     [eCos]     [Linux PCI]     [Linux Fastboot]     [Gcc Help]     [Git]     [DCCP]     [IETF Announce]     [Security]     [Linux MIPS]     [Yosemite Campsites]

  Powered by Linux