Skip to contentSkip to conversation

of: Add generic device tree DMA helpers

PATCH Superseded Jon Hunter 12 participants 129 messages Apr 30, 2012 – Aug 3, 2012

Subsystems (3)

v3 of 6 Superseded Latest is v6 →

lore
Share & tools
lore

Jon Hunter

author
#0 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

From: Jon Hunter <[email protected]>

This is based upon the work by Benoit Cousson [1] and Nicolas Ferre [2] to add some basic helpers to retrieve a DMA controller device_node and the DMA request/channel information.

Aim of DMA helpers
- The purpose of device-tree (as far as I understand), is to describe the capabilites of the hardware. Thinking about DMA controllers purely from the context of the hardware to begin with, we can describe a device in terms of a DMA controller as follows ...
1. Number of DMA controllers
2. Number of channels (maybe physical or logical)
3. Mapping of DMA requests signals to DMA controller
4. Number of DMA interrupts
5. Mapping of DMA interrupts to channels
- With the above in mind the aim of the DT DMA helper functions is to extract the above information from the DT and provide to the appropriate driver. However, due to the vast number of DMA controllers and not all are using a common driver (such as DMA Engine) it has been seen that this is not a trivial task. In previous discussions on this topic the following concerns have been raised ...
1. How does the binding identify when there are multiple DMA controllers?
2. How to support both legacy DMA controllers not using DMA Engine as well as those that support DMA Engine.
3. When using with DMA Engine how do we support the various implementations where the opaque filter function parameter differs between implementations?
4. How do we handle DMA channels that are identified with a string versus a integer?
- Hence the design of the DMA helpers has to accomodate the above or align on an agreement what can be or should be supported.

Design of DMA helpers

1. Supporting devices with multiple DMA controllers

In the case of DMA controllers that are using DMA Engine, requesting a channel is performed by calling the following function.

	struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
			dma_filter_fn filter_fn,
			void *filter_param);

The mask variable is used to identify the device controller in a list of controllers. The filter_fn and filter_param are used to identify the required dma channel and return a handle to the dma channel of type dma_chan. From the examples I have seen, the mask and filter_fn are constant for a given DMA controller. Therefore, when registering a DMA controller with device tree we can pass these parameters and store them so that a device can request them when requesting a channel. Hence, based upon this our register function for the DMA controller now looks like this.

	int of_dma_controller_register(struct device_node *np,
		dma_cap_mask_t *mask, dma_filter_fn fn);

2. Supporting legacy devices not using DMA Engine

These devices present a problem, as there may not be a uniform way to easily support them with regard to device tree. However, _IF_ legacy devices that are not using DMA Engine, only have a single DMA controller, then this problem is a lot simpler. For example, if we look at the previously proposed API for registering a DMA controller (where we pass the mask and function pointer to the DMA Engine filter function) we can simply pass NULL and hence, a driver requesting the DMA channel information would receive NULL for the DMA Engine specific parameters. Then for legacy devices we simply need a means to return the channel information (more on this later). If there are legacy devices that do have multiple DMA controllers, then maybe they need to be converted to support DMA Engine. I am not sure if this is unreasonable???

3. Representing and requesting channel information

From a hardware perspective, a DMA channel could be represented as ...

i. channel index/number
ii. channel transfer type (optional)
iii. DMA interrupt mapping (optional)

Please note that the transfer type is used to indicate if the transfer is to device from memory, to memory from device, to memory from memory, etc. This can be useful when there is a device such as an MMC device that uses two DMA channels, one for reading (RX) and one for writing (TX).

Forgetting device tree for now, some drivers use strings to represent a DMA channel instead of using an integer. I assume that these drivers then employ some sort of look-up table to convert the string into a channel number/index that the hardware understands. If this assumption is correct then when moving to a device tree implementation having such look-up tables in the driver should no longer be necessary as the device tree will provide the mapping of channel index/number to the device. Furthermore, it makes sense that device tree uses integers to represent channel as opposed to strings to save the driver having to convert the string into a integer at some later stage.

Next we need to think about how the DMA controller and channels are described in the device tree itself. The following device tree node example describes the properties of the DMA controller that includes, the register address range, number of interrupt supported, number of channels and number of request signals. This has been enhanced from the previous versions by adding number of channels and number of request signals.

	sdma: dma-controller at 4A056000 {
		compatible = "ti,omap4-sdma";
		reg = <0x4A056000 0x1000>;
		interrupts = <4>;
		#dma-cells = <2>;
		#dma-channels = <32>;
		#dma-requests = <127>;
	};

Given the above controller definition, DMA resources for a device, such as an MMC that uses two DMA channels, can be declared as follows.

	mmc1: mmc at 4809c000 {
		...
		dma = <&sdma 61 1 &sdma 62 2>;
		...
	};

The above syntax to represent each DMA resource is "controller-phandle + dma-channel + transfer-type". The transfer-type here is defined to match the types in DMA Engine dma_transfer_direction enumeration
(see include/linux/dmaengine.h). Hence, a "1" means DMA_MEM_TO_DEV and a "2" means "DMA_DEV_TO_MEM". This will be helpful later when requesting the channel information. You will also notice here that there is no entry for representing the interrupt used by the DMA channel and this is because this version has not added this capability. I believe that this will be important to define in the device tree, but at the moment this has been left out purely because passing this information was not supported for the device (OMAP) that I was using to implement this. This could be easily added if people find this implementation acceptable.

A driver can now request the DMA channel information by calling the following function.

int of_get_dma_channel_info(struct device_node *np, int type,
struct of_dma_channel_info *info)

Where type represents the transfer-type (again the DMA Engine dma_transfer_direction enumeration can be used here regardless of if DMA Engine is used) and of_dma_channel_info is defined as follows.

	struct of_dma_channel_info {
		int		dma_channel;
		dma_cap_mask_t	dma_cap;
		dma_filter_fn	dma_filter_func;
	};

Here dma_channel will always be valid and the other fields are optional depending on whether DMA Engine is used.

This implementation has been tested on OMAP4430 using Russell King's latest DMA Engine series for OMAP [3] and with Benoit Cousson latest DT changes for OMAP4 [4]. I have validated that MMC is working on the PANDA board with this implementation. I have not included all the changes for PANDA board here but just wished to share the implementation.

My aim here was to restart the dialogue on this topic. Please let me know your thoughts and if there are any glaring short-comings with my assumptions and ideas :-)

v3: - avoid passing an xlate function and instead pass DMA engine parameters
- define number of dma channels and requests in dma-controller node

v2: - remove of_dma_to_resource API
- make property #dma-cells required (no fallback anymore)
- another check in of_dma_xlate_onenumbercell() function

[1] http://article.gmane.org/gmane.linux.drivers.devicetree/12022
[2] http://article.gmane.org/gmane.linux.ports.arm.omap/73622
[3] http://article.gmane.org/gmane.linux.ports.arm.omap/75366
[4] http://permalink.gmane.org/gmane.linux.ports.arm.omap/73263

Cc Nicolas Ferre <[email protected]>
Cc Benoit Cousson <[email protected]>
Cc Stephen Warren <[email protected]>
Cc Grant Likely <[email protected]>
Cc Russell King <[email protected]>
Cc Rob Herring <[email protected]>
Cc Arnd Bergmann <[email protected]>
---
 Documentation/devicetree/bindings/dma/dma.txt |   47 ++++++
 drivers/of/Makefile                           |    2 +-
 drivers/of/dma.c                              |  203 +++++++++++++++++++++++++
 include/linux/of_dma.h                        |   35 +++++
 4 files changed, 286 insertions(+), 1 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/dma.txt
 create mode 100644 drivers/of/dma.c
 create mode 100644 include/linux/of_dma.h
Documentation/devicetree/bindings/dma/dma.txt new file +47 -0
new file mode 100644
index 0000000..b9e838d
@@ -0,0 +1,47 @@
+* Generic DMA Controller and DMA request bindings
+
+Generic binding to provide a way for a driver using DMA Engine to retrieve the
+DMA request or channel information that goes from a hardware device to a DMA
+controller.
+
+
+* DMA controller
+
+Required property:
+    - #dma-cells: Number elements to describe DMA channel information. Must be
+                  2 with current implementation but in future we could allow
+		  more than 2 to describe interrupt mapping as well.
+    - #dma-channels: Number of DMA channels supported by the controller.
+    - #dma-requests: Number of DMA requests signals supported by the controller.
+
+Example:
+
+	sdma: dmaengine at 48000000 {
+		compatible = "ti,omap4-sdma"
+		reg = <0x48000000 0x1000>;
+		interrupts = <4>;
+		#dma-cells = <2>;
+		#dma-channels = <32>;
+		#dma-requests = <127>;
+	};
+
+
+* DMA client
+
+Client drivers should specify the DMA property using a phandle to the controller
+followed by the number of DMA request/channel and the transfer type of the
+channel (eg. device-to-memory, memory-to-device, memory-to-memory, etc). Drivers
+should use the DMA Engine enum dma_transfer_direction (eg. DMA_DEV_TO_MEM,
+DMA_MEM_TO_DEV, etc) for specifying the transfer type.
+
+Required property:
+    - dma: List of phandle + dma-request/channel + transfer-type,
+      one group per request "line".
+
+Example:
+
+	i2c1: i2c at 1 {
+		...
+		dma = <&sdma 2 1 &sdma 3 2>;
+		...
+	};
drivers/of/Makefile +1 -1
index aa90e60..fd9f4eb 100644
@@ -1,4 +1,4 @@
-obj-y = base.o
+obj-y = base.o dma.o
 obj-$(CONFIG_OF_FLATTREE) += fdt.o
 obj-$(CONFIG_OF_PROMTREE) += pdt.o
 obj-$(CONFIG_OF_ADDRESS)  += address.o
drivers/of/dma.c new file +203 -0

203 lines not on this page · raw message

include/linux/of_dma.h new file +35 -0
new file mode 100644
index 0000000..5ff0a6f
@@ -0,0 +1,35 @@
+/*
+ * OF helpers for DMA request / controller
+ *
+ * Based on of_gpio.h
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#ifndef __LINUX_OF_DMA_H
+#define __LINUX_OF_DMA_H
+
+#include <linux/ioport.h>
+#include <linux/of.h>
+#include <linux/dmaengine.h>
+
+struct device_node;
+
+struct of_dma_channel_info {
+	int		dma_channel;
+	dma_cap_mask_t	dma_cap;
+	dma_filter_fn	dma_filter_func;
+};
+
+extern int of_dma_controller_register(struct device_node *np,
+			dma_cap_mask_t *mask,
+			bool (*of_dma_filer_fn)(struct dma_chan *, void *));
+extern void of_dma_controller_free(struct device_node *np);
+extern int of_get_dma_channel_info(struct device_node *np, int index,
+			struct of_dma_channel_info *info);
+
+#endif /* __LINUX_OF_DMA_H */
Signature · 1 line
1.7.5.4
#1 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 5 lines · Jon Hunter

From: Jon Hunter <[email protected]>

This is based upon the work by Benoit Cousson [1] and Nicolas Ferre [2] to add some basic helpers to retrieve a DMA controller device_node and the DMA request/channel information.

I'll reply to the binding documentation first; perhaps that'll set the scene for my questions better.

Quoted 4 lines

+++ b/Documentation/devicetree/bindings/dma/dma.txt

Documentation/devicetree/bindings/dma/dma.txt new file +3 -0
+* Generic DMA Controller and DMA request bindings
+
+Generic binding to provide a way for a driver using DMA Engine to retrieve the

Documentation/devicetree/bindings/dma/dma.txt line 13

Quoted 10 lines
Documentation/devicetree/bindings/dma/dma.txt new file +10 -0
+DMA request or channel information that goes from a hardware device to a DMA
+controller.
+
+
+* DMA controller
+
+Required property:
+    - #dma-cells: Number elements to describe DMA channel information. Must be
+                  2 with current implementation but in future we could allow
+		  more than 2 to describe interrupt mapping as well.

That makes sense.

Documentation/devicetree/bindings/dma/dma.txt line 15

Quoted 2 lines
Documentation/devicetree/bindings/dma/dma.txt new file +2 -0
+    - #dma-channels: Number of DMA channels supported by the controller.
+    - #dma-requests: Number of DMA requests signals supported by the controller.

I don't see why those properties would be mandatory in device tree. They don't appear to be involved in parsing a DMA client's DMA specifier. Shouldn't this information be provided at run-time by the DMA controller driver. If it supports different HW models with different capabilities, then it certainly could represent those values in DT, but I don't think this should be required.

Quoted 6 lines
Documentation/devicetree/bindings/dma/dma.txt new file +6 -0
+Example:
+
+	sdma: dmaengine at 48000000 {
+		compatible = "ti,omap4-sdma"
+		reg = <0x48000000 0x1000>;
+		interrupts = <4>;

Documentation/devicetree/bindings/dma/dma.txt line 32

Quoted 10 lines
Documentation/devicetree/bindings/dma/dma.txt new file +10 -0
+		#dma-cells = <2>;
+		#dma-channels = <32>;
+		#dma-requests = <127>;
+	};
+
+
+* DMA client
+
+Client drivers should specify the DMA property using a phandle to the controller
+followed by the number of DMA request/channel and the transfer type of the

What exactly is "request/channel"? Is it a request ID, a channel ID, both packed into a single integer (which bits are used for each field), etc.?

If this is up to the individual controller binding, then I think the description should just specify that there is a phandle followed by a DMA specifier, and the DMA specifier contains #dma-cells from the phandle node. See other similar bindings for suitable wording.

Documentation/devicetree/bindings/dma/dma.txt line 35

Quoted 3 lines
Documentation/devicetree/bindings/dma/dma.txt new file +3 -0
+channel (eg. device-to-memory, memory-to-device, memory-to-memory, etc). Drivers
+should use the DMA Engine enum dma_transfer_direction (eg. DMA_DEV_TO_MEM,
+DMA_MEM_TO_DEV, etc) for specifying the transfer type.

The binding document should stand alone; you shouldn't need to go look up values in any particular OS/driver's source code. In other words, this should explicitly enumerate the values for DMA_DEV_TO_MEM etc. here. That said, I'm not sure it's appropriate to mandate that every DMA controller's DMA specifier actually include this information in DT (a controller might only support DEV_TO_MEM for example, and hence not need this information in DT at all).

The DMA client's binding should specify how many entries it needs in the dma property and what they mean, e.g. it should know that dma property index 0 is the TX DMA specifier, and index 1 is the RX specifier.

Documentation/devicetree/bindings/dma/dma.txt line 45

Quoted 9 lines
Documentation/devicetree/bindings/dma/dma.txt new file +9 -0
+Required property:
+    - dma: List of phandle + dma-request/channel + transfer-type,
+      one group per request "line".
+
+Example:
+
+	i2c1: i2c at 1 {
+		...
+		dma = <&sdma 2 1 &sdma 3 2>;

Should that be "dmas" (plural) to be consistency with interrupts, gpios, ...?

Back to pieces of your patch description:

Quoted 2 lines

v3: - avoid passing an xlate function and instead pass DMA engine parameters
- define number of dma channels and requests in dma-controller node

Perhaps I lack context of previous discussion, but that seems the wrong direction, and doesn't allow DMA controllers to define the format of their DMA specifiers.

I'd expect the process to work just like other DT bindings:

* Client calls dma_request(index)
* OF DMA core gets property, does the following until it hits index:
** Get phandle
** Get provider node for phandle
** Parses #dma-cells from provider node
** If at appropriate index:
*** call xlate/get function to convert the DMA specifier to something that could be passed to e.g. dma_request_channel.
*** else skip that many cells and loop

Now, the structure returned from the xlate function could encompass filter_fn and filter_param if required.

In fact, I'd expect that all xlate return something like:

struct of_dma_filter_param {
    struct device_node *node;
    dma_filter_fn filter_fn;
    void *filter_param;
};

and the following filter function to always be used for the DT case:

bool of_dma_filter_func(...)

{
    struct of_dma_filter_param *p = ...;

    /* First, only match the controller of the DT node that parsed this
       filter data */
    if (p->node != xxx->node)
        return false;

    /* Then let the individual controller do whatever match it needs */
    return p->filter_fn(xxx, p->filter_param);
}
Quoted 7 lines

3. Representing and requesting channel information

From a hardware perspective, a DMA channel could be represented as ...

i. channel index/number
ii. channel transfer type (optional)
iii. DMA interrupt mapping (optional)

I think the representation should be down to the individual DMA controller.

For example, Tegra has n identical DMA channels, and each can be used with any peripheral. However, when allocating the channel, you have to specify which peripheral request to use on that channel. So, you need to specify DMA request ID for Tegra, not DMA channel ID.

I can imagine another DMA controller where each channel is dedicated to one particular piece of HW (e.g. I2S controller 0 TX FIFO). In this case, you'd need to specify DMA channel ID here, not request ID (well, I guess they're equivalent 1:1)

This is why I think DMA controller should specify the format of their own DMA specifier in DT, and why they should provide an xlate function to parse that.

#2 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 13 lines · Stephen Warren
Quoted 12 lines · Jon Hunter
Documentation/devicetree/bindings/dma/dma.txt new file +12 -0
+Example:
+
+	sdma: dmaengine at 48000000 {
+		compatible = "ti,omap4-sdma"
+		reg = <0x48000000 0x1000>;
+		interrupts = <4>;
+		#dma-cells = <2>;
+		#dma-channels = <32>;
+		#dma-requests = <127>;
+	};
+
+
Quoted 8 lines

Documentation/devicetree/bindings/dma/dma.txt line 32

Quoted 4 lines
Documentation/devicetree/bindings/dma/dma.txt new file +4 -0
+* DMA client
+
+Client drivers should specify the DMA property using a phandle to the controller
+followed by the number of DMA request/channel and the transfer type of the

What exactly is "request/channel"? Is it a request ID, a channel ID, both packed into a single integer (which bits are used for each field), etc.?

Agreed - because with this definition, applied to the PL08x found on Versatile platforms, it will be impossible to describe the DMA bindings due to intervening MUX hardware.

Quoted 12 lines

Documentation/devicetree/bindings/dma/dma.txt line 35

Quoted 3 lines
Documentation/devicetree/bindings/dma/dma.txt new file +3 -0
+channel (eg. device-to-memory, memory-to-device, memory-to-memory, etc). Drivers
+should use the DMA Engine enum dma_transfer_direction (eg. DMA_DEV_TO_MEM,
+DMA_MEM_TO_DEV, etc) for specifying the transfer type.

The binding document should stand alone; you shouldn't need to go look up values in any particular OS/driver's source code. In other words, this should explicitly enumerate the values for DMA_DEV_TO_MEM etc. here. That said, I'm not sure it's appropriate to mandate that every DMA controller's DMA specifier actually include this information in DT (a controller might only support DEV_TO_MEM for example, and hence not need this information in DT at all).

Quoted 3 lines

The DMA client's binding should specify how many entries it needs in the dma property and what they mean, e.g. it should know that dma property index 0 is the TX DMA specifier, and index 1 is the RX specifier.

(Mostly to Jon)

Also bear in mind that as far as DMA engine is concerned, every channel is _potentially_ bidirectional without it having to be released and reacquired. We have some drivers setup to behave like that too. So stuffing stuff like the transfer type into the selection adds restrictions.

On platforms where the DMA transfer type does matter (such as OMAP), that's normally because one DMA request signal is associated with a particular DMA direction. That makes it a property of the DMA request signal, not of the requested channel.

#3 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Stephen Warren
Quoted 9 lines · Stephen Warren

Documentation/devicetree/bindings/dma/dma.txt line 15

Quoted 2 lines
Documentation/devicetree/bindings/dma/dma.txt new file +2 -0
+    - #dma-channels: Number of DMA channels supported by the controller.
+    - #dma-requests: Number of DMA requests signals supported by the controller.

I don't see why those properties would be mandatory in device tree. They don't appear to be involved in parsing a DMA client's DMA specifier. Shouldn't this information be provided at run-time by the DMA controller driver. If it supports different HW models with different capabilities, then it certainly could represent those values in DT, but I don't think this should be required.

Agreed. I would list them as 'optional' though, so that every specific binding that needs these will have to use the same format.

Arnd

author
#4 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Stephen Warren

Hi Stephen,

Quoted 30 lines · Stephen Warren
Quoted 5 lines · Jon Hunter

From: Jon Hunter <[email protected]>

This is based upon the work by Benoit Cousson [1] and Nicolas Ferre [2] to add some basic helpers to retrieve a DMA controller device_node and the DMA request/channel information.

I'll reply to the binding documentation first; perhaps that'll set the scene for my questions better.

Quoted 4 lines

+++ b/Documentation/devicetree/bindings/dma/dma.txt

Documentation/devicetree/bindings/dma/dma.txt new file +3 -0
+* Generic DMA Controller and DMA request bindings
+
+Generic binding to provide a way for a driver using DMA Engine to retrieve the

Documentation/devicetree/bindings/dma/dma.txt line 13

Quoted 10 lines
Documentation/devicetree/bindings/dma/dma.txt new file +10 -0
+DMA request or channel information that goes from a hardware device to a DMA
+controller.
+
+
+* DMA controller
+
+Required property:
+    - #dma-cells: Number elements to describe DMA channel information. Must be
+                  2 with current implementation but in future we could allow
+		  more than 2 to describe interrupt mapping as well.

That makes sense.

Documentation/devicetree/bindings/dma/dma.txt line 15

Quoted 2 lines
Documentation/devicetree/bindings/dma/dma.txt new file +2 -0
+    - #dma-channels: Number of DMA channels supported by the controller.
+    - #dma-requests: Number of DMA requests signals supported by the controller.
Quoted 6 lines

I don't see why those properties would be mandatory in device tree. They don't appear to be involved in parsing a DMA client's DMA specifier. Shouldn't this information be provided at run-time by the DMA controller driver. If it supports different HW models with different capabilities, then it certainly could represent those values in DT, but I don't think this should be required.

Yes you are right. These should not be required.

Quoted 12 lines
Quoted 12 lines
Documentation/devicetree/bindings/dma/dma.txt new file +12 -0
+Example:
+
+	sdma: dmaengine at 48000000 {
+		compatible = "ti,omap4-sdma"
+		reg = <0x48000000 0x1000>;
+		interrupts = <4>;
+		#dma-cells = <2>;
+		#dma-channels = <32>;
+		#dma-requests = <127>;
+	};
+
+
Quoted 8 lines

Documentation/devicetree/bindings/dma/dma.txt line 32

Quoted 4 lines
Documentation/devicetree/bindings/dma/dma.txt new file +4 -0
+* DMA client
+
+Client drivers should specify the DMA property using a phandle to the controller
+followed by the number of DMA request/channel and the transfer type of the

What exactly is "request/channel"? Is it a request ID, a channel ID, both packed into a single integer (which bits are used for each field), etc.?

The thought here was that some DMAs may distinguish between devices by a request ID or a channel ID or both. In the case of say an OMAP4, we have 32 channels and 127 request IDs. From a h/w perspective we need to know both. Each of the 32 channels can be programmed to use any one of the 127 h/w request signals.

Other DMAs may only need to specify requests or channels. However, the thought was you could specific either or both depending on your needs. Again these should have been optional parameters.

Quoted 4 lines

If this is up to the individual controller binding, then I think the description should just specify that there is a phandle followed by a DMA specifier, and the DMA specifier contains #dma-cells from the phandle node. See other similar bindings for suitable wording.

Ok, thanks. Still a bit green (new) on the DT stuff.

Quoted 12 lines

Documentation/devicetree/bindings/dma/dma.txt line 35

Quoted 3 lines
Documentation/devicetree/bindings/dma/dma.txt new file +3 -0
+channel (eg. device-to-memory, memory-to-device, memory-to-memory, etc). Drivers
+should use the DMA Engine enum dma_transfer_direction (eg. DMA_DEV_TO_MEM,
+DMA_MEM_TO_DEV, etc) for specifying the transfer type.

The binding document should stand alone; you shouldn't need to go look up values in any particular OS/driver's source code. In other words, this should explicitly enumerate the values for DMA_DEV_TO_MEM etc. here. That said, I'm not sure it's appropriate to mandate that every DMA controller's DMA specifier actually include this information in DT (a controller might only support DEV_TO_MEM for example, and hence not need this information in DT at all).

Quoted 3 lines

The DMA client's binding should specify how many entries it needs in the dma property and what they mean, e.g. it should know that dma property index 0 is the TX DMA specifier, and index 1 is the RX specifier.

Ok. I was trying to add another parameter to make this explicit in the property. When I was looking at the bindings it is not clear what index 0 is, what index 1, etc, and I needed to look at both the client driver and DT to figure out what they think the indexes represent. Hence, I thought a parameter that identified this could be useful. However, your point is well taken and I agree that it would be cleaner to keep it separated. If it is preferred to have the client driver understand the indexes then that is fine.

Quoted 4 lines
Quoted 4 lines
Documentation/devicetree/bindings/dma/dma.txt new file +4 -0
+Required property:
+    - dma: List of phandle + dma-request/channel + transfer-type,
+      one group per request "line".
+
Quoted 8 lines

Documentation/devicetree/bindings/dma/dma.txt line 45

Quoted 5 lines
Documentation/devicetree/bindings/dma/dma.txt new file +5 -0
+Example:
+
+	i2c1: i2c at 1 {
+		...
+		dma = <&sdma 2 1 &sdma 3 2>;

Should that be "dmas" (plural) to be consistency with interrupts, gpios, ...?

It could be. However, there could also be cases where there is a single DMA request/channel. However, to be consistent with others we can make it dmas.

Quoted 35 lines

Back to pieces of your patch description:

Quoted 2 lines

v3: - avoid passing an xlate function and instead pass DMA engine parameters
- define number of dma channels and requests in dma-controller node

Perhaps I lack context of previous discussion, but that seems the wrong direction, and doesn't allow DMA controllers to define the format of their DMA specifiers.

I'd expect the process to work just like other DT bindings:

* Client calls dma_request(index)
* OF DMA core gets property, does the following until it hits index:
** Get phandle
** Get provider node for phandle
** Parses #dma-cells from provider node
** If at appropriate index:
*** call xlate/get function to convert the DMA specifier to something that could be passed to e.g. dma_request_channel.
*** else skip that many cells and loop

Now, the structure returned from the xlate function could encompass filter_fn and filter_param if required.

In fact, I'd expect that all xlate return something like:

struct of_dma_filter_param {
    struct device_node *node;
    dma_filter_fn filter_fn;
    void *filter_param;
};

and the following filter function to always be used for the DT case:

bool of_dma_filter_func(...)

Quoted 11 lines
{
    struct of_dma_filter_param *p = ...;

    /* First, only match the controller of the DT node that parsed this
       filter data */
    if (p->node != xxx->node)
        return false;

    /* Then let the individual controller do whatever match it needs */
    return p->filter_fn(xxx, p->filter_param);
}

Yes we could definitely do something like this. I guess I was trying to avoid returning a void *, but may be that is unavoidable in this case.

Quoted 1 line
Quoted 1 line

3. Representing and requesting channel information

Sorry I think that I am mixing terms here! May be this should be ...

3. Representing and requesting _DMA_ _resource_ information

Quoted 2 lines
Quoted 2 lines

From a hardware perspective, a DMA channel could be represented as ...

This should be ...

Quoted 4 lines

From a hardware perspective, a DMA _resource_ could be represented as ...

Quoted 2 lines

i. channel index/number

This should be ...

i. channel/request index/number

Quoted 4 lines
Quoted 2 lines

ii. channel transfer type (optional)
iii. DMA interrupt mapping (optional)

I think the representation should be down to the individual DMA controller.

Right I was trying to think generically about all DMA controllers I have dealt with how they could be represented. However, I will admit those DMA controllers are TI controllers, however, they can be very different (EDMA vs SDMA, etc). My aim here was to try and so if people thought that we could represent any controller in this fashion or don't even bother.

Quoted 4 lines

For example, Tegra has n identical DMA channels, and each can be used with any peripheral. However, when allocating the channel, you have to specify which peripheral request to use on that channel. So, you need to specify DMA request ID for Tegra, not DMA channel ID.

Yes this is the same as OMAPs SDMA. In the case of such DMA controllers you only really care about the request ID and total number of channels that are available to you.

Quoted 4 lines

I can imagine another DMA controller where each channel is dedicated to one particular piece of HW (e.g. I2S controller 0 TX FIFO). In this case, you'd need to specify DMA channel ID here, not request ID (well, I guess they're equivalent 1:1)

Yes exactly. I was thinking about the same case too.

Quoted 3 lines

This is why I think DMA controller should specify the format of their own DMA specifier in DT, and why they should provide an xlate function to parse that.

Ok fair enough. However, it seems that at a minimum we could provide one or two xlate functions in the generic binding for people to use. One could be the DMA engine xlate binding and another could be the simple xlate binding Nicolas proposed for a DMA controller that returns a single channel/request ID.

However, at the same time, may be people would prefer that devices such as tegra, omap, at91, etc, offer their own xlate function for DMA engine. I am not sure, but we could go either way.

Thanks for the review and comments.

Cheers
Jon

#5 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 9 lines · Jon Hunter

The thought here was that some DMAs may distinguish between devices by a request ID or a channel ID or both. In the case of say an OMAP4, we have 32 channels and 127 request IDs. From a h/w perspective we need to know both. Each of the 32 channels can be programmed to use any one of the 127 h/w request signals.

Other DMAs may only need to specify requests or channels. However, the thought was you could specific either or both depending on your needs. Again these should have been optional parameters.

As being the one who is converting you over to DMA engine, I can't agree with what you've just said. I don't see that there's anything specific to any particular DMA channel. I don't see that a driver would need to obtain a reference to any particular channel.

This seems to be supported by the current OMAP DMA API which merely returns any one of the 32 channels that it can find whenever omap_request_dma() is called.

At the moment, the DMA engine support I'm working on totally hides the physical DMA channels behind a set of virtual DMA channels, one for each DMA request signal. This appears to work well, and is compatible with how existing drivers use the current OMAP DMA API.

#6 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Jon Hunter
Quoted 9 lines · Jon Hunter

Hi Stephen,

Quoted 6 lines · Stephen Warren
Quoted 5 lines · Jon Hunter

From: Jon Hunter <[email protected]>

This is based upon the work by Benoit Cousson [1] and Nicolas Ferre [2] to add some basic helpers to retrieve a DMA controller device_node and the DMA request/channel information.

...

Quoted 20 lines
Quoted 11 lines
Quoted 11 lines
Documentation/devicetree/bindings/dma/dma.txt new file +11 -0
+
+	sdma: dmaengine at 48000000 {
+		compatible = "ti,omap4-sdma"
+		reg = <0x48000000 0x1000>;
+		interrupts = <4>;
+		#dma-cells = <2>;
+		#dma-channels = <32>;
+		#dma-requests = <127>;
+	};
+
+
Quoted 8 lines

Documentation/devicetree/bindings/dma/dma.txt line 32

Quoted 4 lines
Documentation/devicetree/bindings/dma/dma.txt new file +4 -0
+* DMA client
+
+Client drivers should specify the DMA property using a phandle to the controller
+followed by the number of DMA request/channel and the transfer type of the

What exactly is "request/channel"? Is it a request ID, a channel ID, both packed into a single integer (which bits are used for each field), etc.?

Quoted 7 lines

The thought here was that some DMAs may distinguish between devices by a request ID or a channel ID or both. In the case of say an OMAP4, we have 32 channels and 127 request IDs. From a h/w perspective we need to know both. Each of the 32 channels can be programmed to use any one of the 127 h/w request signals.

From a HW perspective, do you actually need to know both? I think the HW

description must specify the request ID, but because any channel can be programmed to any request ID, you don't actually care about the channel ID; it can be dynamically allocated by the DMA driver when the client driver calls dma_request_channel().

Actually, you say the following below, so I guess you already agree here:

Quoted 3 lines

Yes this is the same as OMAPs SDMA. In the case of such DMA controllers you only really care about the request ID and total number of channels that are available to you.

...

Quoted 10 lines
Quoted 3 lines

This is why I think DMA controller should specify the format of their own DMA specifier in DT, and why they should provide an xlate function to parse that.

Ok fair enough. However, it seems that at a minimum we could provide one or two xlate functions in the generic binding for people to use. One could be the DMA engine xlate binding and another could be the simple xlate binding Nicolas proposed for a DMA controller that returns a single channel/request ID.

Quoted 3 lines

However, at the same time, may be people would prefer that devices such as tegra, omap, at91, etc, offer their own xlate function for DMA engine. I am not sure, but we could go either way.

I'd expect the bindings to be written to allow the individual DMA controllers to have complete control over the meaning of the DMA specifier.

That said, I would certainly expect some common patterns to emerge, such as a single cell to specify the DMA channel ID, or a single cell to specify the DMA request/selector ID. We should certainly make sure that where different controllers need the same information, they use the same way to represent it, and use common utility code to implement the xlate functionality. We could perhaps even write these common cases into the core DMA bindings as examples to help ensure uniformity. However, we just need to do this in a way that allows other cases too.

author
#7 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Stephen,

Quoted 37 lines · Stephen Warren
Quoted 9 lines · Jon Hunter

Hi Stephen,

Quoted 6 lines · Stephen Warren
Quoted 5 lines · Jon Hunter

From: Jon Hunter <[email protected]>

This is based upon the work by Benoit Cousson [1] and Nicolas Ferre [2] to add some basic helpers to retrieve a DMA controller device_node and the DMA request/channel information.

...

Quoted 20 lines
Quoted 11 lines
Quoted 11 lines
Documentation/devicetree/bindings/dma/dma.txt new file +11 -0
+
+	sdma: dmaengine at 48000000 {
+		compatible = "ti,omap4-sdma"
+		reg = <0x48000000 0x1000>;
+		interrupts = <4>;
+		#dma-cells = <2>;
+		#dma-channels = <32>;
+		#dma-requests = <127>;
+	};
+
+
Quoted 8 lines

Documentation/devicetree/bindings/dma/dma.txt line 32

Quoted 4 lines
Documentation/devicetree/bindings/dma/dma.txt new file +4 -0
+* DMA client
+
+Client drivers should specify the DMA property using a phandle to the controller
+followed by the number of DMA request/channel and the transfer type of the

What exactly is "request/channel"? Is it a request ID, a channel ID, both packed into a single integer (which bits are used for each field), etc.?

Quoted 5 lines

The thought here was that some DMAs may distinguish between devices by a request ID or a channel ID or both. In the case of say an OMAP4, we have 32 channels and 127 request IDs. From a h/w perspective we need to know both. Each of the 32 channels can be programmed to use any one of the 127 h/w request signals.

Quoted 7 lines

From a HW perspective, do you actually need to know both? I think the HW description must specify the request ID, but because any channel can be programmed to any request ID, you don't actually care about the channel ID; it can be dynamically allocated by the DMA driver when the client driver calls dma_request_channel().

From the perspective of a driver using the DMA, no. However, I thought

that having the number of programmable channels stored in the device tree could be useful so that the DMA driver could query how many programmable channels are available. So my point was the DMA driver needs to know how many channels it has. However, this does not need to belong in the device tree. I added it for completeness of the DMA controller description really. Does that make sense?

Quoted 1 line

Actually, you say the following below, so I guess you already agree here:

Yes.

Quoted 15 lines
Quoted 3 lines

Yes this is the same as OMAPs SDMA. In the case of such DMA controllers you only really care about the request ID and total number of channels that are available to you.

...

Quoted 10 lines
Quoted 3 lines

This is why I think DMA controller should specify the format of their own DMA specifier in DT, and why they should provide an xlate function to parse that.

Ok fair enough. However, it seems that at a minimum we could provide one or two xlate functions in the generic binding for people to use. One could be the DMA engine xlate binding and another could be the simple xlate binding Nicolas proposed for a DMA controller that returns a single channel/request ID.

Quoted 6 lines
Quoted 3 lines

However, at the same time, may be people would prefer that devices such as tegra, omap, at91, etc, offer their own xlate function for DMA engine. I am not sure, but we could go either way.

I'd expect the bindings to be written to allow the individual DMA controllers to have complete control over the meaning of the DMA specifier.

Ok.

Quoted 8 lines

That said, I would certainly expect some common patterns to emerge, such as a single cell to specify the DMA channel ID, or a single cell to specify the DMA request/selector ID. We should certainly make sure that where different controllers need the same information, they use the same way to represent it, and use common utility code to implement the xlate functionality. We could perhaps even write these common cases into the core DMA bindings as examples to help ensure uniformity. However, we just need to do this in a way that allows other cases too.

Yes this makes sense. I could have a go at re-writing next week sometime.

Thanks
Jon

#8 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Jon Hunter
Quoted 6 lines · Jon Hunter

From: Jon Hunter <[email protected]>

This is based upon the work by Benoit Cousson [1] and Nicolas Ferre [2] to add some basic helpers to retrieve a DMA controller device_node and the DMA request/channel information.

Quoted 16 lines

Aim of DMA helpers
- The purpose of device-tree (as far as I understand), is to describe the ?capabilites of the hardware. Thinking about DMA controllers purely from the ?context of the hardware to begin with, we can describe a device in terms of ?a DMA controller as follows ...
? ? ? ?1. Number of DMA controllers
? ? ? ?2. Number of channels (maybe physical or logical)
? ? ? ?3. Mapping of DMA requests signals to DMA controller
? ? ? ?4. Number of DMA interrupts
? ? ? ?5. Mapping of DMA interrupts to channels
- With the above in mind the aim of the DT DMA helper functions is to extract ?the above information from the DT and provide to the appropriate driver. ?However, due to the vast number of DMA controllers and not all are using a ?common driver (such as DMA Engine) it has been seen that this is not a ?trivial task.

Sorry for being slow, but so far I thought DT is only to provide _h/w_ specific info
to the _controller_ drivers. It was not supposed to provide any info pertaining to
some API (dmaengine in this case).

And I believe this is one of few situations where we are better off not generalizing
the interface - pass controller specific info in the controller driver's specified format.
Generalizing only seems to complicate things here, when we anyway have machine specific dtb, which could always have clients requesting and the controllers given
dma's info in controller driver's specific format.

Perhaps I am overlooking the need to generalize. If you think so, please help me understand by pointing out some use case for it.

Thanks.

author
#9 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Jassi,

Quoted 38 lines · Jassi Brar
Quoted 6 lines · Jon Hunter

From: Jon Hunter <[email protected]>

This is based upon the work by Benoit Cousson [1] and Nicolas Ferre [2] to add some basic helpers to retrieve a DMA controller device_node and the DMA request/channel information.

Quoted 16 lines

Aim of DMA helpers
- The purpose of device-tree (as far as I understand), is to describe the capabilites of the hardware. Thinking about DMA controllers purely from the context of the hardware to begin with, we can describe a device in terms of a DMA controller as follows ...
1. Number of DMA controllers
2. Number of channels (maybe physical or logical)
3. Mapping of DMA requests signals to DMA controller
4. Number of DMA interrupts
5. Mapping of DMA interrupts to channels
- With the above in mind the aim of the DT DMA helper functions is to extract the above information from the DT and provide to the appropriate driver. However, due to the vast number of DMA controllers and not all are using a common driver (such as DMA Engine) it has been seen that this is not a trivial task.

Sorry for being slow, but so far I thought DT is only to provide _h/w_ specific info
to the _controller_ drivers. It was not supposed to provide any info pertaining to
some API (dmaengine in this case).

And I believe this is one of few situations where we are better off not generalizing
the interface - pass controller specific info in the controller driver's specified format.
Generalizing only seems to complicate things here, when we anyway have machine specific dtb, which could always have clients requesting and the controllers given
dma's info in controller driver's specific format.

Quoted 2 lines

Perhaps I am overlooking the need to generalize. If you think so, please help me understand by pointing out some use case for it.

No not really, your points are valid. From reading the previous discussions one of the items that was clearly lacking was the ability to represent and identify a device having more than one DMA controller. In other words, when you request the DMA resource, how do you identify which DMA controller in the system that resource belongs too. With DMA engine there are ways we can do this.

However, thinking about this now. Instead of passing specific DMA engine parameters to the register function may be we can pass a generic void * pointer with the information and completely abstract the binding from DMA engine. This is probably a better approach.

Cheers
Jon

#10 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 44 lines · Jon Hunter

Hi Jassi,

Quoted 38 lines · Jassi Brar
Quoted 6 lines · Jon Hunter

From: Jon Hunter <[email protected]>

This is based upon the work by Benoit Cousson [1] and Nicolas Ferre [2] to add some basic helpers to retrieve a DMA controller device_node and the DMA request/channel information.

Quoted 16 lines

Aim of DMA helpers
- The purpose of device-tree (as far as I understand), is to describe the ?capabilites of the hardware. Thinking about DMA controllers purely from the ?context of the hardware to begin with, we can describe a device in terms of ?a DMA controller as follows ...
? ? ? ?1. Number of DMA controllers
? ? ? ?2. Number of channels (maybe physical or logical)
? ? ? ?3. Mapping of DMA requests signals to DMA controller
? ? ? ?4. Number of DMA interrupts
? ? ? ?5. Mapping of DMA interrupts to channels
- With the above in mind the aim of the DT DMA helper functions is to extract ?the above information from the DT and provide to the appropriate driver. ?However, due to the vast number of DMA controllers and not all are using a ?common driver (such as DMA Engine) it has been seen that this is not a ?trivial task.

Sorry for being slow, but so far I thought DT is only to provide _h/w_ specific info
to the _controller_ drivers. It was not supposed to provide any info pertaining to
some API (dmaengine in this case).

And I believe this is one of few situations where we are better off not generalizing
the interface - pass controller specific info in the controller driver's specified format.
Generalizing only seems to complicate things here, when we anyway have machine specific dtb, which could always have clients requesting and the controllers given
dma's info in controller driver's specific format.

Quoted 2 lines

Perhaps I am overlooking the need to generalize. If you think so, please help me understand by pointing out some use case for it.

Quoted 7 lines

No not really, your points are valid. From reading the previous discussions one of the items that was clearly lacking was the ability to represent and identify a device having more than one DMA controller. In other words, when you request the DMA resource, how do you identify which DMA controller in the system that resource belongs too. With DMA engine there are ways we can do this.

Well, if we really can't have dmac drivers make 'intelligent' runtime decision of request mapping on more than one capable controllers, we still can make it simpler than the proposed scheme.

+ i2c1: i2c at 1 {

+               ...
+               dma = <&sdma 2 1 &sdma 3 2>;
+               ...

+ };

Quoted 1 line

I see this requires a client driver to specify a particular req_line on a particular dma controller. I am not sure if this is most optimal.

I think such client->req_line map should be provided to the dmac controller driver via its dt node in some format. The dmac driver could then populate a dma_chan, or similar, only for that req_line and not for the unused one which otherwise could also have served the same client.

Ideally the I2C driver should simply ask, say, a channel for TX and another for RX, everything else should already be setup via dmac's dt nodes.

Channel properties like duplex, priority etc specified in client's dt node doesn't seem really necessary - the client's driver is able to adjust according to the capability of the channel the dmaengine api is able to provide and the client driver can't really do anything if it saw "txrx" specified in it's dt node while it doesn't yet support full-duplex (say).

Having spilled my guts and realizing the fact that the Maradonas and Peles of the game seem to have already bought the scheme, I am afraid it only points to my not yet diagnosed adhd :o

#11 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 10 lines · Jassi Brar

I see this requires a client driver to specify a particular req_line on a particular dma controller. I am not sure if this is most optimal.

I think such client->req_line map should be provided to the dmac controller driver via its dt node in some format. The dmac driver could then populate a dma_chan, or similar, only for that req_line and not for the unused one which otherwise could also have served the same client.

Ideally the I2C driver should simply ask, say, a channel for TX and another for RX, everything else should already be setup via dmac's dt nodes.

If I understand you correctly, you think we can generalize the dma-request data in a way that we don't need to pass a specific dma engine phandle. I very much doubt this is possible, given how different the requirements are for each of the engines we support. You really need to pass a specific phandle so that we can find the code that can interpret the data in a meaningful way.

It would be nice though if we could support your scenario where multiple dma engines are available that can be used by a single client. I've already mentioned that I think we can provide multiple channel definitions and let the driver request each of them until one succeeds, but that does require extra code inside of each driver that might need to do this.
Another alternative would be to change the binding so that it can deal with multiple distinct dmaengine instances using a single device node.

Given the example from exynos5250.dtsi, which currently contains this fragment:

                pdma0: pdma at 121A0000 {
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x121A0000 0x1000>;
                        interrupts = <0 34 0>;
                };

                pdma1: pdma at 121B0000 {
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x121B0000 0x1000>;
                        interrupts = <0 35 0>;
                };

                mdma0: pdma at 10800000 {
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x10800000 0x1000>;
                        interrupts = <0 33 0>;
                };

                mdma1: pdma at 11C10000 {
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x11C10000 0x1000>;
                        interrupts = <0 124 0>;
                };

We could transform it into one node with multiple children:

	dma: dma-engines {
                compatible = "arm,pl330-multi", "arm,primecell";
		#dma-cells = <3>;
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;

                pdma at 121A0000 {
                        compatible = "arm,pl330", "arm,primecell";
			arm,pl330-instance = <0>;
                        reg = <0x121A0000 0x1000>;
                        interrupts = <0 34 0>;
                };

                pdma at 121B0000 {
                        compatible = "arm,pl330", "arm,primecell";
			arm,pl330-instance = <1>;
                        reg = <0x121B0000 0x1000>;
                        interrupts = <0 35 0>;
                };

                pdma at 10800000 {
                        compatible = "arm,pl330", "arm,primecell";
			arm,pl330-instance = <2>;
                        reg = <0x10800000 0x1000>;
                        interrupts = <0 33 0>;
                };

                pdma at 11C10000 {
                        compatible = "arm,pl330", "arm,primecell";
			arm,pl330-instance = <3>;
                        reg = <0x11C10000 0x1000>;
                        interrupts = <0 124 0>;
                };
	};

This way, a client would just point to the dma-engines device node that cover all of the actual engines, and the pl330 code registers the four devices with the dmaengine layer.

Arnd

#12 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 12 lines · Arnd Bergmann
Quoted 10 lines · Jassi Brar

I see this requires a client driver to specify a particular req_line on a particular dma controller. I am not sure if this is most optimal.

I think such client->req_line map should be provided to the dmac controller driver via its dt node in some format. The dmac driver could then populate a dma_chan, or similar, only for that req_line and not for the unused one which otherwise could also have served the same client.

Ideally the I2C driver should simply ask, say, a channel for TX and another for RX, everything else should already be setup via dmac's dt nodes.

Quoted 7 lines

If I understand you correctly, you think we can generalize the dma-request data in a way that we don't need to pass a specific dma engine phandle. I very much doubt this is possible, given how different the requirements are for each of the engines we support. You really need to pass a specific phandle so that we can find the code that can interpret the data in a meaningful way.

Hmm... there ought to be a way by which a client is handed a random 'token' via its dt node and similarly the dmac informed which channel (and with what capabilities) to allocate should it see a request coming with that token.

That way dmac and client drivers using DT could do away with the filter_fn.

Roughly speaking (I am not very well versed with DT syntax)

Client Node:-

mmc1: mmc at 13002000 {
...
dma_tx = <891> //some platform-wide unique value
dma_rx = <927> //some platform-wide unique value
...
};

Say the PL330 chapter of SoC's trm specifies that "channel_id" for MMC1_TX is 7 and MMC1_RX is 8 on second instance of PL330.

DMAC's Node:-

pdma2: pdma at 10800000 {
         .......
        dma_map = <891, 7>,       //Map mmc1_tx onto i/f 7
                              <927, 8>,      //Map mmc1_rx onto i/f 8
                              <487, 9>,      // Map other dma clients
                                    .......
};

The dma_map could also encode features like duplex, priority etc depending on the needs of the client and capability of the dmac. (The "channel_id" could very well be an composite value specifying more than one parameter.... basically a value private to the dmac driver)

As a positive side effect, the dmac controller could populate channels only for which some client exists on the machine.

Also the decision to map a client onto one of two or more supporting dmacs is made here - token 927 wouldn't appear in dma_map of pdma1 even if it also could do RX for MMC1.

The solution seems so simple that I am already cringing at the thought of having overlooked something fundamental. Please clarify :)

#13 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 20 lines · Jassi Brar
Quoted 12 lines · Arnd Bergmann
Quoted 10 lines · Jassi Brar

I see this requires a client driver to specify a particular req_line on a particular dma controller. I am not sure if this is most optimal.

I think such client->req_line map should be provided to the dmac controller driver via its dt node in some format. The dmac driver could then populate a dma_chan, or similar, only for that req_line and not for the unused one which otherwise could also have served the same client.

Ideally the I2C driver should simply ask, say, a channel for TX and another for RX, everything else should already be setup via dmac's dt nodes.

Quoted 7 lines

If I understand you correctly, you think we can generalize the dma-request data in a way that we don't need to pass a specific dma engine phandle. I very much doubt this is possible, given how different the requirements are for each of the engines we support. You really need to pass a specific phandle so that we can find the code that can interpret the data in a meaningful way.

Quoted 3 lines

Hmm... there ought to be a way by which a client is handed a random 'token' via its dt node and similarly the dmac informed which channel (and with what capabilities) to allocate should it see a request coming with that token.

I think that's the whole point of the patch.

However, the token needs to be some driver-specific struct, since the required information may be more than just a single channel or request ID in general.

Quoted 4 lines

That way dmac and client drivers using DT could do away with the filter_fn.

Roughly speaking (I am not very well versed with DT syntax)

Quoted 8 lines

Client Node:-

mmc1: mmc at 13002000 {
...
dma_tx = <891> //some platform-wide unique value
dma_rx = <927> //some platform-wide unique value
...
};

I believe we specifically don't want to introduce any global concept of DMA channel ID, either within the kernel, or at the device tree level.

While we do have global interrupt and GPIO IDs within the kernel, this has caused problems, I think primarily due to the need to manage this unified namespace and allocate a single global ID for a bunch of different ranges of controller-specific IDs.

Within device tree, everything is always represented as an ID relative-to or within a particular controller, so it's easy to namespace things separately.

#14 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 6 lines · Stephen Warren
Quoted 3 lines · Jassi Brar

Hmm... there ought to be a way by which a client is handed a random 'token' via its dt node and similarly the dmac informed which channel (and with what capabilities) to allocate should it see a request coming with that token.

Quoted 6 lines

I think that's the whole point of the patch.

However, the token needs to be some driver-specific struct, since the required information may be more than just a single channel or request ID in general.

Well, what I call 'token' could just as well be some numerical hash of what you call 'driver-specific struct'.
And I never thought we could do without h/w specific information, just that peculiarities lie with the dmac controllers and that's where the discerning should happen.

Our opinions differ in that, I believe client side shouldn't need to parse/decode the h/w specific parameters from data gotten via DT (what I call 'token' and you 'driver-specific struct') - because that is the key to having common client drivers working with different dma controllers. And yes, I don't think we could find a future proof generic and simple enough representation of dma resource specification in a DT node :)

Instead, I suggest we encode the finer details of each channel-request in node of the dma controller matched against the 'token' assigned to the respective clients. That encoding("channel_id") would be dma controller specific and if we also manage to contain it within fixed number of bytes we could also have common helpers for fetching it, though it still would need to be decoded by dmac controller driver - which I think we can't do without, considering the variety of dma floating around.

Quoted 13 lines
Quoted 4 lines

That way dmac and client drivers using DT could do away with the filter_fn.

Roughly speaking (I am not very well versed with DT syntax)

Quoted 8 lines

Client Node:-

mmc1: mmc at 13002000 {
? ? ? ? ...
? ? ? ? dma_tx = <891> ? //some platform-wide unique value ? ? ? ? dma_rx = <927> ? //some platform-wide unique value ? ? ? ? ...
?};

Quoted 3 lines

I believe we specifically don't want to introduce any global concept of DMA channel ID, either within the kernel, or at the device tree level.

I don't think these tokens have to be global.
They just need to be common for .dts that define client and dmac nodes
- which would usually be the same file. They just have to be unique across all dma clients on a given machine.

#15 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 19 lines · Jassi Brar
Quoted 6 lines · Stephen Warren
Quoted 3 lines · Jassi Brar

Hmm... there ought to be a way by which a client is handed a random 'token' via its dt node and similarly the dmac informed which channel (and with what capabilities) to allocate should it see a request coming with that token.

Quoted 6 lines

I think that's the whole point of the patch.

However, the token needs to be some driver-specific struct, since the required information may be more than just a single channel or request ID in general.

Well, what I call 'token' could just as well be some numerical hash of what you call 'driver-specific struct'.
And I never thought we could do without h/w specific information, just that peculiarities lie with the dmac controllers and that's where the discerning should happen.

Quoted 7 lines

Our opinions differ in that, I believe client side shouldn't need to parse/decode the h/w specific parameters from data gotten via DT (what I call 'token' and you 'driver-specific struct') - because that is the key to having common client drivers working with different dma controllers. And yes, I don't think we could find a future proof generic and simple enough representation of dma resource specification in a DT node :)

Yes, I don't believe that follows.

The data doesn't need to be part of the DMA controller node in order for the DMA controller driver to be the entity interpreting it.

In many existing DT bindings, the structure of the client's property is:

phandle specifier

... all possibly repeated n times if you need to represent n resources, like n interrupts, n GPIOs, n DMA channels/...)

... where specifier is some arbitrary sequence of cells, whose size and format are entirely determined by the driver for the node referred to by phandle.

The parsing of this whole construct is hidden inside some utility code, so clients simply call e.g. of_get_gpio(), which internally calls a function in the relevant GPIO driver (as specified by the phandle) to parse the specifier, and return whatever representation of that specifier is required for the client to either use directly (e.g. GPIO ID to pass to gpio_request()) or pass back to the relevant APIs for the driver's subsystem (e.g. complete possibly driver-specific DMA filter/data representation for dmaengine).

The advantage here is that:

* The specifier is stored in the client, not the IRQ/GPIO/DMA controller's node, so it's located right at the usage site, which typically makes working out what resources a client uses easier. This also keeps client-specific information out of the provider node, allowing it to be fully generic.

* The client doesn't know anything about the format of "specifier", since the provider driver parses it, so clients can still work with arbitrary providers of resources.

Quoted 3 lines

Instead, I suggest we encode the finer details of each channel-request in node of the dma controller matched against the 'token' assigned to the respective clients.

Well, I guess I addressed that above - there's no need for the data to be in the DMA controller node for the DMA controller driver to parse it.

Quoted 3 lines

That encoding("channel_id") would be dma
controller specific and if we also manage to contain it within fixed number of bytes we could also have common helpers for fetching it,

I don't think there's any need for it to fit into a fixed number of bytes; the parsing routine can simply return a pointer to a driver-specific structure (or perhaps a dmaengine-defined structure, which in turn might contain a pointer to a driver-specific structure). That would allow complete flexibility in the representation of the driver-specific data.

Quoted 3 lines

though
it still would need to be decoded by dmac controller driver - which I think we can't do without, considering the variety of dma floating around.

#16 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 4 lines · Stephen Warren

The data doesn't need to be part of the DMA controller node in order for the DMA controller driver to be the entity interpreting it.

I rather say, if the dma controller driver is the entity going to interpret the data, why not provide the data directly through its node at one go?

There is important difference between providing data via clients during runtime vs providing info about every client to the dmac driver at one go during its probe.

Quoted 7 lines

The advantage here is that:

* The specifier is stored in the client, not the IRQ/GPIO/DMA controller's node, so it's located right at the usage site, which typically makes working out what resources a client uses easier.

A client doesn't really need some n'th channel of some m'th dma controller. A client simply needs one channel for transmitting data whichever platform it be.
So {n,m}_channel isn't really a required resource, dma_tx is, which I still specify in the client's node.
The fact that this information is simply fwd by the client as such to the dmac
(via utility code), makes the ritual even more pointless.

Quoted 3 lines

This also keeps client-specific information out of the provider node, allowing it to be fully generic.

A typical Samsung SoC has 2 peripheral DMA controllers and
about 40 possible clients. Of which ~20 clients could be served by either of the two dmacs. Of course hardly ever a machine has 10 clients. It would be desirable if the dma driver doesn't populate the unused 54(32+32-10) channels,
presumably also reserving limited resources for each, on the machine.

Consider this example ...
A PL330 instance has 8 physical channels and 32 client i/f.
So only 8 client reqs could be active at any time.
PL330 doesn't provide a way to program a true LLI transfer(very useful for audio) using a single physical channel. However, we could emulate true LLI if we employ 2 physical channels for one audio channel request.

Obviously, if a machine had 7 or lesser clients, one would freely employ 2 physical channels for audio and yet not worry about starving other clients. How would we achieve this if the dmac driver was initialized as "fully generic" ?

Quoted 7 lines
Quoted 4 lines

That encoding("channel_id") would be dma
controller specific and if we also manage to contain it within fixed number of bytes we could also have common helpers for fetching it,

I don't think there's any need for it to fit into a fixed number of bytes

Yeah, I realized that soon after posting.

I think I have run out of ways to explain myself better. FWIW, I won't object to whatever mechanism folks decide after knowing my concerns.

Best Regards,
-Jassi

#17 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 11 lines · Jassi Brar
Quoted 4 lines · Stephen Warren

The data doesn't need to be part of the DMA controller node in order for the DMA controller driver to be the entity interpreting it.

I rather say, if the dma controller driver is the entity going to interpret the data, why not provide the data directly through its node at one go?

There is important difference between providing data via clients during runtime vs providing info about every client to the dmac driver at one go during its probe.

IMHO the important aspect is what that data contains. The dma engine device node should only describe what that device looks like in hardware, but not how it is being used. If you have two machines that have the same dma engine, but different devices attached to it, the only difference in the device tree ought to be in those devices, not in the parts that are common.

Quoted 10 lines
Quoted 6 lines
Quoted 3 lines

That encoding("channel_id") would be dma
controller specific and if we also manage to contain it within fixed number of bytes we could also have common helpers for fetching it,

I don't think there's any need for it to fit into a fixed number of bytes

Yeah, I realized that soon after posting.

I think I have run out of ways to explain myself better. FWIW, I won't object to whatever mechanism folks decide after knowing my concerns.

I think we should try hard to make it possible to describe your hardware correctly, but we don't need to optimize the syntax for that case if that means making the common case more complex. I'd rather make the common case simple and the exception possible using some extension.

Arnd

#18 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Jassi Brar
Quoted 11 lines · Jassi Brar
Quoted 4 lines · Stephen Warren

The data doesn't need to be part of the DMA controller node in order for the DMA controller driver to be the entity interpreting it.

I rather say, if the dma controller driver is the entity going to interpret the data, why not provide the data directly through its node at one go?

There is important difference between providing data via clients during runtime vs providing info about every client to the dmac driver at one go during its probe.

I certainly see that there is a difference.

I don't understand why it's an important difference; I think everything needs to be handled at run-time no matter what:

Just because there is information in the DT that "this client DT node uses this channel/request-ID/... of this DMA controller" doesn't mean that the driver for the client is going to be loaded, or that SW running on the system is going to cause that driver to actually be opened and do any DMA. As such, any resource allocation rules etc. must be evaluated only if/when a driver actually requests/uses a DMA channel, so having "all the information up front" doesn't seem like a theoretically possible thing anyway.

Very similar to this, in order to support your point that a given client could potentially use a channel from either of 2 different DMA controller instances, you don't know until run-time which controller will be used, so can't have up-front information in this scenario either, even if the DMA does actually take place.

Quoted 6 lines
Quoted 5 lines

The advantage here is that:

* The specifier is stored in the client, not the IRQ/GPIO/DMA controller's node, so it's located right at the usage site, which typically makes working out what resources a client uses easier.

Quoted 7 lines

A client doesn't really need some n'th channel of some m'th dma controller. A client simply needs one channel for transmitting data whichever platform it be.
So {n,m}_channel isn't really a required resource, dma_tx is, which I still specify in the client's node.
The fact that this information is simply fwd by the client as such to the dmac
(via utility code), makes the ritual even more pointless.

Ah, I see your point now.

To solve this, we would need to (optionally?) model the DMA request signal routing in the DT, so that one could explicitly model the 1:1 or 1:n situation.

And since a given DMA client might be able to use the services of 2 different DMA controllers, those controllers might not even be identical HW, and hence would potentially not have identical DMA bindings. So, that doesn't work; we really do need device-agnostic DMA bindings in order to support this while maintaining all features.

That all said, do we want to:

a) Have the DT specify exactly which controller a given client will use, i.e. pick a particular one even when multiple are possible in HW.

This is supported by the currently proposed bindings without issue; we just ignore the fact that the DT author could have connected the client to a different controller if they wanted.

b) Have the DT represent exactly what exists in HW, i.e. that the client's DMA request signal is routed to N places, and have the SW pick which to use at runtime.

You're obviously arguing for (b), and indeed that does seem more like a simple representation of the HW, rather than SW's use of HW, and so is indeed more appropriate.

Solving (b) seems to require something very roughly like:

dma-controller at 0 {
    compatible = "foo,dmac-xxx";
    dma-requests = <
		&client0 0 // DMAC req 0 is client0's 0th req output
		&client0 1
		&client1 0
		&client1 1
		&client2 0
		...>;
};
dma-controller at 1 {
    compatible = "bar,dmac-yyy";
    dma-requests = <
		// Supports some client modules, but not the same ones
		&client0 0
		&client1 0
		&client3 0
		...>;
};
client0: i2s {
    /* has 2 DMA request output signals: 0, 1 */
};
client1: spdif {
    /* has 2 DMA request signals: 0, 1 */
};
client2: foo {
    /* has 1 DMA request signal: 0 */
};
client3: bar {
    /* has 1 DMA request signal: 0 */
};

and then having the core DMA code have an API like:

channel = dma_request(clients_dma_req_output_id)

which looks in each DMA controller's dma-requests list for the client's phandle and matching dma_req_output_id.

Quoted 9 lines
Quoted 2 lines

This also keeps client-specific information out of the provider node, allowing it to be fully generic.

A typical Samsung SoC has 2 peripheral DMA controllers and
about 40 possible clients. Of which ~20 clients could be served by either of the two dmacs. Of course hardly ever a machine has 10 clients. It would be desirable if the dma driver doesn't populate the unused 54(32+32-10) channels,
presumably also reserving limited resources for each, on the machine.

Quoted 6 lines

Consider this example ...
A PL330 instance has 8 physical channels and 32 client i/f.
So only 8 client reqs could be active at any time.
PL330 doesn't provide a way to program a true LLI transfer(very useful for audio) using a single physical channel. However, we could emulate true LLI if we employ 2 physical channels for one audio channel request.

I'm not familiar with what LLI means. I assume it's when the HW can be programmed with 2 DMA requests, and automatically starts the second once the first has completed, without SW intervention or interrupt latency.

Quoted 4 lines

Obviously, if a machine had 7 or lesser clients, one would freely employ 2 physical channels for audio and yet not worry about starving other clients. How would we achieve this if the dmac driver was initialized as "fully generic" ?

Well, the DMA controller's binding could easily allow representation of "single-channel" v.s. "double-channel" by specifying just one ID or two IDs in the binding. It'd make the binding more complex, but it is possible.

#19 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 11 lines · Stephen Warren
Quoted 4 lines · Jassi Brar

There is important difference between providing data via clients during runtime vs providing info about every client to the dmac driver at one go during its probe.

I certainly see that there is a difference.

I don't understand why it's an important difference; I think everything needs to be handled at run-time no matter what:

Quoted 9 lines

Just because there is information in the DT that "this client DT node uses this channel/request-ID/... of this DMA controller" doesn't mean that the driver for the client is going to be loaded, or that SW running on the system is going to cause that driver to actually be opened and do any DMA. As such, any resource allocation rules etc. must be evaluated only if/when a driver actually requests/uses a DMA channel, so having "all the information up front" doesn't seem like a theoretically possible thing anyway.

One point is about 'qos' here.... something like bandwidth allocation. If the dmac driver knew up-front the max possible clients that could be active simultaneously, it could "divide the bandwidth" accordingly. Again, the example of PL330 employing 2physical channels for better service - LLI (you got it right), where even 1 physical channel would also have served only not as reliably. I believe there would be more such scenarios.

Another minor benefit could be that the dmac driver populate only as many "struct dma_chan" as there are actually clients on the machine (and this population has to be done during probe). It could mean ~8 instead of ~40 channels populated on a machine. Note, a PL330 dmac can have 32 channels, OMAP's has 128....

Most importantly, I just think it's a cleaner approach.

Quoted 6 lines

Very similar to this, in order to support your point that a given client could potentially use a channel from either of 2 different DMA controller instances, you don't know until run-time which controller will be used, so can't have up-front information in this scenario either, even if the DMA does actually take place.

Sorry, perhaps I wasn't clear enough.
A client sees _no_ difference between the two channels that could serve it. And it can't start using two, if two are available.
Client just needs one suitable channel on whichever dmac that might be. If the channel for a client is to be switched runtime, that decision should lie with the dmac driver, not the client. And I am not really after implementing that runtime decision support.

Quoted 39 lines

Solving (b) seems to require something very roughly like:

dma-controller at 0 {
? ?compatible = "foo,dmac-xxx";
? ?dma-requests = <
? ? ? ? ? ? ? ?&client0 0 // DMAC req 0 is client0's 0th req output ? ? ? ? ? ? ? ?&client0 1
? ? ? ? ? ? ? ?&client1 0
? ? ? ? ? ? ? ?&client1 1
? ? ? ? ? ? ? ?&client2 0
? ? ? ? ? ? ? ?...>;
};

dma-controller at 1 {
? ?compatible = "bar,dmac-yyy";
? ?dma-requests = <
? ? ? ? ? ? ? ?// Supports some client modules, but not the same ones ? ? ? ? ? ? ? ?&client0 0
? ? ? ? ? ? ? ?&client1 0
? ? ? ? ? ? ? ?&client3 0
? ? ? ? ? ? ? ?...>;
};

client0: i2s {
? ?/* has 2 DMA request output signals: 0, 1 */
};

client1: spdif {
? ?/* has 2 DMA request signals: 0, 1 */
};

client2: foo {
? ?/* has 1 DMA request signal: 0 */
};

client3: bar {
? ?/* has 1 DMA request signal: 0 */
};

Quoted 7 lines

and then having the core DMA code have an API like:

channel = dma_request(clients_dma_req_output_id)

which looks in each DMA controller's dma-requests list for the client's phandle and matching dma_req_output_id.

Almost what I proposed in my third post in this thread !!

The minor difference being, you use the {request-signal, phandle} pair to find the right channel, I used only 'token'.

Please note, with this method we specify info about every client at one go and via dmac's DT node - hence those benefits.

Also note that, a client's dma specifier becomes perfectly general and future-proof

   client1: spdif {
          dma_tx = <278>
          dma_rx = <723>
    };

otherwise the following representation

    client1: spdif {
               dma = <&sdma 2 1 &sdma 3 2>;
     };

could break with some weird dma setups (IIANW Russell already finds it wouldn't work for him).

I am arguing for (b) for the above mentioned reasons, and not because I want to have clients switching channels in runtime.

Thanks,
Jassi

#20 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 21 lines · Jassi Brar
Quoted 11 lines · Stephen Warren
Quoted 4 lines · Jassi Brar

There is important difference between providing data via clients during runtime vs providing info about every client to the dmac driver at one go during its probe.

I certainly see that there is a difference.

I don't understand why it's an important difference; I think everything needs to be handled at run-time no matter what:

Quoted 8 lines

Just because there is information in the DT that "this client DT node uses this channel/request-ID/... of this DMA controller" doesn't mean that the driver for the client is going to be loaded, or that SW running on the system is going to cause that driver to actually be opened and do any DMA. As such, any resource allocation rules etc. must be evaluated only if/when a driver actually requests/uses a DMA channel, so having "all the information up front" doesn't seem like a theoretically possible thing anyway.

Quoted 7 lines

One point is about 'qos' here.... something like bandwidth allocation. If the dmac driver knew up-front the max possible clients that could be active simultaneously, it could "divide the bandwidth" accordingly. Again, the example of PL330 employing 2physical channels for better service - LLI (you got it right), where even 1 physical channel would also have served only not as reliably. I believe there would be more such scenarios.

QoS seems like policy to me, whereas DT is more about describing the HW. Is DT the correct place to describe QoS policy?

I guess you are talking more about deriving policy from the description of HW, i.e. how many client described in DT. However, for some reason that seems dangerous to me; what if clients can be instantiated some other way?

Quoted 15 lines

Another minor benefit could be that the dmac driver populate only as many "struct dma_chan" as there are actually clients on the machine (and this population has to be done during probe). It could mean ~8 instead of ~40 channels populated on a machine. Note, a PL330 dmac can have 32 channels, OMAP's has 128....

Most importantly, I just think it's a cleaner approach.

Quoted 5 lines

Very similar to this, in order to support your point that a given client could potentially use a channel from either of 2 different DMA controller instances, you don't know until run-time which controller will be used, so can't have up-front information in this scenario either, even if the DMA does actually take place.

Quoted 7 lines

Sorry, perhaps I wasn't clear enough.
A client sees _no_ difference between the two channels that could serve it. And it can't start using two, if two are available.
Client just needs one suitable channel on whichever dmac that might be. If the channel for a client is to be switched runtime, that decision should lie with the dmac driver, not the client. And I am not really after implementing that runtime decision support.

Yes, I understood that point. The issue is:

For a 1:1 mapping (or 1:n mapping in HW with static selection specified in the DT) between DMA client and DMA controller, perhaps the controller can indeed make QoS decisions based on which (how many) clients are connected to it.

However, if a DMA client can be serviced by more than 1 DMA engine, and the decision as to which DMA engine to use occurs at run-time by the DMA driver core, rather than being statically configured in the DT, then the DMA controller drivers cannot know ahead of time which will be used, and hence cannot have the full information they need to make accurate QoS decisions ahead of time; they can only make these decisions at run-time when the DMA channels are actually opened.

So, I believe coupling any QoS decisions to DT content alone is not correct.

Quoted 39 lines
Quoted 39 lines

Solving (b) seems to require something very roughly like:

dma-controller at 0 {
   compatible = "foo,dmac-xxx";
   dma-requests = <
               &client0 0 // DMAC req 0 is client0's 0th req output
               &client0 1
               &client1 0
               &client1 1
               &client2 0
               ...>;
};
dma-controller at 1 {
   compatible = "bar,dmac-yyy";
   dma-requests = <
               // Supports some client modules, but not the same ones
               &client0 0
               &client1 0
               &client3 0
               ...>;
};
client0: i2s {
   /* has 2 DMA request output signals: 0, 1 */
};
client1: spdif {
   /* has 2 DMA request signals: 0, 1 */
};
client2: foo {
   /* has 1 DMA request signal: 0 */
};
client3: bar {
   /* has 1 DMA request signal: 0 */
};
Quoted 8 lines
Quoted 6 lines

and then having the core DMA code have an API like:

channel = dma_request(clients_dma_req_output_id)

which looks in each DMA controller's dma-requests list for the client's phandle and matching dma_req_output_id.

Almost what I proposed in my third post in this thread !!

Yes, looking back it's quite similar, but...

Quoted 2 lines

The minor difference being, you use the {request-signal, phandle} pair to find the right channel, I used only 'token'.

That's a pretty big difference, I think.

In your proposal, every token was globally unique (well, within the 1 DT file). I'd rather not see any more global numbering schemes.

As such, each token has to encode both some object that it's relative to, and some ID relative to that object.

In DT parlance, the encoding of the object would be a phandle.

Now, DMA requests are signals /from/ a DMA client to a DMA controller ("send more data please", or "pull more data please"). Hence, I assert that the phandle should refer to the DMA client, not the DMA controller.

Quoted 11 lines

Please note, with this method we specify info about every client at one go and via dmac's DT node - hence those benefits.

Also note that, a client's dma specifier becomes perfectly general and future-proof

   client1: spdif {
          dma_tx = <278>
          dma_rx = <723>
    };
Quoted 8 lines

otherwise the following representation

    client1: spdif {
               dma = <&sdma 2 1 &sdma 3 2>;
     };

could break with some weird dma setups (IIANW Russell already finds it wouldn't work for him).

To solve Russell's HW, we need some way of representing the mux directly in DT irrespective of how the DMA controller or DMA client specify what they're connected to. Anything else isn't representing the HW in DT.

Also, who knows how to control the mux? We need that to be fully general, and so the mux itself really needs some kind of driver which the DMA core or DMA controller can call into when the channel is allocated in order to set up the mux. Right now, Russell's driver calls in the a platform-/board-provided callback, but we should really architect a generic driver framework for this.

I'd propose something like the following to handle this:

dma-controller {
compatible = "foo,dmac-xxx";
dma-requests = <

		&dma_req_mux 0 // Perhaps RX is mux'd
		&client0 1 // But the 2 TX channels aren't
		&client1 1
		>;
};

The driver for this would somehow register with the DMA core, so that when the driver for e.g. I2S attempts to allocate a DMA channel, the DMA core knows to ask the mux driver to route the correct signal upstream to the DMA controller:

dma_req_mux: mux {
compatible = "foo,dma-req-mux";
dma-requests = <&client0 0 &client1 0>;
// A GPIO-based mux might use a regular GPIO binding for its control:
gpios = <&gpio 0 0>;
};

client0: i2s {
/* has 2 DMA request output signals: 0, 1 */
};

client1: spdif {
/* has 2 DMA request signals: 0, 1 */
};

#21 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 10 lines · Stephen Warren
Quoted 7 lines · Jassi Brar

One point is about 'qos' here.... something like bandwidth allocation. If the dmac driver knew up-front the max possible clients that could be active simultaneously, it could "divide the bandwidth" accordingly. Again, the example of PL330 employing 2physical channels for better service - LLI (you got it right), where even 1 physical channel would also have served only not as reliably. I believe there would be more such scenarios.

Quoted 6 lines

QoS seems like policy to me, whereas DT is more about describing the HW. Is DT the correct place to describe QoS policy?

I guess you are talking more about deriving policy from the description of HW, i.e. how many client described in DT.

Yeah, that's what I meant.

Quoted 3 lines

However, for some reason that seems dangerous to me; what if clients can be instantiated some other way?

The other way could be hotplug ?
Anyway in those machines every channel would be populated and dmac driver would always account for the all-ports-plugged case.

Quoted 11 lines

For a 1:1 mapping (or 1:n mapping in HW with static selection specified in the DT) between DMA client and DMA controller, perhaps the controller can indeed make QoS decisions based on which (how many) clients are connected to it.

However, if a DMA client can be serviced by more than 1 DMA engine, and the decision as to which DMA engine to use occurs at run-time by the DMA driver core, rather than being statically configured in the DT, then the DMA controller drivers cannot know ahead of time which will be used

I think the dmac driver would make use of the routing flexibility to sustain its 'qos', and not the other way around (decide qos based on which one of the two dmacs would provide a channel to a client in future).
Anyways, so far only Samsung SoCs seem to have that flexibility/redundancy and I have never had anyone asking for that runtime decision making.

Quoted 9 lines
Quoted 3 lines

The minor difference being, you use the {request-signal, phandle} pair to find the right channel, I used only 'token'.

That's a pretty big difference, I think.

In your proposal, every token was globally unique (well, within the 1 DT file). I'd rather not see any more global numbering schemes.

Probably my shallow experience, but "globally unique, within a file" sounds like an oxymoron :)
I think arbitrary numerical tokens are a reasonable price to pay for the robustness and simplicity they bring.

Quoted 5 lines

Now, DMA requests are signals /from/ a DMA client to a DMA controller ("send more data please", or "pull more data please"). Hence, I assert that the phandle should refer to the DMA client, not the DMA controller.

OK, though we may just want to convey information about the h/w setup from the s/w POV, rather than info to simulate the h/w ;) For ex, the dma api and controller drivers don't really care about the fact that the client's driver must set some bit to trigger operation, whereas some simulator would need to care about that.

Anyways, I am OK with whatever works well and make things simpler.

Quoted 22 lines
Quoted 9 lines

Also note that, a client's dma specifier becomes perfectly general and future-proof

? ?client1: spdif {
? ? ? ? ? dma_tx = <278>
? ? ? ? ? dma_rx = <723>
? ? };

Quoted 8 lines

otherwise the following representation

? ? client1: spdif {
? ? ? ? ? ? ? ?dma = <&sdma 2 1 &sdma 3 2>;
? ? ?};

could break with some weird dma setups (IIANW Russell already finds it wouldn't work for him).

To solve Russell's HW, we need some way of representing the mux directly in DT irrespective of how the DMA controller or DMA client specify what they're connected to. Anything else isn't representing the HW in DT.

Quoted 7 lines

Also, who knows how to control the mux? We need that to be fully general, and so the mux itself really needs some kind of driver which the DMA core or DMA controller can call into when the channel is allocated in order to set up the mux. Right now, Russell's driver calls in the a platform-/board-provided callback, but we should really architect a generic driver framework for this.

Well, I doubt if there would ever be enough such platforms to warrant a new generic framework. For now, I would leave that to be a matter between the dmac driver and its DT node.
Similarly let every dmac, being unique, require DT data in it's own custom format - I don't believe we can find a generic DT format for every kind of dmac that does exist or would exist. (For ex, you found a way for RMK's mux'ed req_lines, but what about assigning priorities to clients which is possible with PL08X dmacs but not most others?)

So, I would strive only to make clients' dma specifier generic.

Quoted 8 lines

client0: i2s {
/* has 2 DMA request output signals: 0, 1 */
};

client1: spdif {
/* has 2 DMA request signals: 0, 1 */
};

Do we also need to somehow tag these signals for the client to differentiate between TX and RX channel ?

#22 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 17 lines · Jassi Brar
Quoted 10 lines · Stephen Warren
Quoted 7 lines · Jassi Brar

One point is about 'qos' here.... something like bandwidth allocation. If the dmac driver knew up-front the max possible clients that could be active simultaneously, it could "divide the bandwidth" accordingly. Again, the example of PL330 employing 2physical channels for better service - LLI (you got it right), where even 1 physical channel would also have served only not as reliably. I believe there would be more such scenarios.

Quoted 5 lines

QoS seems like policy to me, whereas DT is more about describing the HW. Is DT the correct place to describe QoS policy?

I guess you are talking more about deriving policy from the description of HW, i.e. how many client described in DT.

Quoted 6 lines

Yeah, that's what I meant.

Quoted 2 lines

However, for some reason that seems dangerous to me; what if clients can be instantiated some other way?

The other way could be hotplug ?

Yes. Also, there's probably some mix of DT-driven and non-DT-driven instantiation during the transition to DT, although that's probably temporary.

Quoted 22 lines

Anyway in those machines every channel would be populated and dmac driver would always account for the all-ports-plugged case.

Quoted 9 lines

For a 1:1 mapping (or 1:n mapping in HW with static selection specified in the DT) between DMA client and DMA controller, perhaps the controller can indeed make QoS decisions based on which (how many) clients are connected to it.

However, if a DMA client can be serviced by more than 1 DMA engine, and the decision as to which DMA engine to use occurs at run-time by the DMA driver core, rather than being statically configured in the DT, then the DMA controller drivers cannot know ahead of time which will be used

I think the dmac driver would make use of the routing flexibility to sustain its 'qos', and not the other way around (decide qos based on which one of the two dmacs would provide a channel to a client in future).
Anyways, so far only Samsung SoCs seem to have that flexibility/redundancy and I have never had anyone asking for that runtime decision making.

Quoted 3 lines
Quoted 2 lines

The minor difference being, you use the {request-signal, phandle} pair to find the right channel, I used only 'token'.

Quoted 7 lines
Quoted 4 lines

That's a pretty big difference, I think.

In your proposal, every token was globally unique (well, within the 1 DT file). I'd rather not see any more global numbering schemes.

Probably my shallow experience, but "globally unique, within a file" sounds like an oxymoron :)

To the kernel, that one file describes everything it knows about the HW (except for probed information), so it's global:-) Aside from that, I've often seen the term "global" used relative to some specific scope.

Quoted 2 lines

I think arbitrary numerical tokens are a reasonable price to pay for the robustness and simplicity they bring.

I have to disagree here.

Using phandle+ID is almost as simple, and much more flexible. Global IDs have a number of disadvantages:

a) You have to somehow keep them unique. Even with just a single .dts file, that's going to be a little painful since there's no central table of these IDs.

What if the DT is composed of a bunch of chunks that represent pluggable boards, which may be mixed/matched together depending on what the user actually plugged in? Then, you have to be very careful to keep the n different files' numbering ranges segregated, or conflicts will occur.

b) Everything else in DT already uses phandle+ID, so doing the same thing would be much more familiar and consistent for DT users.

Quoted 6 lines
Quoted 3 lines

Now, DMA requests are signals /from/ a DMA client to a DMA controller ("send more data please", or "pull more data please"). Hence, I assert that the phandle should refer to the DMA client, not the DMA controller.

OK, though we may just want to convey information about the h/w setup from the s/w POV, rather than info to simulate the h/w ;)

DT is specifically about describing the HW from a HW perspective.

Quoted 38 lines

For ex, the dma api and controller drivers don't really care about the fact that the client's driver must set some bit to trigger operation, whereas some simulator would need to care about that.

Anyways, I am OK with whatever works well and make things simpler.

Quoted 21 lines
Quoted 8 lines

Also note that, a client's dma specifier becomes perfectly general and future-proof

   client1: spdif {
          dma_tx = <278>
          dma_rx = <723>
    };
Quoted 8 lines

otherwise the following representation

    client1: spdif {
               dma = <&sdma 2 1 &sdma 3 2>;
     };

could break with some weird dma setups (IIANW Russell already finds it wouldn't work for him).

To solve Russell's HW, we need some way of representing the mux directly in DT irrespective of how the DMA controller or DMA client specify what they're connected to. Anything else isn't representing the HW in DT.

Quoted 6 lines

Also, who knows how to control the mux? We need that to be fully general, and so the mux itself really needs some kind of driver which the DMA core or DMA controller can call into when the channel is allocated in order to set up the mux. Right now, Russell's driver calls in the a platform-/board-provided callback, but we should really architect a generic driver framework for this.

Well, I doubt if there would ever be enough such platforms to warrant a new generic framework. For now, I would leave that to be a matter between the dmac driver and its DT node.

Quoted 5 lines

Similarly let every dmac, being unique, require DT data in it's own custom format - I don't believe we can find a generic DT format for every kind of dmac that does exist or would exist. (For ex, you found a way for RMK's mux'ed req_lines, but what about assigning priorities to clients which is possible with PL08X dmacs but not most others?)

Good question. Again thought that sounds a little like policy, so perhaps should be negotiated at runtime rather than described in DT?

Quoted 6 lines

So, I would strive only to make clients' dma specifier generic.

Quoted 4 lines

client0: i2s {
/* has 2 DMA request output signals: 0, 1 */
};

Quoted 6 lines
Quoted 4 lines

client1: spdif {
/* has 2 DMA request signals: 0, 1 */
};

Do we also need to somehow tag these signals for the client to differentiate between TX and RX channel ?

Yes, the client's DT binding would certainly need to describe how many DMA request signals its HW generates, and give a unique ID to each. The driver would need to request a DMA channel for a specific one of its DMA requests.

#23 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 10 lines · Stephen Warren
Quoted 2 lines · Jassi Brar

I think arbitrary numerical tokens are a reasonable price to pay for the robustness and simplicity they bring.

I have to disagree here.

Using phandle+ID is almost as simple, and much more flexible. Global IDs have a number of disadvantages:

Quoted 9 lines

a) You have to somehow keep them unique. Even with just a single .dts file, that's going to be a little painful since there's no central table of these IDs.

What if the DT is composed of a bunch of chunks that represent pluggable boards, which may be mixed/matched together depending on what the user actually plugged in? Then, you have to be very careful to keep the n different files' numbering ranges segregated, or conflicts will occur.

You might want to revisit this point after working out the finer details of what you propose for a client's specifier :)

Quoted 5 lines
Quoted 5 lines

Well, I doubt if there would ever be enough such platforms to warrant a new generic framework. For now, I would leave that to be a matter between the dmac driver and its DT node.

Quoted 9 lines
Quoted 5 lines

Similarly let every dmac, being unique, require DT data in it's own custom format - I don't believe we can find a generic DT format for every kind of dmac that does exist or would exist. (For ex, you found a way for RMK's mux'ed req_lines, but what about assigning priorities to clients which is possible with PL08X dmacs but not most others?)

Good question. Again thought that sounds a little like policy, so perhaps should be negotiated at runtime rather than described in DT?

As much as we love everything to be runtime configurable, I am afraid it can't be. We can't add new calls to the dmaengine api for simply supporting specific features of various dmacs (priority in this case) Because that would mean ideally every client going through the mostly useless ritual of querying/setting those features and most dmacs just 'pretending' to support some, except for the rare ones that actually do. So as much as these sound like policy, they would usually be directly hardcoded via dt for the machine or deducted by the dmac driver.

Quoted 9 lines
Quoted 9 lines
Quoted 9 lines

client0: i2s {
? /* has 2 DMA request output signals: 0, 1 */
};

client1: spdif {
? /* has 2 DMA request signals: 0, 1 */
};

Quoted 8 lines
Quoted 2 lines

Do we also need to somehow tag these signals for the client to differentiate between TX and RX channel ?

Yes, the client's DT binding would certainly need to describe how many DMA request signals its HW generates, and give a unique ID to each. The driver would need to request a DMA channel for a specific one of its DMA requests.

Did I read "give a unique ID to each" correctly ?
Could you please take some time out to jot down an example of how a typical client's dma specifier should look.

FWIW, I think I can live with what you propose. Let us go for the kill.

Thanks.

#24 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 2 lines · Jassi Brar
Quoted 1 line · Stephen Warren

On 05/10/2012 01:59 PM, Jassi Brar wrote:

...

Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
Quoted 8 lines

client0: i2s {
/* has 2 DMA request output signals: 0, 1 */
};

client1: spdif {
/* has 2 DMA request signals: 0, 1 */
};

Do we also need to somehow tag these signals for the client to differentiate between TX and RX channel ?

Quoted 6 lines
Quoted 5 lines

Yes, the client's DT binding would certainly need to describe how many DMA request signals its HW generates, and give a unique ID to each. The driver would need to request a DMA channel for a specific one of its DMA requests.

Did I read "give a unique ID to each" correctly ?

It'd be unique relative to that individual device or DT node, not at any larger scope.

Quoted 2 lines

Could you please take some time out to jot down an example of how a typical client's dma specifier should look.

With this proposal, I'm not sure that the client DT node would need any DMA information at all, at least nothing that identifies which DMA controllers, channels, or requests are required to service this node/device's DMA requests - that routing information is all represented in the DMA controller itself.

(I think Arnd made the following point earlier in this thread):

If you did need to put any other information in DT, then that probably would go in the DMA client node, since it'd presumably be the same irrespective of which DMA controller got used. However, that information presumably wouldn't be needed in DT at all, since the driver would know it, since it'd be a facet of the HW.

Note: I'm thinking things like DMA physical address (presumably an offset from the reg property), DMA access size (presumably a fixed property of the HW), DMA burst size (presumably a property of the HW, although at least some HW can be programmed to raise the DMA request signal with a varying number of FIFO entries free, so not fixed), etc.

Quoted 1 line

FWIW, I think I can live with what you propose. Let us go for the kill.

#25 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 20 lines · Stephen Warren
Quoted 2 lines · Jassi Brar
Quoted 1 line · Stephen Warren

On 05/10/2012 01:59 PM, Jassi Brar wrote:

...

Quoted 16 lines
Quoted 16 lines
Quoted 10 lines
Quoted 8 lines

client0: i2s {
? /* has 2 DMA request output signals: 0, 1 */
};

client1: spdif {
? /* has 2 DMA request signals: 0, 1 */
};

Do we also need to somehow tag these signals for the client to differentiate between TX and RX channel ?

Yes, the client's DT binding would certainly need to describe how many DMA request signals its HW generates, and give a unique ID to each. The driver would need to request a DMA channel for a specific one of its DMA requests.

Quoted 5 lines
Quoted 1 line

Did I read "give a unique ID to each" correctly ?

It'd be unique relative to that individual device or DT node, not at any larger scope.

OK.

Quoted 17 lines
Quoted 2 lines

Could you please take some time out to jot down an example of how a typical client's dma specifier should look.

With this proposal, I'm not sure that the client DT node would need any DMA information at all, at least nothing that identifies which DMA controllers, channels, or requests are required to service this node/device's DMA requests - that routing information is all represented in the DMA controller itself.

(I think Arnd made the following point earlier in this thread):

If you did need to put any other information in DT, then that probably would go in the DMA client node, since it'd presumably be the same irrespective of which DMA controller got used. However, that information presumably wouldn't be needed in DT at all, since the driver would know it, since it'd be a facet of the HW.

Quoted 6 lines

Note: I'm thinking things like DMA physical address (presumably an offset from the reg property), DMA access size (presumably a fixed property of the HW), DMA burst size (presumably a property of the HW, although at least some HW can be programmed to raise the DMA request signal with a varying number of FIFO entries free, so not fixed), etc.

Yeah, neither did I think a client node should tell more than IDs of its channels
- which we now decide to simply mention in its binding.

How do I know if you or someone is interested in reworking the patchset or want me to give it a try?

Thanks,
Jassi

author
#26 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Jassi,

Quoted 51 lines · Jassi Brar
Quoted 20 lines · Stephen Warren
Quoted 2 lines · Jassi Brar
Quoted 1 line · Stephen Warren

On 05/10/2012 01:59 PM, Jassi Brar wrote:

...

Quoted 16 lines
Quoted 16 lines
Quoted 10 lines
Quoted 8 lines

client0: i2s {
/* has 2 DMA request output signals: 0, 1 */
};

client1: spdif {
/* has 2 DMA request signals: 0, 1 */
};

Do we also need to somehow tag these signals for the client to differentiate between TX and RX channel ?

Yes, the client's DT binding would certainly need to describe how many DMA request signals its HW generates, and give a unique ID to each. The driver would need to request a DMA channel for a specific one of its DMA requests.

Quoted 5 lines
Quoted 1 line

Did I read "give a unique ID to each" correctly ?

It'd be unique relative to that individual device or DT node, not at any larger scope.

OK.

Quoted 17 lines
Quoted 2 lines

Could you please take some time out to jot down an example of how a typical client's dma specifier should look.

With this proposal, I'm not sure that the client DT node would need any DMA information at all, at least nothing that identifies which DMA controllers, channels, or requests are required to service this node/device's DMA requests - that routing information is all represented in the DMA controller itself.

(I think Arnd made the following point earlier in this thread):

If you did need to put any other information in DT, then that probably would go in the DMA client node, since it'd presumably be the same irrespective of which DMA controller got used. However, that information presumably wouldn't be needed in DT at all, since the driver would know it, since it'd be a facet of the HW.

Quoted 6 lines

Note: I'm thinking things like DMA physical address (presumably an offset from the reg property), DMA access size (presumably a fixed property of the HW), DMA burst size (presumably a property of the HW, although at least some HW can be programmed to raise the DMA request signal with a varying number of FIFO entries free, so not fixed), etc.

Quoted 6 lines

Yeah, neither did I think a client node should tell more than IDs of its channels
- which we now decide to simply mention in its binding.

How do I know if you or someone is interested in reworking the patchset or want me to give it a try?

Sorry for not participating more in the discussion here, but I got tied up. I was planning on a V4 on the patch-set last week, but it did not happen. So I was planning for it this week. The V4 I had in mind was a more generic version of what I previously submitted, using xlate function to permit different DT tree formats. However, there would be a couple default xlate functions for people to use.

I am concerned that this implementation may not address all your concerns. So if you have something to propose then please feel free to do so.

By the way, what it unclear to me, if you have a client that could use more than one channel of multiple controllers, how is the handled? Who makes the decision on which to use?

The TI DMAs are somewhat inflexible and simple in this manner that you don't have a choice :-)

Cheers
Jon

#27 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Stephen Warren
Quoted 3 lines · Stephen Warren

To solve Russell's HW, we need some way of representing the mux directly in DT irrespective of how the DMA controller or DMA client specify what they're connected to. Anything else isn't representing the HW in DT.

Note that it's now no longer _just_ my hardware.

The Spear family of SoCs have a very similar setup - they mux the DMA request signals between the PL08x and their peripherals. It looks like each of the 16 DMA requests to the PL08x can be independently muxed between four possibilities via a common register.

See arch/arm/plat-spear/pl080.c in current arm-soc.

#28 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Stephen Warren
Quoted 13 lines · Stephen Warren
Quoted 4 lines

That way dmac and client drivers using DT could do away with the filter_fn.

Roughly speaking (I am not very well versed with DT syntax)

Quoted 8 lines

Client Node:-

mmc1: mmc at 13002000 {
...
dma_tx = <891> //some platform-wide unique value
dma_rx = <927> //some platform-wide unique value
...
};

Quoted 2 lines

I believe we specifically don't want to introduce any global concept of DMA channel ID, either within the kernel, or at the device tree level.

I agree.

Quoted 8 lines

While we do have global interrupt and GPIO IDs within the kernel, this has caused problems, I think primarily due to the need to manage this unified namespace and allocate a single global ID for a bunch of different ranges of controller-specific IDs.

Within device tree, everything is always represented as an ID relative-to or within a particular controller, so it's easy to namespace things separately.

Right. Note that strictly speaking the requirement is that everything is local to a particular namespace, which does not have to be the device controlling the property.

For instance, we can map interrupt numbers to different controllers using the interrupt-maps property. It is a fairly complex method, but something similar or a somewhat simpler method could be applied to define a namespace for dma controllers from which you can pick a request line.

The example I've given earlier does just that.

Arnd

author
#29 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Jassi Brar

Hi Jassi,

Quoted 62 lines · Jassi Brar
Quoted 44 lines · Jon Hunter

Hi Jassi,

Quoted 38 lines · Jassi Brar
Quoted 6 lines · Jon Hunter

From: Jon Hunter <[email protected]>

This is based upon the work by Benoit Cousson [1] and Nicolas Ferre [2] to add some basic helpers to retrieve a DMA controller device_node and the DMA request/channel information.

Quoted 16 lines

Aim of DMA helpers
- The purpose of device-tree (as far as I understand), is to describe the capabilites of the hardware. Thinking about DMA controllers purely from the context of the hardware to begin with, we can describe a device in terms of a DMA controller as follows ...
1. Number of DMA controllers
2. Number of channels (maybe physical or logical)
3. Mapping of DMA requests signals to DMA controller
4. Number of DMA interrupts
5. Mapping of DMA interrupts to channels
- With the above in mind the aim of the DT DMA helper functions is to extract the above information from the DT and provide to the appropriate driver. However, due to the vast number of DMA controllers and not all are using a common driver (such as DMA Engine) it has been seen that this is not a trivial task.

Sorry for being slow, but so far I thought DT is only to provide _h/w_ specific info
to the _controller_ drivers. It was not supposed to provide any info pertaining to
some API (dmaengine in this case).

And I believe this is one of few situations where we are better off not generalizing
the interface - pass controller specific info in the controller driver's specified format.
Generalizing only seems to complicate things here, when we anyway have machine specific dtb, which could always have clients requesting and the controllers given
dma's info in controller driver's specific format.

Quoted 2 lines

Perhaps I am overlooking the need to generalize. If you think so, please help me understand by pointing out some use case for it.

Quoted 7 lines

No not really, your points are valid. From reading the previous discussions one of the items that was clearly lacking was the ability to represent and identify a device having more than one DMA controller. In other words, when you request the DMA resource, how do you identify which DMA controller in the system that resource belongs too. With DMA engine there are ways we can do this.

Well, if we really can't have dmac drivers make 'intelligent' runtime decision of request mapping on more than one capable controllers, we still can make it simpler than the proposed scheme.

Documentation/devicetree/bindings/dma/dma.txt new file +5 -0
+       i2c1: i2c at 1 {
+               ...
+               dma = <&sdma 2 1 &sdma 3 2>;
+               ...
+       };
Quoted 1 line
Quoted 2 lines

I see this requires a client driver to specify a particular req_line on a particular dma controller. I am not sure if this is most optimal.

Actually, no. The phandle in the DT specifies the DMA controller to use. Then the client simply asks for a channel with a particular property, for example, DMA_MEM_TO_DEV (ie. TX) and the channel information is return.

Quoted 7 lines

I think such client->req_line map should be provided to the dmac controller driver via its dt node in some format. The dmac driver could then populate a dma_chan, or similar, only for that req_line and not for the unused one which otherwise could also have served the same client.

Ideally the I2C driver should simply ask, say, a channel for TX and another for RX, everything else should already be setup via dmac's dt nodes.

Yes that is the intention here.

Cheers
Jon

#30 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Jon,

Quoted 8 lines · Jon Hunter
Quoted 7 lines · Jassi Brar

+ ? ? ? i2c1: i2c at 1 {
+ ? ? ? ? ? ? ? ...
+ ? ? ? ? ? ? ? dma = <&sdma 2 1 &sdma 3 2>;
+ ? ? ? ? ? ? ? ...
+ ? ? ? };

Quoted 1 line
Quoted 7 lines
Quoted 2 lines

I see this requires a client driver to specify a particular req_line on a particular dma controller. I am not sure if this is most optimal.

Actually, no. The phandle in the DT specifies the DMA controller to use. Then the client simply asks for a channel with a particular property, for example, DMA_MEM_TO_DEV (ie. TX) and the channel information is return.

See below.

Quoted 10 lines
Quoted 7 lines

I think such client->req_line map should be provided to the dmac controller driver via its dt node in some format. The dmac driver could then populate a dma_chan, or similar, only for that req_line and not for the unused one which otherwise could also have served the same client.

Ideally the I2C driver should simply ask, say, a channel for TX and another for RX, everything else should already be setup via dmac's dt nodes.

Yes that is the intention here.

But the client is required to specify the dmac that would serve it. Which is more
than simply asking for "some suitable channel".

If you read the whole exchange between I and Stephen, we converged on a scheme of clients' node having nothing to specify and DMAC told all about every client in one palce. Which resembles closer to reality and is much simpler.
I already started on a patchset and should be able submit for review in a day or two.

author
#31 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Jassi,

Quoted 25 lines · Jassi Brar

Hi Jon,

Quoted 8 lines · Jon Hunter
Quoted 7 lines · Jassi Brar
Documentation/devicetree/bindings/dma/dma.txt new file +5 -0
+       i2c1: i2c at 1 {
+               ...
+               dma = <&sdma 2 1 &sdma 3 2>;
+               ...
+       };
Quoted 1 line
Quoted 7 lines
Quoted 2 lines

I see this requires a client driver to specify a particular req_line on a particular dma controller. I am not sure if this is most optimal.

Actually, no. The phandle in the DT specifies the DMA controller to use. Then the client simply asks for a channel with a particular property, for example, DMA_MEM_TO_DEV (ie. TX) and the channel information is return.

See below.

Quoted 5 lines
Quoted 5 lines

I think such client->req_line map should be provided to the dmac controller driver via its dt node in some format. The dmac driver could then populate a dma_chan, or similar, only for that req_line and not for the unused one which otherwise could also have served the same client.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Ideally the I2C driver should simply ask, say, a channel for TX and another for RX, everything else should already be setup via dmac's dt nodes.

Yes that is the intention here.

But the client is required to specify the dmac that would serve it. Which is more
than simply asking for "some suitable channel".

No this is not the case with what I propose. The client knows nothing about the dmac.

Quoted 6 lines

If you read the whole exchange between I and Stephen, we converged on a scheme of clients' node having nothing to specify and DMAC told all about every client in one palce. Which resembles closer to reality and is much simpler.
I already started on a patchset and should be able submit for review in a day or two.

Ok. I look forward to your implementation :-)

Jon

#32 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 31 lines · Jon Hunter

Hi Jassi,

Quoted 28 lines · Jassi Brar

Hi Jon,

Quoted 8 lines · Jon Hunter
Quoted 7 lines · Jassi Brar
(quoted diff) +5 -0
+       i2c1: i2c at 1 {
+               ...
+               dma = <&sdma 2 1 &sdma 3 2>;
+               ...
+       };
Quoted 1 line
Quoted 7 lines
Quoted 2 lines

I see this requires a client driver to specify a particular req_line on a particular dma controller. I am not sure if this is most optimal.

Actually, no. The phandle in the DT specifies the DMA controller to use. Then the client simply asks for a channel with a particular property, for example, DMA_MEM_TO_DEV (ie. TX) and the channel information is return.

See below.

Quoted 8 lines
Quoted 7 lines

I think such client->req_line map should be provided to the dmac controller driver via its dt node in some format. The dmac driver could then populate a dma_chan, or similar, only for that req_line and not for the unused one which otherwise could also have served the same client.

Ideally the I2C driver should simply ask, say, a channel for TX and another for RX, everything else should already be setup via dmac's dt nodes.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Yes that is the intention here.

But the client is required to specify the dmac that would serve it. Which is more
than simply asking for "some suitable channel".

No this is not the case with what I propose. The client knows nothing about the dmac.

I think you're both talking about slightly different things.

Jon: You're talking about the driver code.
Jassi: You're talking about the device tree.

By including a property in the DMA client's DT node that describes which DMA controller services it, the device (the DT node) "knows" about the DMA controllers.

By moving the information to the DMA controller and specifying which DMA clients can be serviced, that DMA client DT node no longer contains any information about the DMA controller that serves it, and hence it's not bound to a single controller, and hence can select from 1 of n controllers at run-time if applicable given the HW.

Either way, the DMA client driver is just going to call some DMA channel request API, and hence not know anything directly about the DMA controller.

author
#33 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 38 lines · Stephen Warren
Quoted 37 lines · Jon Hunter

Hi Jassi,

Quoted 33 lines · Jassi Brar

Hi Jon,

Quoted 8 lines · Jon Hunter
Quoted 7 lines · Jassi Brar
(quoted diff) +5 -0
+       i2c1: i2c at 1 {
+               ...
+               dma = <&sdma 2 1 &sdma 3 2>;
+               ...
+       };
Quoted 1 line
Quoted 7 lines
Quoted 2 lines

I see this requires a client driver to specify a particular req_line on a particular dma controller. I am not sure if this is most optimal.

Actually, no. The phandle in the DT specifies the DMA controller to use. Then the client simply asks for a channel with a particular property, for example, DMA_MEM_TO_DEV (ie. TX) and the channel information is return.

See below.

Quoted 10 lines
Quoted 7 lines

I think such client->req_line map should be provided to the dmac controller driver via its dt node in some format. The dmac driver could then populate a dma_chan, or similar, only for that req_line and not for the unused one which otherwise could also have served the same client.

Ideally the I2C driver should simply ask, say, a channel for TX and another for RX, everything else should already be setup via dmac's dt nodes.

Yes that is the intention here.

But the client is required to specify the dmac that would serve it. Which is more
than simply asking for "some suitable channel".

Quoted 7 lines
Quoted 2 lines

No this is not the case with what I propose. The client knows nothing about the dmac.

I think you're both talking about slightly different things.

Jon: You're talking about the driver code.
Jassi: You're talking about the device tree.

Yes you are right. However, I do see Jassi's point now.

Quoted 9 lines

By including a property in the DMA client's DT node that describes which DMA controller services it, the device (the DT node) "knows" about the DMA controllers.

By moving the information to the DMA controller and specifying which DMA clients can be serviced, that DMA client DT node no longer contains any information about the DMA controller that serves it, and hence it's not bound to a single controller, and hence can select from 1 of n controllers at run-time if applicable given the HW.

Yes I see the need for this. My concern (and I just sent another follow-up) was how readable is the device-tree for a human by using such a token. Is it intuitive enough for a human to understand the options available.

Cheers
Jon

author
#34 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Jon Hunter
Quoted 31 lines · Jon Hunter

Hi Jassi,

Quoted 28 lines · Jassi Brar

Hi Jon,

Quoted 8 lines · Jon Hunter
Quoted 7 lines · Jassi Brar
(quoted diff) +5 -0
+       i2c1: i2c at 1 {
+               ...
+               dma = <&sdma 2 1 &sdma 3 2>;
+               ...
+       };
Quoted 1 line
Quoted 7 lines
Quoted 2 lines

I see this requires a client driver to specify a particular req_line on a particular dma controller. I am not sure if this is most optimal.

Actually, no. The phandle in the DT specifies the DMA controller to use. Then the client simply asks for a channel with a particular property, for example, DMA_MEM_TO_DEV (ie. TX) and the channel information is return.

See below.

Quoted 8 lines
Quoted 7 lines

I think such client->req_line map should be provided to the dmac controller driver via its dt node in some format. The dmac driver could then populate a dma_chan, or similar, only for that req_line and not for the unused one which otherwise could also have served the same client.

Ideally the I2C driver should simply ask, say, a channel for TX and another for RX, everything else should already be setup via dmac's dt nodes.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Yes that is the intention here.

But the client is required to specify the dmac that would serve it. Which is more
than simply asking for "some suitable channel".

No this is not the case with what I propose. The client knows nothing about the dmac.

By the way, I do see your point. You wish to describe the all the mappings available to all dma controllers and then set a mapping in the device tree. Where as I am simply setting a mapping and do not list all other possibilities (assuming that there some).

What is still unclear to me, is if you use this token approach how readable is the device-tree? For example, if you have a client that can use one of two dmac and for each dmac the request/channel number is different, then by using a global token how can I determine what the options available for this client are?

Take your example ...

mmc1: mmc at 13002000 {
...
dma_tx = <891> //some platform-wide unique value
dma_rx = <927> //some platform-wide unique value
...
};

DMAC's Node:-

pdma2: pdma at 10800000 {
         .......
	dma_map = <891, 7>,       // Map mmc1_tx onto i/f 7
		  <927, 8>,       // Map mmc1_rx onto i/f 8
	.......
};

But now I have another dmac which has the following options ...

pdma1: pdma at 10000000 {
         .......
	dma_map = <598, 2>,       // Map mmc1_tx onto i/f 2
		  <230, 3>,       // Map mmc1_rx onto i/f 3
	.......
};

Other than using a comment or yet another token to represent the client, it is not clear from the arbitrary token value itself what my options are.

One way around this would be to have an enable/disable flag along with the token such as ...

mmc1: mmc at 13002000 {
        ...
        dma_tx = <891, 1>   // default tx channel
        dma_rx = <927, 1>   // default rx channel
        dma_tx = <598, 0>   // other available tx channel
        dma_rx = <230, 0>   // other available rx channel
        ...
};

That being said, we could take the same approach with using the dmac phandle instead of the token. So you would have ...

mmc1: mmc at 13002000 {
...
// phandle + channel + enable/disable
dma_tx = <pdma0, 7, 1> // default tx channel
dma_rx = <pdma0, 8, 1> // default rx channel
dma_tx = <pdma1, 2, 0> // other available tx channel
dma_rx = <pdma1, 3, 0> // other available rx channel
...
};

Then you could eliminate the random token and dma map from the dmac. Seems easier to read too.

Cheers
Jon

#35 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

On 05/16/2012 10:01 AM, Jon Hunter wrote:
...

Quoted 11 lines

By the way, I do see your point. You wish to describe the all the mappings available to all dma controllers and then set a mapping in the device tree. Where as I am simply setting a mapping and do not list all other possibilities (assuming that there some).

What is still unclear to me, is if you use this token approach how readable is the device-tree? For example, if you have a client that can use one of two dmac and for each dmac the request/channel number is different, then by using a global token how can I determine what the options available for this client are?

Quoted 8 lines

Take your example ...

mmc1: mmc at 13002000 {
...
dma_tx = <891> //some platform-wide unique value
dma_rx = <927> //some platform-wide unique value
...
};

I believe those properties (in the DMA client) should be completely omitted; there's no need for them.

Also, we definitely should not be using "some platform-wide unique value", but rather the phandle of the DMA client, plus some client-defined client channel ID. ...

(oh, and - rather than _ is idiomatic for DT property names)

Quoted 8 lines

DMAC's Node:-

pdma2: pdma at 10800000 {
         .......
	dma_map = <891, 7>,       // Map mmc1_tx onto i/f 7
		  <927, 8>,       // Map mmc1_rx onto i/f 8
	.......
};

So this would become:

pdma2: pdma at 10800000 {
	.......
	dma-map =
		... entries for channels 0.. 6
		<&mmc1, 0>,       // Map mmc1_tx onto i/f 7
		<&mmc1, 1>,       // Map mmc1_rx onto i/f 8
		... ;
	.......
};

This (a) follows existing DT practice of using phandle + specifier, and
(b) makes it easy to know exactly what clients you're talking about, since all you need to do is search for the label "mmc1" throughout the DT.

Quoted 8 lines

But now I have another dmac which has the following options ...

pdma1: pdma at 10000000 {
         .......
	dma_map = <598, 2>,       // Map mmc1_tx onto i/f 2
		  <230, 3>,       // Map mmc1_rx onto i/f 3
	.......
};

Which would become something very similar:

pdma1: pdma at 10000000 {
	.......
	dma-map =
		... entries for channels 0.. 1
		<&mmc1, 0>,       // Map mmc1_tx onto i/f 2
		<&mmc1, 1>,       // Map mmc1_rx onto i/f 3
		... ;
	.......
};

Note that dma-map here is describing the list of DMA requests that the DMA controller knows about. As far as the binding goes, these are irrelevant to channels; only the driver for the DMAC knows whether it needs to use a specific channel ID to service a particular DMA request signal, or not.

Quoted 31 lines

Other than using a comment or yet another token to represent the client, it is not clear from the arbitrary token value itself what my options are.

One way around this would be to have an enable/disable flag along with the token such as ...

mmc1: mmc at 13002000 {
        ...
        dma_tx = <891, 1>   // default tx channel
        dma_rx = <927, 1>   // default rx channel
        dma_tx = <598, 0>   // other available tx channel
        dma_rx = <230, 0>   // other available rx channel
        ...
};

That being said, we could take the same approach with using the dmac phandle instead of the token. So you would have ...

mmc1: mmc at 13002000 {
...
// phandle + channel + enable/disable
dma_tx = <pdma0, 7, 1> // default tx channel
dma_rx = <pdma0, 8, 1> // default rx channel
dma_tx = <pdma1, 2, 0> // other available tx channel
dma_rx = <pdma1, 3, 0> // other available rx channel
...
};

Then you could eliminate the random token and dma map from the dmac. Seems easier to read too.

#36 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 77 lines · Stephen Warren

On 05/16/2012 10:01 AM, Jon Hunter wrote:
...

Quoted 11 lines

By the way, I do see your point. You wish to describe the all the mappings available to all dma controllers and then set a mapping in the device tree. Where as I am simply setting a mapping and do not list all other possibilities (assuming that there some).

What is still unclear to me, is if you use this token approach how readable is the device-tree? For example, if you have a client that can use one of two dmac and for each dmac the request/channel number is different, then by using a global token how can I determine what the options available for this client are?

Quoted 8 lines

Take your example ...

mmc1: mmc at 13002000 {
? ? ? ? ...
? ? ? ? dma_tx = <891> ? //some platform-wide unique value ? ? ? ? dma_rx = <927> ? //some platform-wide unique value ? ? ? ? ...
};

I believe those properties (in the DMA client) should be completely omitted; there's no need for them.

Also, we definitely should not be using "some platform-wide unique value", but rather the phandle of the DMA client, plus some client-defined client channel ID. ...

(oh, and - rather than _ is idiomatic for DT property names)

Quoted 8 lines

DMAC's Node:-

pdma2: pdma at 10800000 {
? ? ? ? ?.......
? ? ? dma_map = <891, 7>, ? ? ? // Map mmc1_tx onto i/f 7 ? ? ? ? ? ? ? ? <927, 8>, ? ? ? // Map mmc1_rx onto i/f 8 ? ? ? .......
};

So this would become:

pdma2: pdma at 10800000 {
? ? ? ?.......
? ? ? ?dma-map =
? ? ? ? ? ? ? ?... entries for channels 0.. 6
? ? ? ? ? ? ? ?<&mmc1, 0>, ? ? ? // Map mmc1_tx onto i/f 7 ? ? ? ? ? ? ? ?<&mmc1, 1>, ? ? ? // Map mmc1_rx onto i/f 8 ? ? ? ? ? ? ? ?... ;
? ? ? ?.......
};

This (a) follows existing DT practice of using phandle + specifier, and
(b) makes it easy to know exactly what clients you're talking about, since all you need to do is search for the label "mmc1" throughout the DT.

Quoted 8 lines

But now I have another dmac which has the following options ...

pdma1: pdma at 10000000 {
? ? ? ? ?.......
? ? ? dma_map = <598, 2>, ? ? ? // Map mmc1_tx onto i/f 2 ? ? ? ? ? ? ? ? <230, 3>, ? ? ? // Map mmc1_rx onto i/f 3 ? ? ? .......
};

Which would become something very similar:

pdma1: pdma at 10000000 {
? ? ? ?.......
? ? ? ?dma-map =
? ? ? ? ? ? ? ?... entries for channels 0.. 1
? ? ? ? ? ? ? ?<&mmc1, 0>, ? ? ? // Map mmc1_tx onto i/f 2 ? ? ? ? ? ? ? ?<&mmc1, 1>, ? ? ? // Map mmc1_rx onto i/f 3 ? ? ? ? ? ? ? ?... ;
? ? ? ?.......
};

Quoted 6 lines

Note that dma-map here is describing the list of DMA requests that the DMA controller knows about. As far as the binding goes, these are irrelevant to channels; only the driver for the DMAC knows whether it needs to use a specific channel ID to service a particular DMA request signal, or not.

OK, my guts feel people might be interested in what's cooking on my side. I started with the binding text first and then would write code based upon that approach.

The following might be tweaked as I look deeper into client and DMAC drivers while deciding upon what the helper functions should be optimally...

-------------------- 8< --------------------

Generic binding to provide a way to provide the client-channel map and other dmac specific parameters to the dma controller driver

DMA Model:-
Only the most common characteristics of a dma setup are assumed
in this binding.
Client: Some h/w controller that could request a DMA controller in the system to perform data transfer on its behalf. Example SPI, MMC, I2S etc.
DMAC: A DMA Controller instance. Example, PL330, PL08X, SDMA etc.

The assumed model of the DMAC, in this binding, has P peripheral
interfaces (P request signals) that could request a data transfer and C physical channels that actually do the data transfers, hence, at most C out of P peripherals could be served by the DMAC at any point of time. Usually C := P, but not always. Usually, any of the physical channels could be employed by the DMAC driver to serve any client.
The DMAC driver identifies a client by its i/f number, 'peri_id'
on the given DMAC. For example, TX for SPI has 7th while RX_TX (half-duplex) for MMC has 10th peripheral interface (request-signal) on a given DMAC. Usually, any of the physical channels could be employed by the DMAC driver to serve a client.

* DMA Controller

Required property:

- #map-cells: Number of elements in each chan-map entry. At least 3 elements are required by this binding.

- chan-map: List of entries that specify clients' 'peri_id'. and also possibly DMAC specific per-client data. The first element of each entry being the client's phandle. The second the direction of data transfer w.r.t the client 1 for RX, 2 for TX and 3 for RX|TX. The third the 'peri_id' of the client's request signal on the DMAC.

Optional properties:

- #dma-peri-ifs: P, usually the DMAC driver would simply assume the number of entries in the 'chan-map' property to be the effective number of peripheral request interfaces on the DMAC. If specified, it should be at least the number of entries in the 'chan-map' property.

- #dma-channels: C, if specified, it should neither be more than the value of 'dma-peri-ifs' nor equal to zero.
If unspecified, it is assumed to be equal to the value of
'dma-peri-ifs', i.e, C := P

- #private-data: Peculiarities of the DMAC setup, not taken into account by this generic model. The decoding of it would be private to the DMAC's driver. For ex, some DMAC drivers for dmaengine would specify dma_cap_mask_t for the DMAC, if they don't need to specify it on a per-client basis (i.e, via 4th element of a 'chan-map' entry).

Example:

	dma-controller@0 {
		compatible = "foo,dmac-xxx";
		#private-data = <0x80808080>;
		#dma-peri-ifs = <32>;
		#dma-channels = <8>;
		#map-cells = <3>;
		chan-map =
			<&i2s1 1 2>,     /* peri_id of I2S's RX is 2 */
			<&i2s1 2 3>,     /* peri_id of I2S's TX is 3 */
			<&mmc1 3 5>,  /* peri_id of MMC's RX_TX is 5 */
			<&spi1 1 6>,
			<&spi1 2 8>,
			...;
	};

* Client Controller

Required property: None.
The client's DT node doesn't need any DMA specifier. Typically it would only comment about the data transfer direction associated with each of its request signal. Preferably also mentioned in the binding.

Optional property: None.

Example:

	i2s1: i2s at 70002800 {
	/* This controller has a request-signal for TX and RX each
	 * i.e, the driver is going to request a channel for RX(1)
	 * and another for TX(2).
	 */
		...
	};

	mmc1: mmci at 05000 {
	/* This controller has only one request-signal which is
	 * common for TX and RX (3), i.e, the mmci driver is
	 * going to request a channel with half-duplex capability.
	 */
		...
	};

---------------------- >8------------------

author
#37 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

On 05/16/2012 11:22 AM, Jassi Brar wrote:

[...]

Quoted 89 lines

OK, my guts feel people might be interested in what's cooking on my side. I started with the binding text first and then would write code based upon that approach.

The following might be tweaked as I look deeper into client and DMAC drivers while deciding upon what the helper functions should be optimally...

-------------------- 8< --------------------

Generic binding to provide a way to provide the client-channel map and other dmac specific parameters to the dma controller driver

DMA Model:-
Only the most common characteristics of a dma setup are assumed
in this binding.
Client: Some h/w controller that could request a DMA controller in the system to perform data transfer on its behalf. Example SPI, MMC, I2S etc.
DMAC: A DMA Controller instance. Example, PL330, PL08X, SDMA etc.

The assumed model of the DMAC, in this binding, has P peripheral
interfaces (P request signals) that could request a data transfer and C physical channels that actually do the data transfers, hence, at most C out of P peripherals could be served by the DMAC at any point of time. Usually C := P, but not always. Usually, any of the physical channels could be employed by the DMAC driver to serve any client.
The DMAC driver identifies a client by its i/f number, 'peri_id'
on the given DMAC. For example, TX for SPI has 7th while RX_TX (half-duplex) for MMC has 10th peripheral interface (request-signal) on a given DMAC. Usually, any of the physical channels could be employed by the DMAC driver to serve a client.

* DMA Controller

Required property:

- #map-cells: Number of elements in each chan-map entry. At least 3 elements are required by this binding.

- chan-map: List of entries that specify clients' 'peri_id'. and also possibly DMAC specific per-client data. The first element of each entry being the client's phandle. The second the direction of data transfer w.r.t the client 1 for RX, 2 for TX and 3 for RX|TX. The third the 'peri_id' of the client's request signal on the DMAC.

Optional properties:

- #dma-peri-ifs: P, usually the DMAC driver would simply assume the number of entries in the 'chan-map' property to be the effective number of peripheral request interfaces on the DMAC. If specified, it should be at least the number of entries in the 'chan-map' property.

- #dma-channels: C, if specified, it should neither be more than the value of 'dma-peri-ifs' nor equal to zero.
If unspecified, it is assumed to be equal to the value of
'dma-peri-ifs', i.e, C := P

- #private-data: Peculiarities of the DMAC setup, not taken into account by this generic model. The decoding of it would be private to the DMAC's driver. For ex, some DMAC drivers for dmaengine would specify dma_cap_mask_t for the DMAC, if they don't need to specify it on a per-client basis (i.e, via 4th element of a 'chan-map' entry).

Example:

	dma-controller at 0 {
		compatible = "foo,dmac-xxx";
		#private-data = <0x80808080>;
		#dma-peri-ifs = <32>;
		#dma-channels = <8>;
		#map-cells = <3>;
		chan-map =
			<&i2s1 1 2>,     /* peri_id of I2S's RX is 2 */
			<&i2s1 2 3>,     /* peri_id of I2S's TX is 3 */
			<&mmc1 3 5>,  /* peri_id of MMC's RX_TX is 5 */
			<&spi1 1 6>,
			<&spi1 2 8>,
			...;
	};

* Client Controller

Quoted 7 lines

Required property: None.
The client's DT node doesn't need any DMA specifier. Typically it would only comment about the data transfer direction associated with each of its request signal. Preferably also mentioned in the binding.

Optional property: None.

May be I am still missing something here, but in the case where a client can use one of two dma controllers, how do you specify which to use? Who decides?

I was under the impression that you would use the phandle of the dma controller to specify which controller is used in the client node.

For example ...

i2s1: i2s at 70002800 {
/* This controller has a request-signal for TX and RX each
* i.e, the driver is going to request a channel for RX(1)
* and another for TX(2).
*/
dma = <dma-controller0>
...
};

Cheers
Jon

#38 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Jassi Brar
Quoted 14 lines · Jassi Brar

On 16 May 2012 21:45, Stephen Warren <[email protected]> wrote:

Generic binding to provide a way to provide the client-channel map and other dmac specific parameters to the dma controller driver

DMA Model:-
Only the most common characteristics of a dma setup are assumed
in this binding.
Client: Some h/w controller that could request a DMA controller in the system to perform data transfer on its behalf. Example SPI, MMC, I2S etc.
DMAC: A DMA Controller instance. Example, PL330, PL08X, SDMA etc.

Quoted 12 lines

The assumed model of the DMAC, in this binding, has P peripheral
interfaces (P request signals) that could request a data transfer and C physical channels that actually do the data transfers, hence, at most C out of P peripherals could be served by the DMAC at any point of time. Usually C := P, but not always. Usually, any of the physical channels could be employed by the DMAC driver to serve any client.
The DMAC driver identifies a client by its i/f number, 'peri_id'
on the given DMAC. For example, TX for SPI has 7th while RX_TX (half-duplex) for MMC has 10th peripheral interface (request-signal) on a given DMAC. Usually, any of the physical channels could be employed by the DMAC driver to serve a client.

I'm still anything but convinced by this model. Basically it's the exact opposite of what we do for every other subsystem (irq, pinctrl, regulator, gpio, ...), where the device using some infrastructure contains the information about who provides it, whereas here you move all the information into the device that provides the functionality, and have no handle in the device using it by which the driver can identify it.

I believe that it can work and that it solves the problem you are faced with at minimal complexity, but you put the burden of this complexity on everybody who does not have this issue, and make the general binding confusing and harder to read. It also adds much more data to the device tree (in source and binary form) because you need to describe every device using a dma controller and have a label to reference it. More importantly, you make it very hard to add devices in a board file to a dma controller that already has descriptions for some channels, because you cannot easily extend the chan-map unless you rewrite all of it.

We really need something simpler than this for the common case. I have already made suggestions for how to make it still possible to cover the corner case of multiple dma engines connected to the same slave, which would keep the complexity local to those devices that actually need it.

Arnd

#39 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 12 lines · Arnd Bergmann
Quoted 12 lines

Generic binding to provide a way to provide the client-channel map and other dmac specific parameters to the dma controller driver

DMA Model:-
? Only the most common characteristics of a dma setup are assumed in this binding.
Client: Some h/w controller that could request a DMA controller in the system to perform data transfer on its behalf. Example SPI, MMC, I2S etc.
DMAC: A DMA Controller instance. Example, PL330, PL08X, SDMA etc.

Quoted 13 lines
Quoted 4 lines

?The assumed model of the DMAC, in this binding, has P peripheral interfaces (P request signals) that could request a data transfer and C physical channels that actually do the data transfers, hence, at most C out of P peripherals could be served by the DMAC at any

Quoted 8 lines

point of time. Usually C := P, but not always. Usually, any of the physical channels could be employed by the DMAC driver to serve any client.
?The DMAC driver identifies a client by its i/f number, 'peri_id' on the given DMAC. For example, TX for SPI has 7th while RX_TX (half-duplex) for MMC has 10th peripheral interface (request-signal) on a given DMAC. Usually, any of the physical channels could be employed by the DMAC driver to serve a client.

Btw, just to be clear... this is not _my_ setup.
The dma controller manuals might use different terms but underneath most(if not all) dma controllers fit this model. At lease every dmac on Samsung SoCs and ARM's PL330 and PL08x does.
In fact, I have trouble imaging some dmac not conforming to this model... but then again it could be just me.

Quoted 8 lines

I'm still anything but convinced by this model. Basically it's the exact opposite of what we do for every other subsystem (irq, pinctrl, regulator, gpio, ...), where the device using some infrastructure contains the information about who provides it, whereas here you move all the information into the device that provides the functionality, and have no handle in the device using it by which the driver can identify it.

The idea was that a client shouldn't need to know/tell which dma controller serves it or which peripheral interface of a dma controller.
I think in future third-party device IPs, like ARM's Primecell, are only gonna get more common so it makes even more sense.

Quoted 5 lines

I believe that it can work and that it solves the problem you are faced with at minimal complexity, but you put the burden of this complexity on everybody who does not have this issue, and make the general binding confusing and harder to read.

I am sorry if I gave you the wrong impression, but I didn't intend to just scratch my personal itch. I truly believed I and Stephen reached a generic solution i.e, as much as it could be.

Quoted 4 lines

It also adds much more data to the device tree (in source and binary form) because you need to describe every device using a dma controller and have a label to reference it.

I don't see why one can't add entries to chan-map as and when more clients appear for the DMAC ? It should be perfectly ok to specify less than the maximum possible clients in chan-map.
Requiring labels - yes, doesn't sound very nice, but many nodes already do.

Quoted 4 lines

More importantly, you make it very hard to add devices in a board file to a dma controller that already has descriptions for some channels, because you cannot easily extend the chan-map unless you rewrite all of it.

I am not sure I understand the point.

Quoted 6 lines

We really need something simpler than this for the common case. I have already made suggestions for how to make it still possible to cover the corner case of multiple dma engines connected to the same slave, which would keep the complexity local to those devices that actually need it.

Thanks $DEITY, I posted a preview. Maybe I should put it on hold. And thank you for speaking up immediately. Really!

#40 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 1 line · Jassi Brar

On 17 May 2012 01:12, Arnd Bergmann <[email protected]> wrote:

...

Quoted 5 lines
Quoted 4 lines

More importantly, you make it very hard to add devices in a board file to a dma controller that already has descriptions for some channels, because you cannot easily extend the chan-map unless you rewrite all of it.

I am not sure I understand the point.

Ah yes, Arnd has a good point.

If the DMA request routing information is in each client node, then it's trivial to add DMA clients to board files; you just put the board-specific nodes and properties in the board file, and there's no possibility of conflicts; you aren't having to add to or override any existing property in the base SoC file.

(As background, most ARM device trees are separated out into 1 file defining all the SoC devices e.g. soc.dtsi, and a separate file for each board e.g. board.dts, which includes the SoC file.)

Now, the DMA node for an on-SoC DMAC would be in soc.dtsi. Typically, the DMAC is connected to many on-SoC devices, and hence soc.dtsi would need to specify the routing information for all those devices to avoid duplicating it in every board.dts. Now, if you have some DMA requests that go off-SoC, the board.dts file might want to add to the routing table to indicate what clients connect to those DMA requests. However, there's no way in the device tree compiler right now to add to a property; you can only completely replace it. That would entail duplicating the entire routing information from soc.dtsi into each board.dts that wanted to add to it - a bad situation. Splitting the routing information into chunks in the client nodes avoids this issue entirely.

#41 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 14 lines · Stephen Warren

Now, the DMA node for an on-SoC DMAC would be in soc.dtsi. Typically, the DMAC is connected to many on-SoC devices, and hence soc.dtsi would need to specify the routing information for all those devices to avoid duplicating it in every board.dts. Now, if you have some DMA requests that go off-SoC, the board.dts file might want to add to the routing table to indicate what clients connect to those DMA requests. However, there's no way in the device tree compiler right now to add to a property; you can only completely replace it. That would entail duplicating the entire routing information from soc.dtsi into each board.dts that wanted to add to it - a bad situation. Splitting the routing information into chunks in the client nodes avoids this issue entirely.

As already noted by Russell, the dma setup is different than irq or
gpio which deliberately lend to off-SoC attachments. Without fpga'ing, I find it hard to imagine request-signals going off-SoC.

I only see the issue of different boards sporting a different sub-sets of clients i.e, a map entry may or may exist for a board but it would be same for two boards that have it.
Maybe we could somehow separate out the chan-map and private-data
into board.dts ?
Even if it has to stay in soc.dts, we still have the benefit of having dmac agnostic client nodes.

cheers!

#42 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Jassi Brar
Quoted 10 lines · Jassi Brar
Quoted 8 lines · Arnd Bergmann

I'm still anything but convinced by this model. Basically it's the exact opposite of what we do for every other subsystem (irq, pinctrl, regulator, gpio, ...), where the device using some infrastructure contains the information about who provides it, whereas here you move all the information into the device that provides the functionality, and have no handle in the device using it by which the driver can identify it.

Quoted 4 lines

The idea was that a client shouldn't need to know/tell which dma controller serves it or which peripheral interface of a dma controller.
I think in future third-party device IPs, like ARM's Primecell, are only gonna get more common so it makes even more sense.

I don't understand why this is an advantage. I definitely agree that the client driver should not know or care about the type of DMA controller that is being used, IMHO it makes a lot of sense if the device node specifies the dma line in the way that is specific to the controller. It already does the same thing for IRQ, GPIO and other stuff, so it's consistent and not an additional burden on the author of the device tree source file.

Quoted 8 lines
Quoted 5 lines

I believe that it can work and that it solves the problem you are faced with at minimal complexity, but you put the burden of this complexity on everybody who does not have this issue, and make the general binding confusing and harder to read.

I am sorry if I gave you the wrong impression, but I didn't intend to just scratch my personal itch. I truly believed I and Stephen reached a generic solution i.e, as much as it could be.

Yes, I realize I should have stepped in earlier. The proposal you have made is indeed generic and can cover important cases that the original proposal did not. My objection is that it's too complex at doing that for the common case though and that I think we can get a simpler solution that still solves the same problem.

I already replied to Stephen expanding on his proposed solution, which I find reasonable, especially in the refined version of my reply. Like your proposal, it treats multiple dma engines for the same client as the normal case, by slightly extending the binding that Jon posted.

Another solution that I find equally ok is the one that I proposed earlier in this thread, where we assume that for each dma request line there is exactly one dma engine master, and then add either a map (similar to the interrupt-map property) to cover the complex case in a special way, or to extend the binding for a specific dma engine so that you can have a single device node represent all dma engines of the same soc, separating this from the multiple struct dma_device instances that represent the multiple hardware blocks in Linux.

Arnd

#43 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Arnd Bergmann
Quoted 28 lines · Arnd Bergmann
Quoted 14 lines · Jassi Brar

On 16 May 2012 21:45, Stephen Warren <[email protected]> wrote:

Generic binding to provide a way to provide the client-channel map and other dmac specific parameters to the dma controller driver

DMA Model:-
Only the most common characteristics of a dma setup are assumed
in this binding.
Client: Some h/w controller that could request a DMA controller in the system to perform data transfer on its behalf. Example SPI, MMC, I2S etc.
DMAC: A DMA Controller instance. Example, PL330, PL08X, SDMA etc.

Quoted 12 lines

The assumed model of the DMAC, in this binding, has P peripheral
interfaces (P request signals) that could request a data transfer and C physical channels that actually do the data transfers, hence, at most C out of P peripherals could be served by the DMAC at any point of time. Usually C := P, but not always. Usually, any of the physical channels could be employed by the DMAC driver to serve any client.
The DMAC driver identifies a client by its i/f number, 'peri_id'
on the given DMAC. For example, TX for SPI has 7th while RX_TX (half-duplex) for MMC has 10th peripheral interface (request-signal) on a given DMAC. Usually, any of the physical channels could be employed by the DMAC driver to serve a client.

Quoted 7 lines

I'm still anything but convinced by this model. Basically it's the exact opposite of what we do for every other subsystem (irq, pinctrl, regulator, gpio, ...), where the device using some infrastructure contains the information about who provides it, whereas here you move all the information into the device that provides the functionality, and have no handle in the device using it by which the driver can identify it.

Yes, I guess this is backwards. But, the HW is a little different too; GPIOs (and probably interrupts) don't have multiple places they could come from.

The problem is that if we did something like this in the DMA client:

dma-reqs = <&dmac1 DMAC1_DMA_REQ_6 &dmac1 DMAC1_DMA_REQ_8>;

how do we know if the client is emitting 2 DMA request signals that get routed to two different inputs on the DMA controller, or whether this is two alternatives for the same signal.

Perhaps we can separate each logical request into separate properties. This will make the simple case slightly more complex, since there are n properties rather than n entries in each property, but still allow the more complex case:

Simple case:

/* e.g. FIFO TX DMA req - 2 DMACs possible */
dma-req-0 = <&dmac1 DMAC1_DMA_REQ_6>;
/* e.g. FIFO RX DMA req 1 DMAC possible */
dma-req-1 = <&dmac1 DMAC1_DMA_REQ_8>;

Multiple DMAC case:

/* e.g. FIFO TX DMA req - 2 DMACs possible */ dma-req-0 = <&dmac1 DMAC1_DMA_REQ_6 &dmac2 DMA_2_DMA_REQ_8>; /* e.g. FIFO RX DMA req 1 DMAC possible */ dma-req-1 = <&dmac1 DMAC1_DMA_REQ_8>;

Then, when the DMA client calls the standard API to "get DMA channel for my outbound DMA request "n", the core code will kasprintf("dma-req-%d", n); to generate the property name. That's how pinctrl works.

Does that seem better?

#44 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 37 lines · Stephen Warren
Quoted 25 lines
Quoted 12 lines

Generic binding to provide a way to provide the client-channel map and other dmac specific parameters to the dma controller driver

DMA Model:-
? Only the most common characteristics of a dma setup are assumed in this binding.
Client: Some h/w controller that could request a DMA controller in the system to perform data transfer on its behalf. Example SPI, MMC, I2S etc.
DMAC: A DMA Controller instance. Example, PL330, PL08X, SDMA etc.

Quoted 12 lines

?The assumed model of the DMAC, in this binding, has P peripheral interfaces (P request signals) that could request a data transfer and C physical channels that actually do the data transfers, hence, at most C out of P peripherals could be served by the DMAC at any point of time. Usually C := P, but not always. Usually, any of the physical channels could be employed by the DMAC driver to serve any client.
?The DMAC driver identifies a client by its i/f number, 'peri_id' on the given DMAC. For example, TX for SPI has 7th while RX_TX (half-duplex) for MMC has 10th peripheral interface (request-signal) on a given DMAC. Usually, any of the physical channels could be employed by the DMAC driver to serve a client.

Quoted 7 lines

I'm still anything but convinced by this model. Basically it's the exact opposite of what we do for every other subsystem (irq, pinctrl, regulator, gpio, ...), where the device using some infrastructure contains the information about who provides it, whereas here you move all the information into the device that provides the functionality, and have no handle in the device using it by which the driver can identify it.

Yes, I guess this is backwards. But, the HW is a little different too; GPIOs (and probably interrupts) don't have multiple places they could come from.

Quoted 8 lines

The problem is that if we did something like this in the DMA client:

dma-reqs = <&dmac1 DMAC1_DMA_REQ_6 &dmac1 DMAC1_DMA_REQ_8>;

how do we know if the client is emitting 2 DMA request signals that get routed to two different inputs on the DMA controller, or whether this is two alternatives for the same signal.

FWIW, I wouldn't lose sleep over the possibility of redundancy on same DMAC. If a client's request signal is routed to 2 inputs, they are usually on different DMACs.

#45 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Stephen Warren
Quoted 14 lines · Stephen Warren

Simple case:

/* e.g. FIFO TX DMA req - 2 DMACs possible */
dma-req-0 = <&dmac1 DMAC1_DMA_REQ_6>;
/* e.g. FIFO RX DMA req 1 DMAC possible */
dma-req-1 = <&dmac1 DMAC1_DMA_REQ_8>;

Multiple DMAC case:

/* e.g. FIFO TX DMA req - 2 DMACs possible */ dma-req-0 = <&dmac1 DMAC1_DMA_REQ_6 &dmac2 DMA_2_DMA_REQ_8>; /* e.g. FIFO RX DMA req 1 DMAC possible */ dma-req-1 = <&dmac1 DMAC1_DMA_REQ_8>;

Quoted 5 lines

Then, when the DMA client calls the standard API to "get DMA channel for my outbound DMA request "n", the core code will kasprintf("dma-req-%d", n); to generate the property name. That's how pinctrl works.

Does that seem better?

Yes, that is one way that I suggested at an earlier point. After some discussion, I would use a different syntax for these though, to the exact same effect, writing it as

	dmas = <&dmac1 DMAC1_DMA_REQ_6>,  <&dmac2 DMA_2_DMA_REQ_8>,  <&dmac1 DMAC1_DMA_REQ_8>;
	dma-names = "tx", "tx", "rx";

The driver can still request the dma line by name "tx" and the subsystem would pick one out of those with the same name.

For the majority of cases, we would only need a single dma request line and could leave out the dma-names property, so when you don't ask for a specific name, you just get any dma line out of the dmas array.

Arnd

#46 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 21 lines · Arnd Bergmann
Quoted 14 lines · Stephen Warren

Simple case:

/* e.g. FIFO TX DMA req - 2 DMACs possible */
dma-req-0 = <&dmac1 DMAC1_DMA_REQ_6>;
/* e.g. FIFO RX DMA req 1 DMAC possible */
dma-req-1 = <&dmac1 DMAC1_DMA_REQ_8>;

Multiple DMAC case:

/* e.g. FIFO TX DMA req - 2 DMACs possible */ dma-req-0 = <&dmac1 DMAC1_DMA_REQ_6 &dmac2 DMA_2_DMA_REQ_8>; /* e.g. FIFO RX DMA req 1 DMAC possible */ dma-req-1 = <&dmac1 DMAC1_DMA_REQ_8>;

Quoted 5 lines

Then, when the DMA client calls the standard API to "get DMA channel for my outbound DMA request "n", the core code will kasprintf("dma-req-%d", n); to generate the property name. That's how pinctrl works.

Does that seem better?

Quoted 7 lines

Yes, that is one way that I suggested at an earlier point. After some discussion, I would use a different syntax for these though, to the exact same effect, writing it as

	dmas = <&dmac1 DMAC1_DMA_REQ_6>,  <&dmac2 DMA_2_DMA_REQ_8>,  <&dmac1 DMAC1_DMA_REQ_8>;
	dma-names = "tx", "tx", "rx";

That looks pretty reasonable. One comment below.

Quoted 4 lines

The driver can still request the dma line by name "tx" and the subsystem would pick one out of those with the same name.

For the majority of cases, we would only need a single dma request line

Hmm. Many devices have multiple different FIFOs, and hence multiple DMA request signals (e.g. Tegra I2S has separate RX and TX FIFO, Tegra S/PDIF has 2 FIFOs in each direction). That would require the driver to always use get_by_name() to differentiate between 2/4 options for the same DMA req or 2/4 different DMA requests. Most other bindings allow use of get_by_id() or get_by_name() interchangeably.

Quoted 5 lines

and could leave out the dma-names property, so when you don't ask for a specific name, you just get any dma line out of the dmas array.

Arnd

#47 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 11 lines · Stephen Warren
Quoted 4 lines

The driver can still request the dma line by name "tx" and the subsystem would pick one out of those with the same name.

For the majority of cases, we would only need a single dma request line

Hmm. Many devices have multiple different FIFOs, and hence multiple DMA request signals (e.g. Tegra I2S has separate RX and TX FIFO, Tegra S/PDIF has 2 FIFOs in each direction). That would require the driver to always use get_by_name() to differentiate between 2/4 options for the same DMA req or 2/4 different DMA requests. Most other bindings allow use of get_by_id() or get_by_name() interchangeably.

Ok, good point. So we could make the common case that they are numbered but not named and require all drivers to use named properties when there is the possibility that the device might be connected to multiple controllers, but that seems tricky because a driver can start being used on a platform that has only one controller and have no dma-name property in the device tree but then get used on a different soc that actually has multiple controllers.
So if we do that, we might want to make the dma-names property mandatory for every device, and document what the names are.

Another option would be to encode the direction in the property in a generic way and provide an API that lets you ask specifically for a read, write or readwrite channel out of the ones that are available, rather than assuming there is only one kind. Consequently, any device that uses more than one read channel or more than one write channel would still have to use names to identify them.

Arnd

#48 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 13 lines · Arnd Bergmann
Quoted 11 lines · Stephen Warren
Quoted 4 lines

The driver can still request the dma line by name "tx" and the subsystem would pick one out of those with the same name.

For the majority of cases, we would only need a single dma request line

Hmm. Many devices have multiple different FIFOs, and hence multiple DMA request signals (e.g. Tegra I2S has separate RX and TX FIFO, Tegra S/PDIF has 2 FIFOs in each direction). That would require the driver to always use get_by_name() to differentiate between 2/4 options for the same DMA req or 2/4 different DMA requests. Most other bindings allow use of get_by_id() or get_by_name() interchangeably.

Quoted 7 lines

Ok, good point. So we could make the common case that they are numbered but not named and require all drivers to use named properties when there is the possibility that the device might be connected to multiple controllers, but that seems tricky because a driver can start being used on a platform that has only one controller and have no dma-name property in the device tree but then get used on a different soc that actually has multiple controllers.

Indeed.

Quoted 2 lines

So if we do that, we might want to make the dma-names property mandatory for every device, and document what the names are.

We could do that, but one more proposal: Add the client's ID/index into the dmas property, so:

simple 1 req:

dmas = <0 &dmac1 xxx>;

simple 2 req:

dmas = <0 &dmac1 xxx 1 &dmac1 yyy>;

multiple dmacs:

dmas = <0 &dmac1 xxx 0 &dmac2 zzz 1 &dmac1 yyy>;

(i.e. dmas = [client_dma_req_id phandle dma-specifier]*)

(where 0==TX_FIFO, 1=RX_FIFO for example, but could also have 2=TX_FIFO_B, 3=RX_FIFO_B, ...)

Then dma-names would map name to ID, but you'd still need to search all through the dmas property to find the ID match.

Quoted 6 lines

Another option would be to encode the direction in the property in a generic way and provide an API that lets you ask specifically for a read, write or readwrite channel out of the ones that are available, rather than assuming there is only one kind. Consequently, any device that uses more than one read channel or more than one write channel would still have to use names to identify them.

I'm not sure that /just/ direction cuts it; Tegra's SPDIF has 2 TX DMAs ("PCM" data and control data) and same for RX. The format above is roughly the same as what you proposed, but with an explicit ID rather than direction in the dmas property.

#49 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 20 lines · Stephen Warren
Quoted 2 lines · Arnd Bergmann

So if we do that, we might want to make the dma-names property mandatory for every device, and document what the names are.

We could do that, but one more proposal: Add the client's ID/index into the dmas property, so:

simple 1 req:

dmas = <0 &dmac1 xxx>;

simple 2 req:

dmas = <0 &dmac1 xxx 1 &dmac1 yyy>;

multiple dmacs:

dmas = <0 &dmac1 xxx 0 &dmac2 zzz 1 &dmac1 yyy>;

Quoted 7 lines

(i.e. dmas = [client_dma_req_id phandle dma-specifier]*)

(where 0==TX_FIFO, 1=RX_FIFO for example, but could also have 2=TX_FIFO_B, 3=RX_FIFO_B, ...)

Then dma-names would map name to ID, but you'd still need to search all through the dmas property to find the ID match.

Again, this would probably work, but it adds complexity and inconsistency for the common case, as nothing else requires these. I think it's much better than putting the information into the dma controller node, but not ideal.

Quoted 11 lines
Quoted 6 lines

Another option would be to encode the direction in the property in a generic way and provide an API that lets you ask specifically for a read, write or readwrite channel out of the ones that are available, rather than assuming there is only one kind. Consequently, any device that uses more than one read channel or more than one write channel would still have to use names to identify them.

I'm not sure that just direction cuts it; Tegra's SPDIF has 2 TX DMAs ("PCM" data and control data) and same for RX. The format above is roughly the same as what you proposed, but with an explicit ID rather than direction in the dmas property.

The point with the direction was that it covers most cases and makes them rather simple, while for the rare case where you need more than two channels, you just use the otherwise optional named interface rather than the numbered one. My feeling is that this also makes a lot of sense at the driver API level: most dirvers just ask for the read and write channels using a very simple interface, and those drivers that have more than two will want to name them anyway.

Arnd

#50 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 46 lines · Arnd Bergmann
Quoted 20 lines · Stephen Warren
Quoted 2 lines · Arnd Bergmann

So if we do that, we might want to make the dma-names property mandatory for every device, and document what the names are.

We could do that, but one more proposal: Add the client's ID/index into the dmas property, so:

simple 1 req:

dmas = <0 &dmac1 xxx>;

simple 2 req:

dmas = <0 &dmac1 xxx 1 &dmac1 yyy>;

multiple dmacs:

dmas = <0 &dmac1 xxx 0 &dmac2 zzz 1 &dmac1 yyy>;

Quoted 7 lines

(i.e. dmas = [client_dma_req_id phandle dma-specifier]*)

(where 0==TX_FIFO, 1=RX_FIFO for example, but could also have 2=TX_FIFO_B, 3=RX_FIFO_B, ...)

Then dma-names would map name to ID, but you'd still need to search all through the dmas property to find the ID match.

Again, this would probably work, but it adds complexity and inconsistency for the common case, as nothing else requires these. I think it's much better than putting the information into the dma controller node, but not ideal.

Quoted 11 lines
Quoted 6 lines

Another option would be to encode the direction in the property in a generic way and provide an API that lets you ask specifically for a read, write or readwrite channel out of the ones that are available, rather than assuming there is only one kind. Consequently, any device that uses more than one read channel or more than one write channel would still have to use names to identify them.

I'm not sure that just direction cuts it; Tegra's SPDIF has 2 TX DMAs ("PCM" data and control data) and same for RX. The format above is roughly the same as what you proposed, but with an explicit ID rather than direction in the dmas property.

Quoted 7 lines

The point with the direction was that it covers most cases and makes them rather simple, while for the rare case where you need more than two channels, you just use the otherwise optional named interface rather than the numbered one. My feeling is that this also makes a lot of sense at the driver API level: most dirvers just ask for the read and write channels using a very simple interface, and those drivers that have more than two will want to name them anyway.

How are you thinking of representing the direction in DT - as part of the DMA request specifier, so in a DMAC-specific way?

If so, that seems a little odd; you have to request a DMA channel for "TX", but then end up having the common code check all the entries in the dmas property since it can't know which are TX, and then have the wrong ones almost accidentally fail, since the DMAC will then determine that it can't support TX on the RX DMA request IDs.

If not, then presumably there's going to be a cell for "direction", so it may as well just be a cell for "outgoing DMA request ID" - the two are equivalent in the simple case.

#51 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 9 lines · Stephen Warren
Quoted 8 lines

The point with the direction was that it covers most cases and makes them rather simple, while for the rare case where you need more than two channels, you just use the otherwise optional named interface rather than the numbered one. My feeling is that this also makes a lot of sense at the driver API level: most dirvers just ask for the read and write channels using a very simple interface, and those drivers that have more than two will want to name them anyway.

Quoted 8 lines

How are you thinking of representing the direction in DT - as part of the DMA request specifier, so in a DMAC-specific way?

If so, that seems a little odd; you have to request a DMA channel for "TX", but then end up having the common code check all the entries in the dmas property since it can't know which are TX, and then have the wrong ones almost accidentally fail, since the DMAC will then determine that it can't support TX on the RX DMA request IDs.

I think the direction must be encoded in a way that does not depend on the binding for the specific controller. There are two ways I can see how we might do it:

1. have separate property names for tx and rx channels, and probably one for combined rx/tx channels
2. define the second cell in each channel specifier to be the direction in a predefined format, followed by the other (controller specific) attributes, if any.

Arnd

#52 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 23 lines · Arnd Bergmann
Quoted 9 lines · Stephen Warren
Quoted 8 lines

The point with the direction was that it covers most cases and makes them rather simple, while for the rare case where you need more than two channels, you just use the otherwise optional named interface rather than the numbered one. My feeling is that this also makes a lot of sense at the driver API level: most dirvers just ask for the read and write channels using a very simple interface, and those drivers that have more than two will want to name them anyway.

Quoted 8 lines

How are you thinking of representing the direction in DT - as part of the DMA request specifier, so in a DMAC-specific way?

If so, that seems a little odd; you have to request a DMA channel for "TX", but then end up having the common code check all the entries in the dmas property since it can't know which are TX, and then have the wrong ones almost accidentally fail, since the DMAC will then determine that it can't support TX on the RX DMA request IDs.

I think the direction must be encoded in a way that does not depend on the binding for the specific controller. There are two ways I can see how we might do it:

Quoted 6 lines

1. have separate property names for tx and rx channels, and probably one for combined rx/tx channels

2. define the second cell in each channel specifier to be the direction in a predefined format, followed by the other (controller specific) attributes, if any.

In this option, lets say bit 0 is 0==TX, 1==RX (or perhaps 2 bits if combined TX/RX is needed)

Then, we could reserve say bits 7:1 as client DMA request ID.

And then have bits 31:8 as DMAC specific data.

Wouldn't that allow us to have our cake and eat it?

author
#53 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Stephen, Arnd,

Been a while ;-)

Quoted 31 lines · Stephen Warren
Quoted 23 lines · Arnd Bergmann
Quoted 9 lines · Stephen Warren
Quoted 8 lines

The point with the direction was that it covers most cases and makes them rather simple, while for the rare case where you need more than two channels, you just use the otherwise optional named interface rather than the numbered one. My feeling is that this also makes a lot of sense at the driver API level: most dirvers just ask for the read and write channels using a very simple interface, and those drivers that have more than two will want to name them anyway.

Quoted 8 lines

How are you thinking of representing the direction in DT - as part of the DMA request specifier, so in a DMAC-specific way?

If so, that seems a little odd; you have to request a DMA channel for "TX", but then end up having the common code check all the entries in the dmas property since it can't know which are TX, and then have the wrong ones almost accidentally fail, since the DMAC will then determine that it can't support TX on the RX DMA request IDs.

I think the direction must be encoded in a way that does not depend on the binding for the specific controller. There are two ways I can see how we might do it:

Quoted 6 lines

1. have separate property names for tx and rx channels, and probably one for combined rx/tx channels

2. define the second cell in each channel specifier to be the direction in a predefined format, followed by the other (controller specific) attributes, if any.

Quoted 8 lines

In this option, lets say bit 0 is 0==TX, 1==RX (or perhaps 2 bits if combined TX/RX is needed)

Then, we could reserve say bits 7:1 as client DMA request ID.

And then have bits 31:8 as DMAC specific data.

Wouldn't that allow us to have our cake and eat it?

Sorry for not responding sooner.

It seems to me we were pretty close on alignment. In fact, I was quite happy with Steven's 2nd to last proposal of ...

simple 1 req:
dmas = <0 &dmac1 xxx>;

simple 2 req:
dmas = <0 &dmac1 xxx 1 &dmac1 yyy>;

multiple dmacs:
dmas = <0 &dmac1 xxx 0 &dmac2 zzz 1 &dmac1 yyy>;

Arnd, I know that you had some concerns. However, in the above case I would expect that the 3rd parameter be optional and it can be some sort of match variable. In other words, we don't care how the 32-bits are encoded or what they represent but they would be used appropriately by the xlate function being used. So the xlate and this "match" variable would have to speak the same language.

I think that I prefer the idea of having a 3rd optional match variable than encoding the DMA request ID and match data together in 1 32-bit variable. However, not a big deal either way.

Cheers
Jon

#54 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 44 lines · Jon Hunter
Quoted 20 lines · Stephen Warren
Quoted 12 lines · Arnd Bergmann
Quoted 6 lines · Stephen Warren

If so, that seems a little odd; you have to request a DMA channel for "TX", but then end up having the common code check all the entries in the dmas property since it can't know which are TX, and then have the wrong ones almost accidentally fail, since the DMAC will then determine that it can't support TX on the RX DMA request IDs.

I think the direction must be encoded in a way that does not depend on the binding for the specific controller. There are two ways I can see how we might do it:

Quoted 6 lines

1. have separate property names for tx and rx channels, and probably one for combined rx/tx channels

2. define the second cell in each channel specifier to be the direction in a predefined format, followed by the other (controller specific) attributes, if any.

Quoted 8 lines

In this option, lets say bit 0 is 0==TX, 1==RX (or perhaps 2 bits if combined TX/RX is needed)

Then, we could reserve say bits 7:1 as client DMA request ID.

And then have bits 31:8 as DMAC specific data.

Wouldn't that allow us to have our cake and eat it?

Sorry for not responding sooner.

It seems to me we were pretty close on alignment. In fact, I was quite happy with Steven's 2nd to last proposal of ...

simple 1 req:
dmas = <0 &dmac1 xxx>;

simple 2 req:
dmas = <0 &dmac1 xxx 1 &dmac1 yyy>;

multiple dmacs:
dmas = <0 &dmac1 xxx 0 &dmac2 zzz 1 &dmac1 yyy>;

Quoted 6 lines

Arnd, I know that you had some concerns. However, in the above case I would expect that the 3rd parameter be optional and it can be some sort of match variable. In other words, we don't care how the 32-bits are encoded or what they represent but they would be used appropriately by the xlate function being used. So the xlate and this "match" variable would have to speak the same language.

I would at least put the &dmac part first to be consistent with other bindings that refer to some node. That controller should then be able to specify the number of additional cells used to describe the dma request. We can define that the first cell after the controller phandle is always the same thing, e.g. the direction (in/out/inout) or a client-specific ID or a combination of that with other predefined bits that are not dependent on dma controller specifics.

As I said previously, I think just encoding the direction but not the client specific ID (meaning we would have to disambiguate the more complex cases that Stephen mentioned using a dma-names property) would be the best because it keeps the common case simple, but I could live with other things going in there too.

Quoted 3 lines

I think that I prefer the idea of having a 3rd optional match variable than encoding the DMA request ID and match data together in 1 32-bit variable. However, not a big deal either way.

I agree on that part, I would usually prefer to encode different things in separate cells rather than putting them together into a single cell just because they require less than 32 bits combined.

Arnd

author
#55 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Arnd,

Quoted 52 lines · Arnd Bergmann
Quoted 44 lines · Jon Hunter
Quoted 20 lines · Stephen Warren
Quoted 12 lines · Arnd Bergmann
Quoted 6 lines · Stephen Warren

If so, that seems a little odd; you have to request a DMA channel for "TX", but then end up having the common code check all the entries in the dmas property since it can't know which are TX, and then have the wrong ones almost accidentally fail, since the DMAC will then determine that it can't support TX on the RX DMA request IDs.

I think the direction must be encoded in a way that does not depend on the binding for the specific controller. There are two ways I can see how we might do it:

Quoted 6 lines

1. have separate property names for tx and rx channels, and probably one for combined rx/tx channels

2. define the second cell in each channel specifier to be the direction in a predefined format, followed by the other (controller specific) attributes, if any.

Quoted 8 lines

In this option, lets say bit 0 is 0==TX, 1==RX (or perhaps 2 bits if combined TX/RX is needed)

Then, we could reserve say bits 7:1 as client DMA request ID.

And then have bits 31:8 as DMAC specific data.

Wouldn't that allow us to have our cake and eat it?

Sorry for not responding sooner.

It seems to me we were pretty close on alignment. In fact, I was quite happy with Steven's 2nd to last proposal of ...

simple 1 req:
dmas = <0 &dmac1 xxx>;

simple 2 req:
dmas = <0 &dmac1 xxx 1 &dmac1 yyy>;

multiple dmacs:
dmas = <0 &dmac1 xxx 0 &dmac2 zzz 1 &dmac1 yyy>;

Quoted 6 lines

Arnd, I know that you had some concerns. However, in the above case I would expect that the 3rd parameter be optional and it can be some sort of match variable. In other words, we don't care how the 32-bits are encoded or what they represent but they would be used appropriately by the xlate function being used. So the xlate and this "match" variable would have to speak the same language.

Quoted 7 lines

I would at least put the &dmac part first to be consistent with other bindings that refer to some node. That controller should then be able to specify the number of additional cells used to describe the dma request. We can define that the first cell after the controller phandle is always the same thing, e.g. the direction (in/out/inout) or a client-specific ID or a combination of that with other predefined bits that are not dependent on dma controller specifics.

I agree with putting the &dmac phandle first, that makes sense.

Quoted 5 lines

As I said previously, I think just encoding the direction but not the client specific ID (meaning we would have to disambiguate the more complex cases that Stephen mentioned using a dma-names property) would be the best because it keeps the common case simple, but I could live with other things going in there too.

Ok, so you are saying that there are some DMA controllers where there is no channel/request ID and only a direction is needed? So an even simpler case than what I had imagined.

So in that case, I don't see why the first cell after the phandle could not be an index which could be either a direction or request-id and then the next cell after that be a secondary match variable.

So simple case with just a index (either req-id or direction) ...

dmas = <&dmac0 index>

More complex case ...

dmas = <&dmac0 index match>

For example, for OMAP index = req-id and match = direction ...

dmas = <&dmac0 req-id direction>

Or am I way off the page?

Cheers
Jon

#56 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 8 lines · Jon Hunter
Quoted 5 lines · Arnd Bergmann

As I said previously, I think just encoding the direction but not the client specific ID (meaning we would have to disambiguate the more complex cases that Stephen mentioned using a dma-names property) would be the best because it keeps the common case simple, but I could live with other things going in there too.

Quoted 4 lines

Ok, so you are saying that there are some DMA controllers where there is no channel/request ID and only a direction is needed? So an even simpler case than what I had imagined.

I am curious to know which DMA controllers don't need any client ID ? unless it is Mem->Mem (for which even specifying direction is meaningless).
Rather, I think specifying direction is even lesser useful, since usually the client's ID imply the (bi/uni)direction.

#57 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Jon Hunter
Quoted 9 lines · Jon Hunter
Quoted 5 lines

As I said previously, I think just encoding the direction but not the client specific ID (meaning we would have to disambiguate the more complex cases that Stephen mentioned using a dma-names property) would be the best because it keeps the common case simple, but I could live with other things going in there too.

Ok, so you are saying that there are some DMA controllers where there is no channel/request ID and only a direction is needed? So an even simpler case than what I had imagined.

No, that was not the case I was thinking about.

Quoted 10 lines

So in that case, I don't see why the first cell after the phandle could not be an index which could be either a direction or request-id and then the next cell after that be a secondary match variable.

So simple case with just a index (either req-id or direction) ...

dmas = <&dmac0 index>

More complex case ...

Quoted 7 lines

dmas = <&dmac0 index match>

For example, for OMAP index = req-id and match = direction ...

dmas = <&dmac0 req-id direction>

Or am I way off the page?

The intention was instead to remove the need for the /index/ in those cases, because having a client-specific index in here makes it inconsistent with other similar bindings (reg, interrupts, gpios, ...) that people are familiar with. They use an implicit index by counting the fields in the respective properties.

The existing method we have for avoiding index numbers is to use named fields, like

	dmas = <&dmac0 matchA>, <dmac1 matchB>, <dmac2 matchC>;
	dma-names = "rx", "rx", "tx";

This is similar to how we use named interrupt and mmio resources, but it requires that we always request the dma lines by name, which is slightly more complex than we might want it to be.

Because the vast majority of cases just use a single channel, or one channel per direction, my idea was to encode the direction in the dmas property, which lets us request a dma channel by direction from the driver side, without explicitly encoding the name.

This would let us handle the following cases very easily:

1. one read-write channel

	dmas = <&dmac 0x3 match>;

2. a choice of two read-write channels:

	dmas = <&dmacA 0x3 matchA>, <&dmacB 0x3 matchB>;

3. one read-channel, one write channel:

	dmas = <&dmac 0x1 match-read>, <&dmac 0x2 match-write>;

4. a choice of two read channels and one write channel:

	dmas = <&dmacA 0x1 match-readA>, <&dmacA 0x2 match-write> 
			<&dmacB match-readB>;

And only the cases where we have more multiple channels that differ in more aspects would require named properties:

5. two different channels

	dmas = <&dmac 0x3 match-rwdata>, <&dmac 0x1 match-status>;
	dma-names = "rwdata", "status";

6. same as 5, but with a choice of channels:

	dmas = <&dmacA 0x3 match-rwdataA>, <&dmacA 0x1 match-status>;
		<dmacB 0x3 match-rwdataB>;
	dma-names = "rwdata", "status", "rwdata";

With a definition like that, we can implement a very simple device driver interface for the common cases, and a slightly more complex one for the more complex cases:

1. chan = of_dma_request_channel(dev->of_node, 0);
2. chan = of_dma_request_channel(dev->of_node, 0);
3. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV); txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
4. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV); txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
5. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0); auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);
6. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0); auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);

Arnd

author
#58 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 8 lines · Arnd Bergmann
Quoted 6 lines · Jon Hunter
Quoted 5 lines

As I said previously, I think just encoding the direction but not the client specific ID (meaning we would have to disambiguate the more complex cases that Stephen mentioned using a dma-names property) would be the best because it keeps the common case simple, but I could live with other things going in there too.

Quoted 5 lines
Quoted 3 lines

Ok, so you are saying that there are some DMA controllers where there is no channel/request ID and only a direction is needed? So an even simpler case than what I had imagined.

No, that was not the case I was thinking about.

Ok, good because that would be the most simple dma controller I have heard about ;-)

Quoted 16 lines
Quoted 16 lines

So in that case, I don't see why the first cell after the phandle could not be an index which could be either a direction or request-id and then the next cell after that be a secondary match variable.

So simple case with just a index (either req-id or direction) ...

dmas = <&dmac0 index>

More complex case ...

dmas = <&dmac0 index match>

For example, for OMAP index = req-id and match = direction ...

dmas = <&dmac0 req-id direction>

Quoted 7 lines
Quoted 1 line

Or am I way off the page?

The intention was instead to remove the need for the /index/ in those cases, because having a client-specific index in here makes it inconsistent with other similar bindings (reg, interrupts, gpios, ...) that people are familiar with. They use an implicit index by counting the fields in the respective properties.

So maybe "index" was not the right term to use here. What I meant was that this is really the req/chan-id associated with this device. It is not an arbitrary index that in turn gets resolved into the req-id. So in other words, just like gpio where you have the gpio number, here you have the dma req-id.

Quoted 9 lines

The existing method we have for avoiding index numbers is to use named fields, like

	dmas = <&dmac0 matchA>, <dmac1 matchB>, <dmac2 matchC>;
	dma-names = "rx", "rx", "tx";

This is similar to how we use named interrupt and mmio resources, but it requires that we always request the dma lines by name, which is slightly more complex than we might want it to be.

Ok, but how do you get the req-id from the above binding? Doesn't it need to be stored there somewhere even for the most simplest case? Or are you saying that in this case you are just returning a name and the dma driver resolves that into a req-id?

Quoted 4 lines

Because the vast majority of cases just use a single channel, or one channel per direction, my idea was to encode the direction in the dmas property, which lets us request a dma channel by direction from the driver side, without explicitly encoding the name.

Yes, thats fine and so the direction is really the match criteria in this case.

Quoted 5 lines

This would let us handle the following cases very easily:

1. one read-write channel

	dmas = <&dmac 0x3 match>;

Where 0x3 is the req-id? Just to confirm ;-)

Why not have match after the phandle to be consistent with the simple example using name fields above?

Quoted 34 lines

2. a choice of two read-write channels:

	dmas = <&dmacA 0x3 matchA>, <&dmacB 0x3 matchB>;

3. one read-channel, one write channel:

	dmas = <&dmac 0x1 match-read>, <&dmac 0x2 match-write>;

4. a choice of two read channels and one write channel:

	dmas = <&dmacA 0x1 match-readA>, <&dmacA 0x2 match-write> 
			<&dmacB match-readB>;

And only the cases where we have more multiple channels that differ in more aspects would require named properties:

5. two different channels

	dmas = <&dmac 0x3 match-rwdata>, <&dmac 0x1 match-status>;
	dma-names = "rwdata", "status";

6. same as 5, but with a choice of channels:

	dmas = <&dmacA 0x3 match-rwdataA>, <&dmacA 0x1 match-status>;
		<dmacB 0x3 match-rwdataB>;
	dma-names = "rwdata", "status", "rwdata";

With a definition like that, we can implement a very simple device driver interface for the common cases, and a slightly more complex one for the more complex cases:

1. chan = of_dma_request_channel(dev->of_node, 0);
2. chan = of_dma_request_channel(dev->of_node, 0);

Quoted 8 lines
3. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
4. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
5. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);
6. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);

Yes, that looks good to me.

Cheers
Jon

#59 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 27 lines · Jon Hunter
Quoted 17 lines · Arnd Bergmann
Quoted 16 lines · Jon Hunter

So in that case, I don't see why the first cell after the phandle could not be an index which could be either a direction or request-id and then the next cell after that be a secondary match variable.

So simple case with just a index (either req-id or direction) ...

dmas = <&dmac0 index>

More complex case ...

dmas = <&dmac0 index match>

For example, for OMAP index = req-id and match = direction ...

dmas = <&dmac0 req-id direction>

Quoted 7 lines
Quoted 1 line

Or am I way off the page?

The intention was instead to remove the need for the /index/ in those cases, because having a client-specific index in here makes it inconsistent with other similar bindings (reg, interrupts, gpios, ...) that people are familiar with. They use an implicit index by counting the fields in the respective properties.

Quoted 5 lines

So maybe "index" was not the right term to use here. What I meant was that this is really the req/chan-id associated with this device. It is not an arbitrary index that in turn gets resolved into the req-id. So in other words, just like gpio where you have the gpio number, here you have the dma req-id.

Ok, we're on the same page then.

I got confused because you were quoting Stephen's example of

multiple dmacs:
dmas = <0 &dmac1 xxx 0 &dmac2 zzz 1 &dmac1 yyy>;

which used an aribitrary slave-side index (0, 1), the dmaengine phandle and the dmaengine specific request id (xxx,yyy,zzz).

Leaving out the index means that we require at least one of "dma-names" strings or adding the direction.

Quoted 6 lines
Quoted 6 lines

The existing method we have for avoiding index numbers is to use named fields, like

	dmas = <&dmac0 matchA>, <dmac1 matchB>, <dmac2 matchC>;
	dma-names = "rx", "rx", "tx";
Quoted 8 lines
Quoted 3 lines

This is similar to how we use named interrupt and mmio resources, but it requires that we always request the dma lines by name, which is slightly more complex than we might want it to be.

Ok, but how do you get the req-id from the above binding? Doesn't it need to be stored there somewhere even for the most simplest case? Or are you saying that in this case you are just returning a name and the dma driver resolves that into a req-id?

the req-id is what I called matchA, matchB, matchC here, it could be a set of multiple cells, the number of which gets determined by the dmaengine's #dma-cells property.

Quoted 7 lines
Quoted 4 lines

Because the vast majority of cases just use a single channel, or one channel per direction, my idea was to encode the direction in the dmas property, which lets us request a dma channel by direction from the driver side, without explicitly encoding the name.

Yes, thats fine and so the direction is really the match criteria in this case.

No, it's not :(

Quoted 10 lines
Quoted 5 lines

This would let us handle the following cases very easily:

1. one read-write channel

	dmas = <&dmac 0x3 match>;

Where 0x3 is the req-id? Just to confirm ;-)

Why not have match after the phandle to be consistent with the simple example using name fields above?

The 0x3 is the direction, 1 for read, 2 for write, and 3 for read-write in this example. Sorry for being unclear.

The direction has to come before the dma-engine specific request ID data so that the common code can interpret it, while the variable-length data after it is only interpreted by the dmaengine driver.

Arnd

author
#60 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Arnd Bergmann

Hi Arnd,

On 06/14/2012 06:48 AM, Arnd Bergmann wrote:

[snip]

Quoted 40 lines

This would let us handle the following cases very easily:

1. one read-write channel

	dmas = <&dmac 0x3 match>;

2. a choice of two read-write channels:

	dmas = <&dmacA 0x3 matchA>, <&dmacB 0x3 matchB>;

3. one read-channel, one write channel:

	dmas = <&dmac 0x1 match-read>, <&dmac 0x2 match-write>;

4. a choice of two read channels and one write channel:

	dmas = <&dmacA 0x1 match-readA>, <&dmacA 0x2 match-write> 
			<&dmacB match-readB>;

And only the cases where we have more multiple channels that differ in more aspects would require named properties:

5. two different channels

	dmas = <&dmac 0x3 match-rwdata>, <&dmac 0x1 match-status>;
	dma-names = "rwdata", "status";

6. same as 5, but with a choice of channels:

	dmas = <&dmacA 0x3 match-rwdataA>, <&dmacA 0x1 match-status>;
		<dmacB 0x3 match-rwdataB>;
	dma-names = "rwdata", "status", "rwdata";

With a definition like that, we can implement a very simple device driver interface for the common cases, and a slightly more complex one for the more complex cases:

1. chan = of_dma_request_channel(dev->of_node, 0);
2. chan = of_dma_request_channel(dev->of_node, 0);

Quoted 8 lines
3. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
4. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
5. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);
6. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);

In the above examples, did you imply that the of_dma_request_channel() function would return a type of "struct dma_chan" and so be calling dma_request_channel() underneath?

I am been prototyping something, but wanted to make sure I am completely aligned on this :-)

Cheers
Jon

#61 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Before this goes much further... one fairly obvious and important point must be made.

You're designing an API here. You're designing it *WITHOUT* involving the two most important people in its design that there are. The DMA engine maintainers. Is this how we go about designing APIs - behind maintainers backs and then presenting it to the maintainers as a fait accompli?

There's 86 messages in this thread, none of which have been copied to them in any way. Why aren't they involved?

Quoted 64 lines · Jon Hunter

Hi Arnd,

On 06/14/2012 06:48 AM, Arnd Bergmann wrote:

[snip]

Quoted 40 lines

This would let us handle the following cases very easily:

1. one read-write channel

	dmas = <&dmac 0x3 match>;

2. a choice of two read-write channels:

	dmas = <&dmacA 0x3 matchA>, <&dmacB 0x3 matchB>;

3. one read-channel, one write channel:

	dmas = <&dmac 0x1 match-read>, <&dmac 0x2 match-write>;

4. a choice of two read channels and one write channel:

	dmas = <&dmacA 0x1 match-readA>, <&dmacA 0x2 match-write> 
			<&dmacB match-readB>;

And only the cases where we have more multiple channels that differ in more aspects would require named properties:

5. two different channels

	dmas = <&dmac 0x3 match-rwdata>, <&dmac 0x1 match-status>;
	dma-names = "rwdata", "status";

6. same as 5, but with a choice of channels:

	dmas = <&dmacA 0x3 match-rwdataA>, <&dmacA 0x1 match-status>;
		<dmacB 0x3 match-rwdataB>;
	dma-names = "rwdata", "status", "rwdata";

With a definition like that, we can implement a very simple device driver interface for the common cases, and a slightly more complex one for the more complex cases:

1. chan = of_dma_request_channel(dev->of_node, 0);
2. chan = of_dma_request_channel(dev->of_node, 0);

Quoted 8 lines
3. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
4. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
5. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);
6. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);

In the above examples, did you imply that the of_dma_request_channel() function would return a type of "struct dma_chan" and so be calling dma_request_channel() underneath?

I am been prototyping something, but wanted to make sure I am completely aligned on this :-)

Cheers
Jon

author
#62 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Russell,

Quoted 8 lines · Russell King - ARM Linux

Before this goes much further... one fairly obvious and important point must be made.

You're designing an API here. You're designing it *WITHOUT* involving the two most important people in its design that there are. The DMA engine maintainers. Is this how we go about designing APIs - behind maintainers backs and then presenting it to the maintainers as a fait accompli?

Absolutely not, this was not the intent and your point is well understood. I have added Dan and Vinod, and will ensure that he is added in future.

Quoted 2 lines

There's 86 messages in this thread, none of which have been copied to them in any way. Why aren't they involved?

Initially this binding was not dma-engine centric. However, I should have included them in this version from the beginning as I had evolved it in that direction.

Dan, Vinod, in this thread we have been discussing the addition of a generic device-tree binding for DMA controllers. In the below, we were discussing the addition of a device-tree API, which would work as a wrapper to the dma-engine dma_request_channel() API. I apologise for adding you late into the discussion. If you have any questions/comments let me know.

Jon

Quoted 65 lines · Jon Hunter
Quoted 64 lines

Hi Arnd,

On 06/14/2012 06:48 AM, Arnd Bergmann wrote:

[snip]

Quoted 40 lines

This would let us handle the following cases very easily:

1. one read-write channel

	dmas = <&dmac 0x3 match>;

2. a choice of two read-write channels:

	dmas = <&dmacA 0x3 matchA>, <&dmacB 0x3 matchB>;

3. one read-channel, one write channel:

	dmas = <&dmac 0x1 match-read>, <&dmac 0x2 match-write>;

4. a choice of two read channels and one write channel:

	dmas = <&dmacA 0x1 match-readA>, <&dmacA 0x2 match-write> 
			<&dmacB match-readB>;

And only the cases where we have more multiple channels that differ in more aspects would require named properties:

5. two different channels

	dmas = <&dmac 0x3 match-rwdata>, <&dmac 0x1 match-status>;
	dma-names = "rwdata", "status";

6. same as 5, but with a choice of channels:

	dmas = <&dmacA 0x3 match-rwdataA>, <&dmacA 0x1 match-status>;
		<dmacB 0x3 match-rwdataB>;
	dma-names = "rwdata", "status", "rwdata";

With a definition like that, we can implement a very simple device driver interface for the common cases, and a slightly more complex one for the more complex cases:

1. chan = of_dma_request_channel(dev->of_node, 0);
2. chan = of_dma_request_channel(dev->of_node, 0);

Quoted 8 lines
3. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
4. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
5. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);
6. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);

In the above examples, did you imply that the of_dma_request_channel() function would return a type of "struct dma_chan" and so be calling dma_request_channel() underneath?

I am been prototyping something, but wanted to make sure I am completely aligned on this :-)

Cheers
Jon

#63 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 23 lines · Jon Hunter

Hi Russell,

Quoted 8 lines · Russell King - ARM Linux

Before this goes much further... one fairly obvious and important point must be made.

You're designing an API here. You're designing it *WITHOUT* involving the two most important people in its design that there are. The DMA engine maintainers. Is this how we go about designing APIs - behind maintainers backs and then presenting it to the maintainers as a fait accompli?

Absolutely not, this was not the intent and your point is well understood. I have added Dan and Vinod, and will ensure that he is added in future.

Quoted 2 lines

There's 86 messages in this thread, none of which have been copied to them in any way. Why aren't they involved?

Initially this binding was not dma-engine centric. However, I should have included them in this version from the beginning as I had evolved it in that direction.

Quoted 6 lines

Dan, Vinod, in this thread we have been discussing the addition of a generic device-tree binding for DMA controllers. In the below, we were discussing the addition of a device-tree API, which would work as a wrapper to the dma-engine dma_request_channel() API. I apologise for adding you late into the discussion. If you have any questions/comments let me know.

Looks like this a long discussion, I will try to go through archives.

But am still unsure about about dmaengine part. If we have DT binding for dma controllers, why it they worry about dma_request_channel() IMO, the problem of channel mapping is not DT specific, it need to be solved at dmaengine and possibly the required mapping can come from DT among other mechanisms for various platforms.

This is what google told me about this patch set:

Quoted 20 lines

Design of DMA helpers

1. Supporting devices with multiple DMA controllers

In the case of DMA controllers that are using DMA Engine, requesting a channel is performed by calling the following function.

	struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
			dma_filter_fn filter_fn,
			void *filter_param);

The mask variable is used to identify the device controller in a list of controllers. The filter_fn and filter_param are used to identify the required dma channel and return a handle to the dma channel of type dma_chan. From the examples I have seen, the mask and filter_fn are constant for a given DMA controller. Therefore, when registering a DMA controller with device tree we can pass these parameters and store them so that a device can request them when requesting a channel. Hence, based upon this our register function for the DMA controller now looks like this.

Quoted 2 lines
	int of_dma_controller_register(struct device_node *np,
		dma_cap_mask_t *mask, dma_filter_fn fn);

IMO we should do away with filer functions.
If we solve the mapping problem, then we don't need a filer.

Quoted 14 lines

2. Supporting legacy devices not using DMA Engine

These devices present a problem, as there may not be a uniform way to easily support them with regard to device tree. However, _IF_ legacy devices that are not using DMA Engine, only have a single DMA controller, then this problem is a lot simpler. For example, if we look at the previously proposed API for registering a DMA controller (where we pass the mask and function pointer to the DMA Engine filter function) we can simply pass NULL and hence, a driver requesting the DMA channel information would receive NULL for the DMA Engine specific parameters. Then for legacy devices we simply need a means to return the channel information (more on this later). If there are legacy devices that do have multiple DMA controllers, then maybe they need to be converted to support DMA Engine. I am not sure if this is unreasonable???

Why should these be supported? They should be converted to use dmaengine over a reasonable amount of time.

Quoted 9 lines

3. Representing and requesting channel information

From a hardware perspective, a DMA channel could be represented as ...

i. channel index/number
ii. channel transfer type (optional)
iii. DMA interrupt mapping (optional)

Quoted 5 lines

Please note that the transfer type is used to indicate if the transfer is to device from memory, to memory from device, to memory from memory, etc. This can be useful when there is a device such as an MMC device that uses two DMA channels, one for reading (RX) and one for writing (TX).
From a dma controller perspective, it can service both with single

channel.
I have dma controller which can talk to three peripherals on both transmit and receive direction. The point is that 1:1 mapping of dma channel does not exist. So any representation which tries to do this may not work.

Quoted 66 lines

Forgetting device tree for now, some drivers use strings to represent a DMA channel instead of using an integer. I assume that these drivers then employ some sort of look-up table to convert the string into a channel number/index that the hardware understands. If this assumption is correct then when moving to a device tree implementation having such look-up tables in the driver should no longer be necessary as the device tree will provide the mapping of channel index/number to the device. Furthermore, it makes sense that device tree uses integers to represent channel as opposed to strings to save the driver having to convert the string into a integer at some later stage.

Next we need to think about how the DMA controller and channels are described in the device tree itself. The following device tree node example describes the properties of the DMA controller that includes, the register address range, number of interrupt supported, number of channels and number of request signals. This has been enhanced from the previous versions by adding number of channels and number of request signals.

	sdma: dma-controller at 4A056000 {
		compatible = "ti,omap4-sdma";
		reg = <0x4A056000 0x1000>;
		interrupts = <4>;
		#dma-cells = <2>;
		#dma-channels = <32>;
		#dma-requests = <127>;
	};

Given the above controller definition, DMA resources for a device, such as an MMC that uses two DMA channels, can be declared as follows.

	mmc1: mmc at 4809c000 {
		...
		dma = <&sdma 61 1 &sdma 62 2>;
		...
	};

The above syntax to represent each DMA resource is "controller-phandle + dma-channel + transfer-type". The transfer-type here is defined to match the types in DMA Engine dma_transfer_direction enumeration
(see include/linux/dmaengine.h). Hence, a "1" means DMA_MEM_TO_DEV and a "2" means "DMA_DEV_TO_MEM". This will be helpful later when requesting the channel information. You will also notice here that there is no entry for representing the interrupt used by the DMA channel and this is because this version has not added this capability. I believe that this will be important to define in the device tree, but at the moment this has been left out purely because passing this information was not supported for the device (OMAP) that I was using to implement this. This could be easily added if people find this implementation acceptable.

A driver can now request the DMA channel information by calling the following function.

int of_get_dma_channel_info(struct device_node *np, int type,
struct of_dma_channel_info *info)

Where type represents the transfer-type (again the DMA Engine dma_transfer_direction enumeration can be used here regardless of if DMA Engine is used) and of_dma_channel_info is defined as follows.

	struct of_dma_channel_info {
		int		dma_channel;
		dma_cap_mask_t	dma_cap;
		dma_filter_fn	dma_filter_func;
	};
Quoted 8 lines

Here dma_channel will always be valid and the other fields are optional depending on whether DMA Engine is used.

This implementation has been tested on OMAP4430 using Russell King's latest DMA Engine series for OMAP [3] and with Benoit Cousson latest DT changes for OMAP4 [4]. I have validated that MMC is working on the PANDA board with this implementation. I have not included all the changes for PANDA board here but just wished to share the implementation.

I am still unclear on how this attempts to solve mapping problem? Maybe i need more coffee at midnight break!

Quoted 71 lines
Quoted 60 lines · Jon Hunter
Quoted 59 lines

Hi Arnd,

On 06/14/2012 06:48 AM, Arnd Bergmann wrote:

[snip]

Quoted 40 lines

This would let us handle the following cases very easily:

1. one read-write channel

	dmas = <&dmac 0x3 match>;

2. a choice of two read-write channels:

	dmas = <&dmacA 0x3 matchA>, <&dmacB 0x3 matchB>;

3. one read-channel, one write channel:

	dmas = <&dmac 0x1 match-read>, <&dmac 0x2 match-write>;

4. a choice of two read channels and one write channel:

	dmas = <&dmacA 0x1 match-readA>, <&dmacA 0x2 match-write> 
			<&dmacB match-readB>;

And only the cases where we have more multiple channels that differ in more aspects would require named properties:

5. two different channels

	dmas = <&dmac 0x3 match-rwdata>, <&dmac 0x1 match-status>;
	dma-names = "rwdata", "status";

6. same as 5, but with a choice of channels:

	dmas = <&dmacA 0x3 match-rwdataA>, <&dmacA 0x1 match-status>;
		<dmacB 0x3 match-rwdataB>;
	dma-names = "rwdata", "status", "rwdata";

With a definition like that, we can implement a very simple device driver interface for the common cases, and a slightly more complex one for the more complex cases:

1. chan = of_dma_request_channel(dev->of_node, 0);
2. chan = of_dma_request_channel(dev->of_node, 0);

Quoted 8 lines
3. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
4. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
5. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);
6. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);

In the above examples, did you imply that the of_dma_request_channel() function would return a type of "struct dma_chan" and so be calling dma_request_channel() underneath?

Quoted 5 lines
Quoted 5 lines

I am been prototyping something, but wanted to make sure I am completely aligned on this :-)

Cheers
Jon

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

Signature · 1 line
~Vinod
#64 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 11 lines · Vinod Koul
Quoted 8 lines · Jon Hunter

Hi Russell,

Dan, Vinod, in this thread we have been discussing the addition of a generic device-tree binding for DMA controllers. In the below, we were discussing the addition of a device-tree API, which would work as a wrapper to the dma-engine dma_request_channel() API. I apologise for adding you late into the discussion. If you have any questions/comments let me know.

Looks like this a long discussion, I will try to go through archives.

Quoted 7 lines

But am still unsure about about dmaengine part. If we have DT binding for dma controllers, why it they worry about dma_request_channel() IMO, the problem of channel mapping is not DT specific, it need to be solved at dmaengine and possibly the required mapping can come from DT among other mechanisms for various platforms.

This is what google told me about this patch set:

dma_request_channel is called with some information about the channel provided in its arguments, and the driver might get that from a number of places.

In the case of having a fully populated device tree with this binding, the driver calling (of_)dma_request_channel does not need to know about any of that information because we should be able to encapsulate that completely in device tree data. It does not replace the regular interface but wraps around it to provide a higher abstraction level where possible.

Of course if you think we should not be doing that but instead have of_dma_request_channel() live besides dma_request_channel() rather than calling it, that should be absolutely fine too.

Quoted 16 lines
Quoted 16 lines

In the case of DMA controllers that are using DMA Engine, requesting a channel is performed by calling the following function.

	struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
			dma_filter_fn filter_fn,
			void *filter_param);

The mask variable is used to identify the device controller in a list of controllers. The filter_fn and filter_param are used to identify the required dma channel and return a handle to the dma channel of type dma_chan. From the examples I have seen, the mask and filter_fn are constant for a given DMA controller. Therefore, when registering a DMA controller with device tree we can pass these parameters and store them so that a device can request them when requesting a channel. Hence, based upon this our register function for the DMA controller now looks like this.

Quoted 4 lines
Quoted 2 lines
	int of_dma_controller_register(struct device_node *np,
		dma_cap_mask_t *mask, dma_filter_fn fn);

IMO we should do away with filter functions.
If we solve the mapping problem, then we don't need a filer.

The channel data in the device tree is still in a format that is specific to that dmaengine driver and interpreted by it. Using the regular dma_filter_fn prototype is not necessary, but it would be convenient because the dmaengine code already knows how to deal with it. If we don't use this method, how about adding another callback to struct dma_device like

bool (*device_match)(struct dma_chan *chan, struct property *req);

Quoted 14 lines
Quoted 13 lines

2. Supporting legacy devices not using DMA Engine

These devices present a problem, as there may not be a uniform way to easily support them with regard to device tree. However, _IF_ legacy devices that are not using DMA Engine, only have a single DMA controller, then this problem is a lot simpler. For example, if we look at the previously proposed API for registering a DMA controller (where we pass the mask and function pointer to the DMA Engine filter function) we can simply pass NULL and hence, a driver requesting the DMA channel information would receive NULL for the DMA Engine specific parameters. Then for legacy devices we simply need a means to return the channel information (more on this later). If there are legacy devices that do have multiple DMA controllers, then maybe they need to be converted to support DMA Engine. I am not sure if this is unreasonable???

Quoted 2 lines

Why should these be supported? They should be converted to use dmaengine over a reasonable amount of time.

I agree, at least for the long run. However, that is a separate issue to work on. Right now we need a generic way to represent dma requests independent of how they are used in the kernel. The device tree binding is supposed to be operating system independent so there should be nothing in it that requires the use of the linux dmaengine code.

For drivers that do not use dmaengine, we have to make a decision whether it's worth adding support for the DT binding first and converting the driver and its users to dmaengine later, or whether it's better to use the dmaengine API right away to avoid having to do changes twice.

Quoted 13 lines
Quoted 8 lines

3. Representing and requesting channel information

From a hardware perspective, a DMA channel could be represented as ...

i. channel index/number
ii. channel transfer type (optional)
iii. DMA interrupt mapping (optional)

Quoted 5 lines

Please note that the transfer type is used to indicate if the transfer is to device from memory, to memory from device, to memory from memory, etc. This can be useful when there is a device such as an MMC device that uses two DMA channels, one for reading (RX) and one for writing (TX).
From a dma controller perspective, it can service both with single

Quoted 5 lines

channel.
I have dma controller which can talk to three peripherals on both transmit and receive direction. The point is that 1:1 mapping of dma channel does not exist. So any representation which tries to do this may not work.

In the device tree, we know both the dmaengine and its slave, so we also know whether to put one or more requests in there.

Quoted 10 lines
Quoted 10 lines
	struct of_dma_channel_info {
		int		dma_channel;
		dma_cap_mask_t	dma_cap;
		dma_filter_fn	dma_filter_func;
	};

Here dma_channel will always be valid and the other fields are optional depending on whether DMA Engine is used.

Quoted 7 lines
Quoted 5 lines

This implementation has been tested on OMAP4430 using Russell King's latest DMA Engine series for OMAP [3] and with Benoit Cousson latest DT changes for OMAP4 [4]. I have validated that MMC is working on the PANDA board with this implementation. I have not included all the changes for PANDA board here but just wished to share the implementation.

I am still unclear on how this attempts to solve mapping problem? Maybe i need more coffee at midnight break!

I believe we have moved on from this proposal to a simpler one, doing away with the of_dma_channel_info.

Quoted 13 lines
Quoted 13 lines
Quoted 13 lines · Jon Hunter
Quoted 12 lines
Quoted 11 lines

1. chan = of_dma_request_channel(dev->of_node, 0);
2. chan = of_dma_request_channel(dev->of_node, 0);

3. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
4. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
5. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);
6. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

In the above examples, did you imply that the of_dma_request_channel() function would return a type of "struct dma_chan" and so be calling dma_request_channel() underneath?

I am been prototyping something, but wanted to make sure I am completely aligned on this :-)

This is what I think we need to be heading to.

Arnd

#65 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 3 lines · Arnd Bergmann

dma_request_channel is called with some information about the channel provided in its arguments, and the driver might get that from a number of places.

Today, we just ask for a channel with specific mask. Further filtering is done in filter function as we request a channel, not a specific one. In most slave cases, we need a specific channel from a specific controller, and that is where DT can play a role. In addition to DMA resources for dma and client driver, I would expect DT to provide the channel mapping information, which is anyway known only by platform. That should be a dmaengine binding and not client or controller specific. For different platforms this information can come from DT or something else.
Then, once a channel is requested dmaengine knows what to provide. And as you see the filter becomes redundant.

Quoted 64 lines

In the case of having a fully populated device tree with this binding, the driver calling (of_)dma_request_channel does not need to know about any of that information because we should be able to encapsulate that completely in device tree data. It does not replace the regular interface but wraps around it to provide a higher abstraction level where possible.

Of course if you think we should not be doing that but instead have of_dma_request_channel() live besides dma_request_channel() rather than calling it, that should be absolutely fine too.

Quoted 16 lines
Quoted 16 lines

In the case of DMA controllers that are using DMA Engine, requesting a channel is performed by calling the following function.

	struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
			dma_filter_fn filter_fn,
			void *filter_param);

The mask variable is used to identify the device controller in a list of controllers. The filter_fn and filter_param are used to identify the required dma channel and return a handle to the dma channel of type dma_chan. From the examples I have seen, the mask and filter_fn are constant for a given DMA controller. Therefore, when registering a DMA controller with device tree we can pass these parameters and store them so that a device can request them when requesting a channel. Hence, based upon this our register function for the DMA controller now looks like this.

Quoted 4 lines
Quoted 2 lines
	int of_dma_controller_register(struct device_node *np,
		dma_cap_mask_t *mask, dma_filter_fn fn);

IMO we should do away with filter functions.
If we solve the mapping problem, then we don't need a filer.

The channel data in the device tree is still in a format that is specific to that dmaengine driver and interpreted by it. Using the regular dma_filter_fn prototype is not necessary, but it would be convenient because the dmaengine code already knows how to deal with it. If we don't use this method, how about adding another callback to struct dma_device like

bool (*device_match)(struct dma_chan *chan, struct property *req);

Quoted 14 lines
Quoted 13 lines

2. Supporting legacy devices not using DMA Engine

These devices present a problem, as there may not be a uniform way to easily support them with regard to device tree. However, _IF_ legacy devices that are not using DMA Engine, only have a single DMA controller, then this problem is a lot simpler. For example, if we look at the previously proposed API for registering a DMA controller (where we pass the mask and function pointer to the DMA Engine filter function) we can simply pass NULL and hence, a driver requesting the DMA channel information would receive NULL for the DMA Engine specific parameters. Then for legacy devices we simply need a means to return the channel information (more on this later). If there are legacy devices that do have multiple DMA controllers, then maybe they need to be converted to support DMA Engine. I am not sure if this is unreasonable???

Quoted 2 lines

Why should these be supported? They should be converted to use dmaengine over a reasonable amount of time.

I agree, at least for the long run. However, that is a separate issue to work on. Right now we need a generic way to represent dma requests independent of how they are used in the kernel. The device tree binding is supposed to be operating system independent so there should be nothing in it that requires the use of the linux dmaengine code.

Quoted 4 lines

For drivers that do not use dmaengine, we have to make a decision whether it's worth adding support for the DT binding first and converting the driver and its users to dmaengine later, or whether it's better to use the dmaengine API right away to avoid having to do changes twice.

Latter please :)

Quoted 57 lines
Quoted 14 lines
Quoted 9 lines

3. Representing and requesting channel information

From a hardware perspective, a DMA channel could be represented as ...

i. channel index/number
ii. channel transfer type (optional)
iii. DMA interrupt mapping (optional)

Quoted 5 lines

Please note that the transfer type is used to indicate if the transfer is to device from memory, to memory from device, to memory from memory, etc. This can be useful when there is a device such as an MMC device that uses two DMA channels, one for reading (RX) and one for writing (TX).
From a dma controller perspective, it can service both with single

Quoted 5 lines

channel.
I have dma controller which can talk to three peripherals on both transmit and receive direction. The point is that 1:1 mapping of dma channel does not exist. So any representation which tries to do this may not work.

In the device tree, we know both the dmaengine and its slave, so we also know whether to put one or more requests in there.

Quoted 10 lines
Quoted 10 lines
	struct of_dma_channel_info {
		int		dma_channel;
		dma_cap_mask_t	dma_cap;
		dma_filter_fn	dma_filter_func;
	};

Here dma_channel will always be valid and the other fields are optional depending on whether DMA Engine is used.

Quoted 7 lines
Quoted 5 lines

This implementation has been tested on OMAP4430 using Russell King's latest DMA Engine series for OMAP [3] and with Benoit Cousson latest DT changes for OMAP4 [4]. I have validated that MMC is working on the PANDA board with this implementation. I have not included all the changes for PANDA board here but just wished to share the implementation.

I am still unclear on how this attempts to solve mapping problem? Maybe i need more coffee at midnight break!

I believe we have moved on from this proposal to a simpler one, doing away with the of_dma_channel_info.

Quoted 13 lines
Quoted 13 lines
Quoted 13 lines · Jon Hunter
Quoted 12 lines
Quoted 11 lines

1. chan = of_dma_request_channel(dev->of_node, 0);
2. chan = of_dma_request_channel(dev->of_node, 0);

3. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
4. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
5. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);
6. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);
Quoted 8 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 6 lines

In the above examples, did you imply that the of_dma_request_channel() function would return a type of "struct dma_chan" and so be calling dma_request_channel() underneath?

I am been prototyping something, but wanted to make sure I am completely aligned on this :-)

This is what I think we need to be heading to.

I am not sure about this, maybe haven't understood all details yet.

But, I was hoping the DT binding will be "hidden". DMAengine driver will get resource information from DT. Clients will get DMA resource information from DT. And if possible dmaengine gets mapping information from DT.
So then why should we have xx_dma_xxx apis?

Quoted 2 lines

Arnd

Signature · 1 line
~Vinod
#66 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 6 lines · Vinod Koul

Today, we just ask for a channel with specific mask. Further filtering is done in filter function as we request a channel, not a specific one. In most slave cases, we need a specific channel from a specific controller, and that is where DT can play a role. In addition to DMA resources for dma and client driver, I would expect DT to provide the channel mapping information, which is anyway known only by platform.

Can you describe what you mean by "channel mapping information"? Is that not what we pass into the filter function?

Quoted 5 lines

That should be a dmaengine binding and not client or controller specific. For different platforms this information can come from DT or something else.
Then, once a channel is requested dmaengine knows what to provide. And as you see the filter becomes redundant.

But what code interprets the channel mapping then?

Quoted 7 lines · Arnd Bergmann
Quoted 6 lines

I agree, at least for the long run. However, that is a separate issue to work on. Right now we need a generic way to represent dma requests independent of how they are used in the kernel. The device tree binding is supposed to be operating system independent so there should be nothing in it that requires the use of the linux dmaengine code.

Quoted 5 lines
Quoted 4 lines

For drivers that do not use dmaengine, we have to make a decision whether it's worth adding support for the DT binding first and converting the driver and its users to dmaengine later, or whether it's better to use the dmaengine API right away to avoid having to do changes twice.

Latter please :)

I'd always leave that decision up to the author of each driver that gets converted. Fortunately there are very few left that are not already using the dmaengine interfaces.

Quoted 20 lines
Quoted 20 lines
Quoted 19 lines
Quoted 19 lines
Quoted 19 lines · Jon Hunter
Quoted 18 lines
Quoted 11 lines

1. chan = of_dma_request_channel(dev->of_node, 0);
2. chan = of_dma_request_channel(dev->of_node, 0);

3. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
4. rxchan = of_dma_request_channel(dev->of_node, DMA_MEM_TO_DEV);
   txchan = of_dma_request_channel(dev->of_node, DMA_DEV_TO_MEM);
5. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);
6. chan = of_dma_request_named_channel(dev->of_node, "rwdata", 0);
   auxchan = of_dma_request_named_channel(dev->of_node, "status", DMA_DEV_TO_MEM);

In the above examples, did you imply that the of_dma_request_channel() function would return a type of "struct dma_chan" and so be calling dma_request_channel() underneath?

I am been prototyping something, but wanted to make sure I am completely aligned on this :-)

Quoted 8 lines
Quoted 1 line

This is what I think we need to be heading to.

I am not sure about this, maybe haven't understood all details yet.

But, I was hoping the DT binding will be "hidden". DMAengine driver will get resource information from DT. Clients will get DMA resource information from DT. And if possible dmaengine gets mapping information from DT.
So then why should we have xx_dma_xxx apis?

I think encoding a description for a dma request in a single number is the last thing we want to do here. We've tried that with IRQ and GPIO numbers and it got us into a huge mess that will need a long time to get out of.

Some platforms actually use IORESOURCE_DMA, which was useful to describe ISA DMA channels, for encoding some form of channel or request number, but this causes all sorts of problems. These are almost exclusively used by those platforms that don't have a dmaengine driver yet, so I'd hope that we can remove this as we convert those platforms over to dmaengine and device tree.

The representation in device tree as we have it now is a combination of a pointer to the dmaengine and a description of the request line in it, typically a single small integer number local to the dmaengine. We should not try to make that a global integer number again that just serves the purpose of looking up the dmaengine and local number again.

IMHO no device driver should be bothered with any artificial resource information, but instead I want all the DT parsing to happen in the dmaengine code (or some wrapper around it) where it gets used. The only thing that a device driver needs to know is that it wants to use a channel based on what is described in the device tree.

Arnd

#67 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 10 lines · Arnd Bergmann
Quoted 6 lines · Vinod Koul

Today, we just ask for a channel with specific mask. Further filtering is done in filter function as we request a channel, not a specific one. In most slave cases, we need a specific channel from a specific controller, and that is where DT can play a role. In addition to DMA resources for dma and client driver, I would expect DT to provide the channel mapping information, which is anyway known only by platform.

Can you describe what you mean by "channel mapping information"? Is that not what we pass into the filter function?

Today many dmaengine drivers have a filter function which is exported and then used by clients to filter out the channel. That is not a right way to do, so any future plan which is based on filter is not correct. IMHO dmaengine driver should *not* know anything about mapping. By mapping I refer to platform information which tells me which client can use which channel from which dmac.
If the dmaengine hardware has mux then we have flexible mapping, other cases would be where request lines are hard wired, so mapping is pretty much static.
This information if provided to dmaengine can result in dmaengine doing proper allocation of dma channels.
One of the proposals we discussed sometime back:
https://lkml.org/lkml/2012/3/8/26

Quoted 7 lines
Quoted 5 lines

That should be a dmaengine binding and not client or controller specific. For different platforms this information can come from DT or something else.
Then, once a channel is requested dmaengine knows what to provide. And as you see the filter becomes redundant.

But what code interprets the channel mapping then?

only dmaengine. In this case the mapping comes from DT.

Quoted 4 lines

I think encoding a description for a dma request in a single number is the last thing we want to do here. We've tried that with IRQ and GPIO numbers and it got us into a huge mess that will need a long time to get out of.

No i wasn't thinking of a number. The mapping shouldn't be a global number at all, though that is a very easy but not very scalable solution.
We need to take care of 1:1 mapping of client and channels as well as many:1 cases as well. A single global number cannot represent that properly.

My idea is platform gives this information to dmaengine. Clients and dmaengine driver do not worry about it. That also paves way for arch independent clients and drivers.

Quoted 14 lines

Some platforms actually use IORESOURCE_DMA, which was useful to describe ISA DMA channels, for encoding some form of channel or request number, but this causes all sorts of problems. These are almost exclusively used by those platforms that don't have a dmaengine driver yet, so I'd hope that we can remove this as we convert those platforms over to dmaengine and device tree.

The representation in device tree as we have it now is a combination of a pointer to the dmaengine and a description of the request line in it, typically a single small integer number local to the dmaengine. We should not try to make that a global integer number again that just serves the purpose of looking up the dmaengine and local number again.

Quoted 5 lines

IMHO no device driver should be bothered with any artificial resource information, but instead I want all the DT parsing to happen in the dmaengine code (or some wrapper around it) where it gets used. The only thing that a device driver needs to know is that it wants to use a channel based on what is described in the device tree.

Sure, but I would expect the clients and dmacs to find information about their devices from DT?
dmaengine should get only mapping information used for allocating channel to client.

Signature · 1 line
~Vinod
#68 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 9 lines · Vinod Koul
Quoted 8 lines · Arnd Bergmann
Quoted 6 lines · Vinod Koul

Today, we just ask for a channel with specific mask. Further filtering is done in filter function as we request a channel, not a specific one. In most slave cases, we need a specific channel from a specific controller, and that is where DT can play a role. In addition to DMA resources for dma and client driver, I would expect DT to provide the channel mapping information, which is anyway known only by platform.

Quoted 6 lines
Quoted 2 lines

Can you describe what you mean by "channel mapping information"? Is that not what we pass into the filter function?

Today many dmaengine drivers have a filter function which is exported and then used by clients to filter out the channel. That is not a right way to do, so any future plan which is based on filter is not correct.

I agree that exporting a filter function from the dmaengine driver is very wrong and should not be done because it requires that the device driver knows which engine is used and that is contrary to the idea of having an abstraction layer.

We were talking about using a filter function because that would be easy to do without changing the core dmaengine code. However, in the proposal, there would actually just be a single filter function that gets used by all drivers that have DT bindings, and it can be completely encapsulated in the of_dma_request_channel() function so it does not have to be a global symbol.

If we instead modify the dmaengine code itself to know about DT rather than wrapping around it, we would not need this filter function, but we should still have a probe() function that is called by dmaengine code to interpret the data that is specific to one dmaengine driver.

Quoted 3 lines

IMHO dmaengine driver should *not* know anything about mapping. By mapping I refer to platform information which tells me which client can use which channel from which dmac.

Agreed too. That information shoudd be part of the slave device-node in DT, as I have argued in this thread already. The slave device driver does not need to care about the format or the contents of it, but we need some code to interpret the contents. From all I can tell, the structure of this data cannot be completely generic because of all the special cases, so the code to interpret it would live in the probe() function I mentioned about that the dmaengine driver provides.

Quoted 11 lines
Quoted 4 lines

I think encoding a description for a dma request in a single number is the last thing we want to do here. We've tried that with IRQ and GPIO numbers and it got us into a huge mess that will need a long time to get out of.

No i wasn't thinking of a number. The mapping shouldn't be a global number at all, though that is a very easy but not very scalable solution.
We need to take care of 1:1 mapping of client and channels as well as many:1 cases as well. A single global number cannot represent that properly.

Quoted 3 lines

My idea is platform gives this information to dmaengine. Clients and dmaengine driver do not worry about it. That also paves way for arch independent clients and drivers.

IMO the platform should have no part in this. I absolutely want to get rid of any platform-specific hardcoded tables in the kernel for stuff that can easily be run-time detected from the device tree. There are cases where hard-coding in the kernel is easier, but I don't think this is one of them.

Quoted 18 lines
Quoted 13 lines

Some platforms actually use IORESOURCE_DMA, which was useful to describe ISA DMA channels, for encoding some form of channel or request number, but this causes all sorts of problems. These are almost exclusively used by those platforms that don't have a dmaengine driver yet, so I'd hope that we can remove this as we convert those platforms over to dmaengine and device tree.

The representation in device tree as we have it now is a combination of a pointer to the dmaengine and a description of the request line in it, typically a single small integer number local to the dmaengine. We should not try to make that a global integer number again that just serves the purpose of looking up the dmaengine and local number again.

Quoted 5 lines

IMHO no device driver should be bothered with any artificial resource information, but instead I want all the DT parsing to happen in the dmaengine code (or some wrapper around it) where it gets used. The only thing that a device driver needs to know is that it wants to use a channel based on what is described in the device tree.

Quoted 4 lines

Sure, but I would expect the clients and dmacs to find information about their devices from DT?
dmaengine should get only mapping information used for allocating channel to client.

Let's take a look at a concrete example. The arch/arm/mach-ux500/board-mop500-sdi.c file defines dma channel configuration for the mmc devices on the ux500 platform that looks like

static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH, .src_dev_type = STEDMA40_DEV_SRC_MEMORY, .dst_dev_type = DB8500_DMA_DEV28_SD_MM2_TX, .src_info.data_width = STEDMA40_WORD_WIDTH, .dst_info.data_width = STEDMA40_WORD_WIDTH,
};

I want to move this information to the device tree in a way that the device driver does not have to care about it. With the proposed binding, this would mean we get an mmci device node with a property containing something like

	dma-requests = <&dma40  /* pointer to dma engine */
			0x01    /* logical, mem to dev */
			28      /* DEV28_SD_MM2_TX */
			32>,	/* 32 bit width */
		       <&dma40 0x02 32 32>; /* dev to mem channel */ 

The fact that this dmaengine driver requires two cells (request number and data width) should only be known to the code that deals with that one driver and that should interpret those two cells, while the first two cells (pointer to dma-engine and direction) can be handled by the common dmaengine layer.

In order to do that, we need some code in the dmaengine driver that gets the property data as its argument.

Arnd

#69 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 22 lines · Arnd Bergmann
Quoted 9 lines · Vinod Koul
Quoted 8 lines · Arnd Bergmann
Quoted 6 lines · Vinod Koul

Today, we just ask for a channel with specific mask. Further filtering is done in filter function as we request a channel, not a specific one. In most slave cases, we need a specific channel from a specific controller, and that is where DT can play a role. In addition to DMA resources for dma and client driver, I would expect DT to provide the channel mapping information, which is anyway known only by platform.

Quoted 6 lines
Quoted 2 lines

Can you describe what you mean by "channel mapping information"? Is that not what we pass into the filter function?

Today many dmaengine drivers have a filter function which is exported and then used by clients to filter out the channel. That is not a right way to do, so any future plan which is based on filter is not correct.

I agree that exporting a filter function from the dmaengine driver is very wrong and should not be done because it requires that the device driver knows which engine is used and that is contrary to the idea of having an abstraction layer.

Quoted 6 lines

We were talking about using a filter function because that would be easy to do without changing the core dmaengine code. However, in the proposal, there would actually just be a single filter function that gets used by all drivers that have DT bindings, and it can be completely encapsulated in the of_dma_request_channel() function so it does not have to be a global symbol.

I kind of like this idea.

Quoted 6 lines

If we instead modify the dmaengine code itself to know about DT rather than wrapping around it, we would not need this filter function, but we should still have a probe() function that is called by dmaengine code to interpret the data that is specific to one dmaengine driver.

I was hoping we can have dmaengine binding, that way dmaengine core code knows about what to do when some client requests a channel.

Quoted 5 lines
Quoted 4 lines

IMHO dmaengine driver should *not* know anything about mapping. By mapping I refer to platform information which tells me which client can use which channel from which dmac.

Quoted 7 lines

Agreed too. That information shoudd be part of the slave device-node in DT, as I have argued in this thread already. The slave device driver does not need to care about the format or the contents of it, but we need some code to interpret the contents. From all I can tell, the structure of this data cannot be completely generic because of all the special cases, so the code to interpret it would live in the probe() function I mentioned about that the dmaengine driver provides.

rather than slave driver, why dont we keep this binding within dmaengine. That would make slave and clients completely independent.

Quoted 16 lines
Quoted 12 lines
Quoted 5 lines

I think encoding a description for a dma request in a single number is the last thing we want to do here. We've tried that with IRQ and GPIO numbers and it got us into a huge mess that will need a long time to get out of.

No i wasn't thinking of a number. The mapping shouldn't be a global number at all, though that is a very easy but not very scalable solution.
We need to take care of 1:1 mapping of client and channels as well as many:1 cases as well. A single global number cannot represent that properly.

Quoted 3 lines

My idea is platform gives this information to dmaengine. Clients and dmaengine driver do not worry about it. That also paves way for arch independent clients and drivers.

Quoted 5 lines

IMO the platform should have no part in this. I absolutely want to get rid of any platform-specific hardcoded tables in the kernel for stuff that can easily be run-time detected from the device tree. There are cases where hard-coding in the kernel is easier, but I don't think this is one of them.

Again, you got me wrong. We don't want any hardcoded table is kernel. The information in table should come from whatever way that platform can give me. For your case it should be DT.
We can have the map of which client can use which channel as DT binding of dmaengine core. So dmaengine can easily arbitrate about channel requests. Again this mapping information is not some even linux independent

Quoted 49 lines
Quoted 19 lines
Quoted 14 lines

Some platforms actually use IORESOURCE_DMA, which was useful to describe ISA DMA channels, for encoding some form of channel or request number, but this causes all sorts of problems. These are almost exclusively used by those platforms that don't have a dmaengine driver yet, so I'd hope that we can remove this as we convert those platforms over to dmaengine and device tree.

The representation in device tree as we have it now is a combination of a pointer to the dmaengine and a description of the request line in it, typically a single small integer number local to the dmaengine. We should not try to make that a global integer number again that just serves the purpose of looking up the dmaengine and local number again.

Quoted 5 lines

IMHO no device driver should be bothered with any artificial resource information, but instead I want all the DT parsing to happen in the dmaengine code (or some wrapper around it) where it gets used. The only thing that a device driver needs to know is that it wants to use a channel based on what is described in the device tree.

Quoted 4 lines

Sure, but I would expect the clients and dmacs to find information about their devices from DT?
dmaengine should get only mapping information used for allocating channel to client.

Let's take a look at a concrete example. The arch/arm/mach-ux500/board-mop500-sdi.c file defines dma channel configuration for the mmc devices on the ux500 platform that looks like

static struct stedma40_chan_cfg mop500_sdi2_dma_cfg_tx = {
.mode = STEDMA40_MODE_LOGICAL,
.dir = STEDMA40_MEM_TO_PERIPH, .src_dev_type = STEDMA40_DEV_SRC_MEMORY, .dst_dev_type = DB8500_DMA_DEV28_SD_MM2_TX, .src_info.data_width = STEDMA40_WORD_WIDTH, .dst_info.data_width = STEDMA40_WORD_WIDTH,
};

I want to move this information to the device tree in a way that the device driver does not have to care about it. With the proposed binding, this would mean we get an mmci device node with a property containing something like

	dma-requests = <&dma40  /* pointer to dma engine */
			0x01    /* logical, mem to dev */
			28      /* DEV28_SD_MM2_TX */
			32>,	/* 32 bit width */
		       <&dma40 0x02 32 32>; /* dev to mem channel */ 
Quoted 8 lines

The fact that this dmaengine driver requires two cells (request number and data width) should only be known to the code that deals with that one driver and that should interpret those two cells, while the first two cells (pointer to dma-engine and direction) can be handled by the common dmaengine layer.

In order to do that, we need some code in the dmaengine driver that gets the property data as its argument.

Yes but not thru the slave drivers.

Signature · 1 line
~Vinod
#70 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 22 lines · Vinod Koul
Quoted 7 lines · Arnd Bergmann
Quoted 1 line · Vinod Koul

On Tue, 2012-06-26 at 14:59 +0000, Arnd Bergmann wrote:

If we instead modify the dmaengine code itself to know about DT rather than wrapping around it, we would not need this filter function, but we should still have a probe() function that is called by dmaengine code to interpret the data that is specific to one dmaengine driver.

I was hoping we can have dmaengine binding, that way dmaengine core code knows about what to do when some client requests a channel.

Quoted 5 lines
Quoted 4 lines

IMHO dmaengine driver should *not* know anything about mapping. By mapping I refer to platform information which tells me which client can use which channel from which dmac.

Quoted 7 lines

Agreed too. That information shoudd be part of the slave device-node in DT, as I have argued in this thread already. The slave device driver does not need to care about the format or the contents of it, but we need some code to interpret the contents. From all I can tell, the structure of this data cannot be completely generic because of all the special cases, so the code to interpret it would live in the probe() function I mentioned about that the dmaengine driver provides.

Quoted 2 lines

rather than slave driver, why dont we keep this binding within dmaengine. That would make slave and clients completely independent.

Sorry, I believe I was just using the wrong terminology, and what I named the slave here would just be the client.

This may have contributed to a lot of confusion before, so let's make sure I use the right terms now:

a) slave == dmac == dmaengine driver
b) client == device driver, e.g. mmc
c) common code == dmaengine layer

Is this correct?

Quoted 21 lines
Quoted 15 lines
Quoted 11 lines
Quoted 4 lines

I think encoding a description for a dma request in a single number is the last thing we want to do here. We've tried that with IRQ and GPIO numbers and it got us into a huge mess that will need a long time to get out of.

No i wasn't thinking of a number. The mapping shouldn't be a global number at all, though that is a very easy but not very scalable solution.
We need to take care of 1:1 mapping of client and channels as well as many:1 cases as well. A single global number cannot represent that properly.

Quoted 3 lines

My idea is platform gives this information to dmaengine. Clients and dmaengine driver do not worry about it. That also paves way for arch independent clients and drivers.

Quoted 5 lines

IMO the platform should have no part in this. I absolutely want to get rid of any platform-specific hardcoded tables in the kernel for stuff that can easily be run-time detected from the device tree. There are cases where hard-coding in the kernel is easier, but I don't think this is one of them.

Quoted 3 lines

Again, you got me wrong. We don't want any hardcoded table is kernel. The information in table should come from whatever way that platform can give me. For your case it should be DT.

Ok, good.

Quoted 4 lines

We can have the map of which client can use which channel as DT binding of dmaengine core. So dmaengine can easily arbitrate about channel requests. Again this mapping information is not some even linux independent.

Why can't it be OS independent?

Do you mean there must be a global table, or are you ok with putting the information about a channel into the device that uses the channel, as we do for most other subsystems (IRQ, GPIO, pinctrl, ...). If not, what is the problem with that approach?

Arnd

#71 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

On Wed, 2012-06-27 at 15:20 +0000, Arnd Bergmann wrote:
Back from vacation... so restart the pending discussion

Quoted 4 lines

Sorry, I believe I was just using the wrong terminology, and what I named the slave here would just be the client.

Quoted 8 lines

This may have contributed to a lot of confusion before, so let's make sure I use the right terms now:

a) slave == dmac == dmaengine driver
b) client == device driver, e.g. mmc
c) common code == dmaengine layer

Is this correct?

Yup, that is what i use.

Quoted 26 lines
Quoted 22 lines
Quoted 16 lines
Quoted 12 lines
Quoted 5 lines

I think encoding a description for a dma request in a single number is the last thing we want to do here. We've tried that with IRQ and GPIO numbers and it got us into a huge mess that will need a long time to get out of.

No i wasn't thinking of a number. The mapping shouldn't be a global number at all, though that is a very easy but not very scalable solution.
We need to take care of 1:1 mapping of client and channels as well as many:1 cases as well. A single global number cannot represent that properly.

Quoted 3 lines

My idea is platform gives this information to dmaengine. Clients and dmaengine driver do not worry about it. That also paves way for arch independent clients and drivers.

Quoted 5 lines

IMO the platform should have no part in this. I absolutely want to get rid of any platform-specific hardcoded tables in the kernel for stuff that can easily be run-time detected from the device tree. There are cases where hard-coding in the kernel is easier, but I don't think this is one of them.

Quoted 3 lines

Again, you got me wrong. We don't want any hardcoded table is kernel. The information in table should come from whatever way that platform can give me. For your case it should be DT.

Quoted 8 lines

Ok, good.

Quoted 4 lines

We can have the map of which client can use which channel as DT binding of dmaengine core. So dmaengine can easily arbitrate about channel requests. Again this mapping information is not some even linux independent.

Why can't it be OS independent?

I meant OS independent, didn't come out well :(

Quoted 5 lines

Do you mean there must be a global table, or are you ok with putting the information about a channel into the device that uses the channel, as we do for most other subsystems (IRQ, GPIO, pinctrl, ...). If not, what is the problem with that approach?

Today, we simple ask, "give me dma channel with DMA_SLAVE capability".

If we change it to "give me dma channel which suits my need" and have additional information in dmaengine to handle this request effectively.

What that would mean is
a) DMA channel either knows which channel to provide, Or
b) Additional arguments provided to dmaengine API to help it find out which channel to provide.

It would be good to have client ask for a specific channel. But in order to build generic clients, we face a problem that clients may not know how they mapped to dmac by SoC designer. Or the mux maybe entirely flexible on which channel.

If we add this as DT property (which I assume should be platform specific), then client will know which channel to request. It can have two levels, dmac and channel. In case mux is flexible enough then client gets a channel and program the mux for this mapping.

I think this is the most simplistic solution I have for this, thoughts?

Signature · 1 line
~Vinod
#72 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Vinod

Quoted 1 line · Vinod Koul

On Wed, 2012-06-27 at 15:20 +0000, Arnd Bergmann wrote:

[snip]

Quoted 20 lines
Quoted 4 lines

Do you mean there must be a global table, or are you ok with putting the information about a channel into the device that uses the channel, as we do for most other subsystems (IRQ, GPIO, pinctrl, ...). If not, what is the problem with that approach?

Today, we simple ask, "give me dma channel with DMA_SLAVE capability".

If we change it to "give me dma channel which suits my need" and have additional information in dmaengine to handle this request effectively.

What that would mean is
a) DMA channel either knows which channel to provide, Or
b) Additional arguments provided to dmaengine API to help it find out which channel to provide.

It would be good to have client ask for a specific channel. But in order to build generic clients, we face a problem that clients may not know how they mapped to dmac by SoC designer. Or the mux maybe entirely flexible on which channel.

Quoted 6 lines

If we add this as DT property (which I assume should be platform specific), then client will know which channel to request. It can have two levels, dmac and channel. In case mux is flexible enough then client gets a channel and program the mux for this mapping.

I think this is the most simplistic solution I have for this, thoughts?

How about this my idea:

http://thread.gmane.org/gmane.linux.ports.arm.omap/75828/focus=15501

A small correction to it would be, that it shouldn't (necessarily) be a separate driver, because in some cases the mux resides on the DMAC, they share registers, so, it shouldn't really be a separate device and a separate driver, don't think it's worth an MFD set up or anything similar. So, I am trying ATM to implement something along the lines of

struct dma_chan *dma_request_slave_channel(struct device *dev,

		enum dma_transfer_direction direction, const char *name);

The connection between clients and the mux is always static, so, the dmaengine core can always just pass to the mux a client-side "pad" specifier (dev + direction + (optionally) name). The mux call-back will then see, where it can connect that pad and return a suitable channel descriptor - possibly with the help of the DMAC driver proper.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

#73 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Vinod Koul
Quoted 20 lines · Vinod Koul
Quoted 4 lines

Do you mean there must be a global table, or are you ok with putting the information about a channel into the device that uses the channel, as we do for most other subsystems (IRQ, GPIO, pinctrl, ...). If not, what is the problem with that approach?

Today, we simple ask, "give me dma channel with DMA_SLAVE capability".

If we change it to "give me dma channel which suits my need" and have additional information in dmaengine to handle this request effectively.

What that would mean is
a) DMA channel either knows which channel to provide, Or
b) Additional arguments provided to dmaengine API to help it find out which channel to provide.

It would be good to have client ask for a specific channel. But in order to build generic clients, we face a problem that clients may not know how they mapped to dmac by SoC designer. Or the mux maybe entirely flexible on which channel.

Quoted 6 lines

If we add this as DT property (which I assume should be platform specific), then client will know which channel to request. It can have two levels, dmac and channel. In case mux is flexible enough then client gets a channel and program the mux for this mapping.

I think this is the most simplistic solution I have for this, thoughts?

I think we're basically on the same page. Let's see if I have covered all the cases we discussed so far. I've tried to update the binding that Jon sent out initially with everything we've discussed, so please review this to see if I understood you correctly.

Arnd

* Generic DMA Controller and DMA request bindings

Generic binding to provide a way for a driver using DMA Engine to retrieve the DMA request or channel information that goes from a hardware device to a DMA controller.

* DMA controller

Required property:
- #dma-cells: Number elements to describe DMA channel information. Must be at least 2, allowing a phandle and a flags cell, but usually is larger so a client can also specify a request or channel number and/or some configuration.

Optional properties:
- #dma-channels: Number of DMA channels supported by the controller.
- #dma-requests: Number of DMA requests signals supported by the controller.

Example:

       sdma: dmaengine at 48000000 {
               compatible = "ti,omap4-sdma"
               reg = <0x48000000 0x1000>;
               interrupts = <4>;
               #dma-cells = <3>;
               #dma-channels = <32>;
               #dma-requests = <127>;
       };

* DMA client

Client drivers should specify the DMA property using a phandle to the controller followed by the number of DMA request/channel and the transfer type of the channel (eg. device-to-memory, memory-to-device, memory-to-memory, etc).

Required property:
dmas: list of one or more dma specifiers, each consisting of
- phandle pointing to dma controller node
- flags word, a bit map that can hold these flags
* 0x00000001 channel can be used for transfer from device
* 0x00000002 channel can be user for transfer to device
- zero or more cells in a format specific to the the dma controller node listed in the phandle. This typically contains a dma request line number or a channel number, but can contain any data that is used required for configuring a channel.

Optional property:
dma-names: when present, this shall contain one identifier string for each dma specifier in the dmas property. The specific strings that can be used are defined in the binding of the DMA client device. When multiple dma specifiers can be used as alternatives, the dma-names for those dma specifiers must be identical.

Any dma specifiers that have identical flags and identical dma-names (if present) shall refer to different dma controllers that can be used as alternatives, e.g. when a request line is connected to multiple dma controllers. If multiple dma specifiers are listed that have the same flags but refer to different functional channels, the dma-names property must be used to distinguish them.

Examples:

1. One DMA write channel, one DMA read/write channel:

       i2c1: i2c at 1 {
               ...
               dmas = <&sdma 2 1 &sdma 3 2>;
               ...
       };

2. A single read-write channel with two alternative dma controllers providing it:

	dmas = <&dma0 3 5
		&dma1 3 7
		&dma2 3 2>;

3. A device with three channels, one of which has two alternatives:

	dmas = <&dma0 1 4 /* data read */
		&dma0 2 6 /* data write */
		&dma1 1 0 /* error read */
		&dma2 1 0>; /* alternative error read */
	dma-names = "data", "data", "error", "error";

4. A dma controller requiring complex configuration:

       dma: dmaengine at 48000000 {
               compatible = "foo,foo-sdma"
               reg = <0x48000000 0x1000>;
               interrupts = <4>;
               #dma-cells = <6>; /* phandle, flag, request, channel,
					 input-width, output-width */
               #dma-channels = <32>;
               #dma-requests = <127>;
       };

       mmc at 49000000 {
		...
		dmas = <&dma 1	/* read */
			2	/* request line */
			5       /* channel */
			16	/* 16 bit bus width on read */
			8>	/* 8 bit bus width on write */
		       <&dma 2	/* write */
			3	/* request line */
			6       /* channel */
			8	/* 8 bit bus width on read */
			16>	/* 16 bit bus width on write */
#74 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 26 lines · Arnd Bergmann
Quoted 25 lines · Vinod Koul
Quoted 4 lines

Do you mean there must be a global table, or are you ok with putting the information about a channel into the device that uses the channel, as we do for most other subsystems (IRQ, GPIO, pinctrl, ...). If not, what is the problem with that approach?

Today, we simple ask, "give me dma channel with DMA_SLAVE capability".

If we change it to "give me dma channel which suits my need" and have additional information in dmaengine to handle this request effectively.

What that would mean is
a) DMA channel either knows which channel to provide, Or
b) Additional arguments provided to dmaengine API to help it find out which channel to provide.

It would be good to have client ask for a specific channel. But in order to build generic clients, we face a problem that clients may not know how they mapped to dmac by SoC designer. Or the mux maybe entirely flexible on which channel.

If we add this as DT property (which I assume should be platform specific), then client will know which channel to request. It can have two levels, dmac and channel. In case mux is flexible enough then client gets a channel and program the mux for this mapping.

Quoted 6 lines
Quoted 1 line

I think this is the most simplistic solution I have for this, thoughts?

I think we're basically on the same page. Let's see if I have covered all the cases we discussed so far. I've tried to update the binding that Jon sent out initially with everything we've discussed, so please review this to see if I understood you correctly.

I think this looks fine to me. Few comments below on client side

Quoted 40 lines

Arnd

* Generic DMA Controller and DMA request bindings

Generic binding to provide a way for a driver using DMA Engine to retrieve the DMA request or channel information that goes from a hardware device to a DMA controller.

* DMA controller

Required property:
- #dma-cells: Number elements to describe DMA channel information. Must be at least 2, allowing a phandle and a flags cell, but usually is larger so a client can also specify a request or channel number and/or some configuration.

Optional properties:
- #dma-channels: Number of DMA channels supported by the controller.
- #dma-requests: Number of DMA requests signals supported by the controller.

Example:

       sdma: dmaengine@48000000 {
               compatible = "ti,omap4-sdma"
               reg = <0x48000000 0x1000>;
               interrupts = <4>;
               #dma-cells = <3>;
               #dma-channels = <32>;
               #dma-requests = <127>;
       };

* DMA client

Client drivers should specify the DMA property using a phandle to the controller followed by the number of DMA request/channel and the transfer type of the channel (eg. device-to-memory, memory-to-device, memory-to-memory, etc).

Quoted 6 lines

Required property:
dmas: list of one or more dma specifiers, each consisting of
- phandle pointing to dma controller node
- flags word, a bit map that can hold these flags
* 0x00000001 channel can be used for transfer from device
* 0x00000002 channel can be user for transfer to device

Is this for identifying which channel is for TX and RX? If not I am not sure I understood it well

Quoted 44 lines

- zero or more cells in a format specific to the the dma controller node listed in the phandle. This typically contains a dma request line number or a channel number, but can contain any data that is used required for configuring a channel.

Optional property:
dma-names: when present, this shall contain one identifier string for each dma specifier in the dmas property. The specific strings that can be used are defined in the binding of the DMA client device. When multiple dma specifiers can be used as alternatives, the dma-names for those dma specifiers must be identical.

Any dma specifiers that have identical flags and identical dma-names (if present) shall refer to different dma controllers that can be used as alternatives, e.g. when a request line is connected to multiple dma controllers. If multiple dma specifiers are listed that have the same flags but refer to different functional channels, the dma-names property must be used to distinguish them.

Examples:

1. One DMA write channel, one DMA read/write channel:

       i2c1: i2c@1 {
               ...
               dmas = <&sdma 2 1 &sdma 3 2>;
               ...
       };

2. A single read-write channel with two alternative dma controllers providing it:

	dmas = <&dma0 3 5
		&dma1 3 7
		&dma2 3 2>;

3. A device with three channels, one of which has two alternatives:

	dmas = <&dma0 1 4 /* data read */
		&dma0 2 6 /* data write */
		&dma1 1 0 /* error read */
		&dma2 1 0>; /* alternative error read */
	dma-names = "data", "data", "error", "error";
Quoted 8 lines

4. A dma controller requiring complex configuration:

dma: dmaengine@48000000 {
compatible = "foo,foo-sdma"
reg = <0x48000000 0x1000>;
interrupts = <4>;
#dma-cells = <6>; /* phandle, flag, request, channel,
input-width, output-width */

Why would we want the widths to be here?
Assuming a DMA from System memory to a peripheral, source width should be system memory width and destination the peripheral width. IMO these should not be in dma property even if we need these

Quoted 17 lines
               #dma-channels = <32>;
               #dma-requests = <127>;
       };

       mmc@49000000 {
		...
		dmas = <&dma 1	/* read */
			2	/* request line */
			5       /* channel */
			16	/* 16 bit bus width on read */
			8>	/* 8 bit bus width on write */
		       <&dma 2	/* write */
			3	/* request line */
			6       /* channel */
			8	/* 8 bit bus width on read */
			16>	/* 16 bit bus width on write */

From this looks like flag is for TX/RX, so maybe i read correct :)

Signature · 1 line
~Vinod
#75 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 9 lines · Vinod Koul
Quoted 6 lines

Required property:
dmas: list of one or more dma specifiers, each consisting of
- phandle pointing to dma controller node
- flags word, a bit map that can hold these flags
* 0x00000001 channel can be used for transfer from device
* 0x00000002 channel can be user for transfer to device

Is this for identifying which channel is for TX and RX? If not I am not sure I understood it well

Yes, but we can potentially add more flags here.

The argument we had when coming up with this was roughly:

* we need to identify which specifiers are referring to the same conceptual channel and can be used as alternatives
* this could be done just using the dma-names property, but making dma-names mandatory adds complexity for everyone.
* Most devices have just one or two channels, and if they have two, there is usually one input and one output.

=> if the common dmaengine code can find out whether a channel is
input or output without looking at the dmac driver specific configuration, we don't need to add dma-names in most cases, but just let the client driver ask for "give me a channel with these flags".

Quoted 9 lines
Quoted 8 lines

4. A dma controller requiring complex configuration:

dma: dmaengine at 48000000 {
compatible = "foo,foo-sdma"
reg = <0x48000000 0x1000>;
interrupts = <4>;
#dma-cells = <6>; /* phandle, flag, request, channel,
input-width, output-width */

Quoted 4 lines

Why would we want the widths to be here?
Assuming a DMA from System memory to a peripheral, source width should be system memory width and destination the peripheral width. IMO these should not be in dma property even if we need these

I was just trying to come up with an example of something we might put into the additional configuration fields. This may or may not be a realistic one, I have no idea. If you know something else that one of the dma controllers might want to put in there, we should change the example.

I took the example of data width from 'struct stedma40_chan_cfg', which is used in some places to configure this from platform data. My impression was that if we want to move that data from board files into the device tree, it has to be here, but it can well be that there is a better place for it, e.g. in the global (channel independent) configuration of the dmac.

Arnd

#76 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 22 lines · Arnd Bergmann
Quoted 9 lines · Vinod Koul
Quoted 6 lines

Required property:
dmas: list of one or more dma specifiers, each consisting of
- phandle pointing to dma controller node
- flags word, a bit map that can hold these flags
* 0x00000001 channel can be used for transfer from device
* 0x00000002 channel can be user for transfer to device

Is this for identifying which channel is for TX and RX? If not I am not sure I understood it well

Yes, but we can potentially add more flags here.

The argument we had when coming up with this was roughly:

* we need to identify which specifiers are referring to the same conceptual channel and can be used as alternatives
* this could be done just using the dma-names property, but making dma-names mandatory adds complexity for everyone.
* Most devices have just one or two channels, and if they have two, there is usually one input and one output.

Quoted 4 lines

=> if the common dmaengine code can find out whether a channel is
input or output without looking at the dmac driver specific configuration, we don't need to add dma-names in most cases, but just let the client driver ask for "give me a channel with these flags".

No we don't export the direction of the channel and usually channel can be configured either way.
But from a client POV it makes sense as with the given direction you would need a specific request line for a channel. So this is right. But direction is something I don't expect to be used for "give me a channel"

Quoted 28 lines
Quoted 9 lines
Quoted 8 lines

4. A dma controller requiring complex configuration:

dma: dmaengine@48000000 {
compatible = "foo,foo-sdma"
reg = <0x48000000 0x1000>;
interrupts = <4>;
#dma-cells = <6>; /* phandle, flag, request, channel,
input-width, output-width */

Quoted 4 lines

Why would we want the widths to be here?
Assuming a DMA from System memory to a peripheral, source width should be system memory width and destination the peripheral width. IMO these should not be in dma property even if we need these

I was just trying to come up with an example of something we might put into the additional configuration fields. This may or may not be a realistic one, I have no idea. If you know something else that one of the dma controllers might want to put in there, we should change the example.

I took the example of data width from 'struct stedma40_chan_cfg', which is used in some places to configure this from platform data. My impression was that if we want to move that data from board files into the device tree, it has to be here, but it can well be that there is a better place for it, e.g. in the global (channel independent) configuration of the dmac.

Arnd

Signature · 1 line
~Vinod
author
#77 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Vinod,

Quoted 23 lines · Vinod Koul
Quoted 22 lines · Arnd Bergmann
Quoted 9 lines · Vinod Koul
Quoted 6 lines

Required property:
dmas: list of one or more dma specifiers, each consisting of
- phandle pointing to dma controller node
- flags word, a bit map that can hold these flags
* 0x00000001 channel can be used for transfer from device
* 0x00000002 channel can be user for transfer to device

Is this for identifying which channel is for TX and RX? If not I am not sure I understood it well

Yes, but we can potentially add more flags here.

The argument we had when coming up with this was roughly:

* we need to identify which specifiers are referring to the same conceptual channel and can be used as alternatives
* this could be done just using the dma-names property, but making dma-names mandatory adds complexity for everyone.
* Most devices have just one or two channels, and if they have two, there is usually one input and one output.

Quoted 6 lines
Quoted 4 lines

=> if the common dmaengine code can find out whether a channel is
input or output without looking at the dmac driver specific configuration, we don't need to add dma-names in most cases, but just let the client driver ask for "give me a channel with these flags".

No we don't export the direction of the channel and usually channel can be configured either way.

So yes I can see that a channel itself could be configured to support a given direction, but when we ask for a channel via dma_request_channel() we are going to get a channel that matches the criteria we pass using the filter parameter. So here the thinking was that "flags" is a filter parameter that the user could specify and one example being direction but it could be something else too.

Quoted 4 lines

But from a client POV it makes sense as with the given direction you would need a specific request line for a channel. So this is right. But direction is something I don't expect to be used for "give me a channel"

Ok. The thought was that the user would have the following means of requesting a channel ...

1. By name
2. By a filter parameter (flags)
3. By name and a filter parameter

So we would have the following APIs ...

struct dma_chan
*of_dma_request_channel(struct device_node *node, unsigned int flags); struct dma_chan
*of_dma_request_named channel(struct device_node *node, char *name, unsigned int flags);

In both of these the filter parameter flags is optional.

Let me know your thoughts on this.

Cheers
Jon

#78 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 15 lines · Jon Hunter

Ok. The thought was that the user would have the following means of requesting a channel ...

1. By name
2. By a filter parameter (flags)
3. By name and a filter parameter

So we would have the following APIs ...

struct dma_chan
*of_dma_request_channel(struct device_node *node, unsigned int flags); struct dma_chan
*of_dma_request_named channel(struct device_node *node, char *name, unsigned int flags);

Quoted 3 lines

In both of these the filter parameter flags is optional.

Let me know your thoughts on this.

I definitely like this version. I was thinking of a different variant where we have separate functions for each flag value, but I think yours is actually better.

Arnd

#79 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Jon Hunter
Quoted 29 lines · Jon Hunter

Hi Vinod,

Quoted 21 lines
Quoted 21 lines
Quoted 9 lines
Quoted 6 lines

Required property:
dmas: list of one or more dma specifiers, each consisting of
- phandle pointing to dma controller node
- flags word, a bit map that can hold these flags
* 0x00000001 channel can be used for transfer from device
* 0x00000002 channel can be user for transfer to device

Is this for identifying which channel is for TX and RX? If not I am not sure I understood it well

Yes, but we can potentially add more flags here.

The argument we had when coming up with this was roughly:

* we need to identify which specifiers are referring to the same conceptual channel and can be used as alternatives
* this could be done just using the dma-names property, but making dma-names mandatory adds complexity for everyone.
* Most devices have just one or two channels, and if they have two, there is usually one input and one output.

Quoted 6 lines
Quoted 4 lines

=> if the common dmaengine code can find out whether a channel is
input or output without looking at the dmac driver specific configuration, we don't need to add dma-names in most cases, but just let the client driver ask for "give me a channel with these flags".

No we don't export the direction of the channel and usually channel can be configured either way.

Quoted 6 lines

So yes I can see that a channel itself could be configured to support a given direction, but when we ask for a channel via dma_request_channel() we are going to get a channel that matches the criteria we pass using the filter parameter. So here the thinking was that "flags" is a filter parameter that the user could specify and one example being direction but it could be something else too.

Yes that can be done, but I am leaning towards clients not have to do anything :) DMAEngine needs to know mapping and when dma_request_channel() is called it _always_ gives you the right channel.

Maybe for slave case we need to create dma_request_slave_channel() which has additional arguments for dmaengine to do the filtering.

Quoted 9 lines
Quoted 4 lines

But from a client POV it makes sense as with the given direction you would need a specific request line for a channel. So this is right. But direction is something I don't expect to be used for "give me a channel"

Ok. The thought was that the user would have the following means of requesting a channel ...

1. By name

Bare name maynot be enough. In a dmac we have many channels which one to choose?

Quoted 1 line

2. By a filter parameter (flags)

Even with direction same problem can arise

Quoted 1 line

3. By name and a filter parameter

Additionally we need to say which channel, or making dmaengine already aware will help here

Quoted 9 lines

So we would have the following APIs ...

struct dma_chan
*of_dma_request_channel(struct device_node *node, unsigned int flags); struct dma_chan
*of_dma_request_named channel(struct device_node *node, char *name, unsigned int flags);

Quoted 3 lines

In both of these the filter parameter flags is optional.

Let me know your thoughts on this.

I would call them dma_request_slave_channel and try to add to it for additional filtering

Signature · 1 line
~Vinod
#80 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 11 lines · Vinod Koul
Quoted 9 lines
Quoted 4 lines

But from a client POV it makes sense as with the given direction you would need a specific request line for a channel. So this is right. But direction is something I don't expect to be used for "give me a channel"

Ok. The thought was that the user would have the following means of requesting a channel ...

1. By name

Bare name maynot be enough. In a dmac we have many channels which one to choose?

The name is what is associated with the property in the client device node, which describes everything the dmac driver needs to know. If the dmac needs to pick a specific channel, it can find out from the "dmas" property in combination with that name. If it is allowed to pick any channel, it doesn't need to bother.

Quoted 2 lines
Quoted 1 line

2. By a filter parameter (flags)

Even with direction same problem can arise

Again this is just identifying which dma specifier from the "dmas" property to pick. The use case is the very common one that there is at most one "read" and one "write" channel. In this case all the client has to know is that it wants a channel that fits the description given in DT for the direction it's looking for.

Quoted 3 lines
Quoted 1 line

3. By name and a filter parameter

Additionally we need to say which channel, or making dmaengine already aware will help here.

The channel is still described in the specifier, the client should not care about it.

Arnd

#81 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 10 lines · Arnd Bergmann
Quoted 9 lines · Vinod Koul
Quoted 9 lines
Quoted 4 lines

But from a client POV it makes sense as with the given direction you would need a specific request line for a channel. So this is right. But direction is something I don't expect to be used for "give me a channel"

Ok. The thought was that the user would have the following means of requesting a channel ...

1. By name

Quoted 8 lines
Quoted 2 lines

Bare name maynot be enough. In a dmac we have many channels which one to choose?

The name is what is associated with the property in the client device node, which describes everything the dmac driver needs to know. If the dmac needs to pick a specific channel, it can find out from the "dmas" property in combination with that name. If it is allowed to pick any channel, it doesn't need to bother.

dmac doesn't pick a channel. They don't come into picture till dmaengine and client have agreed on channel. And then channel callback in invoked, still it doesn't know which client.

Quoted 9 lines
Quoted 3 lines
Quoted 2 lines

2. By a filter parameter (flags)

Even with direction same problem can arise

Again this is just identifying which dma specifier from the "dmas" property to pick. The use case is the very common one that there is at most one "read" and one "write" channel. In this case all the client has to know is that it wants a channel that fits the description given in DT for the direction it's looking for.

client knows but that needs to be propagated to dmaengine (not dmac) and dmaengine filters this based on new information it has

Quoted 9 lines
Quoted 4 lines
Quoted 2 lines

3. By name and a filter parameter

Additionally we need to say which channel, or making dmaengine already aware will help here.

The channel is still described in the specifier, the client should not care about it.

Arnd

Signature · 1 line
~Vinod
author
#82 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 13 lines · Vinod Koul
Quoted 12 lines · Arnd Bergmann
Quoted 11 lines · Vinod Koul
Quoted 9 lines
Quoted 4 lines

But from a client POV it makes sense as with the given direction you would need a specific request line for a channel. So this is right. But direction is something I don't expect to be used for "give me a channel"

Ok. The thought was that the user would have the following means of requesting a channel ...

1. By name

Bare name maynot be enough. In a dmac we have many channels which one to choose?

Quoted 8 lines
Quoted 5 lines

The name is what is associated with the property in the client device node, which describes everything the dmac driver needs to know. If the dmac needs to pick a specific channel, it can find out from the "dmas" property in combination with that name. If it is allowed to pick any channel, it doesn't need to bother.

dmac doesn't pick a channel. They don't come into picture till dmaengine and client have agreed on channel. And then channel callback in invoked, still it doesn't know which client.

I think what Arnd meant was that dmaengine (not the dmac) would use the DT node and name information to extract the dma mapping information from the device tree and provide a channel back to the client. So yes the dmac is not involved here.

By the way, when I said "by name" above (and probably this was not clear) but it should have been "DT node and name". So really a channel is requested by ...

1. DT node and a name
2. DT node and a filter parameter (flags)
3. DT node, a name and a filter parameter (flags)

The DT node points us to the specific device in the DT, say an MMC node, and the MMC node then contains the DMA mapping info. The device node may have the mapping information have one or more DMA requests/channels and so then the name and/or flags is used to determine which the client needs.

Sorry hope that this is a little clearer.

Cheers
Jon

#83 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 19 lines · Jon Hunter
Quoted 18 lines · Vinod Koul
Quoted 17 lines · Arnd Bergmann
Quoted 11 lines · Vinod Koul
Quoted 9 lines
Quoted 4 lines

But from a client POV it makes sense as with the given direction you would need a specific request line for a channel. So this is right. But direction is something I don't expect to be used for "give me a channel"

Ok. The thought was that the user would have the following means of requesting a channel ...

1. By name

Bare name maynot be enough. In a dmac we have many channels which one to choose?

The name is what is associated with the property in the client device node, which describes everything the dmac driver needs to know. If the dmac needs to pick a specific channel, it can find out from the "dmas" property in combination with that name. If it is allowed to pick any channel, it doesn't need to bother.

Quoted 8 lines
Quoted 3 lines

dmac doesn't pick a channel. They don't come into picture till dmaengine and client have agreed on channel. And then channel callback in invoked, still it doesn't know which client.

I think what Arnd meant was that dmaengine (not the dmac) would use the DT node and name information to extract the dma mapping information from the device tree and provide a channel back to the client. So yes the dmac is not involved here.

Ok good that was main concern :)

Quoted 9 lines

By the way, when I said "by name" above (and probably this was not clear) but it should have been "DT node and name". So really a channel is requested by ...

1. DT node and a name
2. DT node and a filter parameter (flags)
3. DT node, a name and a filter parameter (flags)

Quoted 6 lines

The DT node points us to the specific device in the DT, say an MMC node, and the MMC node then contains the DMA mapping info. The device node may have the mapping information have one or more DMA requests/channels and so then the name and/or flags is used to determine which the client needs.

Sorry hope that this is a little clearer.

It is...

Signature · 1 line
~Vinod
author
#84 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Vinod Koul
Quoted 36 lines · Vinod Koul
Quoted 29 lines · Jon Hunter

Hi Vinod,

Quoted 21 lines
Quoted 21 lines
Quoted 9 lines
Quoted 6 lines

Required property:
dmas: list of one or more dma specifiers, each consisting of
- phandle pointing to dma controller node
- flags word, a bit map that can hold these flags
* 0x00000001 channel can be used for transfer from device
* 0x00000002 channel can be user for transfer to device

Is this for identifying which channel is for TX and RX? If not I am not sure I understood it well

Yes, but we can potentially add more flags here.

The argument we had when coming up with this was roughly:

* we need to identify which specifiers are referring to the same conceptual channel and can be used as alternatives
* this could be done just using the dma-names property, but making dma-names mandatory adds complexity for everyone.
* Most devices have just one or two channels, and if they have two, there is usually one input and one output.

Quoted 6 lines
Quoted 4 lines

=> if the common dmaengine code can find out whether a channel is
input or output without looking at the dmac driver specific configuration, we don't need to add dma-names in most cases, but just let the client driver ask for "give me a channel with these flags".

No we don't export the direction of the channel and usually channel can be configured either way.

Quoted 6 lines

So yes I can see that a channel itself could be configured to support a given direction, but when we ask for a channel via dma_request_channel() we are going to get a channel that matches the criteria we pass using the filter parameter. So here the thinking was that "flags" is a filter parameter that the user could specify and one example being direction but it could be something else too.

Quoted 3 lines

Yes that can be done, but I am leaning towards clients not have to do anything :) DMAEngine needs to know mapping and when dma_request_channel() is called it _always_ gives you the right channel.

Ok, so are you proposing to remove the filter function and parameter from the dma_request_channel()?

Quoted 2 lines

Maybe for slave case we need to create dma_request_slave_channel() which has additional arguments for dmaengine to do the filtering.

Ok, so what is not clear to me is if you envision that dma_request_slave_channel() is using a mapping table based look-up or the DT scheme or both.

As Arnd highlighted the DT convention is to store the DMA info in each of the device nodes and not store in a global mapping table which conflicts with having a mapping table approach for non-DT usage. So I am still not sure how you envision this function working for both the non-DT and DT use-cases.

Jon

#85 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 11 lines · Jon Hunter
Quoted 1 line
Quoted 1 line

So yes I can see that a channel itself could be configured to

support a

Quoted 1 line
Quoted 1 line

given direction, but when we ask for a channel via

dma_request_channel()

Quoted 1 line
Quoted 1 line

we are going to get a channel that matches the criteria we pass

using

Quoted 1 line
Quoted 1 line

the filter parameter. So here the thinking was that "flags" is a

filter

Quoted 1 line
Quoted 1 line

parameter that the user could specify and one example being

direction

Quoted 1 line
Quoted 1 line

but it could be something else too.

Quoted 8 lines
Quoted 1 line

Yes that can be done, but I am leaning towards clients not have to

do

Quoted 2 lines

anything :) DMAEngine needs to know mapping and when dma_request_channel() is called it _always_ gives you the right

channel.

Ok, so are you proposing to remove the filter function and parameter from the dma_request_channel()?

No. But add a new request call, dma_request_slave_channel() which is exclusive for slave usages and takes into account the mapping to be done for channels

Quoted 4 lines
Quoted 2 lines

Maybe for slave case we need to create dma_request_slave_channel()

which

Quoted 1 line

has additional arguments for dmaengine to do the filtering.

Yup

Quoted 4 lines

Ok, so what is not clear to me is if you envision that dma_request_slave_channel() is using a mapping table based look-up or the DT scheme or both.

The API should not worry about it. It would be good to have DT/ other be behind this API, so it is transparent to users. They just request a slave channel.

Quoted 7 lines

As Arnd highlighted the DT convention is to store the DMA info in each of the device nodes and not store in a global mapping table which conflicts with having a mapping table approach for non-DT usage. So I am
still not sure how you envision this function working for both the non-DT and DT use-cases.

I expect the clients to pass the mapping information to dmaengine in way dmaengine understands. This information can come from DT or other places. That way dmaengine gets info from any system being used and be able to allocate slave channel properly.

Signature · 1 line
~Vinod
author
#86 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Vinod,

Quoted 27 lines · Vinod Koul
Quoted 11 lines · Jon Hunter
Quoted 1 line
Quoted 1 line

So yes I can see that a channel itself could be configured to

support a

Quoted 1 line
Quoted 1 line

given direction, but when we ask for a channel via

dma_request_channel()

Quoted 1 line
Quoted 1 line

we are going to get a channel that matches the criteria we pass

using

Quoted 1 line
Quoted 1 line

the filter parameter. So here the thinking was that "flags" is a

filter

Quoted 1 line
Quoted 1 line

parameter that the user could specify and one example being

direction

Quoted 1 line
Quoted 1 line

but it could be something else too.

Quoted 8 lines
Quoted 1 line

Yes that can be done, but I am leaning towards clients not have to

do

Quoted 2 lines

anything :) DMAEngine needs to know mapping and when dma_request_channel() is called it _always_ gives you the right

channel.

Ok, so are you proposing to remove the filter function and parameter from the dma_request_channel()?

No. But add a new request call, dma_request_slave_channel() which is exclusive for slave usages and takes into account the mapping to be done for channels

Quoted 4 lines
Quoted 2 lines

Maybe for slave case we need to create dma_request_slave_channel()

which

Quoted 1 line

has additional arguments for dmaengine to do the filtering.

Quoted 8 lines

Yup

Quoted 4 lines

Ok, so what is not clear to me is if you envision that dma_request_slave_channel() is using a mapping table based look-up or the DT scheme or both.

The API should not worry about it. It would be good to have DT/ other be behind this API, so it is transparent to users. They just request a slave channel.

So would you envision something like (copying from Guennadi's API but changing direction to flags) ...

struct dma_chan *dma_request_slave_channel(struct device *dev,
char *name, unsigned int flags)

{
	/* If device-tree is present get slave info from here */
	if (dev->of_node)
		return of_dma_request_slave_channel(dev, name, flags);

	return NULL;
}

Ok, so right now the above is nothing more than a simple wrapper around a DT dma function to extract the slave info. However, it would allow us to add another means for getting the slave info in the future if necessary by adding an else part to the above.

Cheers
Jon

#87 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 52 lines · Jon Hunter

Hi Vinod,

Quoted 27 lines · Vinod Koul
Quoted 11 lines · Jon Hunter
Quoted 1 line
Quoted 1 line

So yes I can see that a channel itself could be configured to

support a

Quoted 1 line
Quoted 1 line

given direction, but when we ask for a channel via

dma_request_channel()

Quoted 1 line
Quoted 1 line

we are going to get a channel that matches the criteria we pass

using

Quoted 1 line
Quoted 1 line

the filter parameter. So here the thinking was that "flags" is a

filter

Quoted 1 line
Quoted 1 line

parameter that the user could specify and one example being

direction

Quoted 1 line
Quoted 1 line

but it could be something else too.

Quoted 8 lines
Quoted 1 line

Yes that can be done, but I am leaning towards clients not have to

do

Quoted 2 lines

anything :) DMAEngine needs to know mapping and when dma_request_channel() is called it _always_ gives you the right

channel.

Ok, so are you proposing to remove the filter function and parameter from the dma_request_channel()?

No. But add a new request call, dma_request_slave_channel() which is exclusive for slave usages and takes into account the mapping to be done for channels

Quoted 4 lines
Quoted 2 lines

Maybe for slave case we need to create dma_request_slave_channel()

which

Quoted 1 line

has additional arguments for dmaengine to do the filtering.

Quoted 8 lines

Yup

Quoted 4 lines

Ok, so what is not clear to me is if you envision that dma_request_slave_channel() is using a mapping table based look-up or the DT scheme or both.

The API should not worry about it. It would be good to have DT/ other be behind this API, so it is transparent to users. They just request a slave channel.

So would you envision something like (copying from Guennadi's API but changing direction to flags) ...

struct dma_chan *dma_request_slave_channel(struct device *dev,
char *name, unsigned int flags)

{
	/* If device-tree is present get slave info from here */
	if (dev->of_node)
		return of_dma_request_slave_channel(dev, name, flags);

	return NULL;
}
Quoted 5 lines

Ok, so right now the above is nothing more than a simple wrapper around a DT dma function to extract the slave info. However, it would allow us to add another means for getting the slave info in the future if necessary by adding an else part to the above.

Yup, something like above should work well. But without any dependency from dmac's (unlike the RFC propsed)

Signature · 1 line
~Vinod
#88 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Vinod Koul
Quoted 8 lines · Vinod Koul
Quoted 8 lines

4. A dma controller requiring complex configuration:

dma: dmaengine at 48000000 {
compatible = "foo,foo-sdma"
reg = <0x48000000 0x1000>;
interrupts = <4>;
#dma-cells = <6>; /* phandle, flag, request, channel,
input-width, output-width */

Quoted 4 lines

Why would we want the widths to be here?
Assuming a DMA from System memory to a peripheral, source width should be system memory width and destination the peripheral width. IMO these should not be in dma property even if we need these

Hi Vinod,

I know at least one peripheral which accepts 2 widths, 8bit and 16bit, namely the M-Systems DiskOnChip G3 NAND chip.
This device has to configured to choose either 8bit data bus access or 16bit data bus access.

I'm just wondering if that usecase will fit in without the width information embedded, and how will the driver choose the width to use ?

Cheers.

--
Robert

#89 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 14 lines · Robert Jarzmik
Quoted 8 lines · Vinod Koul
Quoted 8 lines

4. A dma controller requiring complex configuration:

dma: dmaengine@48000000 {
compatible = "foo,foo-sdma"
reg = <0x48000000 0x1000>;
interrupts = <4>;
#dma-cells = <6>; /* phandle, flag, request, channel,
input-width, output-width */

Quoted 4 lines

Why would we want the widths to be here?
Assuming a DMA from System memory to a peripheral, source width should be system memory width and destination the peripheral width. IMO these should not be in dma property even if we need these

Quoted 6 lines

Hi Vinod,

I know at least one peripheral which accepts 2 widths, 8bit and 16bit, namely the M-Systems DiskOnChip G3 NAND chip.
This device has to configured to choose either 8bit data bus access or 16bit data bus access.

That would be configured by the client (peripheral) driver and passed to dmaengine driver using the slave config. The point is that it has nothing to do with dma.

Quoted 3 lines

I'm just wondering if that usecase will fit in without the width information embedded, and how will the driver choose the width to use ?

It you need, this should be the client property and passed as argument to dma, not a dma property :)

Signature · 1 line
~Vinod
#90 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Vinod Koul
Quoted 74 lines · Vinod Koul
Quoted 26 lines · Arnd Bergmann
Quoted 25 lines · Vinod Koul
Quoted 4 lines

Do you mean there must be a global table, or are you ok with putting the information about a channel into the device that uses the channel, as we do for most other subsystems (IRQ, GPIO, pinctrl, ...). If not, what is the problem with that approach?

Today, we simple ask, "give me dma channel with DMA_SLAVE capability".

If we change it to "give me dma channel which suits my need" and have additional information in dmaengine to handle this request effectively.

What that would mean is
a) DMA channel either knows which channel to provide, Or
b) Additional arguments provided to dmaengine API to help it find out which channel to provide.

It would be good to have client ask for a specific channel. But in order to build generic clients, we face a problem that clients may not know how they mapped to dmac by SoC designer. Or the mux maybe entirely flexible on which channel.

If we add this as DT property (which I assume should be platform specific), then client will know which channel to request. It can have two levels, dmac and channel. In case mux is flexible enough then client gets a channel and program the mux for this mapping.

Quoted 6 lines
Quoted 1 line

I think this is the most simplistic solution I have for this, thoughts?

I think we're basically on the same page. Let's see if I have covered all the cases we discussed so far. I've tried to update the binding that Jon sent out initially with everything we've discussed, so please review this to see if I understood you correctly.

I think this looks fine to me. Few comments below on client side

Quoted 40 lines

Arnd

* Generic DMA Controller and DMA request bindings

Generic binding to provide a way for a driver using DMA Engine to retrieve the DMA request or channel information that goes from a hardware device to a DMA controller.

* DMA controller

Required property:
- #dma-cells: Number elements to describe DMA channel information. Must be at least 2, allowing a phandle and a flags cell, but usually is larger so a client can also specify a request or channel number and/or some configuration.

Optional properties:
- #dma-channels: Number of DMA channels supported by the controller.
- #dma-requests: Number of DMA requests signals supported by the controller.

Example:

       sdma: dmaengine at 48000000 {
               compatible = "ti,omap4-sdma"
               reg = <0x48000000 0x1000>;
               interrupts = <4>;
               #dma-cells = <3>;
               #dma-channels = <32>;
               #dma-requests = <127>;
       };

* DMA client

Client drivers should specify the DMA property using a phandle to the controller followed by the number of DMA request/channel and the transfer type of the channel (eg. device-to-memory, memory-to-device, memory-to-memory, etc).

Quoted 13 lines
Quoted 6 lines

Required property:
dmas: list of one or more dma specifiers, each consisting of
- phandle pointing to dma controller node
- flags word, a bit map that can hold these flags
* 0x00000001 channel can be used for transfer from device
* 0x00000002 channel can be user for transfer to device

Is this for identifying which channel is for TX and RX? If not I am not sure I understood it well

Quoted 4 lines

- zero or more cells in a format specific to the the dma controller node listed in the phandle. This typically contains a dma request line number or a channel number, but can contain any data that is used required for configuring a channel.

How about extend struct dma_slave_config, adding one member of "request_line", if
"request line" is must config in most platform.

struct dma_slave_config {
~
u32 request_line;
}
The advantage is request_line can be get directly from dmaengine_slave_config regardless of DT.

Quoted 78 lines
Quoted 40 lines

Optional property:
dma-names: when present, this shall contain one identifier string for each dma specifier in the dmas property. The specific strings that can be used are defined in the binding of the DMA client device. When multiple dma specifiers can be used as alternatives, the dma-names for those dma specifiers must be identical.

Any dma specifiers that have identical flags and identical dma-names (if present) shall refer to different dma controllers that can be used as alternatives, e.g. when a request line is connected to multiple dma controllers. If multiple dma specifiers are listed that have the same flags but refer to different functional channels, the dma-names property must be used to distinguish them.

Examples:

1. One DMA write channel, one DMA read/write channel:

       i2c1: i2c at 1 {
               ...
               dmas = <&sdma 2 1 &sdma 3 2>;
               ...
       };

2. A single read-write channel with two alternative dma controllers providing it:

      dmas = <&dma0 3 5
              &dma1 3 7
              &dma2 3 2>;

3. A device with three channels, one of which has two alternatives:

      dmas = <&dma0 1 4 /* data read */
              &dma0 2 6 /* data write */
              &dma1 1 0 /* error read */
              &dma2 1 0>; /* alternative error read */
      dma-names = "data", "data", "error", "error";
Quoted 8 lines

4. A dma controller requiring complex configuration:

dma: dmaengine at 48000000 {
compatible = "foo,foo-sdma"
reg = <0x48000000 0x1000>;
interrupts = <4>;
#dma-cells = <6>; /* phandle, flag, request, channel,
input-width, output-width */

Why would we want the widths to be here?
Assuming a DMA from System memory to a peripheral, source width should be system memory width and destination the peripheral width. IMO these should not be in dma property even if we need these

Quoted 4 lines

#dma-channels = <32>;
#dma-requests = <127>;
};

Quoted 13 lines

mmc at 49000000 {
...
dmas = <&dma 1 /* read */
2 /* request line */
5 /* channel */
16 /* 16 bit bus width on read */
8> /* 8 bit bus width on write */
<&dma 2 /* write */
3 /* request line */
6 /* channel */
8 /* 8 bit bus width on read */
16> /* 16 bit bus width on write */
From this looks like flag is for TX/RX, so maybe i read correct :)

--
~Vinod

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel at lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

#91 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Arnd Bergmann

On 07/17/2012 01:24 PM, Arnd Bergmann wrote:
...

Quoted 4 lines

I think we're basically on the same page. Let's see if I have covered all the cases we discussed so far. I've tried to update the binding that Jon sent out initially with everything we've discussed, so please review this to see if I understood you correctly.

...

Quoted 1 line

* DMA client

...

Quoted 1 line

Examples:

...

Quoted 1 line

3. A device with three channels, one of which has two alternatives:

s/three/four/ s/one of which/both of which/

This binding doc seems reasonable to me.

#92 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 5 lines · Stephen Warren
Quoted 1 line

3. A device with three channels, one of which has two alternatives:

s/three/four/ s/one of which/both of which/

This binding doc seems reasonable to me.

I asked a linguist about it who said that you can't have "both" together with "four". She also mentioned that my text is rather confusing, so maybe you also got it wrong. I'll try adding some explanation:

3. A device with three channels, one of which has two alternatives:

        dmas = <&dma0 1 4   /* first channel,  data read */
                &dma0 2 6   /* second channel, data write */
                &dma1 1 0   /* third channel,  error read */

&dma2 1 0>; /* third channel, ernative error read */
dma-names = "data", "data", "error", "error";

The first two channels are identified by having a unique direction flag in combination with the "data" string. For the third channel, there are two dma specifiers with identical flags (1) and strings ("error"), so only one specifier may be used at a time.

Arnd

#93 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 10 lines · Arnd Bergmann
Quoted 5 lines · Stephen Warren
Quoted 1 line

3. A device with three channels, one of which has two alternatives:

s/three/four/ s/one of which/both of which/

This binding doc seems reasonable to me.

I asked a linguist about it who said that you can't have "both" together with "four". She also mentioned that my text is rather confusing, so maybe you also got it wrong. I'll try adding some explanation:

Oops, I guess I meant s/three/two/ :-)

It seems that given there are two values for dma-names, there really are two channels; it's just that one channel is bi-directional, and the second has two alternatives.

Still, I guess you could also view this as three separate channels instead. In which case, the text below makes sense.

Quoted 12 lines

3. A device with three channels, one of which has two alternatives:

        dmas = <&dma0 1 4   /* first channel,  data read */
                &dma0 2 6   /* second channel, data write */
                &dma1 1 0   /* third channel,  error read */

&dma2 1 0>; /* third channel, ernative error read */
dma-names = "data", "data", "error", "error";

The first two channels are identified by having a unique direction flag in combination with the "data" string. For the third channel, there are two dma specifiers with identical flags (1) and strings ("error"), so only one specifier may be used at a time.

#94 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 4 lines · Stephen Warren

It seems that given there are two values for dma-names, there really are two channels; it's just that one channel is bi-directional, and the second has two alternatives.

Quoted 11 lines

Still, I guess you could also view this as three separate channels instead. In which case, the text below makes sense.

Quoted 8 lines

3. A device with three channels, one of which has two alternatives:

        dmas = <&dma0 1 4   /* first channel,  data read */
                &dma0 2 6   /* second channel, data write */
                &dma1 1 0   /* third channel,  error read */

&dma2 1 0>; /* third channel, ernative error read */
dma-names = "data", "data", "error", "error";

A bidirectional channel would have only one request line, not two, and we would write that as

dmas = <&dma0 3 4>; /* one channel on dmarq 4, read-write */

Arnd

#95 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Stephen Warren

Hello.

Quoted 4 lines · Stephen Warren
Quoted 4 lines

I think we're basically on the same page. Let's see if I have covered all the cases we discussed so far. I've tried to update the binding that Jon sent out initially with everything we've discussed, so please review this to see if I understood you correctly.

Quoted 8 lines

...

Quoted 1 line

* DMA client

...

Quoted 1 line

Examples:

...

Quoted 1 line

3. A device with three channels, one of which has two alternatives:

s/three/four/ s/one of which/both of which/

You can't say "both" of 4 channels, only "all". :-)

WBR, Sergei

#96 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Arnd Bergmann

On Mon, 25 Jun 2012, Arnd Bergmann wrote:

[snip]

Quoted 9 lines

The channel data in the device tree is still in a format that is specific to that dmaengine driver and interpreted by it. Using the regular dma_filter_fn prototype is not necessary, but it would be convenient because the dmaengine code already knows how to deal with it. If we don't use this method, how about adding another callback to struct dma_device like

bool (*device_match)(struct dma_chan *chan, struct property *req);

I like this idea, but why don't we extend it to also cover the non-DT case? I.e., why don't we add the above callback (call it "match" or "filter" or anything else) to dmaengine operations and inside (the extended) dma_request_channel(), instead of calling the filter function, passed as a parameter, we loop over all registered DMAC devices and call their filter callbacks, until one of them returns true? In fact, it goes back to my earlier proposal from
http://thread.gmane.org/gmane.linux.kernel/1246957
which I, possibly, failed to explain properly. So, the transformation chain from today's API would be (all code is approximate):

(today)

<client driver>

	dma_request_channel(mask, filter, filter_arg);

<dmaengine_core>

	for_each_channel() {
		ret = (*filter)(chan, filter_arg);
		if (ret) {
			ret = chan->device->device_alloc_chan_resources(chan);
			if (!ret)
				return chan;
			else
				return NULL;
		}
	}

(can be transformed to)

<client driver>

	dma_request_channel(mask, filter_arg);

<dmaengine_core>

	for_each_channel() {
		ret = chan->device->filter(chan, filter_arg);
		if (ret) {
			<same as above>
		}
	}

(which further could be simplified to)

<client driver>

	dma_request_channel(mask, filter_arg);

<dmaengine_core>

	for_each_channel() {
		ret = chan->device->device_alloc_chan_resources(chan, filter_arg);
		if (!ret)
			return chan;
		else if (ret != -ENODEV)
			return ret;
		/* -ENODEV - try the next channel */
	}

Which is quite similar to my above mentioned proposal. Wouldn't this both improve the present API and prepare it for DT?

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

#97 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 36 lines · Guennadi Liakhovetski

On Mon, 25 Jun 2012, Arnd Bergmann wrote:

[snip]

Quoted 9 lines

The channel data in the device tree is still in a format that is specific to that dmaengine driver and interpreted by it. Using the regular dma_filter_fn prototype is not necessary, but it would be convenient because the dmaengine code already knows how to deal with it. If we don't use this method, how about adding another callback to struct dma_device like

bool (*device_match)(struct dma_chan *chan, struct property *req);

I like this idea, but why don't we extend it to also cover the non-DT case? I.e., why don't we add the above callback (call it "match" or "filter" or anything else) to dmaengine operations and inside (the extended) dma_request_channel(), instead of calling the filter function, passed as a parameter, we loop over all registered DMAC devices and call their filter callbacks, until one of them returns true? In fact, it goes back to my earlier proposal from
http://thread.gmane.org/gmane.linux.kernel/1246957
which I, possibly, failed to explain properly. So, the transformation chain from today's API would be (all code is approximate):

...
<dmaengine_core>

	for_each_channel() {
		ret = chan->device->device_alloc_chan_resources(chan, filter_arg);
		if (!ret)
			return chan;
		else if (ret != -ENODEV)
			return ret;
		/* -ENODEV - try the next channel */
	}
Quoted 2 lines

Which is quite similar to my above mentioned proposal. Wouldn't this both improve the present API and prepare it for DT?

How would the individual driver know the size of the filter_arg? In the device tree code, we would know if from #dma-cells of the engine node, and that gets checked when reading the property, but when you have a free-form data structure, it's much less clear.

Also, you could easily have an argument that looks valid for more than one dmaengine, but really isn't.

I think for your proposal to work, we would need something like the phandle for the dmaengine device that is at the start of the property in the DT case.

Arnd

#98 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Arnd

Quoted 37 lines · Arnd Bergmann
Quoted 36 lines · Guennadi Liakhovetski

On Mon, 25 Jun 2012, Arnd Bergmann wrote:

[snip]

Quoted 9 lines

The channel data in the device tree is still in a format that is specific to that dmaengine driver and interpreted by it. Using the regular dma_filter_fn prototype is not necessary, but it would be convenient because the dmaengine code already knows how to deal with it. If we don't use this method, how about adding another callback to struct dma_device like

bool (*device_match)(struct dma_chan *chan, struct property *req);

I like this idea, but why don't we extend it to also cover the non-DT case? I.e., why don't we add the above callback (call it "match" or "filter" or anything else) to dmaengine operations and inside (the extended) dma_request_channel(), instead of calling the filter function, passed as a parameter, we loop over all registered DMAC devices and call their filter callbacks, until one of them returns true? In fact, it goes back to my earlier proposal from
http://thread.gmane.org/gmane.linux.kernel/1246957
which I, possibly, failed to explain properly. So, the transformation chain from today's API would be (all code is approximate):

...
<dmaengine_core>

	for_each_channel() {
		ret = chan->device->device_alloc_chan_resources(chan, filter_arg);
		if (!ret)
			return chan;
		else if (ret != -ENODEV)
			return ret;
		/* -ENODEV - try the next channel */
	}
Quoted 4 lines
Quoted 2 lines

Which is quite similar to my above mentioned proposal. Wouldn't this both improve the present API and prepare it for DT?

How would the individual driver know the size of the filter_arg?

In exactly the same way as most dmaengine drivers do it today: they don't touch filter_arg until they're sure this is one of their channels. And this they typically do by comparing the driver pointer, e.g.:

bool sa11x0_dma_filter_fn(struct dma_chan *chan, void *param)

{
	if (chan->device->dev->driver == &sa11x0_dma_driver.driver) {

Thanks
Guennadi

Quoted 5 lines

In the
device tree code, we would know if from #dma-cells of the engine node, and that gets checked when reading the property, but when you have a free-form data structure, it's much less clear.

Quoted 9 lines

Also, you could easily have an argument that looks valid for more than one dmaengine, but really isn't.

I think for your proposal to work, we would need something like the phandle for the dmaengine device that is at the start of the property in the DT case.

Arnd

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

#99 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 15 lines · Guennadi Liakhovetski
Quoted 10 lines
Quoted 10 lines

<dmaengine_core>

    for_each_channel() {
            ret = chan->device->device_alloc_chan_resources(chan, filter_arg);
            if (!ret)
                    return chan;
            else if (ret != -ENODEV)
                    return ret;
            /* -ENODEV - try the next channel */
    }
Quoted 4 lines
Quoted 2 lines

Which is quite similar to my above mentioned proposal. Wouldn't this both improve the present API and prepare it for DT?

How would the individual driver know the size of the filter_arg?

Quoted 7 lines

In exactly the same way as most dmaengine drivers do it today: they don't touch filter_arg until they're sure this is one of their channels. And this they typically do by comparing the driver pointer, e.g.:

bool sa11x0_dma_filter_fn(struct dma_chan *chan, void *param)

{
        if (chan->device->dev->driver == &sa11x0_dma_driver.driver) {

I don't understand. This already matches because we're calling the device_alloc_chan_resources() function of the specific device that matches the channel. However, we do the same for each channel, with the same data, but different controllers, each of which will think they match the channel.

Arnd

#100 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Guennadi Liakhovetski
Quoted 5 lines · Guennadi Liakhovetski

Hi Arnd

Quoted 1 line · Arnd Bergmann

How would the individual driver know the size of the filter_arg?

Quoted 7 lines

In exactly the same way as most dmaengine drivers do it today: they don't touch filter_arg until they're sure this is one of their channels. And this they typically do by comparing the driver pointer, e.g.:

bool sa11x0_dma_filter_fn(struct dma_chan *chan, void *param)

{
	if (chan->device->dev->driver == &sa11x0_dma_driver.driver) {

That's utter rubbish, I'm afraid.

Let's say you move that code into sa11x0's alloc_chan_resources() function. It will _never_ be called for a channel which isn't owned by the sa11x0 DMA driver - look at what __dma_request_channel() does:

        list_for_each_entry_safe(device, _d, &dma_device_list, global_node) {

This walks the list of DMA devices.

                chan = private_candidate(mask, device, fn, fn_param);

This walks the channels _on_ _that_ dma device. Those channels can only be owned by the DMA device, which is in turn owned by the driver, which in turn is owned by the struct driver that the above filter function is checking.

So, all in all, this check inside chan_alloc_resources() tells you absolutely _nothing_ about the suitability of dereferencing your filter_arg data. At all.

#101 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Guennadi Liakhovetski
Quoted 41 lines · Guennadi Liakhovetski

I like this idea, but why don't we extend it to also cover the non-DT case? I.e., why don't we add the above callback (call it "match" or "filter" or anything else) to dmaengine operations and inside (the extended) dma_request_channel(), instead of calling the filter function, passed as a parameter, we loop over all registered DMAC devices and call their filter callbacks, until one of them returns true? In fact, it goes back to my earlier proposal from
http://thread.gmane.org/gmane.linux.kernel/1246957
which I, possibly, failed to explain properly. So, the transformation chain from today's API would be (all code is approximate):

(today)

<client driver>

	dma_request_channel(mask, filter, filter_arg);

<dmaengine_core>

	for_each_channel() {
		ret = (*filter)(chan, filter_arg);
		if (ret) {
			ret = chan->device->device_alloc_chan_resources(chan);
			if (!ret)
				return chan;
			else
				return NULL;
		}
	}

(can be transformed to)

<client driver>

	dma_request_channel(mask, filter_arg);

<dmaengine_core>

	for_each_channel() {
		ret = chan->device->filter(chan, filter_arg);
		if (ret) {
			<same as above>
		}
	}
Quoted 8 lines

(which further could be simplified to)

<client driver>

	dma_request_channel(mask, filter_arg);

<dmaengine_core>

	for_each_channel() {
		ret = chan->device->device_alloc_chan_resources(chan, filter_arg);

This looks like you're re-purposing a perfectly good API for something that it wasn't designed to do, namely providing a channel selection mechanism, rather than "allocating channel resources". The hint is in the bloody name, please take a look sometime!

If you want to call into the DMA engine driver for channel selection, then create an _explicit_ API for it. Don't bugger around with existing APIs.

Moreover, the *big* problem that your proposal above creates is this. What _type_ is filter_arg? If it's void *, then your suggestion is nonsense, even if you associate it with a size argument. You have no idea what the bytestream that would be passed via that pointer means, even if the size just happens to look like it's what you expect.

If it's something else, then your mistake above was not defining it, so there's no way to evaluate your proposal given that lack of critical information. And if you define it, whatever you come up with _must_ be suitable for every single DMA engine driver we have today.

#102 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 51 lines · Russell King - ARM Linux
Quoted 41 lines · Guennadi Liakhovetski

I like this idea, but why don't we extend it to also cover the non-DT case? I.e., why don't we add the above callback (call it "match" or "filter" or anything else) to dmaengine operations and inside (the extended) dma_request_channel(), instead of calling the filter function, passed as a parameter, we loop over all registered DMAC devices and call their filter callbacks, until one of them returns true? In fact, it goes back to my earlier proposal from
http://thread.gmane.org/gmane.linux.kernel/1246957
which I, possibly, failed to explain properly. So, the transformation chain from today's API would be (all code is approximate):

(today)

<client driver>

	dma_request_channel(mask, filter, filter_arg);

<dmaengine_core>

	for_each_channel() {
		ret = (*filter)(chan, filter_arg);
		if (ret) {
			ret = chan->device->device_alloc_chan_resources(chan);
			if (!ret)
				return chan;
			else
				return NULL;
		}
	}

(can be transformed to)

<client driver>

	dma_request_channel(mask, filter_arg);

<dmaengine_core>

	for_each_channel() {
		ret = chan->device->filter(chan, filter_arg);
		if (ret) {
			<same as above>
		}
	}
Quoted 8 lines

(which further could be simplified to)

<client driver>

	dma_request_channel(mask, filter_arg);

<dmaengine_core>

	for_each_channel() {
		ret = chan->device->device_alloc_chan_resources(chan, filter_arg);
Quoted 8 lines

This looks like you're re-purposing a perfectly good API for something that it wasn't designed to do, namely providing a channel selection mechanism, rather than "allocating channel resources". The hint is in the bloody name, please take a look sometime!

If you want to call into the DMA engine driver for channel selection, then create an _explicit_ API for it. Don't bugger around with existing APIs.

Sure, it's better to create a new call-back.

Quoted 5 lines

Moreover, the *big* problem that your proposal above creates is this. What _type_ is filter_arg? If it's void *, then your suggestion is nonsense, even if you associate it with a size argument. You have no idea what the bytestream that would be passed via that pointer means, even if the size just happens to look like it's what you expect.

Right, thanks to you and Arnd, who has pointed this out too.

Then it seems to me, that we need to introduce a notion of a mux device. We could of course try to just use some strings instead, arrays of acceptable DMA devices and channels, and most likely we would even be able to find such an approach, that would work for all existing configurations. But it still wouldn't be really fully generic, right? Whereas creating a mux driver we really could cover all possible cases. DMA clients in this case would always be hard wired to only one pin of such a mux, the DMA device on the other side also only has to care about its physical channels. The dmaengine core would then query the mux driver, where it can route specific client request lines?

A separate mux is needed, because several clients can have their DMA handshake lines routed to several DMAC instances, so, this muxing functionality can neither reside on the client nor on the CMAC.

Is this a right direction now? Shall I try to prototype such a DMA mux API?

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

#103 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Guennadi Liakhovetski
Quoted 12 lines · Guennadi Liakhovetski

On Mon, 25 Jun 2012, Arnd Bergmann wrote:

[snip]

Quoted 8 lines

The channel data in the device tree is still in a format that is specific to that dmaengine driver and interpreted by it. Using the regular dma_filter_fn prototype is not necessary, but it would be convenient because the dmaengine code already knows how to deal with it. If we don't use this method, how about adding another callback to struct dma_device like

Quoted 8 lines
Quoted 1 line

bool (*device_match)(struct dma_chan *chan, struct property *req);

I like this idea, but why don't we extend it to also cover the non-DT case? I.e., why don't we add the above callback (call it "match" or "filter" or anything else) to dmaengine operations and inside (the extended) dma_request_channel(), instead of calling the filter function, passed as a parameter, we loop over all registered DMAC devices and call their filter callbacks,

And I have told you many times, that dmacs should not know anything about clients. They should be totally agnostic to it.

Clients need to request a specific channel, and that is where changes should come for. Not having dmac provide one.

Signature · 1 line
~Vinod
#104 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Arnd Bergmann

Hi all

Sorry for jumping in so late in the game. But I think, the model, to which this discussion is slowly converging, is not very well suitable for the shdma DMACs, present on SH and ARM sh-mobile SoCs. I might be wrong and the model is indeed suitable, in which case I'd be grateful, if someone could explain, how this model could be used for shdma. Below I'll try to describe main properties of shdma served DMACs, I've done this a couple of times before during various dmaengine related discussions. Let's see how we can use this model for these SoCs.

Quoted 1 line · Arnd Bergmann

On Friday 08 June 2012, Jon Hunter wrote:

[snip]

Quoted 11 lines
Quoted 11 lines

It seems to me we were pretty close on alignment. In fact, I was quite happy with Steven's 2nd to last proposal of ...

simple 1 req:
dmas = <0 &dmac1 xxx>;

simple 2 req:
dmas = <0 &dmac1 xxx 1 &dmac1 yyy>;

multiple dmacs:
dmas = <0 &dmac1 xxx 0 &dmac2 zzz 1 &dmac1 yyy>;

A typical sh-mobile SoC contains several DMAC instances of several sub-types, all served by the same driver. Let's take sh7372 to be specific (see arch/arm/mach-shmobile/setup-sh7372.c for details). On sh7372 we've got 3 generic DMAC instances and 2 dedicated USB DMACs.

Generic DMACs have 6 physical channels each, USB DMACs 2.

Generic DMACs can perform memory-to-memory DMA, USB DMACs cannot.

Generic DMACs can serve any slave (peripheral) request line on any their physical channel, USB DMACs only serve fixed USB controller instances. To configure (connect) a certain physical DMA channel to s specific peripheral request line, a certain value has to be written to a configuration register of that physical DMA channel.

To add to complexity, on other SoCs (e.g., SuperH sh7724) some of generic DMACs (DMAC0) have external DMA request pins, others don't.

I'm sure there's more to that, but that's about the scope, that's currently supported or wants to be supported by the driver.

Currently we do the slave-switching in the following way: platform data for each DMAC instance references a table of supported peripherals with their IDs and configuration register values. Each peripheral, that wishes to use DMA, provides its slave ID to the DMAC driver, by which it checks, whether this peripheral is supported and, if so, finds its configuration, picks up the next free channel and configures it.

So, with the above in mind, IIUC, the above DT binding proposal would require us to reference all 3 generic DMAC instances in each slave dmas property? Even if we assume, that for this specific case we don't have to map each physical channel, because so far they are "mostly" all equal on each DMAC instance. Mostly, because external DMA request lines on sh7724 can only be used with channels 0 and 1 out of 6 of DMAC0... What we certainly don't want to do is specify fixed physical DMA channels or even controller instances in slave DMA bindings.

To me it looks like the above proposal would only very suboptimally be usable with sh-mobile SoCs...

Thanks
Guennadi

Quoted 25 lines
Quoted 6 lines

Arnd, I know that you had some concerns. However, in the above case I would expect that the 3rd parameter be optional and it can be some sort of match variable. In other words, we don't care how the 32-bits are encoded or what they represent but they would be used appropriately by the xlate function being used. So the xlate and this "match" variable would have to speak the same language.

I would at least put the &dmac part first to be consistent with other bindings that refer to some node. That controller should then be able to specify the number of additional cells used to describe the dma request. We can define that the first cell after the controller phandle is always the same thing, e.g. the direction (in/out/inout) or a client-specific ID or a combination of that with other predefined bits that are not dependent on dma controller specifics.

As I said previously, I think just encoding the direction but not the client specific ID (meaning we would have to disambiguate the more complex cases that Stephen mentioned using a dma-names property) would be the best because it keeps the common case simple, but I could live with other things going in there too.

Quoted 3 lines

I think that I prefer the idea of having a 3rd optional match variable than encoding the DMA request ID and match data together in 1 32-bit variable. However, not a big deal either way.

Quoted 5 lines

I agree on that part, I would usually prefer to encode different things in separate cells rather than putting them together into a single cell just because they require less than 32 bits combined.

Arnd

---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

author
#105 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 29 lines · Guennadi Liakhovetski

Hi all

Sorry for jumping in so late in the game. But I think, the model, to which this discussion is slowly converging, is not very well suitable for the shdma DMACs, present on SH and ARM sh-mobile SoCs. I might be wrong and the model is indeed suitable, in which case I'd be grateful, if someone could explain, how this model could be used for shdma. Below I'll try to describe main properties of shdma served DMACs, I've done this a couple of times before during various dmaengine related discussions. Let's see how we can use this model for these SoCs.

Quoted 1 line · Arnd Bergmann

On Friday 08 June 2012, Jon Hunter wrote:

[snip]

Quoted 11 lines
Quoted 11 lines

It seems to me we were pretty close on alignment. In fact, I was quite happy with Steven's 2nd to last proposal of ...

simple 1 req:
dmas = <0 &dmac1 xxx>;

simple 2 req:
dmas = <0 &dmac1 xxx 1 &dmac1 yyy>;

multiple dmacs:
dmas = <0 &dmac1 xxx 0 &dmac2 zzz 1 &dmac1 yyy>;

Quoted 6 lines

A typical sh-mobile SoC contains several DMAC instances of several sub-types, all served by the same driver. Let's take sh7372 to be specific (see arch/arm/mach-shmobile/setup-sh7372.c for details). On sh7372 we've got 3 generic DMAC instances and 2 dedicated USB DMACs.

Generic DMACs have 6 physical channels each, USB DMACs 2.

For OMAP we also have dedicated DMAC for the USB controllers. However, these DMAC are very much integrated into the USB controller itself. Hence, in the of OMAP we would only be using the binding really to handle the generic DMAC. However, I would not like to think that this is limited to only generic DMAC.

Quoted 7 lines

Generic DMACs can perform memory-to-memory DMA, USB DMACs cannot.

Generic DMACs can serve any slave (peripheral) request line on any their physical channel, USB DMACs only serve fixed USB controller instances. To configure (connect) a certain physical DMA channel to s specific peripheral request line, a certain value has to be written to a configuration register of that physical DMA channel.

Do you still need to specify a request line for the USB DMACs or are these fixed? In other words, what purpose would the DMA binding serve for the USB DMACs?

Quoted 2 lines

To add to complexity, on other SoCs (e.g., SuperH sh7724) some of generic DMACs (DMAC0) have external DMA request pins, others don't.

OMAP also has this. To me an request line going to an external pin can be handled in the same way as one going to a internal peripheral. However, what happens to that pin externally is a different story.

Quoted 10 lines

I'm sure there's more to that, but that's about the scope, that's currently supported or wants to be supported by the driver.

Currently we do the slave-switching in the following way: platform data for each DMAC instance references a table of supported peripherals with their IDs and configuration register values. Each peripheral, that wishes to use DMA, provides its slave ID to the DMAC driver, by which it checks, whether this peripheral is supported and, if so, finds its configuration, picks up the next free channel and configures it.

Quoted 3 lines

So, with the above in mind, IIUC, the above DT binding proposal would require us to reference all 3 generic DMAC instances in each slave dmas property?

You could if you wanted to have the ability to select 1 out of the 3. However, I would not say it is a hard requirement. You could just provide one. Or you could list all 3, but use some form of match variable to indicate a default DMAC for a given peripheral.

Quoted 6 lines

Even if we assume, that for this specific case we don't have to map each physical channel, because so far they are "mostly" all equal on each DMAC instance. Mostly, because external DMA request lines on sh7724 can only be used with channels 0 and 1 out of 6 of DMAC0... What we certainly don't want to do is specify fixed physical DMA channels or even controller instances in slave DMA bindings.

You could just use the binding to return a handle to one DMAC and then just request a channel. I don't see that the binding would require you to specify fixed channels.

Quoted 2 lines

To me it looks like the above proposal would only very suboptimally be usable with sh-mobile SoCs...

I guess I don't see that, but then again I am not familiar with the all the details of the SH devices.

However, thinking about it some more, if a DMAC is this generic, what information do you want the binding to provide?

Cheers
Jon

#106 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 46 lines · Jon Hunter
Quoted 29 lines · Guennadi Liakhovetski

Hi all

Sorry for jumping in so late in the game. But I think, the model, to which this discussion is slowly converging, is not very well suitable for the shdma DMACs, present on SH and ARM sh-mobile SoCs. I might be wrong and the model is indeed suitable, in which case I'd be grateful, if someone could explain, how this model could be used for shdma. Below I'll try to describe main properties of shdma served DMACs, I've done this a couple of times before during various dmaengine related discussions. Let's see how we can use this model for these SoCs.

Quoted 1 line · Arnd Bergmann

On Friday 08 June 2012, Jon Hunter wrote:

[snip]

Quoted 11 lines
Quoted 11 lines

It seems to me we were pretty close on alignment. In fact, I was quite happy with Steven's 2nd to last proposal of ...

simple 1 req:
dmas = <0 &dmac1 xxx>;

simple 2 req:
dmas = <0 &dmac1 xxx 1 &dmac1 yyy>;

multiple dmacs:
dmas = <0 &dmac1 xxx 0 &dmac2 zzz 1 &dmac1 yyy>;

Quoted 6 lines

A typical sh-mobile SoC contains several DMAC instances of several sub-types, all served by the same driver. Let's take sh7372 to be specific (see arch/arm/mach-shmobile/setup-sh7372.c for details). On sh7372 we've got 3 generic DMAC instances and 2 dedicated USB DMACs.

Generic DMACs have 6 physical channels each, USB DMACs 2.

For OMAP we also have dedicated DMAC for the USB controllers. However, these DMAC are very much integrated into the USB controller itself. Hence, in the of OMAP we would only be using the binding really to handle the generic DMAC. However, I would not like to think that this is limited to only generic DMAC.

Quoted 2 lines

Generic DMACs can perform memory-to-memory DMA, USB DMACs cannot.

Quoted 8 lines
Quoted 5 lines

Generic DMACs can serve any slave (peripheral) request line on any their physical channel, USB DMACs only serve fixed USB controller instances. To configure (connect) a certain physical DMA channel to s specific peripheral request line, a certain value has to be written to a configuration register of that physical DMA channel.

Do you still need to specify a request line for the USB DMACs or are these fixed?

I personally haven't worked with the renesas_usbhs USB driver or with the respective DMA driver part, but from what I can see, no "slave-select" values are required, i.e., request lines seem to be fixed.

Quoted 2 lines

In other words, what purpose would the DMA binding serve for the USB DMACs?

The USB driver has to tell the dmaengine which DMAC instances are suitable for it, and which are not.

Quoted 6 lines
Quoted 2 lines

To add to complexity, on other SoCs (e.g., SuperH sh7724) some of generic DMACs (DMAC0) have external DMA request pins, others don't.

OMAP also has this. To me an request line going to an external pin can be handled in the same way as one going to a internal peripheral. However, what happens to that pin externally is a different story.

As has been discussed before, the presence of external DMA request lines makes specifying fixed DMA channel maps in SoC dtsi files impossible.

Quoted 10 lines
Quoted 10 lines

I'm sure there's more to that, but that's about the scope, that's currently supported or wants to be supported by the driver.

Currently we do the slave-switching in the following way: platform data for each DMAC instance references a table of supported peripherals with their IDs and configuration register values. Each peripheral, that wishes to use DMA, provides its slave ID to the DMAC driver, by which it checks, whether this peripheral is supported and, if so, finds its configuration, picks up the next free channel and configures it.

Quoted 8 lines
Quoted 3 lines

So, with the above in mind, IIUC, the above DT binding proposal would require us to reference all 3 generic DMAC instances in each slave dmas property?

You could if you wanted to have the ability to select 1 out of the 3. However, I would not say it is a hard requirement. You could just provide one. Or you could list all 3, but use some form of match variable to indicate a default DMAC for a given peripheral.

Sorry, I don't think artificially limiting the flexibility to just 1 controller is a good option. The option of listing all 3 in each device doesn't seem too good to me either. What if a future SoC version has 5 of them? I really would prefer to have a list of "generic" DMAC instances somewhere and be able to omit any explicit references to specific DMACs in device DMA bindings. I can also imagine a possibility, that in the future we won't have just one "generic" DMAC type, but, say, 2 DMAC groups, serving different, but possibly intersecting, sets of devices. In that case I'd just like to be able to specify "use group A" in the binding. Do I understand correctly, that with the proposed scheme this is impossible?

Quoted 10 lines
Quoted 6 lines

Even if we assume, that for this specific case we don't have to map each physical channel, because so far they are "mostly" all equal on each DMAC instance. Mostly, because external DMA request lines on sh7724 can only be used with channels 0 and 1 out of 6 of DMAC0... What we certainly don't want to do is specify fixed physical DMA channels or even controller instances in slave DMA bindings.

You could just use the binding to return a handle to one DMAC and then just request a channel. I don't see that the binding would require you to specify fixed channels.

That's good, but as I said above, I'd also like to be more flexible in the selection of DMACs.

Quoted 8 lines
Quoted 2 lines

To me it looks like the above proposal would only very suboptimally be usable with sh-mobile SoCs...

I guess I don't see that, but then again I am not familiar with the all the details of the SH devices.

However, thinking about it some more, if a DMAC is this generic, what information do you want the binding to provide?

Configuration data for the DMAC. Currently this consists (apart from FIFO access register addresses) of 2 values: a magic value, specifying a certain slave (DMA request line selection), and a value for a configuration register. The latter contains information about transfer sizes, repeat / reload modes, address incrementing policies etc. These seem to be computable, but they are at least partially SoC-specific too.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

#107 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Jon Hunter
Quoted 11 lines · Jon Hunter
Quoted 7 lines

Generic DMACs can perform memory-to-memory DMA, USB DMACs cannot.

Generic DMACs can serve any slave (peripheral) request line on any their physical channel, USB DMACs only serve fixed USB controller instances. To configure (connect) a certain physical DMA channel to s specific peripheral request line, a certain value has to be written to a configuration register of that physical DMA channel.

Do you still need to specify a request line for the USB DMACs or are these fixed? In other words, what purpose would the DMA binding serve for the USB DMACs?

If I understood Guennadi right, the DMA engines are the same kind as the other ones, so we really want to use the same bindings for each instance.

Quoted 6 lines
Quoted 2 lines

To add to complexity, on other SoCs (e.g., SuperH sh7724) some of generic DMACs (DMAC0) have external DMA request pins, others don't.

OMAP also has this. To me an request line going to an external pin can be handled in the same way as one going to a internal peripheral. However, what happens to that pin externally is a different story.

Right, I don't see a problem here with any of the proposed binding.

Quoted 10 lines
Quoted 10 lines

I'm sure there's more to that, but that's about the scope, that's currently supported or wants to be supported by the driver.

Currently we do the slave-switching in the following way: platform data for each DMAC instance references a table of supported peripherals with their IDs and configuration register values. Each peripheral, that wishes to use DMA, provides its slave ID to the DMAC driver, by which it checks, whether this peripheral is supported and, if so, finds its configuration, picks up the next free channel and configures it.

Quoted 8 lines
Quoted 3 lines

So, with the above in mind, IIUC, the above DT binding proposal would require us to reference all 3 generic DMAC instances in each slave dmas property?

You could if you wanted to have the ability to select 1 out of the 3. However, I would not say it is a hard requirement. You could just provide one. Or you could list all 3, but use some form of match variable to indicate a default DMAC for a given peripheral.

Right. From the description above, it seems that shmobile is actually simpler than some of the others because the slave ID is always the same for each of the controllers.

In the common case, you could have one device connected to the third slave ID of the first controller but the fifth slave ID of the second controller. In this case, you really have to specify each controller with its slave ID separately, even if that means a lot of duplicate data for shmobile.

I'm not sure I understand what the "configuration register values" above are. Most likely, those should all be part of the slave ID, which would then span multiple 32-bit values in the "dmas" property.

Conveniently, that also takes care of removing the DMAC platform data.

Arnd

#108 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Arnd

Quoted 10 lines · Arnd Bergmann
Quoted 8 lines · Jon Hunter
Quoted 7 lines

Generic DMACs can perform memory-to-memory DMA, USB DMACs cannot.

Generic DMACs can serve any slave (peripheral) request line on any their physical channel, USB DMACs only serve fixed USB controller instances. To configure (connect) a certain physical DMA channel to s specific peripheral request line, a certain value has to be written to a configuration register of that physical DMA channel.

Quoted 6 lines
Quoted 3 lines

Do you still need to specify a request line for the USB DMACs or are these fixed? In other words, what purpose would the DMA binding serve for the USB DMACs?

If I understood Guennadi right, the DMA engines are the same kind as the other ones, so we really want to use the same bindings for each instance.

Exactly, at least they are compatible and are presently handles by the same dma-engine driver. There are some differences in the register layout, I think, which we might need to handle at some point, maybe by specifying different "compatible" identifiers or by some other means.

Quoted 23 lines
Quoted 6 lines
Quoted 2 lines

To add to complexity, on other SoCs (e.g., SuperH sh7724) some of generic DMACs (DMAC0) have external DMA request pins, others don't.

OMAP also has this. To me an request line going to an external pin can be handled in the same way as one going to a internal peripheral. However, what happens to that pin externally is a different story.

Right, I don't see a problem here with any of the proposed binding.

Quoted 14 lines
Quoted 13 lines

I'm sure there's more to that, but that's about the scope, that's currently supported or wants to be supported by the driver.

Currently we do the slave-switching in the following way: platform data for each DMAC instance references a table of supported peripherals with their IDs and configuration register values. Each peripheral, that wishes to use DMA, provides its slave ID to the DMAC driver, by which it checks, whether this peripheral is supported and, if so, finds its configuration, picks up the next free channel and configures it.

So, with the above in mind, IIUC, the above DT binding proposal would require us to reference all 3 generic DMAC instances in each slave dmas property?

Quoted 8 lines
Quoted 4 lines

You could if you wanted to have the ability to select 1 out of the 3. However, I would not say it is a hard requirement. You could just provide one. Or you could list all 3, but use some form of match variable to indicate a default DMAC for a given peripheral.

Right. From the description above, it seems that shmobile is actually simpler than some of the others because the slave ID is always the same for each of the controllers.

Exactly.

Quoted 5 lines

In the common case, you could have one device connected to the third slave ID of the first controller but the fifth slave ID of the second controller. In this case, you really have to specify each controller with its slave ID separately, even if that means a lot of duplicate data for shmobile.

So, you don't think it's worth making a short-cut possible to specify a DMAC type instead of each instance phandle? It really would mean __a lot__ of duplication - with 3 generic controllers on (some) current chips and possibly more on those, that I'm not aware about.

Quoted 2 lines

I'm not sure I understand what the "configuration register values" above are.

As I explained in an earlier mail, those include transfer size and other parameters, but cannot be completely calculated in device drivers, because they also vary between SoCs.

Quoted 2 lines

Most likely, those should all be part of the slave ID, which would then span multiple 32-bit values in the "dmas" property.

Yes, we could do that.

Quoted 1 line

Conveniently, that also takes care of removing the DMAC platform data.

Right, my only concern so far is a huge redundancy, that accepting and using the proposed scheme would incur.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

#109 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 10 lines · Guennadi Liakhovetski
Quoted 5 lines

In the common case, you could have one device connected to the third slave ID of the first controller but the fifth slave ID of the second controller. In this case, you really have to specify each controller with its slave ID separately, even if that means a lot of duplicate data for shmobile.

So, you don't think it's worth making a short-cut possible to specify a DMAC type instead of each instance phandle? It really would mean __a lot__ of duplication - with 3 generic controllers on (some) current chips and possibly more on those, that I'm not aware about.

It's certainly possible to make that short-cut, but I'm not convinced if it's worth it. One thing you can do is create a meta-device for all of the identical DMA controllers, and refer to that one from the devices, but make it a separate device node from the actual controllers, of which you can have more than one. This makes the binding for your dma controller more complex but reduces the amount of data required in the other device nodes.

In case of sh7372, this could look something like

	dma: dmac-mux {
		compatible = "renesas,sh-dma-mux";
		#dma-cells = <4>; /* slave-id, addr, chcr, mid-rid */
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;

		dmae at 0xfe008020{
			compatible = "renesas,sh-dma";
			reg = <0xfe008020 0xfe00828f
				0xfe009000 0xfe00900b>
			interrupts = <0x20c0 0x2000 0x2020 0x2040 0x2060 0x2080 0x20a0>;
		};

		dmae at 0xfe018020{
			compatible = "renesas,sh-dma";
			reg = <0xfe018020 0xfe01828f
				0xfe019000 0xfe01900b>
			interrupts = <0x21c0 0x2100 0x2120 0x2140 0x2160 0x2180 0x21a0>;
		};

		dmae at 0xfe028020{
			compatible = "renesas,sh-dma";
			reg = <0xfe028020 0xfe02828f
				0xfe029000 0xfe02900b>
			interrupts = <0x22c0 0x2200 0x2220 0x2240 0x2260 0x2280 0x22a0>;
		};
	};

This way, a slave would refer to the dmac-mux node and while the device driver binds to the child nodes.

Quoted 6 lines
Quoted 2 lines

I'm not sure I understand what the "configuration register values" above are.

As I explained in an earlier mail, those include transfer size and other parameters, but cannot be completely calculated in device drivers, because they also vary between SoCs.

Yes, but they can be part of the device tree source, because when writing that, you know both the requirements of the device and the capabilities of the controller.

Arnd

#110 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 20 lines · Arnd Bergmann
Quoted 10 lines · Guennadi Liakhovetski
Quoted 5 lines

In the common case, you could have one device connected to the third slave ID of the first controller but the fifth slave ID of the second controller. In this case, you really have to specify each controller with its slave ID separately, even if that means a lot of duplicate data for shmobile.

So, you don't think it's worth making a short-cut possible to specify a DMAC type instead of each instance phandle? It really would mean __a lot__ of duplication - with 3 generic controllers on (some) current chips and possibly more on those, that I'm not aware about.

It's certainly possible to make that short-cut, but I'm not convinced if it's worth it. One thing you can do is create a meta-device for all of the identical DMA controllers, and refer to that one from the devices, but make it a separate device node from the actual controllers, of which you can have more than one. This makes the binding for your dma controller more complex but reduces the amount of data required in the other device nodes.

Quoted 8 lines

In case of sh7372, this could look something like

	dma: dmac-mux {
		compatible = "renesas,sh-dma-mux";
		#dma-cells =<4>; /* slave-id, addr, chcr, mid-rid */
		#address-cells =<1>;
		#size-cells =<1>;
		ranges;

In light of the reg entries below, perhaps #size-cells=0 ?

Quoted 44 lines

		dmae at 0xfe008020{
			compatible = "renesas,sh-dma";
			reg =<0xfe008020 0xfe00828f
				0xfe009000 0xfe00900b>
			interrupts =<0x20c0 0x2000 0x2020 0x2040 0x2060 0x2080 0x20a0>;
		};

		dmae at 0xfe018020{
			compatible = "renesas,sh-dma";
			reg =<0xfe018020 0xfe01828f
				0xfe019000 0xfe01900b>
			interrupts =<0x21c0 0x2100 0x2120 0x2140 0x2160 0x2180 0x21a0>;
		};

		dmae at 0xfe028020{
			compatible = "renesas,sh-dma";
			reg =<0xfe028020 0xfe02828f
				0xfe029000 0xfe02900b>
			interrupts =<0x22c0 0x2200 0x2220 0x2240 0x2260 0x2280 0x22a0>;
		};
	};

This way, a slave would refer to the dmac-mux node and while the device driver binds to the child nodes.

Quoted 6 lines
Quoted 2 lines

I'm not sure I understand what the "configuration register values" above are.

As I explained in an earlier mail, those include transfer size and other parameters, but cannot be completely calculated in device drivers, because they also vary between SoCs.

Yes, but they can be part of the device tree source, because when writing that, you know both the requirements of the device and the capabilities of the controller.

Arnd
_______________________________________________
devicetree-discuss mailing list
devicetree-discuss at lists.ozlabs.org
https://lists.ozlabs.org/listinfo/devicetree-discuss

#111 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 4 lines · Mitch Bradley
Quoted 3 lines
              #address-cells =<1>;
              #size-cells =<1>;
              ranges;
Quoted 10 lines

In light of the reg entries below, perhaps #size-cells=0 ?

Quoted 9 lines

              dmae at 0xfe008020{
                      compatible = "renesas,sh-dma";
                      reg =<0xfe008020 0xfe00828f
                              0xfe009000 0xfe00900b>
                      interrupts =<0x20c0 0x2000 0x2020 0x2040 0x2060 0x2080 0x20a0>;
              };

These are actually ranges I copied from the static resource definitions, I just forgot to change the format from start-end to start-length. It should really be

			reg =<0xfe008020 0x270 0xfe009000 0xc>;

Sorry about that.

Arnd

#112 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Arnd Bergmann

Hi Arnd

Sorry for a delayed reply, we had to discuss this your idea internally first before replying.

Quoted 51 lines · Arnd Bergmann
Quoted 10 lines · Guennadi Liakhovetski
Quoted 5 lines

In the common case, you could have one device connected to the third slave ID of the first controller but the fifth slave ID of the second controller. In this case, you really have to specify each controller with its slave ID separately, even if that means a lot of duplicate data for shmobile.

So, you don't think it's worth making a short-cut possible to specify a DMAC type instead of each instance phandle? It really would mean __a lot__ of duplication - with 3 generic controllers on (some) current chips and possibly more on those, that I'm not aware about.

It's certainly possible to make that short-cut, but I'm not convinced if it's worth it. One thing you can do is create a meta-device for all of the identical DMA controllers, and refer to that one from the devices, but make it a separate device node from the actual controllers, of which you can have more than one. This makes the binding for your dma controller more complex but reduces the amount of data required in the other device nodes.

In case of sh7372, this could look something like

	dma: dmac-mux {
		compatible = "renesas,sh-dma-mux";
		#dma-cells = <4>; /* slave-id, addr, chcr, mid-rid */
		#address-cells = <1>;
		#size-cells = <1>;
		ranges;

		dmae at 0xfe008020{
			compatible = "renesas,sh-dma";
			reg = <0xfe008020 0xfe00828f
				0xfe009000 0xfe00900b>
			interrupts = <0x20c0 0x2000 0x2020 0x2040 0x2060 0x2080 0x20a0>;
		};

		dmae at 0xfe018020{
			compatible = "renesas,sh-dma";
			reg = <0xfe018020 0xfe01828f
				0xfe019000 0xfe01900b>
			interrupts = <0x21c0 0x2100 0x2120 0x2140 0x2160 0x2180 0x21a0>;
		};

		dmae at 0xfe028020{
			compatible = "renesas,sh-dma";
			reg = <0xfe028020 0xfe02828f
				0xfe029000 0xfe02900b>
			interrupts = <0x22c0 0x2200 0x2220 0x2240 0x2260 0x2280 0x22a0>;
		};
	};
Quoted 2 lines

This way, a slave would refer to the dmac-mux node and while the device driver binds to the child nodes.

Indeed, this solution should be good enough, thanks! I'm not sure, whether making this multiplexing available requires any additional code to the generic DMA DT binding implementation. If it does - please, let's make this a part of the implementation.

It is also important to provide a flexible multiple channel per device configuration support to let slave drivers distinguish between different DMA channels, that they get back from the API. But I think this is a part of the current proposal and is being taken care of.

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

#113 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 4 lines · Guennadi Liakhovetski

Indeed, this solution should be good enough, thanks! I'm not sure, whether making this multiplexing available requires any additional code to the generic DMA DT binding implementation. If it does - please, let's make this a part of the implementation.

It depends how the dma engine gets represented in Linux then: Either we make the common dmaengine code handle multiple dma-engines with the same of_node pointer, or you make the driver register a single dma-engine to Linux that is backed by the three physical devices but just one of_node pointer. I think either way will work, and someone has to try it to determine which one is simpler.

Quoted 4 lines

It is also important to provide a flexible multiple channel per device configuration support to let slave drivers distinguish between different DMA channels, that they get back from the API. But I think this is a part of the current proposal and is being taken care of.

Yes, it is.

Arnd

#114 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Arnd Bergmann
Quoted 14 lines · Arnd Bergmann
Quoted 4 lines · Jassi Brar

The assumed model of the DMAC, in this binding, has P peripheral
interfaces (P request signals) that could request a data transfer and C physical channels that actually do the data transfers, hence, at most C out of P peripherals could be served by the DMAC at any

Quoted 8 lines

point of time. Usually C := P, but not always. Usually, any of the physical channels could be employed by the DMAC driver to serve any client.
The DMAC driver identifies a client by its i/f number, 'peri_id'
on the given DMAC. For example, TX for SPI has 7th while RX_TX (half-duplex) for MMC has 10th peripheral interface (request-signal) on a given DMAC. Usually, any of the physical channels could be employed by the DMAC driver to serve a client.

Quoted 7 lines

I'm still anything but convinced by this model. Basically it's the exact opposite of what we do for every other subsystem (irq, pinctrl, regulator, gpio, ...), where the device using some infrastructure contains the information about who provides it, whereas here you move all the information into the device that provides the functionality, and have no handle in the device using it by which the driver can identify it.

I think the biggest difference between DMA and other subsystems is that other systems have only one provider.

DMA on the other hand seems to have cases where you can make a choice between two or more providers of the service. The impression that I'm getting from this thread is that it's difficult to describe that kind of relationship in DT - DT is good at describing "A provides X to C" but not "A _or_ B provides X to C and you can chose either A or B depending on <something> to satisfy X".

#115 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 6 lines · Russell King - ARM Linux

DMA on the other hand seems to have cases where you can make a choice between two or more providers of the service. The impression that I'm getting from this thread is that it's difficult to describe that kind of relationship in DT - DT is good at describing "A provides X to C" but not "A _or_ B provides X to C and you can chose either A or B depending on <something> to satisfy X".

A similar thing exists in a lot of clock trees - often the final clock block before an IP block includes a mux which could come from one of a number of sources.

#116 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 9 lines · Mark Brown
Quoted 6 lines · Russell King - ARM Linux

DMA on the other hand seems to have cases where you can make a choice between two or more providers of the service. The impression that I'm getting from this thread is that it's difficult to describe that kind of relationship in DT - DT is good at describing "A provides X to C" but not "A _or_ B provides X to C and you can chose either A or B depending on <something> to satisfy X".

Quoted 3 lines

A similar thing exists in a lot of clock trees - often the final clock block before an IP block includes a mux which could come from one of a number of sources.

At least there, the problem is easier, because we have in place a way to represent muxes separately from everything else.

DMA engine is totally different; there is no representation of this, and I don't see a sane way that it _could_ be represented given the existing structure - certainly not without a major rework.

The first problem is that there is no support for any kind of layering in dma engine at all.

The second problem is that you're actually dealing with muxes at two levels - when you have an external mux to the DMA engine, you normally already have a mux internally within the DMA engine. And you need to set these muxes dynamically according to the next DMA activity that the physical DMA channel is about to process.

That becomes even more fun when you have setups like on the Realview platforms where you have one set of bits which multiplex several different DMA request signals, so changing the mux for one signal changes others. What this means is that you may only find out that you can't route the DMA request when you try to change the muxes to route your DMA request into the DMA controller.

It's all _very_ icky and horrible. Clock muxes are much saner.

That said, I'm quite prepared to say "ok, we just don't bother dealing with that DMA issue on platforms like Realview, hard luck if your hardware team thought it was a good idea, we don't support it."

#117 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Jon Hunter
Quoted 46 lines · Jon Hunter
Quoted 31 lines · Jon Hunter

Hi Jassi,

Quoted 28 lines · Jassi Brar

Hi Jon,

Quoted 8 lines · Jon Hunter
Quoted 7 lines · Jassi Brar

+ ? ? ? i2c1: i2c at 1 {
+ ? ? ? ? ? ? ? ...
+ ? ? ? ? ? ? ? dma = <&sdma 2 1 &sdma 3 2>;
+ ? ? ? ? ? ? ? ...
+ ? ? ? };

Quoted 1 line
Quoted 7 lines
Quoted 2 lines

I see this requires a client driver to specify a particular req_line on a particular dma controller. I am not sure if this is most optimal.

Actually, no. The phandle in the DT specifies the DMA controller to use. Then the client simply asks for a channel with a particular property, for example, DMA_MEM_TO_DEV (ie. TX) and the channel information is return.

See below.

Quoted 8 lines
Quoted 7 lines

I think such client->req_line map should be provided to the dmac controller driver via its dt node in some format. The dmac driver could then populate a dma_chan, or similar, only for that req_line and not for the unused one which otherwise could also have served the same client.

Ideally the I2C driver should simply ask, say, a channel for TX and another for RX, everything else should already be setup via dmac's dt nodes.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Yes that is the intention here.

But the client is required to specify the dmac that would serve it. Which is more
than simply asking for "some suitable channel".

No this is not the case with what I propose. The client knows nothing about the dmac.

By the way, I do see your point. You wish to describe the all the mappings available to all dma controllers and then set a mapping in the device tree. Where as I am simply setting a mapping and do not list all other possibilities (assuming that there some).

Quoted 6 lines

What is still unclear to me, is if you use this token approach how readable is the device-tree? For example, if you have a client that can use one of two dmac and for each dmac the request/channel number is different, then by using a global token how can I determine what the options available for this client are?

Simple - you/client need not know about any option at all :)

Client driver would simply request some channel and if it doesn't get it, it bails out.

It would be the DMACs' DT node that would contain that info.

Quoted 18 lines

Take your example ...

mmc1: mmc at 13002000 {
? ? ? ?...
? ? ? ?dma_tx = <891> ? //some platform-wide unique value ? ? ? ?dma_rx = <927> ? //some platform-wide unique value ? ? ? ?...
};

DMAC's Node:-

pdma2: pdma at 10800000 {
? ? ? ? .......
? ? ? ?dma_map = <891, 7>, ? ? ? // Map mmc1_tx onto i/f 7 ? ? ? ? ? ? ? ? ?<927, 8>, ? ? ? // Map mmc1_rx onto i/f 8 ? ? ? ?.......
};

Quoted 9 lines

But now I have another dmac which has the following options ...

pdma1: pdma at 10000000 {
? ? ? ? .......
? ? ? ?dma_map = <598, 2>, ? ? ? // Map mmc1_tx onto i/f 2 ? ? ? ? ? ? ? ? ?<230, 3>, ? ? ? // Map mmc1_rx onto i/f 3 ? ? ? ?.......
};

No, rather the pdma1 node should look like

pdma1: pdma at 10000000 {
? ? ? ? .......
? ? ? ?dma_map = <891, 2>, ? ? ? // Map mmc1_tx onto i/f 2
? ? ? ? ? ? ? ? ?<927, 3>, ? ? ? // Map mmc1_rx onto i/f 3
? ? ? ?.......
};

Because the tokens 891 and 927 are came from the client's node/driver.

After the DMAC driver has probed both pdma-0 & 1, it would know that MMC1 could be served by 2 DMACs. And basically its the dmac driver that should be making about routing decisions, not the client.

Btw, everything remains same, only we have now decided to not use tokens but phandle+req_sig_ids instead.

author
#118 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 53 lines · Jassi Brar
Quoted 46 lines · Jon Hunter
Quoted 31 lines · Jon Hunter

Hi Jassi,

Quoted 28 lines · Jassi Brar

Hi Jon,

Quoted 8 lines · Jon Hunter
Quoted 7 lines · Jassi Brar
(quoted diff) +5 -0
+       i2c1: i2c at 1 {
+               ...
+               dma = <&sdma 2 1 &sdma 3 2>;
+               ...
+       };
Quoted 1 line
Quoted 7 lines
Quoted 2 lines

I see this requires a client driver to specify a particular req_line on a particular dma controller. I am not sure if this is most optimal.

Actually, no. The phandle in the DT specifies the DMA controller to use. Then the client simply asks for a channel with a particular property, for example, DMA_MEM_TO_DEV (ie. TX) and the channel information is return.

See below.

Quoted 8 lines
Quoted 7 lines

I think such client->req_line map should be provided to the dmac controller driver via its dt node in some format. The dmac driver could then populate a dma_chan, or similar, only for that req_line and not for the unused one which otherwise could also have served the same client.

Ideally the I2C driver should simply ask, say, a channel for TX and another for RX, everything else should already be setup via dmac's dt nodes.

Quoted 8 lines
Quoted 5 lines
Quoted 2 lines

Yes that is the intention here.

But the client is required to specify the dmac that would serve it. Which is more
than simply asking for "some suitable channel".

No this is not the case with what I propose. The client knows nothing about the dmac.

By the way, I do see your point. You wish to describe the all the mappings available to all dma controllers and then set a mapping in the device tree. Where as I am simply setting a mapping and do not list all other possibilities (assuming that there some).

Quoted 6 lines

What is still unclear to me, is if you use this token approach how readable is the device-tree? For example, if you have a client that can use one of two dmac and for each dmac the request/channel number is different, then by using a global token how can I determine what the options available for this client are?

Quoted 6 lines

Simple - you/client need not know about any option at all :)

Client driver would simply request some channel and if it doesn't get it, it bails out.

It would be the DMACs' DT node that would contain that info.

Yes, but what if I am doing some custom application and want to modify the mapping that is being used? So I just wanted to make sure it is easy to understand assuming that you understand what your h/w is capable of.

Quoted 38 lines
Quoted 18 lines

Take your example ...

mmc1: mmc at 13002000 {
...
dma_tx = <891> //some platform-wide unique value
dma_rx = <927> //some platform-wide unique value
...
};

DMAC's Node:-

pdma2: pdma at 10800000 {
        .......
       dma_map = <891, 7>,       // Map mmc1_tx onto i/f 7
                 <927, 8>,       // Map mmc1_rx onto i/f 8
       .......
};
Quoted 9 lines

But now I have another dmac which has the following options ...

pdma1: pdma at 10000000 {
        .......
       dma_map = <598, 2>,       // Map mmc1_tx onto i/f 2
                 <230, 3>,       // Map mmc1_rx onto i/f 3
       .......
};

No, rather the pdma1 node should look like

 pdma1: pdma at 10000000 {
         .......
        dma_map = <891, 2>,       // Map mmc1_tx onto i/f 2
                   <927, 3>,       // Map mmc1_rx onto i/f 3
        .......
};

Because the tokens 891 and 927 are came from the client's node/driver.

Quoted 7 lines

After the DMAC driver has probed both pdma-0 & 1, it would know that MMC1 could be served by 2 DMACs. And basically its the dmac driver that should be making about routing decisions, not the client.

Btw, everything remains same, only we have now decided to not use tokens but phandle+req_sig_ids instead.

Ok, yes Stephen clarified that too. Makes sense.

Cheers
Jon

#119 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 8 lines · Jon Hunter
Quoted 8 lines
Quoted 6 lines

What is still unclear to me, is if you use this token approach how readable is the device-tree? For example, if you have a client that can use one of two dmac and for each dmac the request/channel number is different, then by using a global token how can I determine what the options available for this client are?

Simple - you/client need not know about any option at all :)

Quoted 9 lines
Quoted 4 lines

Client driver would simply request some channel and if it doesn't get it, it bails out.

It would be the DMACs' DT node that would contain that info.

Yes, but what if I am doing some custom application and want to modify the mapping that is being used? So I just wanted to make sure it is easy to understand assuming that you understand what your h/w is capable of.

Any scenario when a client would want to choose which dma controller it runs on?

Because when we say a client could be provided a channel on any of the two given dmacs, it implies that the client wouldn't feel any difference.

author
#120 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 19 lines · Jassi Brar
Quoted 8 lines · Jon Hunter
Quoted 8 lines
Quoted 6 lines

What is still unclear to me, is if you use this token approach how readable is the device-tree? For example, if you have a client that can use one of two dmac and for each dmac the request/channel number is different, then by using a global token how can I determine what the options available for this client are?

Simple - you/client need not know about any option at all :)

Quoted 9 lines
Quoted 4 lines

Client driver would simply request some channel and if it doesn't get it, it bails out.

It would be the DMACs' DT node that would contain that info.

Yes, but what if I am doing some custom application and want to modify the mapping that is being used? So I just wanted to make sure it is easy to understand assuming that you understand what your h/w is capable of.

Quoted 5 lines

Any scenario when a client would want to choose which dma controller it runs on?

Because when we say a client could be provided a channel on any of the two given dmacs, it implies that the client wouldn't feel any difference.

That's not my point. I am saying for some reason, maybe QoS, _I_ want to specify which mapping used. I am the one that knows how the h/w is being used and _I_ want to customise the dma/channel mapping in the DT, such that when the client asks for it I know what it is getting. Yes to the client, it does not care, but I do.

Jon

#121 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 25 lines · Jon Hunter
Quoted 22 lines · Jassi Brar
Quoted 8 lines · Jon Hunter
Quoted 8 lines
Quoted 6 lines

What is still unclear to me, is if you use this token approach how readable is the device-tree? For example, if you have a client that can use one of two dmac and for each dmac the request/channel number is different, then by using a global token how can I determine what the options available for this client are?

Simple - you/client need not know about any option at all :)

Quoted 9 lines
Quoted 4 lines

Client driver would simply request some channel and if it doesn't get it, it bails out.

It would be the DMACs' DT node that would contain that info.

Yes, but what if I am doing some custom application and want to modify the mapping that is being used? So I just wanted to make sure it is easy to understand assuming that you understand what your h/w is capable of.

Any scenario when a client would want to choose which dma controller it runs on?

Quoted 8 lines
Quoted 2 lines

Because when we say a client could be provided a channel on any of the two given dmacs, it implies that the client wouldn't feel any difference.

That's not my point. I am saying for some reason, maybe QoS, _I_ want to specify which mapping used. I am the one that knows how the h/w is being used and _I_ want to customise the dma/channel mapping in the DT, such that when the client asks for it I know what it is getting. Yes to the client, it does not care, but I do.

If you really need to do that, you could always just lie in the DT node of the DMA controllers you don't want to use, and omit the entry for the DMA client(s) you don't want to use it.

Still, this all seems like policy that the DT file shouldn't really be influencing. Admittedly, I'm not sure how else you'd achieve this.

author
#122 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 35 lines · Stephen Warren
Quoted 25 lines · Jon Hunter
Quoted 22 lines · Jassi Brar
Quoted 8 lines · Jon Hunter
Quoted 8 lines
Quoted 6 lines

What is still unclear to me, is if you use this token approach how readable is the device-tree? For example, if you have a client that can use one of two dmac and for each dmac the request/channel number is different, then by using a global token how can I determine what the options available for this client are?

Simple - you/client need not know about any option at all :)

Quoted 9 lines
Quoted 4 lines

Client driver would simply request some channel and if it doesn't get it, it bails out.

It would be the DMACs' DT node that would contain that info.

Yes, but what if I am doing some custom application and want to modify the mapping that is being used? So I just wanted to make sure it is easy to understand assuming that you understand what your h/w is capable of.

Any scenario when a client would want to choose which dma controller it runs on?

Quoted 8 lines
Quoted 2 lines

Because when we say a client could be provided a channel on any of the two given dmacs, it implies that the client wouldn't feel any difference.

That's not my point. I am saying for some reason, maybe QoS, _I_ want to specify which mapping used. I am the one that knows how the h/w is being used and _I_ want to customise the dma/channel mapping in the DT, such that when the client asks for it I know what it is getting. Yes to the client, it does not care, but I do.

Quoted 3 lines

If you really need to do that, you could always just lie in the DT node of the DMA controllers you don't want to use, and omit the entry for the DMA client(s) you don't want to use it.

Exactly. The point I am trying to make, is that whatever binding we have it needs to be intuitive such that someone who knows the hardware could customise by removing entries, etc. This is probably a mute point now that we are not using the token scheme, but I wanted to be clear that I could see people customising the stock dev-trees in the kernel for their particular application. That's all.

Jon

author
#123 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Jassi Brar

Hi Jassi,

Quoted 38 lines · Jassi Brar
Quoted 6 lines · Jon Hunter

From: Jon Hunter <[email protected]>

This is based upon the work by Benoit Cousson [1] and Nicolas Ferre [2] to add some basic helpers to retrieve a DMA controller device_node and the DMA request/channel information.

Quoted 16 lines

Aim of DMA helpers
- The purpose of device-tree (as far as I understand), is to describe the capabilites of the hardware. Thinking about DMA controllers purely from the context of the hardware to begin with, we can describe a device in terms of a DMA controller as follows ...
1. Number of DMA controllers
2. Number of channels (maybe physical or logical)
3. Mapping of DMA requests signals to DMA controller
4. Number of DMA interrupts
5. Mapping of DMA interrupts to channels
- With the above in mind the aim of the DT DMA helper functions is to extract the above information from the DT and provide to the appropriate driver. However, due to the vast number of DMA controllers and not all are using a common driver (such as DMA Engine) it has been seen that this is not a trivial task.

Sorry for being slow, but so far I thought DT is only to provide _h/w_ specific info
to the _controller_ drivers. It was not supposed to provide any info pertaining to
some API (dmaengine in this case).

And I believe this is one of few situations where we are better off not generalizing
the interface - pass controller specific info in the controller driver's specified format.
Generalizing only seems to complicate things here, when we anyway have machine specific dtb, which could always have clients requesting and the controllers given
dma's info in controller driver's specific format.

Quoted 2 lines

Perhaps I am overlooking the need to generalize. If you think so, please help me understand by pointing out some use case for it.

No not really, your points are valid. From reading the previous discussions one of the items that was clearly lacking was the ability to represent and identify a device having more than one DMA controller. In other words, when you request the DMA resource, how do you identify which DMA controller in the system that resource belongs too. With DMA engine there are ways we can do this.

However, thinking about this now. Instead of passing specific DMA engine parameters to the register function may be we can pass a generic void * pointer with the information and completely abstract the binding from DMA engine. This is probably a better approach.

Cheers
Jon

#124 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Jon Hunter
Quoted 5 lines · Jon Hunter

From: Jon Hunter <[email protected]>

This is based upon the work by Benoit Cousson [1] and Nicolas Ferre [2] to add some basic helpers to retrieve a DMA controller device_node and the DMA request/channel information.

Thanks for picking this up again, I very much appreciate it as not having the binding is blocking a number of other activities.

Quoted 11 lines

Design of DMA helpers

1. Supporting devices with multiple DMA controllers

In the case of DMA controllers that are using DMA Engine, requesting a channel is performed by calling the following function.

	struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
			dma_filter_fn filter_fn,
			void *filter_param);
Quoted 5 lines

The mask variable is used to identify the device controller in a list of controllers. The filter_fn and filter_param are used to identify the required dma channel and return a handle to the dma channel of type dma_chan. From the examples I have seen, the mask and filter_fn are constant for a given DMA controller.

I believe this is not entirely correct: sometimes the filter_fn is provided by the slave driver, sometimes by the master driver.

Also, the mask does not identify a specific controller, AFAICT it just provides certain constraints. There are cases where a driver can pick from a multitude of dma engine controllers, as long as the channel the constraints are resolved.
This could be expressed in the device tree by listing multiple dma request lines (one per controller) in the device using it, or the author of the device tree can pick one.

Quoted 7 lines

Therefore, when registering a DMA controller with
device tree we can pass these parameters and store them so that a device can request them when requesting a channel. Hence, based upon this our register function for the DMA controller now looks like this.

	int of_dma_controller_register(struct device_node *np,
		dma_cap_mask_t *mask, dma_filter_fn fn);

This changes the behavior for drivers that provide their own filter functions, which may or may not be a problem.
For examples, have a look at some of these:

drivers/spi/spi-ep93xx.c
drivers/mmc/host/tmio_mmc_dma.c
drivers/usb/renesas_usbhs/fifo.c

Quoted 13 lines

2. Supporting legacy devices not using DMA Engine

These devices present a problem, as there may not be a uniform way to easily support them with regard to device tree. However, _IF_ legacy devices that are not using DMA Engine, only have a single DMA controller, then this problem is a lot simpler. For example, if we look at the previously proposed API for registering a DMA controller (where we pass the mask and function pointer to the DMA Engine filter function) we can simply pass NULL and hence, a driver requesting the DMA channel information would receive NULL for the DMA Engine specific parameters. Then for legacy devices we simply need a means to return the channel information (more on this later). If there are legacy devices that do have multiple DMA controllers, then maybe they need to be converted to support DMA Engine. I am not sure if this is unreasonable???

I think it's even simpler: any device that uses another interface instead of dmaengine will just have to parse the DT information itself. We should make sure that it uses the same binding though, so we can later migrate to the dmaengine API without having to change the device trees.

Quoted 24 lines

3. Representing and requesting channel information

From a hardware perspective, a DMA channel could be represented as ...

i. channel index/number
ii. channel transfer type (optional)
iii. DMA interrupt mapping (optional)

Please note that the transfer type is used to indicate if the transfer is to device from memory, to memory from device, to memory from memory, etc. This can be useful when there is a device such as an MMC device that uses two DMA channels, one for reading (RX) and one for writing (TX).

Forgetting device tree for now, some drivers use strings to represent a DMA channel instead of using an integer. I assume that these drivers then employ some sort of look-up table to convert the string into a channel number/index that the hardware understands. If this assumption is correct then when moving to a device tree implementation having such look-up tables in the driver should no longer be necessary as the device tree will provide the mapping of channel index/number to the device. Furthermore, it makes sense that device tree uses integers to represent channel as opposed to strings to save the driver having to convert the string into a integer at some later stage.

Quoted 6 lines

Next we need to think about how the DMA controller and channels are described in the device tree itself. The following device tree node example describes the properties of the DMA controller that includes, the register address range, number of interrupt supported, number of channels and number of request signals. This has been enhanced from the previous versions by adding number of channels and number of request signals.

I think you can actually use strings, too, as long as you use a fixed number of cells.

Wouldn't something like this work:?

	dma-controller1: dma1 {
		compatible = "something-using-strings";
		#dma-cells = <1>;
	};

	dma-controller2: dma2 {
		compatible = "something-using-integers";
		#dma-cells = <3>
	};

	some-device {
		compatible = "something";
		dmas = <&dma-controller1>, "some-dma",
			<&dma-controller2 1 2 3>;
	}

The only hard requirement is that the format of the attributes is what the binding specific to that controller understands.

Quoted 10 lines

A driver can now request the DMA channel information by calling the following function.

int of_get_dma_channel_info(struct device_node *np, int type,
struct of_dma_channel_info *info)

Where type represents the transfer-type (again the DMA Engine dma_transfer_direction enumeration can be used here regardless of if DMA Engine is used) and of_dma_channel_info is defined as follows.

Quoted 8 lines
	struct of_dma_channel_info {
		int		dma_channel;
		dma_cap_mask_t	dma_cap;
		dma_filter_fn	dma_filter_func;
	};

Here dma_channel will always be valid and the other fields are optional depending on whether DMA Engine is used.

I think a better interface for the device driver would be something that combines your of_get_dma_channel_info() function with the dma_request_channel() function, like

	struct dma_chan *of_dma_request_channel(struct device_node *dn, int index);

When we have the device tree, the driver using that channel doesn't actually have to care about the specific of how the channel is defined any more, it just needs to say which one it's interested in, out of the list of channels defined for that device node.

Arnd

author
#125 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Arnd,

Quoted 9 lines · Arnd Bergmann
Quoted 5 lines · Jon Hunter

From: Jon Hunter <[email protected]>

This is based upon the work by Benoit Cousson [1] and Nicolas Ferre [2] to add some basic helpers to retrieve a DMA controller device_node and the DMA request/channel information.

Thanks for picking this up again, I very much appreciate it as not having the binding is blocking a number of other activities.

No problem.

Quoted 11 lines
Quoted 11 lines

Design of DMA helpers

1. Supporting devices with multiple DMA controllers

In the case of DMA controllers that are using DMA Engine, requesting a channel is performed by calling the following function.

	struct dma_chan *dma_request_channel(dma_cap_mask_t mask,
			dma_filter_fn filter_fn,
			void *filter_param);
Quoted 8 lines
Quoted 5 lines

The mask variable is used to identify the device controller in a list of controllers. The filter_fn and filter_param are used to identify the required dma channel and return a handle to the dma channel of type dma_chan. From the examples I have seen, the mask and filter_fn are constant for a given DMA controller.

I believe this is not entirely correct: sometimes the filter_fn is provided by the slave driver, sometimes by the master driver.

Ok, but in the master case I assume they still use the same API?

Quoted 4 lines

Also, the mask does not identify a specific controller, AFAICT it just provides certain constraints. There are cases where a driver can pick from a multitude of dma engine controllers, as long as the channel the constraints are resolved.

True, but this should still work in that case.

Quoted 12 lines

This could be expressed in the device tree by listing multiple dma request lines (one per controller) in the device using it, or the author of the device tree can pick one.

Quoted 7 lines

Therefore, when registering a DMA controller with
device tree we can pass these parameters and store them so that a device can request them when requesting a channel. Hence, based upon this our register function for the DMA controller now looks like this.

	int of_dma_controller_register(struct device_node *np,
		dma_cap_mask_t *mask, dma_filter_fn fn);
Quoted 7 lines

This changes the behavior for drivers that provide their own filter functions, which may or may not be a problem.
For examples, have a look at some of these:

drivers/spi/spi-ep93xx.c
drivers/mmc/host/tmio_mmc_dma.c
drivers/usb/renesas_usbhs/fifo.c

Ok, thanks for the references! That makes life a little more tricky!

Quoted 14 lines
Quoted 13 lines

2. Supporting legacy devices not using DMA Engine

These devices present a problem, as there may not be a uniform way to easily support them with regard to device tree. However, _IF_ legacy devices that are not using DMA Engine, only have a single DMA controller, then this problem is a lot simpler. For example, if we look at the previously proposed API for registering a DMA controller (where we pass the mask and function pointer to the DMA Engine filter function) we can simply pass NULL and hence, a driver requesting the DMA channel information would receive NULL for the DMA Engine specific parameters. Then for legacy devices we simply need a means to return the channel information (more on this later). If there are legacy devices that do have multiple DMA controllers, then maybe they need to be converted to support DMA Engine. I am not sure if this is unreasonable???

Quoted 4 lines

I think it's even simpler: any device that uses another interface instead of dmaengine will just have to parse the DT information itself. We should make sure that it uses the same binding though, so we can later migrate to the dmaengine API without having to change the device trees.

Yes agreed.

Quoted 52 lines
Quoted 24 lines

3. Representing and requesting channel information

From a hardware perspective, a DMA channel could be represented as ...

i. channel index/number
ii. channel transfer type (optional)
iii. DMA interrupt mapping (optional)

Please note that the transfer type is used to indicate if the transfer is to device from memory, to memory from device, to memory from memory, etc. This can be useful when there is a device such as an MMC device that uses two DMA channels, one for reading (RX) and one for writing (TX).

Forgetting device tree for now, some drivers use strings to represent a DMA channel instead of using an integer. I assume that these drivers then employ some sort of look-up table to convert the string into a channel number/index that the hardware understands. If this assumption is correct then when moving to a device tree implementation having such look-up tables in the driver should no longer be necessary as the device tree will provide the mapping of channel index/number to the device. Furthermore, it makes sense that device tree uses integers to represent channel as opposed to strings to save the driver having to convert the string into a integer at some later stage.

Quoted 6 lines

Next we need to think about how the DMA controller and channels are described in the device tree itself. The following device tree node example describes the properties of the DMA controller that includes, the register address range, number of interrupt supported, number of channels and number of request signals. This has been enhanced from the previous versions by adding number of channels and number of request signals.

I think you can actually use strings, too, as long as you use a fixed number of cells.

Wouldn't something like this work:?

	dma-controller1: dma1 {
		compatible = "something-using-strings";
		#dma-cells = <1>;
	};

	dma-controller2: dma2 {
		compatible = "something-using-integers";
		#dma-cells = <3>
	};

	some-device {
		compatible = "something";
		dmas = <&dma-controller1>, "some-dma",
			<&dma-controller2 1 2 3>;
	}
Quoted 2 lines

The only hard requirement is that the format of the attributes is what the binding specific to that controller understands.

Yes it could. My point was why do this, if at the end of the day you need to resolve the string into a number at some point in the driver? However, this may make the migration easier for those using strings.

Quoted 23 lines
Quoted 10 lines

A driver can now request the DMA channel information by calling the following function.

int of_get_dma_channel_info(struct device_node *np, int type,
struct of_dma_channel_info *info)

Where type represents the transfer-type (again the DMA Engine dma_transfer_direction enumeration can be used here regardless of if DMA Engine is used) and of_dma_channel_info is defined as follows.

Quoted 8 lines
	struct of_dma_channel_info {
		int		dma_channel;
		dma_cap_mask_t	dma_cap;
		dma_filter_fn	dma_filter_func;
	};

Here dma_channel will always be valid and the other fields are optional depending on whether DMA Engine is used.

I think a better interface for the device driver would be something that combines your of_get_dma_channel_info() function with the dma_request_channel() function, like

Quoted 6 lines
	struct dma_chan *of_dma_request_channel(struct device_node *dn, int index);

When we have the device tree, the driver using that channel doesn't actually have to care about the specific of how the channel is defined any more, it just needs to say which one it's interested in, out of the list of channels defined for that device node.

Yes true. I was trying to avoid any changes to DMA engine itself. Plus in the feedback from Stephen his preference was to isolate the binding from DMA engine.

So in your example, is index passed via dma_request_channel()? I assume that of_dma_request_channel() get called in the context of dma_request_channel somewhere???

By the way, have you looked at the pl330_filter() function (drivers/dma/pl330.c)? They parse the device-tree in the filter function itself. The index could be passed as the filter_param. In this type of implementation there would be no need for a generic dma binding. However, would only work for devices supporting DMA engine.

Cheers
Jon

#126 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Quoted 5 lines · Jon Hunter
Quoted 3 lines

I believe this is not entirely correct: sometimes the filter_fn is provided by the slave driver, sometimes by the master driver.

Ok, but in the master case I assume they still use the same API?

The all use dma_request_channel, but the format of the data that gets passed depends only on whoever provides the filter function, which is not necessarily the slave or the master, but could be either one.

FWIW, I believe that for each dma engine implementation we only do one or the other, i.e. if the dmaengine driver provides a filter function, it is always used with these devices.

Quoted 29 lines
Quoted 29 lines
Quoted 7 lines

Next we need to think about how the DMA controller and channels are described in the device tree itself. The following device tree node example describes the properties of the DMA controller that includes, the register address range, number of interrupt supported, number of channels and number of request signals. This has been enhanced from the previous versions by adding number of channels and number of request signals.

I think you can actually use strings, too, as long as you use a fixed number of cells.

Wouldn't something like this work:?

	dma-controller1: dma1 {
		compatible = "something-using-strings";
		#dma-cells = <1>;
	};

	dma-controller2: dma2 {
		compatible = "something-using-integers";
		#dma-cells = <3>
	};

	some-device {
		compatible = "something";
		dmas = <&dma-controller1>, "some-dma",
			<&dma-controller2 1 2 3>;
	}
Quoted 6 lines
Quoted 2 lines

The only hard requirement is that the format of the attributes is what the binding specific to that controller understands.

Yes it could. My point was why do this, if at the end of the day you need to resolve the string into a number at some point in the driver? However, this may make the migration easier for those using strings.

Well, actually Stephen just clarified that we should not use strings here :(
We will always have to use numbers then.

Quoted 11 lines
Quoted 10 lines

I think a better interface for the device driver would be something that combines your of_get_dma_channel_info() function with the dma_request_channel() function, like

	struct dma_chan *of_dma_request_channel(struct device_node *dn, int index);

When we have the device tree, the driver using that channel doesn't actually have to care about the specific of how the channel is defined any more, it just needs to say which one it's interested in, out of the list of channels defined for that device node.

Quoted 7 lines

Yes true. I was trying to avoid any changes to DMA engine itself. Plus in the feedback from Stephen his preference was to isolate the binding from DMA engine.

So in your example, is index passed via dma_request_channel()? I assume that of_dma_request_channel() get called in the context of dma_request_channel somewhere???

What I meant what that you should still provide the existing dma_request_channel interface without changes, and also provide of_dma_request_channel as a wrapper around it that does a lookup in the way that your of_get_dma_channel_info does, passing the data it gets back from the device tree into the filter function that was provided by the dma engine driver.

Quoted 5 lines

By the way, have you looked at the pl330_filter() function (drivers/dma/pl330.c)? They parse the device-tree in the filter function itself. The index could be passed as the filter_param. In this type of implementation there would be no need for a generic dma binding. However, would only work for devices supporting DMA engine.

IMHO this will have to change, we should not have allowed a nonstandard binding for pl330 to be used for the samsung platforms and should migrate to the new binding as soon as possible.

Arnd

author
#127 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

Hi Arnd,

Quoted 8 lines · Arnd Bergmann
Quoted 5 lines · Jon Hunter
Quoted 3 lines

I believe this is not entirely correct: sometimes the filter_fn is provided by the slave driver, sometimes by the master driver.

Ok, but in the master case I assume they still use the same API?

Quoted 7 lines

The all use dma_request_channel, but the format of the data that gets passed depends only on whoever provides the filter function, which is not necessarily the slave or the master, but could be either one.

FWIW, I believe that for each dma engine implementation we only do one or the other, i.e. if the dmaengine driver provides a filter function, it is always used with these devices.

Ok, I think I am with you now. That should be fine.

Quoted 32 lines
Quoted 32 lines
Quoted 31 lines
Quoted 7 lines

Next we need to think about how the DMA controller and channels are described in the device tree itself. The following device tree node example describes the properties of the DMA controller that includes, the register address range, number of interrupt supported, number of channels and number of request signals. This has been enhanced from the previous versions by adding number of channels and number of request signals.

I think you can actually use strings, too, as long as you use a fixed number of cells.

Wouldn't something like this work:?

	dma-controller1: dma1 {
		compatible = "something-using-strings";
		#dma-cells = <1>;
	};

	dma-controller2: dma2 {
		compatible = "something-using-integers";
		#dma-cells = <3>
	};

	some-device {
		compatible = "something";
		dmas = <&dma-controller1>, "some-dma",
			<&dma-controller2 1 2 3>;
	}

The only hard requirement is that the format of the attributes is what the binding specific to that controller understands.

Quoted 7 lines
Quoted 3 lines

Yes it could. My point was why do this, if at the end of the day you need to resolve the string into a number at some point in the driver? However, this may make the migration easier for those using strings.

Well, actually Stephen just clarified that we should not use strings here :(
We will always have to use numbers then.

Ok. I think it makes life easier in the long run too.

Quoted 19 lines
Quoted 11 lines
Quoted 10 lines

I think a better interface for the device driver would be something that combines your of_get_dma_channel_info() function with the dma_request_channel() function, like

	struct dma_chan *of_dma_request_channel(struct device_node *dn, int index);

When we have the device tree, the driver using that channel doesn't actually have to care about the specific of how the channel is defined any more, it just needs to say which one it's interested in, out of the list of channels defined for that device node.

Quoted 7 lines

Yes true. I was trying to avoid any changes to DMA engine itself. Plus in the feedback from Stephen his preference was to isolate the binding from DMA engine.

So in your example, is index passed via dma_request_channel()? I assume that of_dma_request_channel() get called in the context of dma_request_channel somewhere???

Quoted 6 lines

What I meant what that you should still provide the existing dma_request_channel interface without changes, and also provide of_dma_request_channel as a wrapper around it that does a lookup in the way that your of_get_dma_channel_info does, passing the data it gets back from the device tree into the filter function that was provided by the dma engine driver.

Ok, gotcha.

Quoted 9 lines
Quoted 5 lines

By the way, have you looked at the pl330_filter() function (drivers/dma/pl330.c)? They parse the device-tree in the filter function itself. The index could be passed as the filter_param. In this type of implementation there would be no need for a generic dma binding. However, would only work for devices supporting DMA engine.

IMHO this will have to change, we should not have allowed a nonstandard binding for pl330 to be used for the samsung platforms and should migrate to the new binding as soon as possible.

Ok, that's fine with me.

Cheers
Jon

#128 lore raw

PATCH v3 1/2 of: Add generic device tree DMA helpers

In reply to Arnd Bergmann
Quoted 6 lines · Arnd Bergmann
Quoted 5 lines · Jon Hunter

From: Jon Hunter <[email protected]>

This is based upon the work by Benoit Cousson [1] and Nicolas Ferre [2] to add some basic helpers to retrieve a DMA controller device_node and the DMA request/channel information.

...

Quoted 10 lines
Quoted 10 lines

Forgetting device tree for now, some drivers use strings to represent a DMA channel instead of using an integer. I assume that these drivers then employ some sort of look-up table to convert the string into a channel number/index that the hardware understands. If this assumption is correct then when moving to a device tree implementation having such look-up tables in the driver should no longer be necessary as the device tree will provide the mapping of channel index/number to the device. Furthermore, it makes sense that device tree uses integers to represent channel as opposed to strings to save the driver having to convert the string into a integer at some later stage.

...

Quoted 4 lines

I think you can actually use strings, too, as long as you use a fixed number of cells.

Wouldn't something like this work:?

...

Quoted 5 lines
	some-device {
		compatible = "something";
		dmas = <&dma-controller1>, "some-dma",
			<&dma-controller2 1 2 3>;
	}

The idea of mixing integer cells and strings in the same property has come up before for other bindings, but been rejected. IIRC, there are issues such as alignment of the integers after the string (they are not aligned in the DTB) which can cause unaligned accesses, and perhaps other issues I fail to recall - perhaps because it's no longer possible to skip from the &dma-controller1 phandle to the &dma-controller2 phandle using #dma-cells, but rather you need to use strlen() and hence involve the DMA controller driver itself (otherwise, how do you know it's a string?) rather than just the core DMA property parsing code.