Hi Laurent, On 23/01/2020 4.29, Laurent Pinchart wrote: > The new interleaved cyclic transaction type combines interleaved and > cycle transactions. It is designed for DMA engines that back display > controllers, where the same 2D frame needs to be output to the display > until a new frame is available. > > Suggested-by: Vinod Koul <vkoul@xxxxxxxxxx> > Signed-off-by: Laurent Pinchart <laurent.pinchart@xxxxxxxxxxxxxxxx> > --- > drivers/dma/dmaengine.c | 8 +++++++- > include/linux/dmaengine.h | 18 ++++++++++++++++++ > 2 files changed, 25 insertions(+), 1 deletion(-) > > diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c > index 03ac4b96117c..4ffb98a47f31 100644 > --- a/drivers/dma/dmaengine.c > +++ b/drivers/dma/dmaengine.c > @@ -981,7 +981,13 @@ int dma_async_device_register(struct dma_device *device) > "DMA_INTERLEAVE"); > return -EIO; > } > - > + if (dma_has_cap(DMA_INTERLEAVE_CYCLIC, device->cap_mask) && > + !device->device_prep_interleaved_cyclic) { > + dev_err(device->dev, > + "Device claims capability %s, but op is not defined\n", > + "DMA_INTERLEAVE_CYCLIC"); > + return -EIO; > + } > > if (!device->device_tx_status) { > dev_err(device->dev, "Device tx_status is not defined\n"); > diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h > index 8fcdee1c0cf9..e9af3bf835cb 100644 > --- a/include/linux/dmaengine.h > +++ b/include/linux/dmaengine.h > @@ -61,6 +61,7 @@ enum dma_transaction_type { > DMA_SLAVE, > DMA_CYCLIC, > DMA_INTERLEAVE, > + DMA_INTERLEAVE_CYCLIC, > /* last transaction type for creation of the capabilities mask */ > DMA_TX_TYPE_END, > }; > @@ -701,6 +702,10 @@ struct dma_filter { > * The function takes a buffer of size buf_len. The callback function will > * be called after period_len bytes have been transferred. > * @device_prep_interleaved_dma: Transfer expression in a generic way. > + * @device_prep_interleaved_cyclic: prepares an interleaved cyclic transfer. > + * This is similar to @device_prep_interleaved_dma, but the transfer is > + * repeated until a new transfer is issued. This transfer type is meant > + * for display. I think capture (camera) is another potential beneficiary of this. So you don't need to terminate the running interleaved_cyclic and start a new one, but prepare and issue a new one, which would terminate/replace the currently running cyclic interleaved DMA? Can you also update the documentation at Documentation/driver-api/dmaengine/client.rst One more thing might be good to clarify for the interleaved_cyclic: What is expected when DMA_PREP_INTERRUPT is set in the flags? The client's callback is called for each completion of dma_interleaved_template, right? - Péter > * @device_prep_dma_imm_data: DMA's 8 byte immediate data to the dst address > * @device_config: Pushes a new configuration to a channel, return 0 or an error > * code > @@ -785,6 +790,9 @@ struct dma_device { > struct dma_async_tx_descriptor *(*device_prep_interleaved_dma)( > struct dma_chan *chan, struct dma_interleaved_template *xt, > unsigned long flags); > + struct dma_async_tx_descriptor *(*device_prep_interleaved_cyclic)( > + struct dma_chan *chan, struct dma_interleaved_template *xt, > + unsigned long flags); > struct dma_async_tx_descriptor *(*device_prep_dma_imm_data)( > struct dma_chan *chan, dma_addr_t dst, u64 data, > unsigned long flags); > @@ -880,6 +888,16 @@ static inline struct dma_async_tx_descriptor *dmaengine_prep_interleaved_dma( > return chan->device->device_prep_interleaved_dma(chan, xt, flags); > } > > +static inline struct dma_async_tx_descriptor *dmaengine_prep_interleaved_cyclic( > + struct dma_chan *chan, struct dma_interleaved_template *xt, > + unsigned long flags) > +{ > + if (!chan || !chan->device || !chan->device->device_prep_interleaved_cyclic) > + return NULL; > + > + return chan->device->device_prep_interleaved_cyclic(chan, xt, flags); > +} > + > static inline struct dma_async_tx_descriptor *dmaengine_prep_dma_memset( > struct dma_chan *chan, dma_addr_t dest, int value, size_t len, > unsigned long flags) > Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki