Thread (17 messages) 17 messages, 4 authors, 2020-08-27

Re: [RFC PATCH 2/3] dmaengine: add peripheral configuration

From: Peter Ujfalusi <hidden>
Date: 2020-08-25 07:58:27
Also in: linux-arm-msm, linux-devicetree, lkml

Hi Vinod,

On 25/08/2020 10.10, Vinod Koul wrote:
quoted
quoted
 /**
  * struct dma_slave_config - dma slave channel runtime config
  * @direction: whether the data shall go in or out on this slave
@@ -418,6 +485,10 @@ enum dma_slave_buswidth {
  * @slave_id: Slave requester id. Only valid for slave channels. The dma
  * slave peripheral will have unique id as dma requester which need to be
  * pass as slave config.
+ * @peripheral: type of peripheral to DMA to/from
+ * @set_config: set peripheral config
+ * @spi: peripheral config for spi
+ * @:i2c peripheral config for i2c
  *
  * This struct is passed in as configuration data to a DMA engine
  * in order to set up a certain channel for DMA transport at runtime.
@@ -443,6 +514,10 @@ struct dma_slave_config {
 	u32 dst_port_window_size;
 	bool device_fc;
 	unsigned int slave_id;
+	enum dmaengine_peripheral peripheral;
+	u8 set_config;
+	struct dmaengine_spi_config spi;
+	struct dmaengine_i2c_config i2c;
Would it be possible to reuse one of the existing feature already
supported by DMAengine?
We have DMA_PREP_CMD to give a command instead of a real transfer:
dmaengine_prep_slave_single(tx_chan, config_data, config_len,
			    DMA_MEM_TO_DEV, DMA_PREP_CMD);
dmaengine_prep_slave_single(tx_chan, tx_buff, tx_len, DMA_MEM_TO_DEV,
			    DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
dma_async_issue_pending(tx_chan);

or the metadata support:
tx = dmaengine_prep_slave_single(tx_chan, tx_buff, tx_len,
				 DMA_MEM_TO_DEV,
				 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
dmaengine_desc_attach_metadata(tx, config_data, config_len);
dma_async_issue_pending(tx_chan);

By reading the driver itself, it is not clear if you always need to send
the config for TX, or only when the config is changing and what happens
if the first transfer (for SPI, since that is the only implemented one)
is RX, when you don't send config at all...
So this config is sent to driver everytime before the prep call (can be
optimized to once if we have similar transfers in queue).
I see that you queue the TREs in the prep callback.
This config is used to create the configuration passed to dmaengine
which is used to actually program both dmaengine as well as peripheral
registers (i2c/spi/etc), so we need a way to pass the spi/i2c config.
But do you need to send it with each DMA_MEM_TO_DEV or only once?
DMA_DEV_TO_MEM does not set the config, so I assume you must have one TX
to initialize the peripheral as the first transfer.
I think prep cmd can be used to send this data, I do not see any issues
with that, it would work if we want to go that route.
The only thing which might be an issue is that with the DMA_PREP_CMD the
config_data is dma_addr_t (via dmaengine_prep_slave_single).
I did have a prototype with metadata but didnt work very well, the
problem is it assumes metadata for tx/rx but here i send the data
everytime from client data.
Yes, the intended use case for metadata (per descriptor!) is for
channels where each transfer might have different metadata needed for
the given transfer (tx/rx).

In your case you have semi static peripheral configuration data, which
is not really changing between transfers.

A compromise would be to add:
void *peripheral_config;
to the dma_slave_config, move the set_config inside of the device
specific struct you are passing from a client to the core?
quoted
I'm concerned about the size increase of dma_slave_config (it grows by
quoted
30 bytes) and for DMAs with hundreds of channels (UDMA) it will add up
to a sizeable amount.
I agree that is indeed a valid concern, that is the reason I tagged this
as a RFC patch ;-)

I see the prep_cmd is a better approach for this, anyone else has better
suggestions?

Thanks for looking in.
- Péter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help