Re: [RFC]DMA API Update


Liu, Baohong
 

Thanks for the feedback. See my reply inline.

From: Jon Medhurst (Tixy) [mailto:tixy(a)linaro.org]
Sent: Friday, January 13, 2017 5:49 AM

On Wed, 2017-01-11 at 19:49 +0000, Liu, Baohong wrote:

/**
* @brief DMA configuration structure.
*
* config is a bit field with the following parts:
* dma_slot [ 0 : 5 ] --which peripheral and
direction(HW specific)
* hankshake_polarity [ 6 ] --high or low
Is hankshake_polarity something which affects both source_handshake and
dest_handshake? If so, you sure that no hardware combination might want
different polarities for these? And is handshake something that can have
more than one valid setting, or is it determined by how the hardware is
constructed and wired up? If the latter, then these values probably shouldn't
be in a public API for use by applications and instead set by the DMA engine
to the correct values based on the value of dma_slot or something other
property of the transfer it knows.
The setting will be set before a new transfer. But, both sending and receiving
sides must follow the same setting.

This is needed to cater for different SoCs.


* channel_direction [ 7 : 9 ] --0-memory to memory, 1-
memory to peripheral,
* 2-peripheral to memory
* source_data_size [ 10 : 12 ] --source data size(8,16,32,64,128
and 256 bits)
* dest_data_size [ 13 : 15 ] --destination data
size(8,16,32,64,128 and 256 bits)
* source_burst_length [ 16 : 18 ] --number of source data
unit(1,4,8,16,32,64,128 and 256)
* dest_burst_length [ 19 : 21 ] -- number of dest data
unit(1,4,8,16,32,64,128 and 256)

Why are burst lengths a fixed sequence of power's of two? And why isn't '2'
in the list? Why not just have an arbitrary integer? That's a rhetorical question,
I know why, because it matches the Quark hardware, and the DMA API, like a
lot of APIs in Zephyr, is specific to that one piece of hardware.
I can add one more value which is 2. So, the burst length will become power's of two.

In my opinion, it does not need to be an arbitrary integer.


* source_handshake [ 22 ] --HW or SW
* dest_handshake [ 23 ] --HW or SW
* channel_priority [ 24 : 27 ] --DMA channel priority
* RESERVED [ 28 : 31 ]
* dma_callback is the callback function pointer
*/

struct dma_channel_config {
uint32_t config;
void (*dma_callback)(struct device *dev, uint32_t channel, int
error_code); }

The remaining parts will stay the same.
No change to the structure dma_transfer_config.
No change to the API function prototypes:
dma_channel_config(...)
dma_transfer_config(...)
dma_transfer_start(...)
dma_transfer_stop(...)
I also see the existing DMA API doesn't support scatter-gather, that's a fairly
common and useful feature of DMA hardware.
Will add.


But finally, the big elephant in the room is: how are DMA APIs actually
expected to used? And how should the system be configured?
The same way as other device drivers. There will be a driver to implement
the APIs for each SoC. App does the config, and initiate the transfer by
calling the APIs.


Currently, the only code in Zephyr that does DMA is of course Quark, and the
driver for each peripheral that can do DMA is Quark specific and knows about
Quark DMA.

So what about an SoC with a some generic DMA IP that has a Zephyr driver,
and a bunch of generic peripherals with there own drivers, and an application
that wants to use one of the said peripherals, which software component
configures the dma channel and how is the system configured so that has the
right knowledge to do that?

That's probably a rhetorical question to. The answer is that Zephyr get's
device-tree support and pinches designed ideas from Linux (which
presumably borrowed heavily from other places as well).

--
Tixy

Join devel@lists.zephyrproject.org to automatically receive all group messages.