All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 0/7] dmaengine/dra7x: DMA router (crossbar support)
@ 2015-03-11 13:23 ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

Hi,

Changes since v1:
- Comments from Russell King and  Paul Bolle addressed:
 - Use the added defined in the omap-dma changes
 - MODULE_* removed from the ti-dma-crossbar driver.
- DMA router documentation: do not limit the #dma-cells to be the same as the
  dma controller's #dma-cells. It might be possible to have a router which needs
  more information than the DMA controller (direct request pairing for example)
- Use defines in the ti-dma-crossbar driver
- Binding document for the ti-dma-crossbar driver

Intro mail from v1:

The series adds support for DMA router type of devices. They are used in SoCs
which has more peripherals with DMA request lines than the DMA controller can
handle.
The router itself is not part of the DMA controller and it's operation should be
transparent (as it is in the HW) for the SW stack.

This series takes into accound the comments Sricharan received for his version
of the crossbar driver:
https://lkml.org/lkml/2014/3/7/199

This implementation is not tied to any DMA driver so it is possible to use the
framework by other vendors, also ACPI version of binding can be easy enough to
be added.

Regards,
Peter
---
Peter Ujfalusi (7):
  dmaengine: of_dma: Support for DMA routers
  Documentation: devicetree: dma: Binding documentation for TI DMA
    crossbar
  dmaengine: Add driver for TI DMA crossbar on DRA7x
  dmaengine: omap-dma: Use defines for dma channels and request count
  dmaengine: omap-dma: Take DMA request number from DT if it is
    available
  dmaengine: omap-dma: Remove mapping between virtual channels and
    requests
  ARM: DTS: dra7x: Integrate sDMA crossbar

 Documentation/devicetree/bindings/dma/dma.txt      |  28 +++
 .../devicetree/bindings/dma/ti-dma-crossbar.txt    |  52 ++++++
 arch/arm/boot/dts/dra7.dtsi                        |  57 ++++---
 drivers/dma/Kconfig                                |   4 +
 drivers/dma/Makefile                               |   1 +
 drivers/dma/dmaengine.c                            |   7 +
 drivers/dma/of-dma.c                               |  92 ++++++++++
 drivers/dma/omap-dma.c                             |  25 ++-
 drivers/dma/ti-dma-crossbar.c                      | 190 +++++++++++++++++++++
 include/linux/dmaengine.h                          |  17 ++
 include/linux/of_dma.h                             |  21 +++
 11 files changed, 466 insertions(+), 28 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
 create mode 100644 drivers/dma/ti-dma-crossbar.c

-- 
2.3.0


^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 0/7] dmaengine/dra7x: DMA router (crossbar support)
@ 2015-03-11 13:23 ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

Hi,

Changes since v1:
- Comments from Russell King and  Paul Bolle addressed:
 - Use the added defined in the omap-dma changes
 - MODULE_* removed from the ti-dma-crossbar driver.
- DMA router documentation: do not limit the #dma-cells to be the same as the
  dma controller's #dma-cells. It might be possible to have a router which needs
  more information than the DMA controller (direct request pairing for example)
- Use defines in the ti-dma-crossbar driver
- Binding document for the ti-dma-crossbar driver

Intro mail from v1:

The series adds support for DMA router type of devices. They are used in SoCs
which has more peripherals with DMA request lines than the DMA controller can
handle.
The router itself is not part of the DMA controller and it's operation should be
transparent (as it is in the HW) for the SW stack.

This series takes into accound the comments Sricharan received for his version
of the crossbar driver:
https://lkml.org/lkml/2014/3/7/199

This implementation is not tied to any DMA driver so it is possible to use the
framework by other vendors, also ACPI version of binding can be easy enough to
be added.

Regards,
Peter
---
Peter Ujfalusi (7):
  dmaengine: of_dma: Support for DMA routers
  Documentation: devicetree: dma: Binding documentation for TI DMA
    crossbar
  dmaengine: Add driver for TI DMA crossbar on DRA7x
  dmaengine: omap-dma: Use defines for dma channels and request count
  dmaengine: omap-dma: Take DMA request number from DT if it is
    available
  dmaengine: omap-dma: Remove mapping between virtual channels and
    requests
  ARM: DTS: dra7x: Integrate sDMA crossbar

 Documentation/devicetree/bindings/dma/dma.txt      |  28 +++
 .../devicetree/bindings/dma/ti-dma-crossbar.txt    |  52 ++++++
 arch/arm/boot/dts/dra7.dtsi                        |  57 ++++---
 drivers/dma/Kconfig                                |   4 +
 drivers/dma/Makefile                               |   1 +
 drivers/dma/dmaengine.c                            |   7 +
 drivers/dma/of-dma.c                               |  92 ++++++++++
 drivers/dma/omap-dma.c                             |  25 ++-
 drivers/dma/ti-dma-crossbar.c                      | 190 +++++++++++++++++++++
 include/linux/dmaengine.h                          |  17 ++
 include/linux/of_dma.h                             |  21 +++
 11 files changed, 466 insertions(+), 28 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
 create mode 100644 drivers/dma/ti-dma-crossbar.c

-- 
2.3.0


^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 0/7] dmaengine/dra7x: DMA router (crossbar support)
@ 2015-03-11 13:23 ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Changes since v1:
- Comments from Russell King and  Paul Bolle addressed:
 - Use the added defined in the omap-dma changes
 - MODULE_* removed from the ti-dma-crossbar driver.
- DMA router documentation: do not limit the #dma-cells to be the same as the
  dma controller's #dma-cells. It might be possible to have a router which needs
  more information than the DMA controller (direct request pairing for example)
- Use defines in the ti-dma-crossbar driver
- Binding document for the ti-dma-crossbar driver

Intro mail from v1:

The series adds support for DMA router type of devices. They are used in SoCs
which has more peripherals with DMA request lines than the DMA controller can
handle.
The router itself is not part of the DMA controller and it's operation should be
transparent (as it is in the HW) for the SW stack.

This series takes into accound the comments Sricharan received for his version
of the crossbar driver:
https://lkml.org/lkml/2014/3/7/199

This implementation is not tied to any DMA driver so it is possible to use the
framework by other vendors, also ACPI version of binding can be easy enough to
be added.

Regards,
Peter
---
Peter Ujfalusi (7):
  dmaengine: of_dma: Support for DMA routers
  Documentation: devicetree: dma: Binding documentation for TI DMA
    crossbar
  dmaengine: Add driver for TI DMA crossbar on DRA7x
  dmaengine: omap-dma: Use defines for dma channels and request count
  dmaengine: omap-dma: Take DMA request number from DT if it is
    available
  dmaengine: omap-dma: Remove mapping between virtual channels and
    requests
  ARM: DTS: dra7x: Integrate sDMA crossbar

 Documentation/devicetree/bindings/dma/dma.txt      |  28 +++
 .../devicetree/bindings/dma/ti-dma-crossbar.txt    |  52 ++++++
 arch/arm/boot/dts/dra7.dtsi                        |  57 ++++---
 drivers/dma/Kconfig                                |   4 +
 drivers/dma/Makefile                               |   1 +
 drivers/dma/dmaengine.c                            |   7 +
 drivers/dma/of-dma.c                               |  92 ++++++++++
 drivers/dma/omap-dma.c                             |  25 ++-
 drivers/dma/ti-dma-crossbar.c                      | 190 +++++++++++++++++++++
 include/linux/dmaengine.h                          |  17 ++
 include/linux/of_dma.h                             |  21 +++
 11 files changed, 466 insertions(+), 28 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
 create mode 100644 drivers/dma/ti-dma-crossbar.c

-- 
2.3.0

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
  2015-03-11 13:23 ` Peter Ujfalusi
  (?)
@ 2015-03-11 13:23   ` Peter Ujfalusi
  -1 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

DMA routers are transparent devices used to mux DMA requests from
peripherals to DMA controllers. They are used when the SoC integrates more
devices with DMA requests then their controller can handle.
DRA7x is one example of such SoC, where the sDMA can hanlde 128 DMA request
lines, but in SoC level it has 205 DMA requests.

The of_dma_router will be registered as of_dma_controller with special
xlate function and additional parameters and the code will translate and
requests a DMA channel from the real DMA controller.
This way the router can be transparent for the system while remaining generic
enough to be used in different environments.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
 drivers/dma/dmaengine.c                       |  7 ++
 drivers/dma/of-dma.c                          | 92 +++++++++++++++++++++++++++
 include/linux/dmaengine.h                     | 17 +++++
 include/linux/of_dma.h                        | 21 ++++++
 5 files changed, 165 insertions(+)

diff --git a/Documentation/devicetree/bindings/dma/dma.txt b/Documentation/devicetree/bindings/dma/dma.txt
index 82104271e754..f728b978178e 100644
--- a/Documentation/devicetree/bindings/dma/dma.txt
+++ b/Documentation/devicetree/bindings/dma/dma.txt
@@ -31,6 +31,34 @@ Example:
 		dma-requests = <127>;
 	};
 
+* DMA router
+
+DMA routers are transparent IP blocks used to route DMA request lines from
+devices to the DMA controller. Some SoCs (like TI DRA7x) have more peripherals
+integrated with DMA requests than what the DMA controller can handle directly.
+
+Required property:
+- dma-device:		phandle of the DMA controller. The router is modifying
+			the DMA requests for this controller.
+- #dma-cells: 		Must be at least 1. Used to provide DMA router specific
+			information. See DMA client binding below for more
+			details.
+
+Optional properties:
+- dma-requests: 	Number of incoming request lines the router can handle.
+- dma-device
+	- dma-requests:	The router driver might need to look for this in order
+			to configure the routing.
+
+Example:
+	sdma_xbar: dma-router@4a002b78 {
+		compatible = "ti,dra7-dma-crossbar";
+		reg = <0x4a002b78 0xfc>;
+		#dma-cells = <1>;
+		dma-requests = <205>;
+		ti,dma-safe-map = <0>;
+		dma-device = <&sdma>;
+	};
 
 * DMA client
 
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 344b0ac6d985..1bb67dae5880 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -271,6 +271,13 @@ static void dma_chan_put(struct dma_chan *chan)
 	/* This channel is not in use anymore, free it */
 	if (!chan->client_count && chan->device->device_free_chan_resources)
 		chan->device->device_free_chan_resources(chan);
+
+	/* If the channel is used via a DMA request router, free the mapping */
+	if (chan->router && chan->router->route_free) {
+		chan->router->route_free(chan->router->dev, chan->route_data);
+		chan->router = NULL;
+		chan->route_data = NULL;
+	}
 }
 
 enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)
diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index ca31f1b45366..c86f8823da0d 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -45,6 +45,53 @@ static struct of_dma *of_dma_find_controller(struct of_phandle_args *dma_spec)
 }
 
 /**
+ * of_dma_router_xlate - translation function for router devices
+ * @dma_spec:	pointer to DMA specifier as found in the device tree
+ * @of_dma:	pointer to DMA controller data (router information)
+ *
+ * The function creates new dma_spec to be passed to the router driver's
+ * of_dma_route_allocate() function to prepare a dma_spec which will be used
+ * to request channel from the real DMA controller.
+ */
+static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec,
+					    struct of_dma *ofdma)
+{
+	struct dma_chan		*chan;
+	struct of_dma		*ofdma_target;
+	struct device_node	*dma_target;
+	struct of_phandle_args	dma_spec_target;
+	void			*route_data;
+
+	dma_target = of_parse_phandle(dma_spec->np, "dma-device", 0);
+	if (!dma_target) {
+		pr_err("%s: Can't get target DMA\n", __func__);
+		return NULL;
+	}
+
+	/* translate the request for the real DMA controller */
+	memcpy(&dma_spec_target, dma_spec, sizeof(dma_spec_target));
+	dma_spec_target.np = dma_target;
+	route_data = ofdma->of_dma_route_allocate(&dma_spec_target, ofdma);
+
+	ofdma_target = of_dma_find_controller(&dma_spec_target);
+	if (!ofdma_target) {
+		pr_err("%s: Can't get target ofDMA\n", __func__);
+		return NULL;
+	}
+
+	chan = ofdma_target->of_dma_xlate(&dma_spec_target, ofdma_target);
+	if (chan) {
+		chan->router = ofdma->dma_router;
+		chan->route_data = route_data;
+	} else {
+		ofdma->dma_router->route_free(ofdma->dma_router->dev, route_data);
+	}
+
+	of_node_put(dma_target);
+	return chan;
+}
+
+/**
  * of_dma_controller_register - Register a DMA controller to DT DMA helpers
  * @np:			device node of DMA controller
  * @of_dma_xlate:	translation function which converts a phandle
@@ -110,6 +157,51 @@ void of_dma_controller_free(struct device_node *np)
 EXPORT_SYMBOL_GPL(of_dma_controller_free);
 
 /**
+ * of_dma_router_register - Register a DMA router to DT DMA helpers as a
+ *			    controller
+ * @np:				device node of DMA router
+ * @of_dma_route_allocate:	setup function for the router which need to
+ *				modify the dma_spec for the DMA controller to
+ *				use and to set up the requested route.
+ * @dma_router:			pointer to dma_router structure to be used when
+ *				the route need to be free up.
+ *
+ * Returns 0 on success or appropriate errno value on error.
+ *
+ * Allocated memory should be freed with appropriate of_dma_controller_free()
+ * call.
+ */
+int of_dma_router_register(struct device_node *np,
+			   void *(*of_dma_route_allocate)
+			   (struct of_phandle_args *, struct of_dma *),
+			   struct dma_router *dma_router)
+{
+	struct of_dma	*ofdma;
+
+	if (!np || !of_dma_route_allocate || !dma_router) {
+		pr_err("%s: not enough information provided\n", __func__);
+		return -EINVAL;
+	}
+
+	ofdma = kzalloc(sizeof(*ofdma), GFP_KERNEL);
+	if (!ofdma)
+		return -ENOMEM;
+
+	ofdma->of_node = np;
+	ofdma->of_dma_xlate = of_dma_router_xlate;
+	ofdma->of_dma_route_allocate = of_dma_route_allocate;
+	ofdma->dma_router = dma_router;
+
+	/* Now queue of_dma controller structure in list */
+	mutex_lock(&of_dma_lock);
+	list_add_tail(&ofdma->of_dma_controllers, &of_dma_list);
+	mutex_unlock(&of_dma_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_dma_router_register);
+
+/**
  * of_dma_match_channel - Check if a DMA specifier matches name
  * @np:		device node to look for DMA channels
  * @name:	channel name to be matched
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 2bff9abc162a..b6a0e59f1887 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -226,6 +226,16 @@ struct dma_chan_percpu {
 };
 
 /**
+ * struct dma_router - DMA router structure
+ * @dev: pointer to the DMA router device
+ * @route_free: function to be called when the route can be disconnected
+ */
+struct dma_router {
+	struct device *dev;
+	void (*route_free)(struct device *dev, void *route_data);
+};
+
+/**
  * struct dma_chan - devices supply DMA channels, clients use them
  * @device: ptr to the dma device who supplies this channel, always !%NULL
  * @cookie: last cookie value returned to client
@@ -236,6 +246,8 @@ struct dma_chan_percpu {
  * @local: per-cpu pointer to a struct dma_chan_percpu
  * @client_count: how many clients are using this channel
  * @table_count: number of appearances in the mem-to-mem allocation table
+ * @router: pointer to the DMA router structure
+ * @route_data: channel specific data for the router
  * @private: private data for certain client-channel associations
  */
 struct dma_chan {
@@ -251,6 +263,11 @@ struct dma_chan {
 	struct dma_chan_percpu __percpu *local;
 	int client_count;
 	int table_count;
+
+	/* DMA router */
+	struct dma_router *router;
+	void *route_data;
+
 	void *private;
 };
 
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index 56bc026c143f..734e449f87c1 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -23,6 +23,9 @@ struct of_dma {
 	struct device_node	*of_node;
 	struct dma_chan		*(*of_dma_xlate)
 				(struct of_phandle_args *, struct of_dma *);
+	void			*(*of_dma_route_allocate)
+				(struct of_phandle_args *, struct of_dma *);
+	struct dma_router	*dma_router;
 	void			*of_dma_data;
 };
 
@@ -37,12 +40,20 @@ extern int of_dma_controller_register(struct device_node *np,
 		(struct of_phandle_args *, struct of_dma *),
 		void *data);
 extern void of_dma_controller_free(struct device_node *np);
+
+extern int of_dma_router_register(struct device_node *np,
+		void *(*of_dma_route_allocate)
+		(struct of_phandle_args *, struct of_dma *),
+		 struct dma_router *dma_router);
+#define of_dma_router_free of_dma_controller_free
+
 extern struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
 						     const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
 		struct of_dma *ofdma);
 extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
 		struct of_dma *ofdma);
+
 #else
 static inline int of_dma_controller_register(struct device_node *np,
 		struct dma_chan *(*of_dma_xlate)
@@ -56,6 +67,16 @@ static inline void of_dma_controller_free(struct device_node *np)
 {
 }
 
+static inline int of_dma_router_register(struct device_node *np,
+		void *(*of_dma_route_allocate)
+		(struct of_phandle_args *, struct of_dma *),
+		 struct dma_router *dma_router)
+{
+	return -ENODEV;
+}
+
+#define of_dma_router_free of_dma_controller_free
+
 static inline struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
 						     const char *name)
 {
-- 
2.3.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

DMA routers are transparent devices used to mux DMA requests from
peripherals to DMA controllers. They are used when the SoC integrates more
devices with DMA requests then their controller can handle.
DRA7x is one example of such SoC, where the sDMA can hanlde 128 DMA request
lines, but in SoC level it has 205 DMA requests.

The of_dma_router will be registered as of_dma_controller with special
xlate function and additional parameters and the code will translate and
requests a DMA channel from the real DMA controller.
This way the router can be transparent for the system while remaining generic
enough to be used in different environments.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
 drivers/dma/dmaengine.c                       |  7 ++
 drivers/dma/of-dma.c                          | 92 +++++++++++++++++++++++++++
 include/linux/dmaengine.h                     | 17 +++++
 include/linux/of_dma.h                        | 21 ++++++
 5 files changed, 165 insertions(+)

diff --git a/Documentation/devicetree/bindings/dma/dma.txt b/Documentation/devicetree/bindings/dma/dma.txt
index 82104271e754..f728b978178e 100644
--- a/Documentation/devicetree/bindings/dma/dma.txt
+++ b/Documentation/devicetree/bindings/dma/dma.txt
@@ -31,6 +31,34 @@ Example:
 		dma-requests = <127>;
 	};
 
+* DMA router
+
+DMA routers are transparent IP blocks used to route DMA request lines from
+devices to the DMA controller. Some SoCs (like TI DRA7x) have more peripherals
+integrated with DMA requests than what the DMA controller can handle directly.
+
+Required property:
+- dma-device:		phandle of the DMA controller. The router is modifying
+			the DMA requests for this controller.
+- #dma-cells: 		Must be at least 1. Used to provide DMA router specific
+			information. See DMA client binding below for more
+			details.
+
+Optional properties:
+- dma-requests: 	Number of incoming request lines the router can handle.
+- dma-device
+	- dma-requests:	The router driver might need to look for this in order
+			to configure the routing.
+
+Example:
+	sdma_xbar: dma-router@4a002b78 {
+		compatible = "ti,dra7-dma-crossbar";
+		reg = <0x4a002b78 0xfc>;
+		#dma-cells = <1>;
+		dma-requests = <205>;
+		ti,dma-safe-map = <0>;
+		dma-device = <&sdma>;
+	};
 
 * DMA client
 
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 344b0ac6d985..1bb67dae5880 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -271,6 +271,13 @@ static void dma_chan_put(struct dma_chan *chan)
 	/* This channel is not in use anymore, free it */
 	if (!chan->client_count && chan->device->device_free_chan_resources)
 		chan->device->device_free_chan_resources(chan);
+
+	/* If the channel is used via a DMA request router, free the mapping */
+	if (chan->router && chan->router->route_free) {
+		chan->router->route_free(chan->router->dev, chan->route_data);
+		chan->router = NULL;
+		chan->route_data = NULL;
+	}
 }
 
 enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)
diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index ca31f1b45366..c86f8823da0d 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -45,6 +45,53 @@ static struct of_dma *of_dma_find_controller(struct of_phandle_args *dma_spec)
 }
 
 /**
+ * of_dma_router_xlate - translation function for router devices
+ * @dma_spec:	pointer to DMA specifier as found in the device tree
+ * @of_dma:	pointer to DMA controller data (router information)
+ *
+ * The function creates new dma_spec to be passed to the router driver's
+ * of_dma_route_allocate() function to prepare a dma_spec which will be used
+ * to request channel from the real DMA controller.
+ */
+static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec,
+					    struct of_dma *ofdma)
+{
+	struct dma_chan		*chan;
+	struct of_dma		*ofdma_target;
+	struct device_node	*dma_target;
+	struct of_phandle_args	dma_spec_target;
+	void			*route_data;
+
+	dma_target = of_parse_phandle(dma_spec->np, "dma-device", 0);
+	if (!dma_target) {
+		pr_err("%s: Can't get target DMA\n", __func__);
+		return NULL;
+	}
+
+	/* translate the request for the real DMA controller */
+	memcpy(&dma_spec_target, dma_spec, sizeof(dma_spec_target));
+	dma_spec_target.np = dma_target;
+	route_data = ofdma->of_dma_route_allocate(&dma_spec_target, ofdma);
+
+	ofdma_target = of_dma_find_controller(&dma_spec_target);
+	if (!ofdma_target) {
+		pr_err("%s: Can't get target ofDMA\n", __func__);
+		return NULL;
+	}
+
+	chan = ofdma_target->of_dma_xlate(&dma_spec_target, ofdma_target);
+	if (chan) {
+		chan->router = ofdma->dma_router;
+		chan->route_data = route_data;
+	} else {
+		ofdma->dma_router->route_free(ofdma->dma_router->dev, route_data);
+	}
+
+	of_node_put(dma_target);
+	return chan;
+}
+
+/**
  * of_dma_controller_register - Register a DMA controller to DT DMA helpers
  * @np:			device node of DMA controller
  * @of_dma_xlate:	translation function which converts a phandle
@@ -110,6 +157,51 @@ void of_dma_controller_free(struct device_node *np)
 EXPORT_SYMBOL_GPL(of_dma_controller_free);
 
 /**
+ * of_dma_router_register - Register a DMA router to DT DMA helpers as a
+ *			    controller
+ * @np:				device node of DMA router
+ * @of_dma_route_allocate:	setup function for the router which need to
+ *				modify the dma_spec for the DMA controller to
+ *				use and to set up the requested route.
+ * @dma_router:			pointer to dma_router structure to be used when
+ *				the route need to be free up.
+ *
+ * Returns 0 on success or appropriate errno value on error.
+ *
+ * Allocated memory should be freed with appropriate of_dma_controller_free()
+ * call.
+ */
+int of_dma_router_register(struct device_node *np,
+			   void *(*of_dma_route_allocate)
+			   (struct of_phandle_args *, struct of_dma *),
+			   struct dma_router *dma_router)
+{
+	struct of_dma	*ofdma;
+
+	if (!np || !of_dma_route_allocate || !dma_router) {
+		pr_err("%s: not enough information provided\n", __func__);
+		return -EINVAL;
+	}
+
+	ofdma = kzalloc(sizeof(*ofdma), GFP_KERNEL);
+	if (!ofdma)
+		return -ENOMEM;
+
+	ofdma->of_node = np;
+	ofdma->of_dma_xlate = of_dma_router_xlate;
+	ofdma->of_dma_route_allocate = of_dma_route_allocate;
+	ofdma->dma_router = dma_router;
+
+	/* Now queue of_dma controller structure in list */
+	mutex_lock(&of_dma_lock);
+	list_add_tail(&ofdma->of_dma_controllers, &of_dma_list);
+	mutex_unlock(&of_dma_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_dma_router_register);
+
+/**
  * of_dma_match_channel - Check if a DMA specifier matches name
  * @np:		device node to look for DMA channels
  * @name:	channel name to be matched
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 2bff9abc162a..b6a0e59f1887 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -226,6 +226,16 @@ struct dma_chan_percpu {
 };
 
 /**
+ * struct dma_router - DMA router structure
+ * @dev: pointer to the DMA router device
+ * @route_free: function to be called when the route can be disconnected
+ */
+struct dma_router {
+	struct device *dev;
+	void (*route_free)(struct device *dev, void *route_data);
+};
+
+/**
  * struct dma_chan - devices supply DMA channels, clients use them
  * @device: ptr to the dma device who supplies this channel, always !%NULL
  * @cookie: last cookie value returned to client
@@ -236,6 +246,8 @@ struct dma_chan_percpu {
  * @local: per-cpu pointer to a struct dma_chan_percpu
  * @client_count: how many clients are using this channel
  * @table_count: number of appearances in the mem-to-mem allocation table
+ * @router: pointer to the DMA router structure
+ * @route_data: channel specific data for the router
  * @private: private data for certain client-channel associations
  */
 struct dma_chan {
@@ -251,6 +263,11 @@ struct dma_chan {
 	struct dma_chan_percpu __percpu *local;
 	int client_count;
 	int table_count;
+
+	/* DMA router */
+	struct dma_router *router;
+	void *route_data;
+
 	void *private;
 };
 
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index 56bc026c143f..734e449f87c1 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -23,6 +23,9 @@ struct of_dma {
 	struct device_node	*of_node;
 	struct dma_chan		*(*of_dma_xlate)
 				(struct of_phandle_args *, struct of_dma *);
+	void			*(*of_dma_route_allocate)
+				(struct of_phandle_args *, struct of_dma *);
+	struct dma_router	*dma_router;
 	void			*of_dma_data;
 };
 
@@ -37,12 +40,20 @@ extern int of_dma_controller_register(struct device_node *np,
 		(struct of_phandle_args *, struct of_dma *),
 		void *data);
 extern void of_dma_controller_free(struct device_node *np);
+
+extern int of_dma_router_register(struct device_node *np,
+		void *(*of_dma_route_allocate)
+		(struct of_phandle_args *, struct of_dma *),
+		 struct dma_router *dma_router);
+#define of_dma_router_free of_dma_controller_free
+
 extern struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
 						     const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
 		struct of_dma *ofdma);
 extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
 		struct of_dma *ofdma);
+
 #else
 static inline int of_dma_controller_register(struct device_node *np,
 		struct dma_chan *(*of_dma_xlate)
@@ -56,6 +67,16 @@ static inline void of_dma_controller_free(struct device_node *np)
 {
 }
 
+static inline int of_dma_router_register(struct device_node *np,
+		void *(*of_dma_route_allocate)
+		(struct of_phandle_args *, struct of_dma *),
+		 struct dma_router *dma_router)
+{
+	return -ENODEV;
+}
+
+#define of_dma_router_free of_dma_controller_free
+
 static inline struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
 						     const char *name)
 {
-- 
2.3.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: linux-arm-kernel

DMA routers are transparent devices used to mux DMA requests from
peripherals to DMA controllers. They are used when the SoC integrates more
devices with DMA requests then their controller can handle.
DRA7x is one example of such SoC, where the sDMA can hanlde 128 DMA request
lines, but in SoC level it has 205 DMA requests.

The of_dma_router will be registered as of_dma_controller with special
xlate function and additional parameters and the code will translate and
requests a DMA channel from the real DMA controller.
This way the router can be transparent for the system while remaining generic
enough to be used in different environments.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
 drivers/dma/dmaengine.c                       |  7 ++
 drivers/dma/of-dma.c                          | 92 +++++++++++++++++++++++++++
 include/linux/dmaengine.h                     | 17 +++++
 include/linux/of_dma.h                        | 21 ++++++
 5 files changed, 165 insertions(+)

diff --git a/Documentation/devicetree/bindings/dma/dma.txt b/Documentation/devicetree/bindings/dma/dma.txt
index 82104271e754..f728b978178e 100644
--- a/Documentation/devicetree/bindings/dma/dma.txt
+++ b/Documentation/devicetree/bindings/dma/dma.txt
@@ -31,6 +31,34 @@ Example:
 		dma-requests = <127>;
 	};
 
+* DMA router
+
+DMA routers are transparent IP blocks used to route DMA request lines from
+devices to the DMA controller. Some SoCs (like TI DRA7x) have more peripherals
+integrated with DMA requests than what the DMA controller can handle directly.
+
+Required property:
+- dma-device:		phandle of the DMA controller. The router is modifying
+			the DMA requests for this controller.
+- #dma-cells: 		Must be at least 1. Used to provide DMA router specific
+			information. See DMA client binding below for more
+			details.
+
+Optional properties:
+- dma-requests: 	Number of incoming request lines the router can handle.
+- dma-device
+	- dma-requests:	The router driver might need to look for this in order
+			to configure the routing.
+
+Example:
+	sdma_xbar: dma-router at 4a002b78 {
+		compatible = "ti,dra7-dma-crossbar";
+		reg = <0x4a002b78 0xfc>;
+		#dma-cells = <1>;
+		dma-requests = <205>;
+		ti,dma-safe-map = <0>;
+		dma-device = <&sdma>;
+	};
 
 * DMA client
 
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
index 344b0ac6d985..1bb67dae5880 100644
--- a/drivers/dma/dmaengine.c
+++ b/drivers/dma/dmaengine.c
@@ -271,6 +271,13 @@ static void dma_chan_put(struct dma_chan *chan)
 	/* This channel is not in use anymore, free it */
 	if (!chan->client_count && chan->device->device_free_chan_resources)
 		chan->device->device_free_chan_resources(chan);
+
+	/* If the channel is used via a DMA request router, free the mapping */
+	if (chan->router && chan->router->route_free) {
+		chan->router->route_free(chan->router->dev, chan->route_data);
+		chan->router = NULL;
+		chan->route_data = NULL;
+	}
 }
 
 enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)
diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
index ca31f1b45366..c86f8823da0d 100644
--- a/drivers/dma/of-dma.c
+++ b/drivers/dma/of-dma.c
@@ -45,6 +45,53 @@ static struct of_dma *of_dma_find_controller(struct of_phandle_args *dma_spec)
 }
 
 /**
+ * of_dma_router_xlate - translation function for router devices
+ * @dma_spec:	pointer to DMA specifier as found in the device tree
+ * @of_dma:	pointer to DMA controller data (router information)
+ *
+ * The function creates new dma_spec to be passed to the router driver's
+ * of_dma_route_allocate() function to prepare a dma_spec which will be used
+ * to request channel from the real DMA controller.
+ */
+static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec,
+					    struct of_dma *ofdma)
+{
+	struct dma_chan		*chan;
+	struct of_dma		*ofdma_target;
+	struct device_node	*dma_target;
+	struct of_phandle_args	dma_spec_target;
+	void			*route_data;
+
+	dma_target = of_parse_phandle(dma_spec->np, "dma-device", 0);
+	if (!dma_target) {
+		pr_err("%s: Can't get target DMA\n", __func__);
+		return NULL;
+	}
+
+	/* translate the request for the real DMA controller */
+	memcpy(&dma_spec_target, dma_spec, sizeof(dma_spec_target));
+	dma_spec_target.np = dma_target;
+	route_data = ofdma->of_dma_route_allocate(&dma_spec_target, ofdma);
+
+	ofdma_target = of_dma_find_controller(&dma_spec_target);
+	if (!ofdma_target) {
+		pr_err("%s: Can't get target ofDMA\n", __func__);
+		return NULL;
+	}
+
+	chan = ofdma_target->of_dma_xlate(&dma_spec_target, ofdma_target);
+	if (chan) {
+		chan->router = ofdma->dma_router;
+		chan->route_data = route_data;
+	} else {
+		ofdma->dma_router->route_free(ofdma->dma_router->dev, route_data);
+	}
+
+	of_node_put(dma_target);
+	return chan;
+}
+
+/**
  * of_dma_controller_register - Register a DMA controller to DT DMA helpers
  * @np:			device node of DMA controller
  * @of_dma_xlate:	translation function which converts a phandle
@@ -110,6 +157,51 @@ void of_dma_controller_free(struct device_node *np)
 EXPORT_SYMBOL_GPL(of_dma_controller_free);
 
 /**
+ * of_dma_router_register - Register a DMA router to DT DMA helpers as a
+ *			    controller
+ * @np:				device node of DMA router
+ * @of_dma_route_allocate:	setup function for the router which need to
+ *				modify the dma_spec for the DMA controller to
+ *				use and to set up the requested route.
+ * @dma_router:			pointer to dma_router structure to be used when
+ *				the route need to be free up.
+ *
+ * Returns 0 on success or appropriate errno value on error.
+ *
+ * Allocated memory should be freed with appropriate of_dma_controller_free()
+ * call.
+ */
+int of_dma_router_register(struct device_node *np,
+			   void *(*of_dma_route_allocate)
+			   (struct of_phandle_args *, struct of_dma *),
+			   struct dma_router *dma_router)
+{
+	struct of_dma	*ofdma;
+
+	if (!np || !of_dma_route_allocate || !dma_router) {
+		pr_err("%s: not enough information provided\n", __func__);
+		return -EINVAL;
+	}
+
+	ofdma = kzalloc(sizeof(*ofdma), GFP_KERNEL);
+	if (!ofdma)
+		return -ENOMEM;
+
+	ofdma->of_node = np;
+	ofdma->of_dma_xlate = of_dma_router_xlate;
+	ofdma->of_dma_route_allocate = of_dma_route_allocate;
+	ofdma->dma_router = dma_router;
+
+	/* Now queue of_dma controller structure in list */
+	mutex_lock(&of_dma_lock);
+	list_add_tail(&ofdma->of_dma_controllers, &of_dma_list);
+	mutex_unlock(&of_dma_lock);
+
+	return 0;
+}
+EXPORT_SYMBOL_GPL(of_dma_router_register);
+
+/**
  * of_dma_match_channel - Check if a DMA specifier matches name
  * @np:		device node to look for DMA channels
  * @name:	channel name to be matched
diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
index 2bff9abc162a..b6a0e59f1887 100644
--- a/include/linux/dmaengine.h
+++ b/include/linux/dmaengine.h
@@ -226,6 +226,16 @@ struct dma_chan_percpu {
 };
 
 /**
+ * struct dma_router - DMA router structure
+ * @dev: pointer to the DMA router device
+ * @route_free: function to be called when the route can be disconnected
+ */
+struct dma_router {
+	struct device *dev;
+	void (*route_free)(struct device *dev, void *route_data);
+};
+
+/**
  * struct dma_chan - devices supply DMA channels, clients use them
  * @device: ptr to the dma device who supplies this channel, always !%NULL
  * @cookie: last cookie value returned to client
@@ -236,6 +246,8 @@ struct dma_chan_percpu {
  * @local: per-cpu pointer to a struct dma_chan_percpu
  * @client_count: how many clients are using this channel
  * @table_count: number of appearances in the mem-to-mem allocation table
+ * @router: pointer to the DMA router structure
+ * @route_data: channel specific data for the router
  * @private: private data for certain client-channel associations
  */
 struct dma_chan {
@@ -251,6 +263,11 @@ struct dma_chan {
 	struct dma_chan_percpu __percpu *local;
 	int client_count;
 	int table_count;
+
+	/* DMA router */
+	struct dma_router *router;
+	void *route_data;
+
 	void *private;
 };
 
diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
index 56bc026c143f..734e449f87c1 100644
--- a/include/linux/of_dma.h
+++ b/include/linux/of_dma.h
@@ -23,6 +23,9 @@ struct of_dma {
 	struct device_node	*of_node;
 	struct dma_chan		*(*of_dma_xlate)
 				(struct of_phandle_args *, struct of_dma *);
+	void			*(*of_dma_route_allocate)
+				(struct of_phandle_args *, struct of_dma *);
+	struct dma_router	*dma_router;
 	void			*of_dma_data;
 };
 
@@ -37,12 +40,20 @@ extern int of_dma_controller_register(struct device_node *np,
 		(struct of_phandle_args *, struct of_dma *),
 		void *data);
 extern void of_dma_controller_free(struct device_node *np);
+
+extern int of_dma_router_register(struct device_node *np,
+		void *(*of_dma_route_allocate)
+		(struct of_phandle_args *, struct of_dma *),
+		 struct dma_router *dma_router);
+#define of_dma_router_free of_dma_controller_free
+
 extern struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
 						     const char *name);
 extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
 		struct of_dma *ofdma);
 extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
 		struct of_dma *ofdma);
+
 #else
 static inline int of_dma_controller_register(struct device_node *np,
 		struct dma_chan *(*of_dma_xlate)
@@ -56,6 +67,16 @@ static inline void of_dma_controller_free(struct device_node *np)
 {
 }
 
+static inline int of_dma_router_register(struct device_node *np,
+		void *(*of_dma_route_allocate)
+		(struct of_phandle_args *, struct of_dma *),
+		 struct dma_router *dma_router)
+{
+	return -ENODEV;
+}
+
+#define of_dma_router_free of_dma_controller_free
+
 static inline struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
 						     const char *name)
 {
-- 
2.3.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 2/7] Documentation: devicetree: dma: Binding documentation for TI DMA crossbar
  2015-03-11 13:23 ` Peter Ujfalusi
  (?)
@ 2015-03-11 13:23   ` Peter Ujfalusi
  -1 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

The DRA7x has more peripherals with DMA requests than the sDMA can handle:
205 vs 127. All DMA requests are routed through the DMA crossbar, which can
be configured to route selected incoming DMA requests to specific request
line of the DMA controller.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 .../devicetree/bindings/dma/ti-dma-crossbar.txt    | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt

diff --git a/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
new file mode 100644
index 000000000000..e5c2352081b6
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
@@ -0,0 +1,52 @@
+Texas Instruments DMA Crossbar (DMA request router)
+
+Required properties:
+- compatible:	"ti,dra7-dma-crossbar" for DRA7xx DMA crossbar
+- reg:		Memory map for accessing module
+- #dma-cells:	Should be set to <1>.
+		Clients should use the crossbar request number (input)
+- dma-requests:	Number of DMA requests the crossbar can receive
+- dma-device:	phandle pointing to the DMA controller
+
+The DMA controller node need to have the following poroperties:
+- dma-requests:	Number of DMA requests the controller can handle
+
+Optional properties:
+- ti,dma-safe-map: Safe routing value for unused request lines
+
+Example:
+
+/* DMA controller */
+sdma: dma-controller@4a056000 {
+	compatible = "ti,omap4430-sdma";
+	reg = <0x4a056000 0x1000>;
+	interrupts =	<GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+			<GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+			<GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+			<GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+	#dma-cells = <1>;
+	dma-channels = <32>;
+	dma-requests = <127>;
+};
+
+/* DMA crossbar */
+sdma_xbar: dma-router@4a002b78 {
+	compatible = "ti,dra7-dma-crossbar";
+	reg = <0x4a002b78 0xfc>;
+	#dma-cells = <1>;
+	dma-requests = <205>;
+	ti,dma-safe-map = <0>;
+	dma-device = <&sdma>;
+};
+
+/* DMA client */
+uart1: serial@4806a000 {
+	compatible = "ti,omap4-uart";
+	reg = <0x4806a000 0x100>;
+	interrupts-extended = <&gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+	ti,hwmods = "uart1";
+	clock-frequency = <48000000>;
+	status = "disabled";
+	dmas = <&sdma_xbar 49>, <&sdma_xbar 50>;
+	dma-names = "tx", "rx";
+};
-- 
2.3.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 2/7] Documentation: devicetree: dma: Binding documentation for TI DMA crossbar
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

The DRA7x has more peripherals with DMA requests than the sDMA can handle:
205 vs 127. All DMA requests are routed through the DMA crossbar, which can
be configured to route selected incoming DMA requests to specific request
line of the DMA controller.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 .../devicetree/bindings/dma/ti-dma-crossbar.txt    | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt

diff --git a/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
new file mode 100644
index 000000000000..e5c2352081b6
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
@@ -0,0 +1,52 @@
+Texas Instruments DMA Crossbar (DMA request router)
+
+Required properties:
+- compatible:	"ti,dra7-dma-crossbar" for DRA7xx DMA crossbar
+- reg:		Memory map for accessing module
+- #dma-cells:	Should be set to <1>.
+		Clients should use the crossbar request number (input)
+- dma-requests:	Number of DMA requests the crossbar can receive
+- dma-device:	phandle pointing to the DMA controller
+
+The DMA controller node need to have the following poroperties:
+- dma-requests:	Number of DMA requests the controller can handle
+
+Optional properties:
+- ti,dma-safe-map: Safe routing value for unused request lines
+
+Example:
+
+/* DMA controller */
+sdma: dma-controller@4a056000 {
+	compatible = "ti,omap4430-sdma";
+	reg = <0x4a056000 0x1000>;
+	interrupts =	<GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+			<GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+			<GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+			<GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+	#dma-cells = <1>;
+	dma-channels = <32>;
+	dma-requests = <127>;
+};
+
+/* DMA crossbar */
+sdma_xbar: dma-router@4a002b78 {
+	compatible = "ti,dra7-dma-crossbar";
+	reg = <0x4a002b78 0xfc>;
+	#dma-cells = <1>;
+	dma-requests = <205>;
+	ti,dma-safe-map = <0>;
+	dma-device = <&sdma>;
+};
+
+/* DMA client */
+uart1: serial@4806a000 {
+	compatible = "ti,omap4-uart";
+	reg = <0x4806a000 0x100>;
+	interrupts-extended = <&gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+	ti,hwmods = "uart1";
+	clock-frequency = <48000000>;
+	status = "disabled";
+	dmas = <&sdma_xbar 49>, <&sdma_xbar 50>;
+	dma-names = "tx", "rx";
+};
-- 
2.3.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 2/7] Documentation: devicetree: dma: Binding documentation for TI DMA crossbar
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: linux-arm-kernel

The DRA7x has more peripherals with DMA requests than the sDMA can handle:
205 vs 127. All DMA requests are routed through the DMA crossbar, which can
be configured to route selected incoming DMA requests to specific request
line of the DMA controller.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 .../devicetree/bindings/dma/ti-dma-crossbar.txt    | 52 ++++++++++++++++++++++
 1 file changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt

diff --git a/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
new file mode 100644
index 000000000000..e5c2352081b6
--- /dev/null
+++ b/Documentation/devicetree/bindings/dma/ti-dma-crossbar.txt
@@ -0,0 +1,52 @@
+Texas Instruments DMA Crossbar (DMA request router)
+
+Required properties:
+- compatible:	"ti,dra7-dma-crossbar" for DRA7xx DMA crossbar
+- reg:		Memory map for accessing module
+- #dma-cells:	Should be set to <1>.
+		Clients should use the crossbar request number (input)
+- dma-requests:	Number of DMA requests the crossbar can receive
+- dma-device:	phandle pointing to the DMA controller
+
+The DMA controller node need to have the following poroperties:
+- dma-requests:	Number of DMA requests the controller can handle
+
+Optional properties:
+- ti,dma-safe-map: Safe routing value for unused request lines
+
+Example:
+
+/* DMA controller */
+sdma: dma-controller at 4a056000 {
+	compatible = "ti,omap4430-sdma";
+	reg = <0x4a056000 0x1000>;
+	interrupts =	<GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>,
+			<GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>,
+			<GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>,
+			<GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>;
+	#dma-cells = <1>;
+	dma-channels = <32>;
+	dma-requests = <127>;
+};
+
+/* DMA crossbar */
+sdma_xbar: dma-router at 4a002b78 {
+	compatible = "ti,dra7-dma-crossbar";
+	reg = <0x4a002b78 0xfc>;
+	#dma-cells = <1>;
+	dma-requests = <205>;
+	ti,dma-safe-map = <0>;
+	dma-device = <&sdma>;
+};
+
+/* DMA client */
+uart1: serial at 4806a000 {
+	compatible = "ti,omap4-uart";
+	reg = <0x4806a000 0x100>;
+	interrupts-extended = <&gic GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>;
+	ti,hwmods = "uart1";
+	clock-frequency = <48000000>;
+	status = "disabled";
+	dmas = <&sdma_xbar 49>, <&sdma_xbar 50>;
+	dma-names = "tx", "rx";
+};
-- 
2.3.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
  2015-03-11 13:23 ` Peter Ujfalusi
  (?)
@ 2015-03-11 13:23   ` Peter Ujfalusi
  -1 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

The DRA7x has more peripherals with DMA requests than the sDMA can handle:
205 vs 127. All DMA requests are routed through the DMA crossbar, which can
be configured to route selected incoming DMA requests to specific sDMA
request.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/Kconfig           |   4 +
 drivers/dma/Makefile          |   1 +
 drivers/dma/ti-dma-crossbar.c | 190 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 195 insertions(+)
 create mode 100644 drivers/dma/ti-dma-crossbar.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 074ffad334a7..519657a37ca1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -247,6 +247,9 @@ config TI_EDMA
 	  Enable support for the TI EDMA controller. This DMA
 	  engine is found on TI DaVinci and AM33xx parts.
 
+config TI_DMA_CROSSBAR
+	bool
+
 config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
 	bool
 
@@ -332,6 +335,7 @@ config DMA_OMAP
 	depends on ARCH_OMAP
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
+	select TI_DMA_CROSSBAR if SOC_DRA7XX
 
 config DMA_BCM2835
 	tristate "BCM2835 DMA engine support"
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index bf4485800c60..6ec7af6a416c 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
 obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_DMA_OMAP) += omap-dma.o
+obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
 obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c
new file mode 100644
index 000000000000..591307bd4370
--- /dev/null
+++ b/drivers/dma/ti-dma-crossbar.c
@@ -0,0 +1,190 @@
+/*
+ *  Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
+ *  Author: Peter Ujfalusi <peter.ujfalusi@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.
+ *
+ */
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/idr.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+
+#define TI_XBAR_OUTPUTS	127
+#define TI_XBAR_INPUTS	256
+
+static DEFINE_IDR(map_idr);
+
+struct ti_dma_xbar_data {
+	struct dma_router dmarouter;
+	struct regmap *regmap;
+
+	uint safe_val; /* Value to rest the crossbar lines */
+	uint xbar_requests; /* number of DMA requests connected to XBAR */
+	uint dma_requests; /* number of DMA requests forwarded to DMA */
+
+	void __iomem *iomem;
+};
+
+struct ti_dma_xbar_map {
+	int xbar_in;
+	int xbar_out;
+};
+
+static void ti_dma_xbar_free(struct device *dev, void *route_data)
+{
+	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
+	struct ti_dma_xbar_map *map = route_data;
+
+	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
+		map->xbar_in, map->xbar_out);
+
+	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
+	idr_remove(&map_idr, map->xbar_out);
+	kfree(map);
+}
+
+static void *ti_dma_xbar_route_allocate(struct of_phandle_args *dma_spec,
+					struct of_dma *ofdma)
+{
+	struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
+	struct ti_dma_xbar_data *xbar = platform_get_drvdata(pdev);
+	struct ti_dma_xbar_map *map;
+
+	if (dma_spec->args[0] >= xbar->xbar_requests) {
+		dev_err(&pdev->dev, "Invalid XBAR request number: %d\n",
+			dma_spec->args[0]);
+		return NULL;
+	}
+
+	map = kzalloc(sizeof(*map), GFP_KERNEL);
+	if (!map)
+		return NULL;
+
+	map->xbar_out = idr_alloc(&map_idr, NULL, 0, xbar->dma_requests,
+				  GFP_KERNEL);
+	map->xbar_in = dma_spec->args[0];
+
+	/* The DMA request is 1 based in sDMA */
+	dma_spec->args[0] = map->xbar_out + 1;
+
+	dev_dbg(&pdev->dev, "Mapping XBAR%d to DMA%d\n",
+		map->xbar_in, map->xbar_out);
+
+	regmap_write(xbar->regmap, map->xbar_out * 2, map->xbar_in);
+
+	return map;
+}
+
+static const struct regmap_config ti_dma_xbar_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 2,
+	.val_bits = 16,
+	.max_register = 0xfc,
+	.cache_type = REGCACHE_FLAT,
+};
+
+static int ti_dma_xbar_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *dma_node;
+	struct ti_dma_xbar_data *xbar;
+	struct resource *res;
+	void __iomem *iomem;
+	int i, ret;
+
+	if (!node)
+		return -ENODEV;
+
+	dma_node = of_parse_phandle(node, "dma-device", 0);
+	if (!dma_node) {
+		dev_err(&pdev->dev, "Can't get target DMA node\n");
+		return -ENODEV;
+	}
+
+	xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL);
+	if (!xbar)
+		return -ENOMEM;
+
+	if (of_property_read_u32(dma_node, "dma-requests",
+				 &xbar->dma_requests)) {
+		dev_info(&pdev->dev,
+			 "Missing XBAR output information, using %u.\n",
+			 TI_XBAR_OUTPUTS);
+		xbar->dma_requests = TI_XBAR_OUTPUTS;
+	}
+	of_node_put(dma_node);
+
+	if (of_property_read_u32(node, "dma-requests", &xbar->xbar_requests)) {
+		dev_info(&pdev->dev,
+			 "Missing XBAR input information, using %u.\n",
+			 TI_XBAR_INPUTS);
+		xbar->xbar_requests = TI_XBAR_INPUTS;
+	}
+
+	if (of_property_read_u32(node, "ti,dma-safe-map", &xbar->safe_val))
+		xbar->safe_val = 0;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
+				     dev_name(&pdev->dev)))
+		return -ENODEV;
+
+	iomem = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	if (!iomem)
+		return -ENOMEM;
+
+	xbar->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
+					    &ti_dma_xbar_regmap_config);
+	if (IS_ERR(xbar->regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		return PTR_ERR(xbar->regmap);
+	}
+	xbar->iomem = iomem;
+
+	xbar->dmarouter.dev = &pdev->dev;
+	xbar->dmarouter.route_free = ti_dma_xbar_free;
+
+	platform_set_drvdata(pdev, xbar);
+
+	ret = of_dma_router_register(node, ti_dma_xbar_route_allocate,
+				     &xbar->dmarouter);
+	if (ret)
+		return -ENODEV;
+
+	/* Reset the crossbar */
+	for (i = 0; i < xbar->dma_requests; i++)
+		regmap_write(xbar->regmap, i * 2, xbar->safe_val);
+
+	return 0;
+}
+
+static const struct of_device_id ti_dma_xbar_match[] = {
+	{ .compatible = "ti,dra7-dma-crossbar" },
+	{},
+};
+
+static struct platform_driver ti_dma_xbar_driver = {
+	.driver = {
+		.name = "ti-dma-crossbar",
+		.of_match_table = of_match_ptr(ti_dma_xbar_match),
+	},
+	.probe	= ti_dma_xbar_probe,
+};
+
+int omap_dmaxbar_init(void)
+{
+	return platform_driver_register(&ti_dma_xbar_driver);
+}
+arch_initcall(omap_dmaxbar_init);
-- 
2.3.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

The DRA7x has more peripherals with DMA requests than the sDMA can handle:
205 vs 127. All DMA requests are routed through the DMA crossbar, which can
be configured to route selected incoming DMA requests to specific sDMA
request.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/Kconfig           |   4 +
 drivers/dma/Makefile          |   1 +
 drivers/dma/ti-dma-crossbar.c | 190 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 195 insertions(+)
 create mode 100644 drivers/dma/ti-dma-crossbar.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 074ffad334a7..519657a37ca1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -247,6 +247,9 @@ config TI_EDMA
 	  Enable support for the TI EDMA controller. This DMA
 	  engine is found on TI DaVinci and AM33xx parts.
 
+config TI_DMA_CROSSBAR
+	bool
+
 config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
 	bool
 
@@ -332,6 +335,7 @@ config DMA_OMAP
 	depends on ARCH_OMAP
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
+	select TI_DMA_CROSSBAR if SOC_DRA7XX
 
 config DMA_BCM2835
 	tristate "BCM2835 DMA engine support"
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index bf4485800c60..6ec7af6a416c 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
 obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_DMA_OMAP) += omap-dma.o
+obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
 obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c
new file mode 100644
index 000000000000..591307bd4370
--- /dev/null
+++ b/drivers/dma/ti-dma-crossbar.c
@@ -0,0 +1,190 @@
+/*
+ *  Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
+ *  Author: Peter Ujfalusi <peter.ujfalusi@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.
+ *
+ */
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/idr.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+
+#define TI_XBAR_OUTPUTS	127
+#define TI_XBAR_INPUTS	256
+
+static DEFINE_IDR(map_idr);
+
+struct ti_dma_xbar_data {
+	struct dma_router dmarouter;
+	struct regmap *regmap;
+
+	uint safe_val; /* Value to rest the crossbar lines */
+	uint xbar_requests; /* number of DMA requests connected to XBAR */
+	uint dma_requests; /* number of DMA requests forwarded to DMA */
+
+	void __iomem *iomem;
+};
+
+struct ti_dma_xbar_map {
+	int xbar_in;
+	int xbar_out;
+};
+
+static void ti_dma_xbar_free(struct device *dev, void *route_data)
+{
+	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
+	struct ti_dma_xbar_map *map = route_data;
+
+	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
+		map->xbar_in, map->xbar_out);
+
+	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
+	idr_remove(&map_idr, map->xbar_out);
+	kfree(map);
+}
+
+static void *ti_dma_xbar_route_allocate(struct of_phandle_args *dma_spec,
+					struct of_dma *ofdma)
+{
+	struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
+	struct ti_dma_xbar_data *xbar = platform_get_drvdata(pdev);
+	struct ti_dma_xbar_map *map;
+
+	if (dma_spec->args[0] >= xbar->xbar_requests) {
+		dev_err(&pdev->dev, "Invalid XBAR request number: %d\n",
+			dma_spec->args[0]);
+		return NULL;
+	}
+
+	map = kzalloc(sizeof(*map), GFP_KERNEL);
+	if (!map)
+		return NULL;
+
+	map->xbar_out = idr_alloc(&map_idr, NULL, 0, xbar->dma_requests,
+				  GFP_KERNEL);
+	map->xbar_in = dma_spec->args[0];
+
+	/* The DMA request is 1 based in sDMA */
+	dma_spec->args[0] = map->xbar_out + 1;
+
+	dev_dbg(&pdev->dev, "Mapping XBAR%d to DMA%d\n",
+		map->xbar_in, map->xbar_out);
+
+	regmap_write(xbar->regmap, map->xbar_out * 2, map->xbar_in);
+
+	return map;
+}
+
+static const struct regmap_config ti_dma_xbar_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 2,
+	.val_bits = 16,
+	.max_register = 0xfc,
+	.cache_type = REGCACHE_FLAT,
+};
+
+static int ti_dma_xbar_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *dma_node;
+	struct ti_dma_xbar_data *xbar;
+	struct resource *res;
+	void __iomem *iomem;
+	int i, ret;
+
+	if (!node)
+		return -ENODEV;
+
+	dma_node = of_parse_phandle(node, "dma-device", 0);
+	if (!dma_node) {
+		dev_err(&pdev->dev, "Can't get target DMA node\n");
+		return -ENODEV;
+	}
+
+	xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL);
+	if (!xbar)
+		return -ENOMEM;
+
+	if (of_property_read_u32(dma_node, "dma-requests",
+				 &xbar->dma_requests)) {
+		dev_info(&pdev->dev,
+			 "Missing XBAR output information, using %u.\n",
+			 TI_XBAR_OUTPUTS);
+		xbar->dma_requests = TI_XBAR_OUTPUTS;
+	}
+	of_node_put(dma_node);
+
+	if (of_property_read_u32(node, "dma-requests", &xbar->xbar_requests)) {
+		dev_info(&pdev->dev,
+			 "Missing XBAR input information, using %u.\n",
+			 TI_XBAR_INPUTS);
+		xbar->xbar_requests = TI_XBAR_INPUTS;
+	}
+
+	if (of_property_read_u32(node, "ti,dma-safe-map", &xbar->safe_val))
+		xbar->safe_val = 0;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
+				     dev_name(&pdev->dev)))
+		return -ENODEV;
+
+	iomem = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	if (!iomem)
+		return -ENOMEM;
+
+	xbar->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
+					    &ti_dma_xbar_regmap_config);
+	if (IS_ERR(xbar->regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		return PTR_ERR(xbar->regmap);
+	}
+	xbar->iomem = iomem;
+
+	xbar->dmarouter.dev = &pdev->dev;
+	xbar->dmarouter.route_free = ti_dma_xbar_free;
+
+	platform_set_drvdata(pdev, xbar);
+
+	ret = of_dma_router_register(node, ti_dma_xbar_route_allocate,
+				     &xbar->dmarouter);
+	if (ret)
+		return -ENODEV;
+
+	/* Reset the crossbar */
+	for (i = 0; i < xbar->dma_requests; i++)
+		regmap_write(xbar->regmap, i * 2, xbar->safe_val);
+
+	return 0;
+}
+
+static const struct of_device_id ti_dma_xbar_match[] = {
+	{ .compatible = "ti,dra7-dma-crossbar" },
+	{},
+};
+
+static struct platform_driver ti_dma_xbar_driver = {
+	.driver = {
+		.name = "ti-dma-crossbar",
+		.of_match_table = of_match_ptr(ti_dma_xbar_match),
+	},
+	.probe	= ti_dma_xbar_probe,
+};
+
+int omap_dmaxbar_init(void)
+{
+	return platform_driver_register(&ti_dma_xbar_driver);
+}
+arch_initcall(omap_dmaxbar_init);
-- 
2.3.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: linux-arm-kernel

The DRA7x has more peripherals with DMA requests than the sDMA can handle:
205 vs 127. All DMA requests are routed through the DMA crossbar, which can
be configured to route selected incoming DMA requests to specific sDMA
request.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/Kconfig           |   4 +
 drivers/dma/Makefile          |   1 +
 drivers/dma/ti-dma-crossbar.c | 190 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 195 insertions(+)
 create mode 100644 drivers/dma/ti-dma-crossbar.c

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 074ffad334a7..519657a37ca1 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -247,6 +247,9 @@ config TI_EDMA
 	  Enable support for the TI EDMA controller. This DMA
 	  engine is found on TI DaVinci and AM33xx parts.
 
+config TI_DMA_CROSSBAR
+	bool
+
 config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
 	bool
 
@@ -332,6 +335,7 @@ config DMA_OMAP
 	depends on ARCH_OMAP
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
+	select TI_DMA_CROSSBAR if SOC_DRA7XX
 
 config DMA_BCM2835
 	tristate "BCM2835 DMA engine support"
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index bf4485800c60..6ec7af6a416c 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -39,6 +39,7 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
 obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
 obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
 obj-$(CONFIG_DMA_OMAP) += omap-dma.o
+obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
 obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
 obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
 obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c
new file mode 100644
index 000000000000..591307bd4370
--- /dev/null
+++ b/drivers/dma/ti-dma-crossbar.c
@@ -0,0 +1,190 @@
+/*
+ *  Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
+ *  Author: Peter Ujfalusi <peter.ujfalusi@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.
+ *
+ */
+#include <linux/slab.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/list.h>
+#include <linux/io.h>
+#include <linux/regmap.h>
+#include <linux/idr.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_dma.h>
+
+#define TI_XBAR_OUTPUTS	127
+#define TI_XBAR_INPUTS	256
+
+static DEFINE_IDR(map_idr);
+
+struct ti_dma_xbar_data {
+	struct dma_router dmarouter;
+	struct regmap *regmap;
+
+	uint safe_val; /* Value to rest the crossbar lines */
+	uint xbar_requests; /* number of DMA requests connected to XBAR */
+	uint dma_requests; /* number of DMA requests forwarded to DMA */
+
+	void __iomem *iomem;
+};
+
+struct ti_dma_xbar_map {
+	int xbar_in;
+	int xbar_out;
+};
+
+static void ti_dma_xbar_free(struct device *dev, void *route_data)
+{
+	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
+	struct ti_dma_xbar_map *map = route_data;
+
+	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
+		map->xbar_in, map->xbar_out);
+
+	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
+	idr_remove(&map_idr, map->xbar_out);
+	kfree(map);
+}
+
+static void *ti_dma_xbar_route_allocate(struct of_phandle_args *dma_spec,
+					struct of_dma *ofdma)
+{
+	struct platform_device *pdev = of_find_device_by_node(ofdma->of_node);
+	struct ti_dma_xbar_data *xbar = platform_get_drvdata(pdev);
+	struct ti_dma_xbar_map *map;
+
+	if (dma_spec->args[0] >= xbar->xbar_requests) {
+		dev_err(&pdev->dev, "Invalid XBAR request number: %d\n",
+			dma_spec->args[0]);
+		return NULL;
+	}
+
+	map = kzalloc(sizeof(*map), GFP_KERNEL);
+	if (!map)
+		return NULL;
+
+	map->xbar_out = idr_alloc(&map_idr, NULL, 0, xbar->dma_requests,
+				  GFP_KERNEL);
+	map->xbar_in = dma_spec->args[0];
+
+	/* The DMA request is 1 based in sDMA */
+	dma_spec->args[0] = map->xbar_out + 1;
+
+	dev_dbg(&pdev->dev, "Mapping XBAR%d to DMA%d\n",
+		map->xbar_in, map->xbar_out);
+
+	regmap_write(xbar->regmap, map->xbar_out * 2, map->xbar_in);
+
+	return map;
+}
+
+static const struct regmap_config ti_dma_xbar_regmap_config = {
+	.reg_bits = 32,
+	.reg_stride = 2,
+	.val_bits = 16,
+	.max_register = 0xfc,
+	.cache_type = REGCACHE_FLAT,
+};
+
+static int ti_dma_xbar_probe(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct device_node *dma_node;
+	struct ti_dma_xbar_data *xbar;
+	struct resource *res;
+	void __iomem *iomem;
+	int i, ret;
+
+	if (!node)
+		return -ENODEV;
+
+	dma_node = of_parse_phandle(node, "dma-device", 0);
+	if (!dma_node) {
+		dev_err(&pdev->dev, "Can't get target DMA node\n");
+		return -ENODEV;
+	}
+
+	xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL);
+	if (!xbar)
+		return -ENOMEM;
+
+	if (of_property_read_u32(dma_node, "dma-requests",
+				 &xbar->dma_requests)) {
+		dev_info(&pdev->dev,
+			 "Missing XBAR output information, using %u.\n",
+			 TI_XBAR_OUTPUTS);
+		xbar->dma_requests = TI_XBAR_OUTPUTS;
+	}
+	of_node_put(dma_node);
+
+	if (of_property_read_u32(node, "dma-requests", &xbar->xbar_requests)) {
+		dev_info(&pdev->dev,
+			 "Missing XBAR input information, using %u.\n",
+			 TI_XBAR_INPUTS);
+		xbar->xbar_requests = TI_XBAR_INPUTS;
+	}
+
+	if (of_property_read_u32(node, "ti,dma-safe-map", &xbar->safe_val))
+		xbar->safe_val = 0;
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res)
+		return -ENODEV;
+
+	if (!devm_request_mem_region(&pdev->dev, res->start, resource_size(res),
+				     dev_name(&pdev->dev)))
+		return -ENODEV;
+
+	iomem = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	if (!iomem)
+		return -ENOMEM;
+
+	xbar->regmap = devm_regmap_init_mmio(&pdev->dev, iomem,
+					    &ti_dma_xbar_regmap_config);
+	if (IS_ERR(xbar->regmap)) {
+		dev_err(&pdev->dev, "regmap init failed\n");
+		return PTR_ERR(xbar->regmap);
+	}
+	xbar->iomem = iomem;
+
+	xbar->dmarouter.dev = &pdev->dev;
+	xbar->dmarouter.route_free = ti_dma_xbar_free;
+
+	platform_set_drvdata(pdev, xbar);
+
+	ret = of_dma_router_register(node, ti_dma_xbar_route_allocate,
+				     &xbar->dmarouter);
+	if (ret)
+		return -ENODEV;
+
+	/* Reset the crossbar */
+	for (i = 0; i < xbar->dma_requests; i++)
+		regmap_write(xbar->regmap, i * 2, xbar->safe_val);
+
+	return 0;
+}
+
+static const struct of_device_id ti_dma_xbar_match[] = {
+	{ .compatible = "ti,dra7-dma-crossbar" },
+	{},
+};
+
+static struct platform_driver ti_dma_xbar_driver = {
+	.driver = {
+		.name = "ti-dma-crossbar",
+		.of_match_table = of_match_ptr(ti_dma_xbar_match),
+	},
+	.probe	= ti_dma_xbar_probe,
+};
+
+int omap_dmaxbar_init(void)
+{
+	return platform_driver_register(&ti_dma_xbar_driver);
+}
+arch_initcall(omap_dmaxbar_init);
-- 
2.3.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 4/7] dmaengine: omap-dma: Use defines for dma channels and request count
  2015-03-11 13:23 ` Peter Ujfalusi
  (?)
@ 2015-03-11 13:23   ` Peter Ujfalusi
  -1 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

Instead of magic numbers in the code, use define for number of logical DMA
channels and DMA requests.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/omap-dma.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 7dd6dd121681..56c33e93dd24 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -22,6 +22,9 @@
 
 #include "virt-dma.h"
 
+#define OMAP_SDMA_REQUESTS	127
+#define OMAP_SDMA_CHANNELS	32
+
 struct omap_dmadev {
 	struct dma_device ddev;
 	spinlock_t lock;
@@ -33,7 +36,7 @@ struct omap_dmadev {
 	bool legacy;
 	spinlock_t irq_lock;
 	uint32_t irq_enable_mask;
-	struct omap_chan *lch_map[32];
+	struct omap_chan *lch_map[OMAP_SDMA_CHANNELS];
 };
 
 struct omap_chan {
@@ -1115,7 +1118,7 @@ static int omap_dma_probe(struct platform_device *pdev)
 
 	tasklet_init(&od->task, omap_dma_sched, (unsigned long)od);
 
-	for (i = 0; i < 127; i++) {
+	for (i = 0; i < OMAP_SDMA_REQUESTS; i++) {
 		rc = omap_dma_chan_init(od, i);
 		if (rc) {
 			omap_dma_free(od);
-- 
2.3.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 4/7] dmaengine: omap-dma: Use defines for dma channels and request count
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

Instead of magic numbers in the code, use define for number of logical DMA
channels and DMA requests.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/omap-dma.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 7dd6dd121681..56c33e93dd24 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -22,6 +22,9 @@
 
 #include "virt-dma.h"
 
+#define OMAP_SDMA_REQUESTS	127
+#define OMAP_SDMA_CHANNELS	32
+
 struct omap_dmadev {
 	struct dma_device ddev;
 	spinlock_t lock;
@@ -33,7 +36,7 @@ struct omap_dmadev {
 	bool legacy;
 	spinlock_t irq_lock;
 	uint32_t irq_enable_mask;
-	struct omap_chan *lch_map[32];
+	struct omap_chan *lch_map[OMAP_SDMA_CHANNELS];
 };
 
 struct omap_chan {
@@ -1115,7 +1118,7 @@ static int omap_dma_probe(struct platform_device *pdev)
 
 	tasklet_init(&od->task, omap_dma_sched, (unsigned long)od);
 
-	for (i = 0; i < 127; i++) {
+	for (i = 0; i < OMAP_SDMA_REQUESTS; i++) {
 		rc = omap_dma_chan_init(od, i);
 		if (rc) {
 			omap_dma_free(od);
-- 
2.3.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 4/7] dmaengine: omap-dma: Use defines for dma channels and request count
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: linux-arm-kernel

Instead of magic numbers in the code, use define for number of logical DMA
channels and DMA requests.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/omap-dma.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 7dd6dd121681..56c33e93dd24 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -22,6 +22,9 @@
 
 #include "virt-dma.h"
 
+#define OMAP_SDMA_REQUESTS	127
+#define OMAP_SDMA_CHANNELS	32
+
 struct omap_dmadev {
 	struct dma_device ddev;
 	spinlock_t lock;
@@ -33,7 +36,7 @@ struct omap_dmadev {
 	bool legacy;
 	spinlock_t irq_lock;
 	uint32_t irq_enable_mask;
-	struct omap_chan *lch_map[32];
+	struct omap_chan *lch_map[OMAP_SDMA_CHANNELS];
 };
 
 struct omap_chan {
@@ -1115,7 +1118,7 @@ static int omap_dma_probe(struct platform_device *pdev)
 
 	tasklet_init(&od->task, omap_dma_sched, (unsigned long)od);
 
-	for (i = 0; i < 127; i++) {
+	for (i = 0; i < OMAP_SDMA_REQUESTS; i++) {
 		rc = omap_dma_chan_init(od, i);
 		if (rc) {
 			omap_dma_free(od);
-- 
2.3.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 5/7] dmaengine: omap-dma: Take DMA request number from DT if it is available
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

Use the dma-requests property from DT to get the number of DMA requests.
In case of legacy boot or failure to find the property, use the default
127 as number of requests.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/omap-dma.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 56c33e93dd24..2b30acaa721f 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -34,6 +34,7 @@ struct omap_dmadev {
 	const struct omap_dma_reg *reg_map;
 	struct omap_system_dma_plat_info *plat;
 	bool legacy;
+	unsigned dma_requests;
 	spinlock_t irq_lock;
 	uint32_t irq_enable_mask;
 	struct omap_chan *lch_map[OMAP_SDMA_CHANNELS];
@@ -1118,7 +1119,16 @@ static int omap_dma_probe(struct platform_device *pdev)
 
 	tasklet_init(&od->task, omap_dma_sched, (unsigned long)od);
 
-	for (i = 0; i < OMAP_SDMA_REQUESTS; i++) {
+	if (!pdev->dev.of_node || of_property_read_u32(pdev->dev.of_node,
+						       "dma-requests",
+						       &od->dma_requests)) {
+		dev_info(&pdev->dev,
+			 "Missing dma-requests property, using %u.\n",
+			 OMAP_SDMA_REQUESTS);
+		od->dma_requests = OMAP_SDMA_REQUESTS;
+	}
+
+	for (i = 0; i < od->dma_requests; i++) {
 		rc = omap_dma_chan_init(od, i);
 		if (rc) {
 			omap_dma_free(od);
-- 
2.3.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 5/7] dmaengine: omap-dma: Take DMA request number from DT if it is available
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul-ral2JQCrhuEAvxtiuMwx3w, tony-4v6yS6AI5VpBDgjK7y7TUQ,
	linux-lFZ/pmaqli7XmaaqVzeoHQ
  Cc: grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, nm-l0cyMroinI0

Use the dma-requests property from DT to get the number of DMA requests.
In case of legacy boot or failure to find the property, use the default
127 as number of requests.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi-l0cyMroinI0@public.gmane.org>
---
 drivers/dma/omap-dma.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 56c33e93dd24..2b30acaa721f 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -34,6 +34,7 @@ struct omap_dmadev {
 	const struct omap_dma_reg *reg_map;
 	struct omap_system_dma_plat_info *plat;
 	bool legacy;
+	unsigned dma_requests;
 	spinlock_t irq_lock;
 	uint32_t irq_enable_mask;
 	struct omap_chan *lch_map[OMAP_SDMA_CHANNELS];
@@ -1118,7 +1119,16 @@ static int omap_dma_probe(struct platform_device *pdev)
 
 	tasklet_init(&od->task, omap_dma_sched, (unsigned long)od);
 
-	for (i = 0; i < OMAP_SDMA_REQUESTS; i++) {
+	if (!pdev->dev.of_node || of_property_read_u32(pdev->dev.of_node,
+						       "dma-requests",
+						       &od->dma_requests)) {
+		dev_info(&pdev->dev,
+			 "Missing dma-requests property, using %u.\n",
+			 OMAP_SDMA_REQUESTS);
+		od->dma_requests = OMAP_SDMA_REQUESTS;
+	}
+
+	for (i = 0; i < od->dma_requests; i++) {
 		rc = omap_dma_chan_init(od, i);
 		if (rc) {
 			omap_dma_free(od);
-- 
2.3.0

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 5/7] dmaengine: omap-dma: Take DMA request number from DT if it is available
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: linux-arm-kernel

Use the dma-requests property from DT to get the number of DMA requests.
In case of legacy boot or failure to find the property, use the default
127 as number of requests.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/omap-dma.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 56c33e93dd24..2b30acaa721f 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -34,6 +34,7 @@ struct omap_dmadev {
 	const struct omap_dma_reg *reg_map;
 	struct omap_system_dma_plat_info *plat;
 	bool legacy;
+	unsigned dma_requests;
 	spinlock_t irq_lock;
 	uint32_t irq_enable_mask;
 	struct omap_chan *lch_map[OMAP_SDMA_CHANNELS];
@@ -1118,7 +1119,16 @@ static int omap_dma_probe(struct platform_device *pdev)
 
 	tasklet_init(&od->task, omap_dma_sched, (unsigned long)od);
 
-	for (i = 0; i < OMAP_SDMA_REQUESTS; i++) {
+	if (!pdev->dev.of_node || of_property_read_u32(pdev->dev.of_node,
+						       "dma-requests",
+						       &od->dma_requests)) {
+		dev_info(&pdev->dev,
+			 "Missing dma-requests property, using %u.\n",
+			 OMAP_SDMA_REQUESTS);
+		od->dma_requests = OMAP_SDMA_REQUESTS;
+	}
+
+	for (i = 0; i < od->dma_requests; i++) {
 		rc = omap_dma_chan_init(od, i);
 		if (rc) {
 			omap_dma_free(od);
-- 
2.3.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 6/7] dmaengine: omap-dma: Remove mapping between virtual channels and requests
  2015-03-11 13:23 ` Peter Ujfalusi
  (?)
@ 2015-03-11 13:23   ` Peter Ujfalusi
  -1 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

Do not direct map the virtual channels to sDMA request number. When the
sDMA is behind of a crossbar this direct mapping can cause situations when
certain channel can not be requested since the crossbar request number
will no longer match with the sDMA request line.
The direct mapping for virtual channels with HW request lines will make it
harder to implement MEM_TO_MEM mode for the driver.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/omap-dma.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 2b30acaa721f..d83e7bd8dc0a 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -593,6 +593,7 @@ static void omap_dma_free_chan_resources(struct dma_chan *chan)
 	omap_free_dma(c->dma_ch);
 
 	dev_dbg(od->ddev.dev, "freeing channel for %u\n", c->dma_sig);
+	c->dma_sig = 0;
 }
 
 static size_t omap_dma_sg_size(struct omap_sg *sg)
@@ -1049,7 +1050,6 @@ static int omap_dma_chan_init(struct omap_dmadev *od, int dma_sig)
 		return -ENOMEM;
 
 	c->reg_map = od->reg_map;
-	c->dma_sig = dma_sig;
 	c->vc.desc_free = omap_dma_desc_free;
 	vchan_init(&c->vc, &od->ddev);
 	INIT_LIST_HEAD(&c->node);
@@ -1220,10 +1220,14 @@ static struct platform_driver omap_dma_driver = {
 bool omap_dma_filter_fn(struct dma_chan *chan, void *param)
 {
 	if (chan->device->dev->driver == &omap_dma_driver.driver) {
+		struct omap_dmadev *od = to_omap_dma_dev(chan->device);
 		struct omap_chan *c = to_omap_dma_chan(chan);
 		unsigned req = *(unsigned *)param;
 
-		return req == c->dma_sig;
+		if (req <= od->dma_requests) {
+			c->dma_sig = req;
+			return true;
+		}
 	}
 	return false;
 }
-- 
2.3.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 6/7] dmaengine: omap-dma: Remove mapping between virtual channels and requests
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

Do not direct map the virtual channels to sDMA request number. When the
sDMA is behind of a crossbar this direct mapping can cause situations when
certain channel can not be requested since the crossbar request number
will no longer match with the sDMA request line.
The direct mapping for virtual channels with HW request lines will make it
harder to implement MEM_TO_MEM mode for the driver.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/omap-dma.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 2b30acaa721f..d83e7bd8dc0a 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -593,6 +593,7 @@ static void omap_dma_free_chan_resources(struct dma_chan *chan)
 	omap_free_dma(c->dma_ch);
 
 	dev_dbg(od->ddev.dev, "freeing channel for %u\n", c->dma_sig);
+	c->dma_sig = 0;
 }
 
 static size_t omap_dma_sg_size(struct omap_sg *sg)
@@ -1049,7 +1050,6 @@ static int omap_dma_chan_init(struct omap_dmadev *od, int dma_sig)
 		return -ENOMEM;
 
 	c->reg_map = od->reg_map;
-	c->dma_sig = dma_sig;
 	c->vc.desc_free = omap_dma_desc_free;
 	vchan_init(&c->vc, &od->ddev);
 	INIT_LIST_HEAD(&c->node);
@@ -1220,10 +1220,14 @@ static struct platform_driver omap_dma_driver = {
 bool omap_dma_filter_fn(struct dma_chan *chan, void *param)
 {
 	if (chan->device->dev->driver == &omap_dma_driver.driver) {
+		struct omap_dmadev *od = to_omap_dma_dev(chan->device);
 		struct omap_chan *c = to_omap_dma_chan(chan);
 		unsigned req = *(unsigned *)param;
 
-		return req == c->dma_sig;
+		if (req <= od->dma_requests) {
+			c->dma_sig = req;
+			return true;
+		}
 	}
 	return false;
 }
-- 
2.3.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 6/7] dmaengine: omap-dma: Remove mapping between virtual channels and requests
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: linux-arm-kernel

Do not direct map the virtual channels to sDMA request number. When the
sDMA is behind of a crossbar this direct mapping can cause situations when
certain channel can not be requested since the crossbar request number
will no longer match with the sDMA request line.
The direct mapping for virtual channels with HW request lines will make it
harder to implement MEM_TO_MEM mode for the driver.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/omap-dma.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 2b30acaa721f..d83e7bd8dc0a 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -593,6 +593,7 @@ static void omap_dma_free_chan_resources(struct dma_chan *chan)
 	omap_free_dma(c->dma_ch);
 
 	dev_dbg(od->ddev.dev, "freeing channel for %u\n", c->dma_sig);
+	c->dma_sig = 0;
 }
 
 static size_t omap_dma_sg_size(struct omap_sg *sg)
@@ -1049,7 +1050,6 @@ static int omap_dma_chan_init(struct omap_dmadev *od, int dma_sig)
 		return -ENOMEM;
 
 	c->reg_map = od->reg_map;
-	c->dma_sig = dma_sig;
 	c->vc.desc_free = omap_dma_desc_free;
 	vchan_init(&c->vc, &od->ddev);
 	INIT_LIST_HEAD(&c->node);
@@ -1220,10 +1220,14 @@ static struct platform_driver omap_dma_driver = {
 bool omap_dma_filter_fn(struct dma_chan *chan, void *param)
 {
 	if (chan->device->dev->driver == &omap_dma_driver.driver) {
+		struct omap_dmadev *od = to_omap_dma_dev(chan->device);
 		struct omap_chan *c = to_omap_dma_chan(chan);
 		unsigned req = *(unsigned *)param;
 
-		return req == c->dma_sig;
+		if (req <= od->dma_requests) {
+			c->dma_sig = req;
+			return true;
+		}
 	}
 	return false;
 }
-- 
2.3.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 7/7] ARM: DTS: dra7x: Integrate sDMA crossbar
  2015-03-11 13:23 ` Peter Ujfalusi
  (?)
@ 2015-03-11 13:23   ` Peter Ujfalusi
  -1 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

The sDMA requests are routed through the DMA crossbar and without the
crossbar only peripherals using DMA request 0-127 can be used.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 arch/arm/boot/dts/dra7.dtsi | 57 ++++++++++++++++++++++++++-------------------
 1 file changed, 33 insertions(+), 24 deletions(-)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 127608d79033..b6aca837e291 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -253,6 +253,15 @@
 			dma-requests = <127>;
 		};
 
+		sdma_xbar: dma-router@4a002b78 {
+			compatible = "ti,dra7-dma-crossbar";
+			reg = <0x4a002b78 0xfc>;
+			#dma-cells = <1>;
+			dma-requests = <205>;
+			ti,dma-safe-map = <0>;
+			dma-device = <&sdma>;
+		};
+
 		gpio1: gpio@4ae10000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x4ae10000 0x200>;
@@ -348,7 +357,7 @@
 			ti,hwmods = "uart1";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 49>, <&sdma 50>;
+			dmas = <&sdma_xbar 49>, <&sdma_xbar 50>;
 			dma-names = "tx", "rx";
 		};
 
@@ -359,7 +368,7 @@
 			ti,hwmods = "uart2";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 51>, <&sdma 52>;
+			dmas = <&sdma_xbar 51>, <&sdma_xbar 52>;
 			dma-names = "tx", "rx";
 		};
 
@@ -370,7 +379,7 @@
 			ti,hwmods = "uart3";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 53>, <&sdma 54>;
+			dmas = <&sdma_xbar 53>, <&sdma_xbar 54>;
 			dma-names = "tx", "rx";
 		};
 
@@ -381,7 +390,7 @@
 			ti,hwmods = "uart4";
 			clock-frequency = <48000000>;
                         status = "disabled";
-			dmas = <&sdma 55>, <&sdma 56>;
+			dmas = <&sdma_xbar 55>, <&sdma_xbar 56>;
 			dma-names = "tx", "rx";
 		};
 
@@ -392,7 +401,7 @@
 			ti,hwmods = "uart5";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 63>, <&sdma 64>;
+			dmas = <&sdma_xbar 63>, <&sdma_xbar 64>;
 			dma-names = "tx", "rx";
 		};
 
@@ -403,7 +412,7 @@
 			ti,hwmods = "uart6";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 79>, <&sdma 80>;
+			dmas = <&sdma_xbar 79>, <&sdma_xbar 80>;
 			dma-names = "tx", "rx";
 		};
 
@@ -819,7 +828,7 @@
 			ti,hwmods = "mmc1";
 			ti,dual-volt;
 			ti,needs-special-reset;
-			dmas = <&sdma 61>, <&sdma 62>;
+			dmas = <&sdma_xbar 61>, <&sdma_xbar 62>;
 			dma-names = "tx", "rx";
 			status = "disabled";
 			pbias-supply = <&pbias_mmc_reg>;
@@ -831,7 +840,7 @@
 			interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc2";
 			ti,needs-special-reset;
-			dmas = <&sdma 47>, <&sdma 48>;
+			dmas = <&sdma_xbar 47>, <&sdma_xbar 48>;
 			dma-names = "tx", "rx";
 			status = "disabled";
 		};
@@ -842,7 +851,7 @@
 			interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc3";
 			ti,needs-special-reset;
-			dmas = <&sdma 77>, <&sdma 78>;
+			dmas = <&sdma_xbar 77>, <&sdma_xbar 78>;
 			dma-names = "tx", "rx";
 			status = "disabled";
 		};
@@ -853,7 +862,7 @@
 			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc4";
 			ti,needs-special-reset;
-			dmas = <&sdma 57>, <&sdma 58>;
+			dmas = <&sdma_xbar 57>, <&sdma_xbar 58>;
 			dma-names = "tx", "rx";
 			status = "disabled";
 		};
@@ -998,14 +1007,14 @@
 			#size-cells = <0>;
 			ti,hwmods = "mcspi1";
 			ti,spi-num-cs = <4>;
-			dmas = <&sdma 35>,
-			       <&sdma 36>,
-			       <&sdma 37>,
-			       <&sdma 38>,
-			       <&sdma 39>,
-			       <&sdma 40>,
-			       <&sdma 41>,
-			       <&sdma 42>;
+			dmas = <&sdma_xbar 35>,
+			       <&sdma_xbar 36>,
+			       <&sdma_xbar 37>,
+			       <&sdma_xbar 38>,
+			       <&sdma_xbar 39>,
+			       <&sdma_xbar 40>,
+			       <&sdma_xbar 41>,
+			       <&sdma_xbar 42>;
 			dma-names = "tx0", "rx0", "tx1", "rx1",
 				    "tx2", "rx2", "tx3", "rx3";
 			status = "disabled";
@@ -1019,10 +1028,10 @@
 			#size-cells = <0>;
 			ti,hwmods = "mcspi2";
 			ti,spi-num-cs = <2>;
-			dmas = <&sdma 43>,
-			       <&sdma 44>,
-			       <&sdma 45>,
-			       <&sdma 46>;
+			dmas = <&sdma_xbar 43>,
+			       <&sdma_xbar 44>,
+			       <&sdma_xbar 45>,
+			       <&sdma_xbar 46>;
 			dma-names = "tx0", "rx0", "tx1", "rx1";
 			status = "disabled";
 		};
@@ -1035,7 +1044,7 @@
 			#size-cells = <0>;
 			ti,hwmods = "mcspi3";
 			ti,spi-num-cs = <2>;
-			dmas = <&sdma 15>, <&sdma 16>;
+			dmas = <&sdma_xbar 15>, <&sdma_xbar 16>;
 			dma-names = "tx0", "rx0";
 			status = "disabled";
 		};
@@ -1048,7 +1057,7 @@
 			#size-cells = <0>;
 			ti,hwmods = "mcspi4";
 			ti,spi-num-cs = <1>;
-			dmas = <&sdma 70>, <&sdma 71>;
+			dmas = <&sdma_xbar 70>, <&sdma_xbar 71>;
 			dma-names = "tx0", "rx0";
 			status = "disabled";
 		};
-- 
2.3.0


^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 7/7] ARM: DTS: dra7x: Integrate sDMA crossbar
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: vinod.koul, tony, linux
  Cc: grant.likely, dmaengine, linux-kernel, devicetree, linux-omap,
	linux-arm-kernel, robh+dt, nm

The sDMA requests are routed through the DMA crossbar and without the
crossbar only peripherals using DMA request 0-127 can be used.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 arch/arm/boot/dts/dra7.dtsi | 57 ++++++++++++++++++++++++++-------------------
 1 file changed, 33 insertions(+), 24 deletions(-)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 127608d79033..b6aca837e291 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -253,6 +253,15 @@
 			dma-requests = <127>;
 		};
 
+		sdma_xbar: dma-router@4a002b78 {
+			compatible = "ti,dra7-dma-crossbar";
+			reg = <0x4a002b78 0xfc>;
+			#dma-cells = <1>;
+			dma-requests = <205>;
+			ti,dma-safe-map = <0>;
+			dma-device = <&sdma>;
+		};
+
 		gpio1: gpio@4ae10000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x4ae10000 0x200>;
@@ -348,7 +357,7 @@
 			ti,hwmods = "uart1";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 49>, <&sdma 50>;
+			dmas = <&sdma_xbar 49>, <&sdma_xbar 50>;
 			dma-names = "tx", "rx";
 		};
 
@@ -359,7 +368,7 @@
 			ti,hwmods = "uart2";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 51>, <&sdma 52>;
+			dmas = <&sdma_xbar 51>, <&sdma_xbar 52>;
 			dma-names = "tx", "rx";
 		};
 
@@ -370,7 +379,7 @@
 			ti,hwmods = "uart3";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 53>, <&sdma 54>;
+			dmas = <&sdma_xbar 53>, <&sdma_xbar 54>;
 			dma-names = "tx", "rx";
 		};
 
@@ -381,7 +390,7 @@
 			ti,hwmods = "uart4";
 			clock-frequency = <48000000>;
                         status = "disabled";
-			dmas = <&sdma 55>, <&sdma 56>;
+			dmas = <&sdma_xbar 55>, <&sdma_xbar 56>;
 			dma-names = "tx", "rx";
 		};
 
@@ -392,7 +401,7 @@
 			ti,hwmods = "uart5";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 63>, <&sdma 64>;
+			dmas = <&sdma_xbar 63>, <&sdma_xbar 64>;
 			dma-names = "tx", "rx";
 		};
 
@@ -403,7 +412,7 @@
 			ti,hwmods = "uart6";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 79>, <&sdma 80>;
+			dmas = <&sdma_xbar 79>, <&sdma_xbar 80>;
 			dma-names = "tx", "rx";
 		};
 
@@ -819,7 +828,7 @@
 			ti,hwmods = "mmc1";
 			ti,dual-volt;
 			ti,needs-special-reset;
-			dmas = <&sdma 61>, <&sdma 62>;
+			dmas = <&sdma_xbar 61>, <&sdma_xbar 62>;
 			dma-names = "tx", "rx";
 			status = "disabled";
 			pbias-supply = <&pbias_mmc_reg>;
@@ -831,7 +840,7 @@
 			interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc2";
 			ti,needs-special-reset;
-			dmas = <&sdma 47>, <&sdma 48>;
+			dmas = <&sdma_xbar 47>, <&sdma_xbar 48>;
 			dma-names = "tx", "rx";
 			status = "disabled";
 		};
@@ -842,7 +851,7 @@
 			interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc3";
 			ti,needs-special-reset;
-			dmas = <&sdma 77>, <&sdma 78>;
+			dmas = <&sdma_xbar 77>, <&sdma_xbar 78>;
 			dma-names = "tx", "rx";
 			status = "disabled";
 		};
@@ -853,7 +862,7 @@
 			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc4";
 			ti,needs-special-reset;
-			dmas = <&sdma 57>, <&sdma 58>;
+			dmas = <&sdma_xbar 57>, <&sdma_xbar 58>;
 			dma-names = "tx", "rx";
 			status = "disabled";
 		};
@@ -998,14 +1007,14 @@
 			#size-cells = <0>;
 			ti,hwmods = "mcspi1";
 			ti,spi-num-cs = <4>;
-			dmas = <&sdma 35>,
-			       <&sdma 36>,
-			       <&sdma 37>,
-			       <&sdma 38>,
-			       <&sdma 39>,
-			       <&sdma 40>,
-			       <&sdma 41>,
-			       <&sdma 42>;
+			dmas = <&sdma_xbar 35>,
+			       <&sdma_xbar 36>,
+			       <&sdma_xbar 37>,
+			       <&sdma_xbar 38>,
+			       <&sdma_xbar 39>,
+			       <&sdma_xbar 40>,
+			       <&sdma_xbar 41>,
+			       <&sdma_xbar 42>;
 			dma-names = "tx0", "rx0", "tx1", "rx1",
 				    "tx2", "rx2", "tx3", "rx3";
 			status = "disabled";
@@ -1019,10 +1028,10 @@
 			#size-cells = <0>;
 			ti,hwmods = "mcspi2";
 			ti,spi-num-cs = <2>;
-			dmas = <&sdma 43>,
-			       <&sdma 44>,
-			       <&sdma 45>,
-			       <&sdma 46>;
+			dmas = <&sdma_xbar 43>,
+			       <&sdma_xbar 44>,
+			       <&sdma_xbar 45>,
+			       <&sdma_xbar 46>;
 			dma-names = "tx0", "rx0", "tx1", "rx1";
 			status = "disabled";
 		};
@@ -1035,7 +1044,7 @@
 			#size-cells = <0>;
 			ti,hwmods = "mcspi3";
 			ti,spi-num-cs = <2>;
-			dmas = <&sdma 15>, <&sdma 16>;
+			dmas = <&sdma_xbar 15>, <&sdma_xbar 16>;
 			dma-names = "tx0", "rx0";
 			status = "disabled";
 		};
@@ -1048,7 +1057,7 @@
 			#size-cells = <0>;
 			ti,hwmods = "mcspi4";
 			ti,spi-num-cs = <1>;
-			dmas = <&sdma 70>, <&sdma 71>;
+			dmas = <&sdma_xbar 70>, <&sdma_xbar 71>;
 			dma-names = "tx0", "rx0";
 			status = "disabled";
 		};
-- 
2.3.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* [PATCH v2 7/7] ARM: DTS: dra7x: Integrate sDMA crossbar
@ 2015-03-11 13:23   ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-11 13:23 UTC (permalink / raw)
  To: linux-arm-kernel

The sDMA requests are routed through the DMA crossbar and without the
crossbar only peripherals using DMA request 0-127 can be used.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 arch/arm/boot/dts/dra7.dtsi | 57 ++++++++++++++++++++++++++-------------------
 1 file changed, 33 insertions(+), 24 deletions(-)

diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi
index 127608d79033..b6aca837e291 100644
--- a/arch/arm/boot/dts/dra7.dtsi
+++ b/arch/arm/boot/dts/dra7.dtsi
@@ -253,6 +253,15 @@
 			dma-requests = <127>;
 		};
 
+		sdma_xbar: dma-router at 4a002b78 {
+			compatible = "ti,dra7-dma-crossbar";
+			reg = <0x4a002b78 0xfc>;
+			#dma-cells = <1>;
+			dma-requests = <205>;
+			ti,dma-safe-map = <0>;
+			dma-device = <&sdma>;
+		};
+
 		gpio1: gpio at 4ae10000 {
 			compatible = "ti,omap4-gpio";
 			reg = <0x4ae10000 0x200>;
@@ -348,7 +357,7 @@
 			ti,hwmods = "uart1";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 49>, <&sdma 50>;
+			dmas = <&sdma_xbar 49>, <&sdma_xbar 50>;
 			dma-names = "tx", "rx";
 		};
 
@@ -359,7 +368,7 @@
 			ti,hwmods = "uart2";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 51>, <&sdma 52>;
+			dmas = <&sdma_xbar 51>, <&sdma_xbar 52>;
 			dma-names = "tx", "rx";
 		};
 
@@ -370,7 +379,7 @@
 			ti,hwmods = "uart3";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 53>, <&sdma 54>;
+			dmas = <&sdma_xbar 53>, <&sdma_xbar 54>;
 			dma-names = "tx", "rx";
 		};
 
@@ -381,7 +390,7 @@
 			ti,hwmods = "uart4";
 			clock-frequency = <48000000>;
                         status = "disabled";
-			dmas = <&sdma 55>, <&sdma 56>;
+			dmas = <&sdma_xbar 55>, <&sdma_xbar 56>;
 			dma-names = "tx", "rx";
 		};
 
@@ -392,7 +401,7 @@
 			ti,hwmods = "uart5";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 63>, <&sdma 64>;
+			dmas = <&sdma_xbar 63>, <&sdma_xbar 64>;
 			dma-names = "tx", "rx";
 		};
 
@@ -403,7 +412,7 @@
 			ti,hwmods = "uart6";
 			clock-frequency = <48000000>;
 			status = "disabled";
-			dmas = <&sdma 79>, <&sdma 80>;
+			dmas = <&sdma_xbar 79>, <&sdma_xbar 80>;
 			dma-names = "tx", "rx";
 		};
 
@@ -819,7 +828,7 @@
 			ti,hwmods = "mmc1";
 			ti,dual-volt;
 			ti,needs-special-reset;
-			dmas = <&sdma 61>, <&sdma 62>;
+			dmas = <&sdma_xbar 61>, <&sdma_xbar 62>;
 			dma-names = "tx", "rx";
 			status = "disabled";
 			pbias-supply = <&pbias_mmc_reg>;
@@ -831,7 +840,7 @@
 			interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc2";
 			ti,needs-special-reset;
-			dmas = <&sdma 47>, <&sdma 48>;
+			dmas = <&sdma_xbar 47>, <&sdma_xbar 48>;
 			dma-names = "tx", "rx";
 			status = "disabled";
 		};
@@ -842,7 +851,7 @@
 			interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc3";
 			ti,needs-special-reset;
-			dmas = <&sdma 77>, <&sdma 78>;
+			dmas = <&sdma_xbar 77>, <&sdma_xbar 78>;
 			dma-names = "tx", "rx";
 			status = "disabled";
 		};
@@ -853,7 +862,7 @@
 			interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>;
 			ti,hwmods = "mmc4";
 			ti,needs-special-reset;
-			dmas = <&sdma 57>, <&sdma 58>;
+			dmas = <&sdma_xbar 57>, <&sdma_xbar 58>;
 			dma-names = "tx", "rx";
 			status = "disabled";
 		};
@@ -998,14 +1007,14 @@
 			#size-cells = <0>;
 			ti,hwmods = "mcspi1";
 			ti,spi-num-cs = <4>;
-			dmas = <&sdma 35>,
-			       <&sdma 36>,
-			       <&sdma 37>,
-			       <&sdma 38>,
-			       <&sdma 39>,
-			       <&sdma 40>,
-			       <&sdma 41>,
-			       <&sdma 42>;
+			dmas = <&sdma_xbar 35>,
+			       <&sdma_xbar 36>,
+			       <&sdma_xbar 37>,
+			       <&sdma_xbar 38>,
+			       <&sdma_xbar 39>,
+			       <&sdma_xbar 40>,
+			       <&sdma_xbar 41>,
+			       <&sdma_xbar 42>;
 			dma-names = "tx0", "rx0", "tx1", "rx1",
 				    "tx2", "rx2", "tx3", "rx3";
 			status = "disabled";
@@ -1019,10 +1028,10 @@
 			#size-cells = <0>;
 			ti,hwmods = "mcspi2";
 			ti,spi-num-cs = <2>;
-			dmas = <&sdma 43>,
-			       <&sdma 44>,
-			       <&sdma 45>,
-			       <&sdma 46>;
+			dmas = <&sdma_xbar 43>,
+			       <&sdma_xbar 44>,
+			       <&sdma_xbar 45>,
+			       <&sdma_xbar 46>;
 			dma-names = "tx0", "rx0", "tx1", "rx1";
 			status = "disabled";
 		};
@@ -1035,7 +1044,7 @@
 			#size-cells = <0>;
 			ti,hwmods = "mcspi3";
 			ti,spi-num-cs = <2>;
-			dmas = <&sdma 15>, <&sdma 16>;
+			dmas = <&sdma_xbar 15>, <&sdma_xbar 16>;
 			dma-names = "tx0", "rx0";
 			status = "disabled";
 		};
@@ -1048,7 +1057,7 @@
 			#size-cells = <0>;
 			ti,hwmods = "mcspi4";
 			ti,spi-num-cs = <1>;
-			dmas = <&sdma 70>, <&sdma 71>;
+			dmas = <&sdma_xbar 70>, <&sdma_xbar 71>;
 			dma-names = "tx0", "rx0";
 			status = "disabled";
 		};
-- 
2.3.0

^ permalink raw reply related	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
@ 2015-03-26 10:50     ` Vinod Koul
  0 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-26 10:50 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On Wed, Mar 11, 2015 at 03:23:24PM +0200, Peter Ujfalusi wrote:
> DMA routers are transparent devices used to mux DMA requests from
> peripherals to DMA controllers. They are used when the SoC integrates more
> devices with DMA requests then their controller can handle.
> DRA7x is one example of such SoC, where the sDMA can hanlde 128 DMA request
> lines, but in SoC level it has 205 DMA requests.
> 
> The of_dma_router will be registered as of_dma_controller with special
> xlate function and additional parameters and the code will translate and
> requests a DMA channel from the real DMA controller.
> This way the router can be transparent for the system while remaining generic
> enough to be used in different environments.
> 
Looks fine, was expecting a Documentation updates as well, but that can come
as follow up patch too

-- 
~Vinod

> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
>  drivers/dma/dmaengine.c                       |  7 ++
>  drivers/dma/of-dma.c                          | 92 +++++++++++++++++++++++++++
>  include/linux/dmaengine.h                     | 17 +++++
>  include/linux/of_dma.h                        | 21 ++++++
>  5 files changed, 165 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/dma/dma.txt b/Documentation/devicetree/bindings/dma/dma.txt
> index 82104271e754..f728b978178e 100644
> --- a/Documentation/devicetree/bindings/dma/dma.txt
> +++ b/Documentation/devicetree/bindings/dma/dma.txt
> @@ -31,6 +31,34 @@ Example:
>  		dma-requests = <127>;
>  	};
>  
> +* DMA router
> +
> +DMA routers are transparent IP blocks used to route DMA request lines from
> +devices to the DMA controller. Some SoCs (like TI DRA7x) have more peripherals
> +integrated with DMA requests than what the DMA controller can handle directly.
> +
> +Required property:
> +- dma-device:		phandle of the DMA controller. The router is modifying
> +			the DMA requests for this controller.
> +- #dma-cells: 		Must be at least 1. Used to provide DMA router specific
> +			information. See DMA client binding below for more
> +			details.
> +
> +Optional properties:
> +- dma-requests: 	Number of incoming request lines the router can handle.
> +- dma-device
> +	- dma-requests:	The router driver might need to look for this in order
> +			to configure the routing.
> +
> +Example:
> +	sdma_xbar: dma-router@4a002b78 {
> +		compatible = "ti,dra7-dma-crossbar";
> +		reg = <0x4a002b78 0xfc>;
> +		#dma-cells = <1>;
> +		dma-requests = <205>;
> +		ti,dma-safe-map = <0>;
> +		dma-device = <&sdma>;
> +	};
>  
>  * DMA client
>  
> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> index 344b0ac6d985..1bb67dae5880 100644
> --- a/drivers/dma/dmaengine.c
> +++ b/drivers/dma/dmaengine.c
> @@ -271,6 +271,13 @@ static void dma_chan_put(struct dma_chan *chan)
>  	/* This channel is not in use anymore, free it */
>  	if (!chan->client_count && chan->device->device_free_chan_resources)
>  		chan->device->device_free_chan_resources(chan);
> +
> +	/* If the channel is used via a DMA request router, free the mapping */
> +	if (chan->router && chan->router->route_free) {
> +		chan->router->route_free(chan->router->dev, chan->route_data);
> +		chan->router = NULL;
> +		chan->route_data = NULL;
> +	}
>  }
>  
>  enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)
> diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
> index ca31f1b45366..c86f8823da0d 100644
> --- a/drivers/dma/of-dma.c
> +++ b/drivers/dma/of-dma.c
> @@ -45,6 +45,53 @@ static struct of_dma *of_dma_find_controller(struct of_phandle_args *dma_spec)
>  }
>  
>  /**
> + * of_dma_router_xlate - translation function for router devices
> + * @dma_spec:	pointer to DMA specifier as found in the device tree
> + * @of_dma:	pointer to DMA controller data (router information)
> + *
> + * The function creates new dma_spec to be passed to the router driver's
> + * of_dma_route_allocate() function to prepare a dma_spec which will be used
> + * to request channel from the real DMA controller.
> + */
> +static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec,
> +					    struct of_dma *ofdma)
> +{
> +	struct dma_chan		*chan;
> +	struct of_dma		*ofdma_target;
> +	struct device_node	*dma_target;
> +	struct of_phandle_args	dma_spec_target;
> +	void			*route_data;
> +
> +	dma_target = of_parse_phandle(dma_spec->np, "dma-device", 0);
> +	if (!dma_target) {
> +		pr_err("%s: Can't get target DMA\n", __func__);
> +		return NULL;
> +	}
> +
> +	/* translate the request for the real DMA controller */
> +	memcpy(&dma_spec_target, dma_spec, sizeof(dma_spec_target));
> +	dma_spec_target.np = dma_target;
> +	route_data = ofdma->of_dma_route_allocate(&dma_spec_target, ofdma);
> +
> +	ofdma_target = of_dma_find_controller(&dma_spec_target);
> +	if (!ofdma_target) {
> +		pr_err("%s: Can't get target ofDMA\n", __func__);
> +		return NULL;
> +	}
> +
> +	chan = ofdma_target->of_dma_xlate(&dma_spec_target, ofdma_target);
> +	if (chan) {
> +		chan->router = ofdma->dma_router;
> +		chan->route_data = route_data;
> +	} else {
> +		ofdma->dma_router->route_free(ofdma->dma_router->dev, route_data);
> +	}
> +
> +	of_node_put(dma_target);
> +	return chan;
> +}
> +
> +/**
>   * of_dma_controller_register - Register a DMA controller to DT DMA helpers
>   * @np:			device node of DMA controller
>   * @of_dma_xlate:	translation function which converts a phandle
> @@ -110,6 +157,51 @@ void of_dma_controller_free(struct device_node *np)
>  EXPORT_SYMBOL_GPL(of_dma_controller_free);
>  
>  /**
> + * of_dma_router_register - Register a DMA router to DT DMA helpers as a
> + *			    controller
> + * @np:				device node of DMA router
> + * @of_dma_route_allocate:	setup function for the router which need to
> + *				modify the dma_spec for the DMA controller to
> + *				use and to set up the requested route.
> + * @dma_router:			pointer to dma_router structure to be used when
> + *				the route need to be free up.
> + *
> + * Returns 0 on success or appropriate errno value on error.
> + *
> + * Allocated memory should be freed with appropriate of_dma_controller_free()
> + * call.
> + */
> +int of_dma_router_register(struct device_node *np,
> +			   void *(*of_dma_route_allocate)
> +			   (struct of_phandle_args *, struct of_dma *),
> +			   struct dma_router *dma_router)
> +{
> +	struct of_dma	*ofdma;
> +
> +	if (!np || !of_dma_route_allocate || !dma_router) {
> +		pr_err("%s: not enough information provided\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	ofdma = kzalloc(sizeof(*ofdma), GFP_KERNEL);
> +	if (!ofdma)
> +		return -ENOMEM;
> +
> +	ofdma->of_node = np;
> +	ofdma->of_dma_xlate = of_dma_router_xlate;
> +	ofdma->of_dma_route_allocate = of_dma_route_allocate;
> +	ofdma->dma_router = dma_router;
> +
> +	/* Now queue of_dma controller structure in list */
> +	mutex_lock(&of_dma_lock);
> +	list_add_tail(&ofdma->of_dma_controllers, &of_dma_list);
> +	mutex_unlock(&of_dma_lock);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(of_dma_router_register);
> +
> +/**
>   * of_dma_match_channel - Check if a DMA specifier matches name
>   * @np:		device node to look for DMA channels
>   * @name:	channel name to be matched
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index 2bff9abc162a..b6a0e59f1887 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -226,6 +226,16 @@ struct dma_chan_percpu {
>  };
>  
>  /**
> + * struct dma_router - DMA router structure
> + * @dev: pointer to the DMA router device
> + * @route_free: function to be called when the route can be disconnected
> + */
> +struct dma_router {
> +	struct device *dev;
> +	void (*route_free)(struct device *dev, void *route_data);
> +};
> +
> +/**
>   * struct dma_chan - devices supply DMA channels, clients use them
>   * @device: ptr to the dma device who supplies this channel, always !%NULL
>   * @cookie: last cookie value returned to client
> @@ -236,6 +246,8 @@ struct dma_chan_percpu {
>   * @local: per-cpu pointer to a struct dma_chan_percpu
>   * @client_count: how many clients are using this channel
>   * @table_count: number of appearances in the mem-to-mem allocation table
> + * @router: pointer to the DMA router structure
> + * @route_data: channel specific data for the router
>   * @private: private data for certain client-channel associations
>   */
>  struct dma_chan {
> @@ -251,6 +263,11 @@ struct dma_chan {
>  	struct dma_chan_percpu __percpu *local;
>  	int client_count;
>  	int table_count;
> +
> +	/* DMA router */
> +	struct dma_router *router;
> +	void *route_data;
> +
>  	void *private;
>  };
>  
> diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
> index 56bc026c143f..734e449f87c1 100644
> --- a/include/linux/of_dma.h
> +++ b/include/linux/of_dma.h
> @@ -23,6 +23,9 @@ struct of_dma {
>  	struct device_node	*of_node;
>  	struct dma_chan		*(*of_dma_xlate)
>  				(struct of_phandle_args *, struct of_dma *);
> +	void			*(*of_dma_route_allocate)
> +				(struct of_phandle_args *, struct of_dma *);
> +	struct dma_router	*dma_router;
>  	void			*of_dma_data;
>  };
>  
> @@ -37,12 +40,20 @@ extern int of_dma_controller_register(struct device_node *np,
>  		(struct of_phandle_args *, struct of_dma *),
>  		void *data);
>  extern void of_dma_controller_free(struct device_node *np);
> +
> +extern int of_dma_router_register(struct device_node *np,
> +		void *(*of_dma_route_allocate)
> +		(struct of_phandle_args *, struct of_dma *),
> +		 struct dma_router *dma_router);
> +#define of_dma_router_free of_dma_controller_free
> +
>  extern struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
>  						     const char *name);
>  extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
>  		struct of_dma *ofdma);
>  extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
>  		struct of_dma *ofdma);
> +
>  #else
>  static inline int of_dma_controller_register(struct device_node *np,
>  		struct dma_chan *(*of_dma_xlate)
> @@ -56,6 +67,16 @@ static inline void of_dma_controller_free(struct device_node *np)
>  {
>  }
>  
> +static inline int of_dma_router_register(struct device_node *np,
> +		void *(*of_dma_route_allocate)
> +		(struct of_phandle_args *, struct of_dma *),
> +		 struct dma_router *dma_router)
> +{
> +	return -ENODEV;
> +}
> +
> +#define of_dma_router_free of_dma_controller_free
> +
>  static inline struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
>  						     const char *name)
>  {
> -- 
> 2.3.0
> 

-- 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
@ 2015-03-26 10:50     ` Vinod Koul
  0 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-26 10:50 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: tony-4v6yS6AI5VpBDgjK7y7TUQ, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, nm-l0cyMroinI0

On Wed, Mar 11, 2015 at 03:23:24PM +0200, Peter Ujfalusi wrote:
> DMA routers are transparent devices used to mux DMA requests from
> peripherals to DMA controllers. They are used when the SoC integrates more
> devices with DMA requests then their controller can handle.
> DRA7x is one example of such SoC, where the sDMA can hanlde 128 DMA request
> lines, but in SoC level it has 205 DMA requests.
> 
> The of_dma_router will be registered as of_dma_controller with special
> xlate function and additional parameters and the code will translate and
> requests a DMA channel from the real DMA controller.
> This way the router can be transparent for the system while remaining generic
> enough to be used in different environments.
> 
Looks fine, was expecting a Documentation updates as well, but that can come
as follow up patch too

-- 
~Vinod

> Signed-off-by: Peter Ujfalusi <peter.ujfalusi-l0cyMroinI0@public.gmane.org>
> ---
>  Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
>  drivers/dma/dmaengine.c                       |  7 ++
>  drivers/dma/of-dma.c                          | 92 +++++++++++++++++++++++++++
>  include/linux/dmaengine.h                     | 17 +++++
>  include/linux/of_dma.h                        | 21 ++++++
>  5 files changed, 165 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/dma/dma.txt b/Documentation/devicetree/bindings/dma/dma.txt
> index 82104271e754..f728b978178e 100644
> --- a/Documentation/devicetree/bindings/dma/dma.txt
> +++ b/Documentation/devicetree/bindings/dma/dma.txt
> @@ -31,6 +31,34 @@ Example:
>  		dma-requests = <127>;
>  	};
>  
> +* DMA router
> +
> +DMA routers are transparent IP blocks used to route DMA request lines from
> +devices to the DMA controller. Some SoCs (like TI DRA7x) have more peripherals
> +integrated with DMA requests than what the DMA controller can handle directly.
> +
> +Required property:
> +- dma-device:		phandle of the DMA controller. The router is modifying
> +			the DMA requests for this controller.
> +- #dma-cells: 		Must be at least 1. Used to provide DMA router specific
> +			information. See DMA client binding below for more
> +			details.
> +
> +Optional properties:
> +- dma-requests: 	Number of incoming request lines the router can handle.
> +- dma-device
> +	- dma-requests:	The router driver might need to look for this in order
> +			to configure the routing.
> +
> +Example:
> +	sdma_xbar: dma-router@4a002b78 {
> +		compatible = "ti,dra7-dma-crossbar";
> +		reg = <0x4a002b78 0xfc>;
> +		#dma-cells = <1>;
> +		dma-requests = <205>;
> +		ti,dma-safe-map = <0>;
> +		dma-device = <&sdma>;
> +	};
>  
>  * DMA client
>  
> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> index 344b0ac6d985..1bb67dae5880 100644
> --- a/drivers/dma/dmaengine.c
> +++ b/drivers/dma/dmaengine.c
> @@ -271,6 +271,13 @@ static void dma_chan_put(struct dma_chan *chan)
>  	/* This channel is not in use anymore, free it */
>  	if (!chan->client_count && chan->device->device_free_chan_resources)
>  		chan->device->device_free_chan_resources(chan);
> +
> +	/* If the channel is used via a DMA request router, free the mapping */
> +	if (chan->router && chan->router->route_free) {
> +		chan->router->route_free(chan->router->dev, chan->route_data);
> +		chan->router = NULL;
> +		chan->route_data = NULL;
> +	}
>  }
>  
>  enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)
> diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
> index ca31f1b45366..c86f8823da0d 100644
> --- a/drivers/dma/of-dma.c
> +++ b/drivers/dma/of-dma.c
> @@ -45,6 +45,53 @@ static struct of_dma *of_dma_find_controller(struct of_phandle_args *dma_spec)
>  }
>  
>  /**
> + * of_dma_router_xlate - translation function for router devices
> + * @dma_spec:	pointer to DMA specifier as found in the device tree
> + * @of_dma:	pointer to DMA controller data (router information)
> + *
> + * The function creates new dma_spec to be passed to the router driver's
> + * of_dma_route_allocate() function to prepare a dma_spec which will be used
> + * to request channel from the real DMA controller.
> + */
> +static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec,
> +					    struct of_dma *ofdma)
> +{
> +	struct dma_chan		*chan;
> +	struct of_dma		*ofdma_target;
> +	struct device_node	*dma_target;
> +	struct of_phandle_args	dma_spec_target;
> +	void			*route_data;
> +
> +	dma_target = of_parse_phandle(dma_spec->np, "dma-device", 0);
> +	if (!dma_target) {
> +		pr_err("%s: Can't get target DMA\n", __func__);
> +		return NULL;
> +	}
> +
> +	/* translate the request for the real DMA controller */
> +	memcpy(&dma_spec_target, dma_spec, sizeof(dma_spec_target));
> +	dma_spec_target.np = dma_target;
> +	route_data = ofdma->of_dma_route_allocate(&dma_spec_target, ofdma);
> +
> +	ofdma_target = of_dma_find_controller(&dma_spec_target);
> +	if (!ofdma_target) {
> +		pr_err("%s: Can't get target ofDMA\n", __func__);
> +		return NULL;
> +	}
> +
> +	chan = ofdma_target->of_dma_xlate(&dma_spec_target, ofdma_target);
> +	if (chan) {
> +		chan->router = ofdma->dma_router;
> +		chan->route_data = route_data;
> +	} else {
> +		ofdma->dma_router->route_free(ofdma->dma_router->dev, route_data);
> +	}
> +
> +	of_node_put(dma_target);
> +	return chan;
> +}
> +
> +/**
>   * of_dma_controller_register - Register a DMA controller to DT DMA helpers
>   * @np:			device node of DMA controller
>   * @of_dma_xlate:	translation function which converts a phandle
> @@ -110,6 +157,51 @@ void of_dma_controller_free(struct device_node *np)
>  EXPORT_SYMBOL_GPL(of_dma_controller_free);
>  
>  /**
> + * of_dma_router_register - Register a DMA router to DT DMA helpers as a
> + *			    controller
> + * @np:				device node of DMA router
> + * @of_dma_route_allocate:	setup function for the router which need to
> + *				modify the dma_spec for the DMA controller to
> + *				use and to set up the requested route.
> + * @dma_router:			pointer to dma_router structure to be used when
> + *				the route need to be free up.
> + *
> + * Returns 0 on success or appropriate errno value on error.
> + *
> + * Allocated memory should be freed with appropriate of_dma_controller_free()
> + * call.
> + */
> +int of_dma_router_register(struct device_node *np,
> +			   void *(*of_dma_route_allocate)
> +			   (struct of_phandle_args *, struct of_dma *),
> +			   struct dma_router *dma_router)
> +{
> +	struct of_dma	*ofdma;
> +
> +	if (!np || !of_dma_route_allocate || !dma_router) {
> +		pr_err("%s: not enough information provided\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	ofdma = kzalloc(sizeof(*ofdma), GFP_KERNEL);
> +	if (!ofdma)
> +		return -ENOMEM;
> +
> +	ofdma->of_node = np;
> +	ofdma->of_dma_xlate = of_dma_router_xlate;
> +	ofdma->of_dma_route_allocate = of_dma_route_allocate;
> +	ofdma->dma_router = dma_router;
> +
> +	/* Now queue of_dma controller structure in list */
> +	mutex_lock(&of_dma_lock);
> +	list_add_tail(&ofdma->of_dma_controllers, &of_dma_list);
> +	mutex_unlock(&of_dma_lock);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(of_dma_router_register);
> +
> +/**
>   * of_dma_match_channel - Check if a DMA specifier matches name
>   * @np:		device node to look for DMA channels
>   * @name:	channel name to be matched
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index 2bff9abc162a..b6a0e59f1887 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -226,6 +226,16 @@ struct dma_chan_percpu {
>  };
>  
>  /**
> + * struct dma_router - DMA router structure
> + * @dev: pointer to the DMA router device
> + * @route_free: function to be called when the route can be disconnected
> + */
> +struct dma_router {
> +	struct device *dev;
> +	void (*route_free)(struct device *dev, void *route_data);
> +};
> +
> +/**
>   * struct dma_chan - devices supply DMA channels, clients use them
>   * @device: ptr to the dma device who supplies this channel, always !%NULL
>   * @cookie: last cookie value returned to client
> @@ -236,6 +246,8 @@ struct dma_chan_percpu {
>   * @local: per-cpu pointer to a struct dma_chan_percpu
>   * @client_count: how many clients are using this channel
>   * @table_count: number of appearances in the mem-to-mem allocation table
> + * @router: pointer to the DMA router structure
> + * @route_data: channel specific data for the router
>   * @private: private data for certain client-channel associations
>   */
>  struct dma_chan {
> @@ -251,6 +263,11 @@ struct dma_chan {
>  	struct dma_chan_percpu __percpu *local;
>  	int client_count;
>  	int table_count;
> +
> +	/* DMA router */
> +	struct dma_router *router;
> +	void *route_data;
> +
>  	void *private;
>  };
>  
> diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
> index 56bc026c143f..734e449f87c1 100644
> --- a/include/linux/of_dma.h
> +++ b/include/linux/of_dma.h
> @@ -23,6 +23,9 @@ struct of_dma {
>  	struct device_node	*of_node;
>  	struct dma_chan		*(*of_dma_xlate)
>  				(struct of_phandle_args *, struct of_dma *);
> +	void			*(*of_dma_route_allocate)
> +				(struct of_phandle_args *, struct of_dma *);
> +	struct dma_router	*dma_router;
>  	void			*of_dma_data;
>  };
>  
> @@ -37,12 +40,20 @@ extern int of_dma_controller_register(struct device_node *np,
>  		(struct of_phandle_args *, struct of_dma *),
>  		void *data);
>  extern void of_dma_controller_free(struct device_node *np);
> +
> +extern int of_dma_router_register(struct device_node *np,
> +		void *(*of_dma_route_allocate)
> +		(struct of_phandle_args *, struct of_dma *),
> +		 struct dma_router *dma_router);
> +#define of_dma_router_free of_dma_controller_free
> +
>  extern struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
>  						     const char *name);
>  extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
>  		struct of_dma *ofdma);
>  extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
>  		struct of_dma *ofdma);
> +
>  #else
>  static inline int of_dma_controller_register(struct device_node *np,
>  		struct dma_chan *(*of_dma_xlate)
> @@ -56,6 +67,16 @@ static inline void of_dma_controller_free(struct device_node *np)
>  {
>  }
>  
> +static inline int of_dma_router_register(struct device_node *np,
> +		void *(*of_dma_route_allocate)
> +		(struct of_phandle_args *, struct of_dma *),
> +		 struct dma_router *dma_router)
> +{
> +	return -ENODEV;
> +}
> +
> +#define of_dma_router_free of_dma_controller_free
> +
>  static inline struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
>  						     const char *name)
>  {
> -- 
> 2.3.0
> 

-- 
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
@ 2015-03-26 10:50     ` Vinod Koul
  0 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-26 10:50 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 11, 2015 at 03:23:24PM +0200, Peter Ujfalusi wrote:
> DMA routers are transparent devices used to mux DMA requests from
> peripherals to DMA controllers. They are used when the SoC integrates more
> devices with DMA requests then their controller can handle.
> DRA7x is one example of such SoC, where the sDMA can hanlde 128 DMA request
> lines, but in SoC level it has 205 DMA requests.
> 
> The of_dma_router will be registered as of_dma_controller with special
> xlate function and additional parameters and the code will translate and
> requests a DMA channel from the real DMA controller.
> This way the router can be transparent for the system while remaining generic
> enough to be used in different environments.
> 
Looks fine, was expecting a Documentation updates as well, but that can come
as follow up patch too

-- 
~Vinod

> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
>  drivers/dma/dmaengine.c                       |  7 ++
>  drivers/dma/of-dma.c                          | 92 +++++++++++++++++++++++++++
>  include/linux/dmaengine.h                     | 17 +++++
>  include/linux/of_dma.h                        | 21 ++++++
>  5 files changed, 165 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/dma/dma.txt b/Documentation/devicetree/bindings/dma/dma.txt
> index 82104271e754..f728b978178e 100644
> --- a/Documentation/devicetree/bindings/dma/dma.txt
> +++ b/Documentation/devicetree/bindings/dma/dma.txt
> @@ -31,6 +31,34 @@ Example:
>  		dma-requests = <127>;
>  	};
>  
> +* DMA router
> +
> +DMA routers are transparent IP blocks used to route DMA request lines from
> +devices to the DMA controller. Some SoCs (like TI DRA7x) have more peripherals
> +integrated with DMA requests than what the DMA controller can handle directly.
> +
> +Required property:
> +- dma-device:		phandle of the DMA controller. The router is modifying
> +			the DMA requests for this controller.
> +- #dma-cells: 		Must be at least 1. Used to provide DMA router specific
> +			information. See DMA client binding below for more
> +			details.
> +
> +Optional properties:
> +- dma-requests: 	Number of incoming request lines the router can handle.
> +- dma-device
> +	- dma-requests:	The router driver might need to look for this in order
> +			to configure the routing.
> +
> +Example:
> +	sdma_xbar: dma-router at 4a002b78 {
> +		compatible = "ti,dra7-dma-crossbar";
> +		reg = <0x4a002b78 0xfc>;
> +		#dma-cells = <1>;
> +		dma-requests = <205>;
> +		ti,dma-safe-map = <0>;
> +		dma-device = <&sdma>;
> +	};
>  
>  * DMA client
>  
> diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c
> index 344b0ac6d985..1bb67dae5880 100644
> --- a/drivers/dma/dmaengine.c
> +++ b/drivers/dma/dmaengine.c
> @@ -271,6 +271,13 @@ static void dma_chan_put(struct dma_chan *chan)
>  	/* This channel is not in use anymore, free it */
>  	if (!chan->client_count && chan->device->device_free_chan_resources)
>  		chan->device->device_free_chan_resources(chan);
> +
> +	/* If the channel is used via a DMA request router, free the mapping */
> +	if (chan->router && chan->router->route_free) {
> +		chan->router->route_free(chan->router->dev, chan->route_data);
> +		chan->router = NULL;
> +		chan->route_data = NULL;
> +	}
>  }
>  
>  enum dma_status dma_sync_wait(struct dma_chan *chan, dma_cookie_t cookie)
> diff --git a/drivers/dma/of-dma.c b/drivers/dma/of-dma.c
> index ca31f1b45366..c86f8823da0d 100644
> --- a/drivers/dma/of-dma.c
> +++ b/drivers/dma/of-dma.c
> @@ -45,6 +45,53 @@ static struct of_dma *of_dma_find_controller(struct of_phandle_args *dma_spec)
>  }
>  
>  /**
> + * of_dma_router_xlate - translation function for router devices
> + * @dma_spec:	pointer to DMA specifier as found in the device tree
> + * @of_dma:	pointer to DMA controller data (router information)
> + *
> + * The function creates new dma_spec to be passed to the router driver's
> + * of_dma_route_allocate() function to prepare a dma_spec which will be used
> + * to request channel from the real DMA controller.
> + */
> +static struct dma_chan *of_dma_router_xlate(struct of_phandle_args *dma_spec,
> +					    struct of_dma *ofdma)
> +{
> +	struct dma_chan		*chan;
> +	struct of_dma		*ofdma_target;
> +	struct device_node	*dma_target;
> +	struct of_phandle_args	dma_spec_target;
> +	void			*route_data;
> +
> +	dma_target = of_parse_phandle(dma_spec->np, "dma-device", 0);
> +	if (!dma_target) {
> +		pr_err("%s: Can't get target DMA\n", __func__);
> +		return NULL;
> +	}
> +
> +	/* translate the request for the real DMA controller */
> +	memcpy(&dma_spec_target, dma_spec, sizeof(dma_spec_target));
> +	dma_spec_target.np = dma_target;
> +	route_data = ofdma->of_dma_route_allocate(&dma_spec_target, ofdma);
> +
> +	ofdma_target = of_dma_find_controller(&dma_spec_target);
> +	if (!ofdma_target) {
> +		pr_err("%s: Can't get target ofDMA\n", __func__);
> +		return NULL;
> +	}
> +
> +	chan = ofdma_target->of_dma_xlate(&dma_spec_target, ofdma_target);
> +	if (chan) {
> +		chan->router = ofdma->dma_router;
> +		chan->route_data = route_data;
> +	} else {
> +		ofdma->dma_router->route_free(ofdma->dma_router->dev, route_data);
> +	}
> +
> +	of_node_put(dma_target);
> +	return chan;
> +}
> +
> +/**
>   * of_dma_controller_register - Register a DMA controller to DT DMA helpers
>   * @np:			device node of DMA controller
>   * @of_dma_xlate:	translation function which converts a phandle
> @@ -110,6 +157,51 @@ void of_dma_controller_free(struct device_node *np)
>  EXPORT_SYMBOL_GPL(of_dma_controller_free);
>  
>  /**
> + * of_dma_router_register - Register a DMA router to DT DMA helpers as a
> + *			    controller
> + * @np:				device node of DMA router
> + * @of_dma_route_allocate:	setup function for the router which need to
> + *				modify the dma_spec for the DMA controller to
> + *				use and to set up the requested route.
> + * @dma_router:			pointer to dma_router structure to be used when
> + *				the route need to be free up.
> + *
> + * Returns 0 on success or appropriate errno value on error.
> + *
> + * Allocated memory should be freed with appropriate of_dma_controller_free()
> + * call.
> + */
> +int of_dma_router_register(struct device_node *np,
> +			   void *(*of_dma_route_allocate)
> +			   (struct of_phandle_args *, struct of_dma *),
> +			   struct dma_router *dma_router)
> +{
> +	struct of_dma	*ofdma;
> +
> +	if (!np || !of_dma_route_allocate || !dma_router) {
> +		pr_err("%s: not enough information provided\n", __func__);
> +		return -EINVAL;
> +	}
> +
> +	ofdma = kzalloc(sizeof(*ofdma), GFP_KERNEL);
> +	if (!ofdma)
> +		return -ENOMEM;
> +
> +	ofdma->of_node = np;
> +	ofdma->of_dma_xlate = of_dma_router_xlate;
> +	ofdma->of_dma_route_allocate = of_dma_route_allocate;
> +	ofdma->dma_router = dma_router;
> +
> +	/* Now queue of_dma controller structure in list */
> +	mutex_lock(&of_dma_lock);
> +	list_add_tail(&ofdma->of_dma_controllers, &of_dma_list);
> +	mutex_unlock(&of_dma_lock);
> +
> +	return 0;
> +}
> +EXPORT_SYMBOL_GPL(of_dma_router_register);
> +
> +/**
>   * of_dma_match_channel - Check if a DMA specifier matches name
>   * @np:		device node to look for DMA channels
>   * @name:	channel name to be matched
> diff --git a/include/linux/dmaengine.h b/include/linux/dmaengine.h
> index 2bff9abc162a..b6a0e59f1887 100644
> --- a/include/linux/dmaengine.h
> +++ b/include/linux/dmaengine.h
> @@ -226,6 +226,16 @@ struct dma_chan_percpu {
>  };
>  
>  /**
> + * struct dma_router - DMA router structure
> + * @dev: pointer to the DMA router device
> + * @route_free: function to be called when the route can be disconnected
> + */
> +struct dma_router {
> +	struct device *dev;
> +	void (*route_free)(struct device *dev, void *route_data);
> +};
> +
> +/**
>   * struct dma_chan - devices supply DMA channels, clients use them
>   * @device: ptr to the dma device who supplies this channel, always !%NULL
>   * @cookie: last cookie value returned to client
> @@ -236,6 +246,8 @@ struct dma_chan_percpu {
>   * @local: per-cpu pointer to a struct dma_chan_percpu
>   * @client_count: how many clients are using this channel
>   * @table_count: number of appearances in the mem-to-mem allocation table
> + * @router: pointer to the DMA router structure
> + * @route_data: channel specific data for the router
>   * @private: private data for certain client-channel associations
>   */
>  struct dma_chan {
> @@ -251,6 +263,11 @@ struct dma_chan {
>  	struct dma_chan_percpu __percpu *local;
>  	int client_count;
>  	int table_count;
> +
> +	/* DMA router */
> +	struct dma_router *router;
> +	void *route_data;
> +
>  	void *private;
>  };
>  
> diff --git a/include/linux/of_dma.h b/include/linux/of_dma.h
> index 56bc026c143f..734e449f87c1 100644
> --- a/include/linux/of_dma.h
> +++ b/include/linux/of_dma.h
> @@ -23,6 +23,9 @@ struct of_dma {
>  	struct device_node	*of_node;
>  	struct dma_chan		*(*of_dma_xlate)
>  				(struct of_phandle_args *, struct of_dma *);
> +	void			*(*of_dma_route_allocate)
> +				(struct of_phandle_args *, struct of_dma *);
> +	struct dma_router	*dma_router;
>  	void			*of_dma_data;
>  };
>  
> @@ -37,12 +40,20 @@ extern int of_dma_controller_register(struct device_node *np,
>  		(struct of_phandle_args *, struct of_dma *),
>  		void *data);
>  extern void of_dma_controller_free(struct device_node *np);
> +
> +extern int of_dma_router_register(struct device_node *np,
> +		void *(*of_dma_route_allocate)
> +		(struct of_phandle_args *, struct of_dma *),
> +		 struct dma_router *dma_router);
> +#define of_dma_router_free of_dma_controller_free
> +
>  extern struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
>  						     const char *name);
>  extern struct dma_chan *of_dma_simple_xlate(struct of_phandle_args *dma_spec,
>  		struct of_dma *ofdma);
>  extern struct dma_chan *of_dma_xlate_by_chan_id(struct of_phandle_args *dma_spec,
>  		struct of_dma *ofdma);
> +
>  #else
>  static inline int of_dma_controller_register(struct device_node *np,
>  		struct dma_chan *(*of_dma_xlate)
> @@ -56,6 +67,16 @@ static inline void of_dma_controller_free(struct device_node *np)
>  {
>  }
>  
> +static inline int of_dma_router_register(struct device_node *np,
> +		void *(*of_dma_route_allocate)
> +		(struct of_phandle_args *, struct of_dma *),
> +		 struct dma_router *dma_router)
> +{
> +	return -ENODEV;
> +}
> +
> +#define of_dma_router_free of_dma_controller_free
> +
>  static inline struct dma_chan *of_dma_request_slave_channel(struct device_node *np,
>  						     const char *name)
>  {
> -- 
> 2.3.0
> 

-- 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
@ 2015-03-26 10:56     ` Vinod Koul
  0 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-26 10:56 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On Wed, Mar 11, 2015 at 03:23:26PM +0200, Peter Ujfalusi wrote:
> The DRA7x has more peripherals with DMA requests than the sDMA can handle:
> 205 vs 127. All DMA requests are routed through the DMA crossbar, which can
> be configured to route selected incoming DMA requests to specific sDMA
> request.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  drivers/dma/Kconfig           |   4 +
>  drivers/dma/Makefile          |   1 +
>  drivers/dma/ti-dma-crossbar.c | 190 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 195 insertions(+)
>  create mode 100644 drivers/dma/ti-dma-crossbar.c
> 
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 074ffad334a7..519657a37ca1 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -247,6 +247,9 @@ config TI_EDMA
>  	  Enable support for the TI EDMA controller. This DMA
>  	  engine is found on TI DaVinci and AM33xx parts.
>  
> +config TI_DMA_CROSSBAR
> +	bool
> +
>  config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
>  	bool
>  
> @@ -332,6 +335,7 @@ config DMA_OMAP
>  	depends on ARCH_OMAP
>  	select DMA_ENGINE
>  	select DMA_VIRTUAL_CHANNELS
> +	select TI_DMA_CROSSBAR if SOC_DRA7XX
>  
>  config DMA_BCM2835
>  	tristate "BCM2835 DMA engine support"
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index bf4485800c60..6ec7af6a416c 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -39,6 +39,7 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
>  obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
>  obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
>  obj-$(CONFIG_DMA_OMAP) += omap-dma.o
> +obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
>  obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
>  obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
>  obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
> diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c
> new file mode 100644
> index 000000000000..591307bd4370
> --- /dev/null
> +++ b/drivers/dma/ti-dma-crossbar.c
> @@ -0,0 +1,190 @@
> +/*
> + *  Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
> + *  Author: Peter Ujfalusi <peter.ujfalusi@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.
> + *
> + */
> +#include <linux/slab.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/list.h>
> +#include <linux/io.h>
> +#include <linux/regmap.h>
> +#include <linux/idr.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/of_dma.h>
> +
> +#define TI_XBAR_OUTPUTS	127
> +#define TI_XBAR_INPUTS	256
Ideally this should be moved to DT. Will next revision of this chip always
support these output and inputs?

> +
> +static DEFINE_IDR(map_idr);
> +
> +struct ti_dma_xbar_data {
> +	struct dma_router dmarouter;
> +	struct regmap *regmap;
> +
> +	uint safe_val; /* Value to rest the crossbar lines */
> +	uint xbar_requests; /* number of DMA requests connected to XBAR */
> +	uint dma_requests; /* number of DMA requests forwarded to DMA */
> +
> +	void __iomem *iomem;
> +};
> +
> +struct ti_dma_xbar_map {
> +	int xbar_in;
> +	int xbar_out;
> +};
> +
> +static void ti_dma_xbar_free(struct device *dev, void *route_data)
> +{
> +	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
> +	struct ti_dma_xbar_map *map = route_data;
> +
> +	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
> +		map->xbar_in, map->xbar_out);
> +
> +	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
just out of curiosity how much do you save using regmap :)

> +static int ti_dma_xbar_probe(struct platform_device *pdev)
> +{
> +	struct device_node *node = pdev->dev.of_node;
> +	struct device_node *dma_node;
> +	struct ti_dma_xbar_data *xbar;
> +	struct resource *res;
> +	void __iomem *iomem;
> +	int i, ret;
> +
> +	if (!node)
> +		return -ENODEV;
> +
> +	dma_node = of_parse_phandle(node, "dma-device", 0);
> +	if (!dma_node) {
> +		dev_err(&pdev->dev, "Can't get target DMA node\n");
> +		return -ENODEV;
> +	}
> +
> +	xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL);
> +	if (!xbar)
> +		return -ENOMEM;
> +
> +	if (of_property_read_u32(dma_node, "dma-requests",
> +				 &xbar->dma_requests)) {
> +		dev_info(&pdev->dev,
> +			 "Missing XBAR output information, using %u.\n",
> +			 TI_XBAR_OUTPUTS);
> +		xbar->dma_requests = TI_XBAR_OUTPUTS;
> +	}
> +	of_node_put(dma_node);
_put here?

> +int omap_dmaxbar_init(void)
> +{
> +	return platform_driver_register(&ti_dma_xbar_driver);
> +}
> +arch_initcall(omap_dmaxbar_init);
why arch_initcall?

-- 
~Vinod


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
@ 2015-03-26 10:56     ` Vinod Koul
  0 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-26 10:56 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: tony-4v6yS6AI5VpBDgjK7y7TUQ, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, nm-l0cyMroinI0

On Wed, Mar 11, 2015 at 03:23:26PM +0200, Peter Ujfalusi wrote:
> The DRA7x has more peripherals with DMA requests than the sDMA can handle:
> 205 vs 127. All DMA requests are routed through the DMA crossbar, which can
> be configured to route selected incoming DMA requests to specific sDMA
> request.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi-l0cyMroinI0@public.gmane.org>
> ---
>  drivers/dma/Kconfig           |   4 +
>  drivers/dma/Makefile          |   1 +
>  drivers/dma/ti-dma-crossbar.c | 190 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 195 insertions(+)
>  create mode 100644 drivers/dma/ti-dma-crossbar.c
> 
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 074ffad334a7..519657a37ca1 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -247,6 +247,9 @@ config TI_EDMA
>  	  Enable support for the TI EDMA controller. This DMA
>  	  engine is found on TI DaVinci and AM33xx parts.
>  
> +config TI_DMA_CROSSBAR
> +	bool
> +
>  config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
>  	bool
>  
> @@ -332,6 +335,7 @@ config DMA_OMAP
>  	depends on ARCH_OMAP
>  	select DMA_ENGINE
>  	select DMA_VIRTUAL_CHANNELS
> +	select TI_DMA_CROSSBAR if SOC_DRA7XX
>  
>  config DMA_BCM2835
>  	tristate "BCM2835 DMA engine support"
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index bf4485800c60..6ec7af6a416c 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -39,6 +39,7 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
>  obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
>  obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
>  obj-$(CONFIG_DMA_OMAP) += omap-dma.o
> +obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
>  obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
>  obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
>  obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
> diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c
> new file mode 100644
> index 000000000000..591307bd4370
> --- /dev/null
> +++ b/drivers/dma/ti-dma-crossbar.c
> @@ -0,0 +1,190 @@
> +/*
> + *  Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
> + *  Author: Peter Ujfalusi <peter.ujfalusi-l0cyMroinI0@public.gmane.org>
> + *
> + * 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.
> + *
> + */
> +#include <linux/slab.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/list.h>
> +#include <linux/io.h>
> +#include <linux/regmap.h>
> +#include <linux/idr.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/of_dma.h>
> +
> +#define TI_XBAR_OUTPUTS	127
> +#define TI_XBAR_INPUTS	256
Ideally this should be moved to DT. Will next revision of this chip always
support these output and inputs?

> +
> +static DEFINE_IDR(map_idr);
> +
> +struct ti_dma_xbar_data {
> +	struct dma_router dmarouter;
> +	struct regmap *regmap;
> +
> +	uint safe_val; /* Value to rest the crossbar lines */
> +	uint xbar_requests; /* number of DMA requests connected to XBAR */
> +	uint dma_requests; /* number of DMA requests forwarded to DMA */
> +
> +	void __iomem *iomem;
> +};
> +
> +struct ti_dma_xbar_map {
> +	int xbar_in;
> +	int xbar_out;
> +};
> +
> +static void ti_dma_xbar_free(struct device *dev, void *route_data)
> +{
> +	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
> +	struct ti_dma_xbar_map *map = route_data;
> +
> +	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
> +		map->xbar_in, map->xbar_out);
> +
> +	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
just out of curiosity how much do you save using regmap :)

> +static int ti_dma_xbar_probe(struct platform_device *pdev)
> +{
> +	struct device_node *node = pdev->dev.of_node;
> +	struct device_node *dma_node;
> +	struct ti_dma_xbar_data *xbar;
> +	struct resource *res;
> +	void __iomem *iomem;
> +	int i, ret;
> +
> +	if (!node)
> +		return -ENODEV;
> +
> +	dma_node = of_parse_phandle(node, "dma-device", 0);
> +	if (!dma_node) {
> +		dev_err(&pdev->dev, "Can't get target DMA node\n");
> +		return -ENODEV;
> +	}
> +
> +	xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL);
> +	if (!xbar)
> +		return -ENOMEM;
> +
> +	if (of_property_read_u32(dma_node, "dma-requests",
> +				 &xbar->dma_requests)) {
> +		dev_info(&pdev->dev,
> +			 "Missing XBAR output information, using %u.\n",
> +			 TI_XBAR_OUTPUTS);
> +		xbar->dma_requests = TI_XBAR_OUTPUTS;
> +	}
> +	of_node_put(dma_node);
_put here?

> +int omap_dmaxbar_init(void)
> +{
> +	return platform_driver_register(&ti_dma_xbar_driver);
> +}
> +arch_initcall(omap_dmaxbar_init);
why arch_initcall?

-- 
~Vinod

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
@ 2015-03-26 10:56     ` Vinod Koul
  0 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-26 10:56 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 11, 2015 at 03:23:26PM +0200, Peter Ujfalusi wrote:
> The DRA7x has more peripherals with DMA requests than the sDMA can handle:
> 205 vs 127. All DMA requests are routed through the DMA crossbar, which can
> be configured to route selected incoming DMA requests to specific sDMA
> request.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  drivers/dma/Kconfig           |   4 +
>  drivers/dma/Makefile          |   1 +
>  drivers/dma/ti-dma-crossbar.c | 190 ++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 195 insertions(+)
>  create mode 100644 drivers/dma/ti-dma-crossbar.c
> 
> diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
> index 074ffad334a7..519657a37ca1 100644
> --- a/drivers/dma/Kconfig
> +++ b/drivers/dma/Kconfig
> @@ -247,6 +247,9 @@ config TI_EDMA
>  	  Enable support for the TI EDMA controller. This DMA
>  	  engine is found on TI DaVinci and AM33xx parts.
>  
> +config TI_DMA_CROSSBAR
> +	bool
> +
>  config ARCH_HAS_ASYNC_TX_FIND_CHANNEL
>  	bool
>  
> @@ -332,6 +335,7 @@ config DMA_OMAP
>  	depends on ARCH_OMAP
>  	select DMA_ENGINE
>  	select DMA_VIRTUAL_CHANNELS
> +	select TI_DMA_CROSSBAR if SOC_DRA7XX
>  
>  config DMA_BCM2835
>  	tristate "BCM2835 DMA engine support"
> diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
> index bf4485800c60..6ec7af6a416c 100644
> --- a/drivers/dma/Makefile
> +++ b/drivers/dma/Makefile
> @@ -39,6 +39,7 @@ obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
>  obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
>  obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
>  obj-$(CONFIG_DMA_OMAP) += omap-dma.o
> +obj-$(CONFIG_TI_DMA_CROSSBAR) += ti-dma-crossbar.o
>  obj-$(CONFIG_DMA_BCM2835) += bcm2835-dma.o
>  obj-$(CONFIG_MMP_PDMA) += mmp_pdma.o
>  obj-$(CONFIG_DMA_JZ4740) += dma-jz4740.o
> diff --git a/drivers/dma/ti-dma-crossbar.c b/drivers/dma/ti-dma-crossbar.c
> new file mode 100644
> index 000000000000..591307bd4370
> --- /dev/null
> +++ b/drivers/dma/ti-dma-crossbar.c
> @@ -0,0 +1,190 @@
> +/*
> + *  Copyright (C) 2015 Texas Instruments Incorporated - http://www.ti.com
> + *  Author: Peter Ujfalusi <peter.ujfalusi@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.
> + *
> + */
> +#include <linux/slab.h>
> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/list.h>
> +#include <linux/io.h>
> +#include <linux/regmap.h>
> +#include <linux/idr.h>
> +#include <linux/of_address.h>
> +#include <linux/of_device.h>
> +#include <linux/of_dma.h>
> +
> +#define TI_XBAR_OUTPUTS	127
> +#define TI_XBAR_INPUTS	256
Ideally this should be moved to DT. Will next revision of this chip always
support these output and inputs?

> +
> +static DEFINE_IDR(map_idr);
> +
> +struct ti_dma_xbar_data {
> +	struct dma_router dmarouter;
> +	struct regmap *regmap;
> +
> +	uint safe_val; /* Value to rest the crossbar lines */
> +	uint xbar_requests; /* number of DMA requests connected to XBAR */
> +	uint dma_requests; /* number of DMA requests forwarded to DMA */
> +
> +	void __iomem *iomem;
> +};
> +
> +struct ti_dma_xbar_map {
> +	int xbar_in;
> +	int xbar_out;
> +};
> +
> +static void ti_dma_xbar_free(struct device *dev, void *route_data)
> +{
> +	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
> +	struct ti_dma_xbar_map *map = route_data;
> +
> +	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
> +		map->xbar_in, map->xbar_out);
> +
> +	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
just out of curiosity how much do you save using regmap :)

> +static int ti_dma_xbar_probe(struct platform_device *pdev)
> +{
> +	struct device_node *node = pdev->dev.of_node;
> +	struct device_node *dma_node;
> +	struct ti_dma_xbar_data *xbar;
> +	struct resource *res;
> +	void __iomem *iomem;
> +	int i, ret;
> +
> +	if (!node)
> +		return -ENODEV;
> +
> +	dma_node = of_parse_phandle(node, "dma-device", 0);
> +	if (!dma_node) {
> +		dev_err(&pdev->dev, "Can't get target DMA node\n");
> +		return -ENODEV;
> +	}
> +
> +	xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL);
> +	if (!xbar)
> +		return -ENOMEM;
> +
> +	if (of_property_read_u32(dma_node, "dma-requests",
> +				 &xbar->dma_requests)) {
> +		dev_info(&pdev->dev,
> +			 "Missing XBAR output information, using %u.\n",
> +			 TI_XBAR_OUTPUTS);
> +		xbar->dma_requests = TI_XBAR_OUTPUTS;
> +	}
> +	of_node_put(dma_node);
_put here?

> +int omap_dmaxbar_init(void)
> +{
> +	return platform_driver_register(&ti_dma_xbar_driver);
> +}
> +arch_initcall(omap_dmaxbar_init);
why arch_initcall?

-- 
~Vinod

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 4/7] dmaengine: omap-dma: Use defines for dma channels and request count
  2015-03-11 13:23   ` Peter Ujfalusi
@ 2015-03-26 10:57     ` Vinod Koul
  -1 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-26 10:57 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On Wed, Mar 11, 2015 at 03:23:27PM +0200, Peter Ujfalusi wrote:
> Instead of magic numbers in the code, use define for number of logical DMA
> channels and DMA requests.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  drivers/dma/omap-dma.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
> index 7dd6dd121681..56c33e93dd24 100644
> --- a/drivers/dma/omap-dma.c
> +++ b/drivers/dma/omap-dma.c
> @@ -22,6 +22,9 @@
>  
>  #include "virt-dma.h"
>  
> +#define OMAP_SDMA_REQUESTS	127
> +#define OMAP_SDMA_CHANNELS	32
Again why dont we put these things in DT ?

-- 
~Vinod
> +
>  struct omap_dmadev {
>  	struct dma_device ddev;
>  	spinlock_t lock;
> @@ -33,7 +36,7 @@ struct omap_dmadev {
>  	bool legacy;
>  	spinlock_t irq_lock;
>  	uint32_t irq_enable_mask;
> -	struct omap_chan *lch_map[32];
> +	struct omap_chan *lch_map[OMAP_SDMA_CHANNELS];
>  };
>  
>  struct omap_chan {
> @@ -1115,7 +1118,7 @@ static int omap_dma_probe(struct platform_device *pdev)
>  
>  	tasklet_init(&od->task, omap_dma_sched, (unsigned long)od);
>  
> -	for (i = 0; i < 127; i++) {
> +	for (i = 0; i < OMAP_SDMA_REQUESTS; i++) {
>  		rc = omap_dma_chan_init(od, i);
>  		if (rc) {
>  			omap_dma_free(od);
> -- 
> 2.3.0
> 

-- 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 4/7] dmaengine: omap-dma: Use defines for dma channels and request count
@ 2015-03-26 10:57     ` Vinod Koul
  0 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-26 10:57 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Mar 11, 2015 at 03:23:27PM +0200, Peter Ujfalusi wrote:
> Instead of magic numbers in the code, use define for number of logical DMA
> channels and DMA requests.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  drivers/dma/omap-dma.c | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
> index 7dd6dd121681..56c33e93dd24 100644
> --- a/drivers/dma/omap-dma.c
> +++ b/drivers/dma/omap-dma.c
> @@ -22,6 +22,9 @@
>  
>  #include "virt-dma.h"
>  
> +#define OMAP_SDMA_REQUESTS	127
> +#define OMAP_SDMA_CHANNELS	32
Again why dont we put these things in DT ?

-- 
~Vinod
> +
>  struct omap_dmadev {
>  	struct dma_device ddev;
>  	spinlock_t lock;
> @@ -33,7 +36,7 @@ struct omap_dmadev {
>  	bool legacy;
>  	spinlock_t irq_lock;
>  	uint32_t irq_enable_mask;
> -	struct omap_chan *lch_map[32];
> +	struct omap_chan *lch_map[OMAP_SDMA_CHANNELS];
>  };
>  
>  struct omap_chan {
> @@ -1115,7 +1118,7 @@ static int omap_dma_probe(struct platform_device *pdev)
>  
>  	tasklet_init(&od->task, omap_dma_sched, (unsigned long)od);
>  
> -	for (i = 0; i < 127; i++) {
> +	for (i = 0; i < OMAP_SDMA_REQUESTS; i++) {
>  		rc = omap_dma_chan_init(od, i);
>  		if (rc) {
>  			omap_dma_free(od);
> -- 
> 2.3.0
> 

-- 

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
  2015-03-26 10:50     ` Vinod Koul
  (?)
@ 2015-03-26 12:11       ` Peter Ujfalusi
  -1 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-26 12:11 UTC (permalink / raw)
  To: Vinod Koul
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On 03/26/2015 12:50 PM, Vinod Koul wrote:
> On Wed, Mar 11, 2015 at 03:23:24PM +0200, Peter Ujfalusi wrote:
>> DMA routers are transparent devices used to mux DMA requests from
>> peripherals to DMA controllers. They are used when the SoC integrates more
>> devices with DMA requests then their controller can handle.
>> DRA7x is one example of such SoC, where the sDMA can hanlde 128 DMA request
>> lines, but in SoC level it has 205 DMA requests.
>>
>> The of_dma_router will be registered as of_dma_controller with special
>> xlate function and additional parameters and the code will translate and
>> requests a DMA channel from the real DMA controller.
>> This way the router can be transparent for the system while remaining generic
>> enough to be used in different environments.
>>
> Looks fine, was expecting a Documentation updates as well, but that can come
> as follow up patch too

I have added the DT binding document since this series adds support for
routers for platforms booting with DT:

Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++

-- 
Péter

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
@ 2015-03-26 12:11       ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-26 12:11 UTC (permalink / raw)
  To: Vinod Koul
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On 03/26/2015 12:50 PM, Vinod Koul wrote:
> On Wed, Mar 11, 2015 at 03:23:24PM +0200, Peter Ujfalusi wrote:
>> DMA routers are transparent devices used to mux DMA requests from
>> peripherals to DMA controllers. They are used when the SoC integrates more
>> devices with DMA requests then their controller can handle.
>> DRA7x is one example of such SoC, where the sDMA can hanlde 128 DMA request
>> lines, but in SoC level it has 205 DMA requests.
>>
>> The of_dma_router will be registered as of_dma_controller with special
>> xlate function and additional parameters and the code will translate and
>> requests a DMA channel from the real DMA controller.
>> This way the router can be transparent for the system while remaining generic
>> enough to be used in different environments.
>>
> Looks fine, was expecting a Documentation updates as well, but that can come
> as follow up patch too

I have added the DT binding document since this series adds support for
routers for platforms booting with DT:

Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++

-- 
Péter

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
@ 2015-03-26 12:11       ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-26 12:11 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/26/2015 12:50 PM, Vinod Koul wrote:
> On Wed, Mar 11, 2015 at 03:23:24PM +0200, Peter Ujfalusi wrote:
>> DMA routers are transparent devices used to mux DMA requests from
>> peripherals to DMA controllers. They are used when the SoC integrates more
>> devices with DMA requests then their controller can handle.
>> DRA7x is one example of such SoC, where the sDMA can hanlde 128 DMA request
>> lines, but in SoC level it has 205 DMA requests.
>>
>> The of_dma_router will be registered as of_dma_controller with special
>> xlate function and additional parameters and the code will translate and
>> requests a DMA channel from the real DMA controller.
>> This way the router can be transparent for the system while remaining generic
>> enough to be used in different environments.
>>
> Looks fine, was expecting a Documentation updates as well, but that can come
> as follow up patch too

I have added the DT binding document since this series adds support for
routers for platforms booting with DT:

Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++

-- 
P?ter

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
  2015-03-26 10:56     ` Vinod Koul
  (?)
@ 2015-03-26 12:31       ` Peter Ujfalusi
  -1 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-26 12:31 UTC (permalink / raw)
  To: Vinod Koul
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On 03/26/2015 12:56 PM, Vinod Koul wrote:
>> +#define TI_XBAR_OUTPUTS	127
>> +#define TI_XBAR_INPUTS	256
> Ideally this should be moved to DT. Will next revision of this chip always
> support these output and inputs?

They are coming from DT. I'm using these as fall back values in case we can
not get this from DT and a warning will be printed in case if this unlikely
event happens.

>> +
>> +static DEFINE_IDR(map_idr);
>> +
>> +struct ti_dma_xbar_data {
>> +	struct dma_router dmarouter;
>> +	struct regmap *regmap;
>> +
>> +	uint safe_val; /* Value to rest the crossbar lines */
>> +	uint xbar_requests; /* number of DMA requests connected to XBAR */
>> +	uint dma_requests; /* number of DMA requests forwarded to DMA */
>> +
>> +	void __iomem *iomem;
>> +};
>> +
>> +struct ti_dma_xbar_map {
>> +	int xbar_in;
>> +	int xbar_out;
>> +};
>> +
>> +static void ti_dma_xbar_free(struct device *dev, void *route_data)
>> +{
>> +	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
>> +	struct ti_dma_xbar_map *map = route_data;
>> +
>> +	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
>> +		map->xbar_in, map->xbar_out);
>> +
>> +	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
> just out of curiosity how much do you save using regmap :)

good point, not much I guess. I had it implemented w/o regmap as well, but
thought why not use regmap if it is available.

>> +static int ti_dma_xbar_probe(struct platform_device *pdev)
>> +{
>> +	struct device_node *node = pdev->dev.of_node;
>> +	struct device_node *dma_node;
>> +	struct ti_dma_xbar_data *xbar;
>> +	struct resource *res;
>> +	void __iomem *iomem;
>> +	int i, ret;
>> +
>> +	if (!node)
>> +		return -ENODEV;
>> +
>> +	dma_node = of_parse_phandle(node, "dma-device", 0);
>> +	if (!dma_node) {
>> +		dev_err(&pdev->dev, "Can't get target DMA node\n");
>> +		return -ENODEV;
>> +	}
>> +
>> +	xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL);
>> +	if (!xbar)
>> +		return -ENOMEM;
>> +
>> +	if (of_property_read_u32(dma_node, "dma-requests",
>> +				 &xbar->dma_requests)) {
>> +		dev_info(&pdev->dev,
>> +			 "Missing XBAR output information, using %u.\n",
>> +			 TI_XBAR_OUTPUTS);
>> +		xbar->dma_requests = TI_XBAR_OUTPUTS;
>> +	}
>> +	of_node_put(dma_node);
> _put here?

The code takes the real dma controller's node and it should be put back after
I have got the information I needed from it (number of DMA requests).

> 
>> +int omap_dmaxbar_init(void)
>> +{
>> +	return platform_driver_register(&ti_dma_xbar_driver);
>> +}
>> +arch_initcall(omap_dmaxbar_init);
> why arch_initcall?

It should be on the same init level as the real DMA controller. omap-dma at
the moment, but in some platforms this can work with the edma as well.
Since all device in the system (well most of them anyway) uses DMA it is
better to not delay their probe with deferring because the crossbar driver is
still not loaded

-- 
Péter

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
@ 2015-03-26 12:31       ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-26 12:31 UTC (permalink / raw)
  To: Vinod Koul
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On 03/26/2015 12:56 PM, Vinod Koul wrote:
>> +#define TI_XBAR_OUTPUTS	127
>> +#define TI_XBAR_INPUTS	256
> Ideally this should be moved to DT. Will next revision of this chip always
> support these output and inputs?

They are coming from DT. I'm using these as fall back values in case we can
not get this from DT and a warning will be printed in case if this unlikely
event happens.

>> +
>> +static DEFINE_IDR(map_idr);
>> +
>> +struct ti_dma_xbar_data {
>> +	struct dma_router dmarouter;
>> +	struct regmap *regmap;
>> +
>> +	uint safe_val; /* Value to rest the crossbar lines */
>> +	uint xbar_requests; /* number of DMA requests connected to XBAR */
>> +	uint dma_requests; /* number of DMA requests forwarded to DMA */
>> +
>> +	void __iomem *iomem;
>> +};
>> +
>> +struct ti_dma_xbar_map {
>> +	int xbar_in;
>> +	int xbar_out;
>> +};
>> +
>> +static void ti_dma_xbar_free(struct device *dev, void *route_data)
>> +{
>> +	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
>> +	struct ti_dma_xbar_map *map = route_data;
>> +
>> +	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
>> +		map->xbar_in, map->xbar_out);
>> +
>> +	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
> just out of curiosity how much do you save using regmap :)

good point, not much I guess. I had it implemented w/o regmap as well, but
thought why not use regmap if it is available.

>> +static int ti_dma_xbar_probe(struct platform_device *pdev)
>> +{
>> +	struct device_node *node = pdev->dev.of_node;
>> +	struct device_node *dma_node;
>> +	struct ti_dma_xbar_data *xbar;
>> +	struct resource *res;
>> +	void __iomem *iomem;
>> +	int i, ret;
>> +
>> +	if (!node)
>> +		return -ENODEV;
>> +
>> +	dma_node = of_parse_phandle(node, "dma-device", 0);
>> +	if (!dma_node) {
>> +		dev_err(&pdev->dev, "Can't get target DMA node\n");
>> +		return -ENODEV;
>> +	}
>> +
>> +	xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL);
>> +	if (!xbar)
>> +		return -ENOMEM;
>> +
>> +	if (of_property_read_u32(dma_node, "dma-requests",
>> +				 &xbar->dma_requests)) {
>> +		dev_info(&pdev->dev,
>> +			 "Missing XBAR output information, using %u.\n",
>> +			 TI_XBAR_OUTPUTS);
>> +		xbar->dma_requests = TI_XBAR_OUTPUTS;
>> +	}
>> +	of_node_put(dma_node);
> _put here?

The code takes the real dma controller's node and it should be put back after
I have got the information I needed from it (number of DMA requests).

> 
>> +int omap_dmaxbar_init(void)
>> +{
>> +	return platform_driver_register(&ti_dma_xbar_driver);
>> +}
>> +arch_initcall(omap_dmaxbar_init);
> why arch_initcall?

It should be on the same init level as the real DMA controller. omap-dma at
the moment, but in some platforms this can work with the edma as well.
Since all device in the system (well most of them anyway) uses DMA it is
better to not delay their probe with deferring because the crossbar driver is
still not loaded

-- 
Péter
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
@ 2015-03-26 12:31       ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-26 12:31 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/26/2015 12:56 PM, Vinod Koul wrote:
>> +#define TI_XBAR_OUTPUTS	127
>> +#define TI_XBAR_INPUTS	256
> Ideally this should be moved to DT. Will next revision of this chip always
> support these output and inputs?

They are coming from DT. I'm using these as fall back values in case we can
not get this from DT and a warning will be printed in case if this unlikely
event happens.

>> +
>> +static DEFINE_IDR(map_idr);
>> +
>> +struct ti_dma_xbar_data {
>> +	struct dma_router dmarouter;
>> +	struct regmap *regmap;
>> +
>> +	uint safe_val; /* Value to rest the crossbar lines */
>> +	uint xbar_requests; /* number of DMA requests connected to XBAR */
>> +	uint dma_requests; /* number of DMA requests forwarded to DMA */
>> +
>> +	void __iomem *iomem;
>> +};
>> +
>> +struct ti_dma_xbar_map {
>> +	int xbar_in;
>> +	int xbar_out;
>> +};
>> +
>> +static void ti_dma_xbar_free(struct device *dev, void *route_data)
>> +{
>> +	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
>> +	struct ti_dma_xbar_map *map = route_data;
>> +
>> +	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
>> +		map->xbar_in, map->xbar_out);
>> +
>> +	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
> just out of curiosity how much do you save using regmap :)

good point, not much I guess. I had it implemented w/o regmap as well, but
thought why not use regmap if it is available.

>> +static int ti_dma_xbar_probe(struct platform_device *pdev)
>> +{
>> +	struct device_node *node = pdev->dev.of_node;
>> +	struct device_node *dma_node;
>> +	struct ti_dma_xbar_data *xbar;
>> +	struct resource *res;
>> +	void __iomem *iomem;
>> +	int i, ret;
>> +
>> +	if (!node)
>> +		return -ENODEV;
>> +
>> +	dma_node = of_parse_phandle(node, "dma-device", 0);
>> +	if (!dma_node) {
>> +		dev_err(&pdev->dev, "Can't get target DMA node\n");
>> +		return -ENODEV;
>> +	}
>> +
>> +	xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL);
>> +	if (!xbar)
>> +		return -ENOMEM;
>> +
>> +	if (of_property_read_u32(dma_node, "dma-requests",
>> +				 &xbar->dma_requests)) {
>> +		dev_info(&pdev->dev,
>> +			 "Missing XBAR output information, using %u.\n",
>> +			 TI_XBAR_OUTPUTS);
>> +		xbar->dma_requests = TI_XBAR_OUTPUTS;
>> +	}
>> +	of_node_put(dma_node);
> _put here?

The code takes the real dma controller's node and it should be put back after
I have got the information I needed from it (number of DMA requests).

> 
>> +int omap_dmaxbar_init(void)
>> +{
>> +	return platform_driver_register(&ti_dma_xbar_driver);
>> +}
>> +arch_initcall(omap_dmaxbar_init);
> why arch_initcall?

It should be on the same init level as the real DMA controller. omap-dma at
the moment, but in some platforms this can work with the edma as well.
Since all device in the system (well most of them anyway) uses DMA it is
better to not delay their probe with deferring because the crossbar driver is
still not loaded

-- 
P?ter

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 4/7] dmaengine: omap-dma: Use defines for dma channels and request count
  2015-03-26 10:57     ` Vinod Koul
  (?)
@ 2015-03-26 12:32       ` Peter Ujfalusi
  -1 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-26 12:32 UTC (permalink / raw)
  To: Vinod Koul
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On 03/26/2015 12:57 PM, Vinod Koul wrote:
> On Wed, Mar 11, 2015 at 03:23:27PM +0200, Peter Ujfalusi wrote:
>> Instead of magic numbers in the code, use define for number of logical DMA
>> channels and DMA requests.
>>
>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
>> ---
>>  drivers/dma/omap-dma.c | 7 +++++--
>>  1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
>> index 7dd6dd121681..56c33e93dd24 100644
>> --- a/drivers/dma/omap-dma.c
>> +++ b/drivers/dma/omap-dma.c
>> @@ -22,6 +22,9 @@
>>  
>>  #include "virt-dma.h"
>>  
>> +#define OMAP_SDMA_REQUESTS	127
>> +#define OMAP_SDMA_CHANNELS	32
> Again why dont we put these things in DT ?

They are in DT, the next patch will take the needed information from there and
uses these values as fallback values in case they are missing for some reason.

-- 
Péter

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 4/7] dmaengine: omap-dma: Use defines for dma channels and request count
@ 2015-03-26 12:32       ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-26 12:32 UTC (permalink / raw)
  To: Vinod Koul
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On 03/26/2015 12:57 PM, Vinod Koul wrote:
> On Wed, Mar 11, 2015 at 03:23:27PM +0200, Peter Ujfalusi wrote:
>> Instead of magic numbers in the code, use define for number of logical DMA
>> channels and DMA requests.
>>
>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
>> ---
>>  drivers/dma/omap-dma.c | 7 +++++--
>>  1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
>> index 7dd6dd121681..56c33e93dd24 100644
>> --- a/drivers/dma/omap-dma.c
>> +++ b/drivers/dma/omap-dma.c
>> @@ -22,6 +22,9 @@
>>  
>>  #include "virt-dma.h"
>>  
>> +#define OMAP_SDMA_REQUESTS	127
>> +#define OMAP_SDMA_CHANNELS	32
> Again why dont we put these things in DT ?

They are in DT, the next patch will take the needed information from there and
uses these values as fallback values in case they are missing for some reason.

-- 
Péter
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 4/7] dmaengine: omap-dma: Use defines for dma channels and request count
@ 2015-03-26 12:32       ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-26 12:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/26/2015 12:57 PM, Vinod Koul wrote:
> On Wed, Mar 11, 2015 at 03:23:27PM +0200, Peter Ujfalusi wrote:
>> Instead of magic numbers in the code, use define for number of logical DMA
>> channels and DMA requests.
>>
>> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
>> ---
>>  drivers/dma/omap-dma.c | 7 +++++--
>>  1 file changed, 5 insertions(+), 2 deletions(-)
>>
>> diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
>> index 7dd6dd121681..56c33e93dd24 100644
>> --- a/drivers/dma/omap-dma.c
>> +++ b/drivers/dma/omap-dma.c
>> @@ -22,6 +22,9 @@
>>  
>>  #include "virt-dma.h"
>>  
>> +#define OMAP_SDMA_REQUESTS	127
>> +#define OMAP_SDMA_CHANNELS	32
> Again why dont we put these things in DT ?

They are in DT, the next patch will take the needed information from there and
uses these values as fallback values in case they are missing for some reason.

-- 
P?ter

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
@ 2015-03-26 15:22         ` Tony Lindgren
  0 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2015-03-26 15:22 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: Vinod Koul, linux, grant.likely, dmaengine, linux-kernel,
	devicetree, linux-omap, linux-arm-kernel, robh+dt, nm

* Peter Ujfalusi <peter.ujfalusi@ti.com> [150326 05:32]:
> On 03/26/2015 12:56 PM, Vinod Koul wrote:
> >> +
> >> +static void ti_dma_xbar_free(struct device *dev, void *route_data)
> >> +{
> >> +	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
> >> +	struct ti_dma_xbar_map *map = route_data;
> >> +
> >> +	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
> >> +		map->xbar_in, map->xbar_out);
> >> +
> >> +	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
> > just out of curiosity how much do you save using regmap :)
> 
> good point, not much I guess. I had it implemented w/o regmap as well, but
> thought why not use regmap if it is available.

Regmap is nice for slow devices and devices in a shared register
range like the omap syscon general area. For normal use, there's
quite a bit of overhead with regmap compared to just read/write :)

Regards,

Tony

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
@ 2015-03-26 15:22         ` Tony Lindgren
  0 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2015-03-26 15:22 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: Vinod Koul, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, nm-l0cyMroinI0

* Peter Ujfalusi <peter.ujfalusi-l0cyMroinI0@public.gmane.org> [150326 05:32]:
> On 03/26/2015 12:56 PM, Vinod Koul wrote:
> >> +
> >> +static void ti_dma_xbar_free(struct device *dev, void *route_data)
> >> +{
> >> +	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
> >> +	struct ti_dma_xbar_map *map = route_data;
> >> +
> >> +	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
> >> +		map->xbar_in, map->xbar_out);
> >> +
> >> +	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
> > just out of curiosity how much do you save using regmap :)
> 
> good point, not much I guess. I had it implemented w/o regmap as well, but
> thought why not use regmap if it is available.

Regmap is nice for slow devices and devices in a shared register
range like the omap syscon general area. For normal use, there's
quite a bit of overhead with regmap compared to just read/write :)

Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
@ 2015-03-26 15:22         ` Tony Lindgren
  0 siblings, 0 replies; 54+ messages in thread
From: Tony Lindgren @ 2015-03-26 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

* Peter Ujfalusi <peter.ujfalusi@ti.com> [150326 05:32]:
> On 03/26/2015 12:56 PM, Vinod Koul wrote:
> >> +
> >> +static void ti_dma_xbar_free(struct device *dev, void *route_data)
> >> +{
> >> +	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
> >> +	struct ti_dma_xbar_map *map = route_data;
> >> +
> >> +	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
> >> +		map->xbar_in, map->xbar_out);
> >> +
> >> +	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
> > just out of curiosity how much do you save using regmap :)
> 
> good point, not much I guess. I had it implemented w/o regmap as well, but
> thought why not use regmap if it is available.

Regmap is nice for slow devices and devices in a shared register
range like the omap syscon general area. For normal use, there's
quite a bit of overhead with regmap compared to just read/write :)

Regards,

Tony

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
  2015-03-26 12:11       ` Peter Ujfalusi
@ 2015-03-26 15:32         ` Vinod Koul
  -1 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-26 15:32 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On Thu, Mar 26, 2015 at 02:11:38PM +0200, Peter Ujfalusi wrote:
> On 03/26/2015 12:50 PM, Vinod Koul wrote:
> > On Wed, Mar 11, 2015 at 03:23:24PM +0200, Peter Ujfalusi wrote:
> >> DMA routers are transparent devices used to mux DMA requests from
> >> peripherals to DMA controllers. They are used when the SoC integrates more
> >> devices with DMA requests then their controller can handle.
> >> DRA7x is one example of such SoC, where the sDMA can hanlde 128 DMA request
> >> lines, but in SoC level it has 205 DMA requests.
> >>
> >> The of_dma_router will be registered as of_dma_controller with special
> >> xlate function and additional parameters and the code will translate and
> >> requests a DMA channel from the real DMA controller.
> >> This way the router can be transparent for the system while remaining generic
> >> enough to be used in different environments.
> >>
> > Looks fine, was expecting a Documentation updates as well, but that can come
> > as follow up patch too
> 
> I have added the DT binding document since this series adds support for
> routers for platforms booting with DT:
> 
> Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
I meant the update to Documnetation/dmanegine/ for routers :)

-- 
~Vinod

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
@ 2015-03-26 15:32         ` Vinod Koul
  0 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-26 15:32 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 26, 2015 at 02:11:38PM +0200, Peter Ujfalusi wrote:
> On 03/26/2015 12:50 PM, Vinod Koul wrote:
> > On Wed, Mar 11, 2015 at 03:23:24PM +0200, Peter Ujfalusi wrote:
> >> DMA routers are transparent devices used to mux DMA requests from
> >> peripherals to DMA controllers. They are used when the SoC integrates more
> >> devices with DMA requests then their controller can handle.
> >> DRA7x is one example of such SoC, where the sDMA can hanlde 128 DMA request
> >> lines, but in SoC level it has 205 DMA requests.
> >>
> >> The of_dma_router will be registered as of_dma_controller with special
> >> xlate function and additional parameters and the code will translate and
> >> requests a DMA channel from the real DMA controller.
> >> This way the router can be transparent for the system while remaining generic
> >> enough to be used in different environments.
> >>
> > Looks fine, was expecting a Documentation updates as well, but that can come
> > as follow up patch too
> 
> I have added the DT binding document since this series adds support for
> routers for platforms booting with DT:
> 
> Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
I meant the update to Documnetation/dmanegine/ for routers :)

-- 
~Vinod

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
  2015-03-26 12:31       ` Peter Ujfalusi
@ 2015-03-26 15:37         ` Vinod Koul
  -1 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-26 15:37 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On Thu, Mar 26, 2015 at 02:31:30PM +0200, Peter Ujfalusi wrote:
> On 03/26/2015 12:56 PM, Vinod Koul wrote:
> >> +#define TI_XBAR_OUTPUTS	127
> >> +#define TI_XBAR_INPUTS	256
> > Ideally this should be moved to DT. Will next revision of this chip always
> > support these output and inputs?
> 
> They are coming from DT. I'm using these as fall back values in case we can
> not get this from DT and a warning will be printed in case if this unlikely
> event happens.
Oops missed, that. Looks fine then

> 
> >> +
> >> +static DEFINE_IDR(map_idr);
> >> +
> >> +struct ti_dma_xbar_data {
> >> +	struct dma_router dmarouter;
> >> +	struct regmap *regmap;
> >> +
> >> +	uint safe_val; /* Value to rest the crossbar lines */
> >> +	uint xbar_requests; /* number of DMA requests connected to XBAR */
> >> +	uint dma_requests; /* number of DMA requests forwarded to DMA */
> >> +
> >> +	void __iomem *iomem;
> >> +};
> >> +
> >> +struct ti_dma_xbar_map {
> >> +	int xbar_in;
> >> +	int xbar_out;
> >> +};
> >> +
> >> +static void ti_dma_xbar_free(struct device *dev, void *route_data)
> >> +{
> >> +	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
> >> +	struct ti_dma_xbar_map *map = route_data;
> >> +
> >> +	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
> >> +		map->xbar_in, map->xbar_out);
> >> +
> >> +	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
> > just out of curiosity how much do you save using regmap :)
> 
> good point, not much I guess. I had it implemented w/o regmap as well, but
> thought why not use regmap if it is available.
Yes but there is overhead involved in setting it up. I though you have some
latency issues. It is okay to have it :)
Cache is anyways fastest :)

> >> +static int ti_dma_xbar_probe(struct platform_device *pdev)
> >> +{
> >> +	struct device_node *node = pdev->dev.of_node;
> >> +	struct device_node *dma_node;
> >> +	struct ti_dma_xbar_data *xbar;
> >> +	struct resource *res;
> >> +	void __iomem *iomem;
> >> +	int i, ret;
> >> +
> >> +	if (!node)
> >> +		return -ENODEV;
> >> +
> >> +	dma_node = of_parse_phandle(node, "dma-device", 0);
> >> +	if (!dma_node) {
> >> +		dev_err(&pdev->dev, "Can't get target DMA node\n");
> >> +		return -ENODEV;
> >> +	}
> >> +
> >> +	xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL);
> >> +	if (!xbar)
> >> +		return -ENOMEM;
> >> +
> >> +	if (of_property_read_u32(dma_node, "dma-requests",
> >> +				 &xbar->dma_requests)) {
> >> +		dev_info(&pdev->dev,
> >> +			 "Missing XBAR output information, using %u.\n",
> >> +			 TI_XBAR_OUTPUTS);
> >> +		xbar->dma_requests = TI_XBAR_OUTPUTS;
> >> +	}
> >> +	of_node_put(dma_node);
> > _put here?
> 
> The code takes the real dma controller's node and it should be put back after
> I have got the information I needed from it (number of DMA requests).
> 
> > 
> >> +int omap_dmaxbar_init(void)
> >> +{
> >> +	return platform_driver_register(&ti_dma_xbar_driver);
> >> +}
> >> +arch_initcall(omap_dmaxbar_init);
> > why arch_initcall?
> 
> It should be on the same init level as the real DMA controller. omap-dma at
> the moment, but in some platforms this can work with the edma as well.
> Since all device in the system (well most of them anyway) uses DMA it is
> better to not delay their probe with deferring because the crossbar driver is
> still not loaded
Deferring if resources not available is the right thing and helps you get rid
of init level ordering magic...

-- 
~Vinod


^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x
@ 2015-03-26 15:37         ` Vinod Koul
  0 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-26 15:37 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Mar 26, 2015 at 02:31:30PM +0200, Peter Ujfalusi wrote:
> On 03/26/2015 12:56 PM, Vinod Koul wrote:
> >> +#define TI_XBAR_OUTPUTS	127
> >> +#define TI_XBAR_INPUTS	256
> > Ideally this should be moved to DT. Will next revision of this chip always
> > support these output and inputs?
> 
> They are coming from DT. I'm using these as fall back values in case we can
> not get this from DT and a warning will be printed in case if this unlikely
> event happens.
Oops missed, that. Looks fine then

> 
> >> +
> >> +static DEFINE_IDR(map_idr);
> >> +
> >> +struct ti_dma_xbar_data {
> >> +	struct dma_router dmarouter;
> >> +	struct regmap *regmap;
> >> +
> >> +	uint safe_val; /* Value to rest the crossbar lines */
> >> +	uint xbar_requests; /* number of DMA requests connected to XBAR */
> >> +	uint dma_requests; /* number of DMA requests forwarded to DMA */
> >> +
> >> +	void __iomem *iomem;
> >> +};
> >> +
> >> +struct ti_dma_xbar_map {
> >> +	int xbar_in;
> >> +	int xbar_out;
> >> +};
> >> +
> >> +static void ti_dma_xbar_free(struct device *dev, void *route_data)
> >> +{
> >> +	struct ti_dma_xbar_data *xbar = dev_get_drvdata(dev);
> >> +	struct ti_dma_xbar_map *map = route_data;
> >> +
> >> +	dev_dbg(dev, "Unmapping XBAR%d (was routed to %d)\n",
> >> +		map->xbar_in, map->xbar_out);
> >> +
> >> +	regmap_write(xbar->regmap, map->xbar_out * 2, 0);
> > just out of curiosity how much do you save using regmap :)
> 
> good point, not much I guess. I had it implemented w/o regmap as well, but
> thought why not use regmap if it is available.
Yes but there is overhead involved in setting it up. I though you have some
latency issues. It is okay to have it :)
Cache is anyways fastest :)

> >> +static int ti_dma_xbar_probe(struct platform_device *pdev)
> >> +{
> >> +	struct device_node *node = pdev->dev.of_node;
> >> +	struct device_node *dma_node;
> >> +	struct ti_dma_xbar_data *xbar;
> >> +	struct resource *res;
> >> +	void __iomem *iomem;
> >> +	int i, ret;
> >> +
> >> +	if (!node)
> >> +		return -ENODEV;
> >> +
> >> +	dma_node = of_parse_phandle(node, "dma-device", 0);
> >> +	if (!dma_node) {
> >> +		dev_err(&pdev->dev, "Can't get target DMA node\n");
> >> +		return -ENODEV;
> >> +	}
> >> +
> >> +	xbar = devm_kzalloc(&pdev->dev, sizeof(*xbar), GFP_KERNEL);
> >> +	if (!xbar)
> >> +		return -ENOMEM;
> >> +
> >> +	if (of_property_read_u32(dma_node, "dma-requests",
> >> +				 &xbar->dma_requests)) {
> >> +		dev_info(&pdev->dev,
> >> +			 "Missing XBAR output information, using %u.\n",
> >> +			 TI_XBAR_OUTPUTS);
> >> +		xbar->dma_requests = TI_XBAR_OUTPUTS;
> >> +	}
> >> +	of_node_put(dma_node);
> > _put here?
> 
> The code takes the real dma controller's node and it should be put back after
> I have got the information I needed from it (number of DMA requests).
> 
> > 
> >> +int omap_dmaxbar_init(void)
> >> +{
> >> +	return platform_driver_register(&ti_dma_xbar_driver);
> >> +}
> >> +arch_initcall(omap_dmaxbar_init);
> > why arch_initcall?
> 
> It should be on the same init level as the real DMA controller. omap-dma at
> the moment, but in some platforms this can work with the edma as well.
> Since all device in the system (well most of them anyway) uses DMA it is
> better to not delay their probe with deferring because the crossbar driver is
> still not loaded
Deferring if resources not available is the right thing and helps you get rid
of init level ordering magic...

-- 
~Vinod

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
  2015-03-26 15:32         ` Vinod Koul
  (?)
@ 2015-03-27 12:25           ` Peter Ujfalusi
  -1 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-27 12:25 UTC (permalink / raw)
  To: Vinod Koul
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On 03/26/2015 05:32 PM, Vinod Koul wrote:
>> I have added the DT binding document since this series adds support for
>> routers for platforms booting with DT:
>>
>> Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
> I meant the update to Documnetation/dmanegine/ for routers :)

I see. In what form you think we should have the documentation? Is it adequate
to lift and adjust the text from the DT binding document here? Should we have
a separate file for the router description?
My concern was and this is why I did not wrote anything under here is that the
code I add is only covers the DT boot case and I'm not planning to add legacy
support. The ACPI binding can be done in a similar fashion as the DT so you
would have a translator driver with ACPI API.

-- 
Péter

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
@ 2015-03-27 12:25           ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-27 12:25 UTC (permalink / raw)
  To: Vinod Koul
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On 03/26/2015 05:32 PM, Vinod Koul wrote:
>> I have added the DT binding document since this series adds support for
>> routers for platforms booting with DT:
>>
>> Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
> I meant the update to Documnetation/dmanegine/ for routers :)

I see. In what form you think we should have the documentation? Is it adequate
to lift and adjust the text from the DT binding document here? Should we have
a separate file for the router description?
My concern was and this is why I did not wrote anything under here is that the
code I add is only covers the DT boot case and I'm not planning to add legacy
support. The ACPI binding can be done in a similar fashion as the DT so you
would have a translator driver with ACPI API.

-- 
Péter

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
@ 2015-03-27 12:25           ` Peter Ujfalusi
  0 siblings, 0 replies; 54+ messages in thread
From: Peter Ujfalusi @ 2015-03-27 12:25 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/26/2015 05:32 PM, Vinod Koul wrote:
>> I have added the DT binding document since this series adds support for
>> routers for platforms booting with DT:
>>
>> Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
> I meant the update to Documnetation/dmanegine/ for routers :)

I see. In what form you think we should have the documentation? Is it adequate
to lift and adjust the text from the DT binding document here? Should we have
a separate file for the router description?
My concern was and this is why I did not wrote anything under here is that the
code I add is only covers the DT boot case and I'm not planning to add legacy
support. The ACPI binding can be done in a similar fashion as the DT so you
would have a translator driver with ACPI API.

-- 
P?ter

^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
@ 2015-03-30 17:20             ` Vinod Koul
  0 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-30 17:20 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: tony, linux, grant.likely, dmaengine, linux-kernel, devicetree,
	linux-omap, linux-arm-kernel, robh+dt, nm

On Fri, Mar 27, 2015 at 02:25:29PM +0200, Peter Ujfalusi wrote:
> On 03/26/2015 05:32 PM, Vinod Koul wrote:
> >> I have added the DT binding document since this series adds support for
> >> routers for platforms booting with DT:
> >>
> >> Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
> > I meant the update to Documnetation/dmanegine/ for routers :)
> 
> I see. In what form you think we should have the documentation? Is it adequate
> to lift and adjust the text from the DT binding document here? Should we have
> a separate file for the router description?
> My concern was and this is why I did not wrote anything under here is that the
> code I add is only covers the DT boot case and I'm not planning to add legacy
> support. The ACPI binding can be done in a similar fashion as the DT so you
> would have a translator driver with ACPI API.
Not the binding part but more of a guideline on how to go about solving the
DMA router design for drivers

-- 
~Vinod


^ permalink raw reply	[flat|nested] 54+ messages in thread

* Re: [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
@ 2015-03-30 17:20             ` Vinod Koul
  0 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-30 17:20 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: tony-4v6yS6AI5VpBDgjK7y7TUQ, linux-lFZ/pmaqli7XmaaqVzeoHQ,
	grant.likely-QSEj5FYQhm4dnm+yROfE0A,
	dmaengine-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	robh+dt-DgEjT+Ai2ygdnm+yROfE0A, nm-l0cyMroinI0

On Fri, Mar 27, 2015 at 02:25:29PM +0200, Peter Ujfalusi wrote:
> On 03/26/2015 05:32 PM, Vinod Koul wrote:
> >> I have added the DT binding document since this series adds support for
> >> routers for platforms booting with DT:
> >>
> >> Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
> > I meant the update to Documnetation/dmanegine/ for routers :)
> 
> I see. In what form you think we should have the documentation? Is it adequate
> to lift and adjust the text from the DT binding document here? Should we have
> a separate file for the router description?
> My concern was and this is why I did not wrote anything under here is that the
> code I add is only covers the DT boot case and I'm not planning to add legacy
> support. The ACPI binding can be done in a similar fashion as the DT so you
> would have a translator driver with ACPI API.
Not the binding part but more of a guideline on how to go about solving the
DMA router design for drivers

-- 
~Vinod

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 54+ messages in thread

* [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers
@ 2015-03-30 17:20             ` Vinod Koul
  0 siblings, 0 replies; 54+ messages in thread
From: Vinod Koul @ 2015-03-30 17:20 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Mar 27, 2015 at 02:25:29PM +0200, Peter Ujfalusi wrote:
> On 03/26/2015 05:32 PM, Vinod Koul wrote:
> >> I have added the DT binding document since this series adds support for
> >> routers for platforms booting with DT:
> >>
> >> Documentation/devicetree/bindings/dma/dma.txt | 28 ++++++++
> > I meant the update to Documnetation/dmanegine/ for routers :)
> 
> I see. In what form you think we should have the documentation? Is it adequate
> to lift and adjust the text from the DT binding document here? Should we have
> a separate file for the router description?
> My concern was and this is why I did not wrote anything under here is that the
> code I add is only covers the DT boot case and I'm not planning to add legacy
> support. The ACPI binding can be done in a similar fashion as the DT so you
> would have a translator driver with ACPI API.
Not the binding part but more of a guideline on how to go about solving the
DMA router design for drivers

-- 
~Vinod

^ permalink raw reply	[flat|nested] 54+ messages in thread

end of thread, other threads:[~2015-03-30 17:24 UTC | newest]

Thread overview: 54+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-03-11 13:23 [PATCH v2 0/7] dmaengine/dra7x: DMA router (crossbar support) Peter Ujfalusi
2015-03-11 13:23 ` Peter Ujfalusi
2015-03-11 13:23 ` Peter Ujfalusi
2015-03-11 13:23 ` [PATCH v2 1/7] dmaengine: of_dma: Support for DMA routers Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi
2015-03-26 10:50   ` Vinod Koul
2015-03-26 10:50     ` Vinod Koul
2015-03-26 10:50     ` Vinod Koul
2015-03-26 12:11     ` Peter Ujfalusi
2015-03-26 12:11       ` Peter Ujfalusi
2015-03-26 12:11       ` Peter Ujfalusi
2015-03-26 15:32       ` Vinod Koul
2015-03-26 15:32         ` Vinod Koul
2015-03-27 12:25         ` Peter Ujfalusi
2015-03-27 12:25           ` Peter Ujfalusi
2015-03-27 12:25           ` Peter Ujfalusi
2015-03-30 17:20           ` Vinod Koul
2015-03-30 17:20             ` Vinod Koul
2015-03-30 17:20             ` Vinod Koul
2015-03-11 13:23 ` [PATCH v2 2/7] Documentation: devicetree: dma: Binding documentation for TI DMA crossbar Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi
2015-03-11 13:23 ` [PATCH v2 3/7] dmaengine: Add driver for TI DMA crossbar on DRA7x Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi
2015-03-26 10:56   ` Vinod Koul
2015-03-26 10:56     ` Vinod Koul
2015-03-26 10:56     ` Vinod Koul
2015-03-26 12:31     ` Peter Ujfalusi
2015-03-26 12:31       ` Peter Ujfalusi
2015-03-26 12:31       ` Peter Ujfalusi
2015-03-26 15:22       ` Tony Lindgren
2015-03-26 15:22         ` Tony Lindgren
2015-03-26 15:22         ` Tony Lindgren
2015-03-26 15:37       ` Vinod Koul
2015-03-26 15:37         ` Vinod Koul
2015-03-11 13:23 ` [PATCH v2 4/7] dmaengine: omap-dma: Use defines for dma channels and request count Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi
2015-03-26 10:57   ` Vinod Koul
2015-03-26 10:57     ` Vinod Koul
2015-03-26 12:32     ` Peter Ujfalusi
2015-03-26 12:32       ` Peter Ujfalusi
2015-03-26 12:32       ` Peter Ujfalusi
2015-03-11 13:23 ` [PATCH v2 5/7] dmaengine: omap-dma: Take DMA request number from DT if it is available Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi
2015-03-11 13:23 ` [PATCH v2 6/7] dmaengine: omap-dma: Remove mapping between virtual channels and requests Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi
2015-03-11 13:23 ` [PATCH v2 7/7] ARM: DTS: dra7x: Integrate sDMA crossbar Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi
2015-03-11 13:23   ` Peter Ujfalusi

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.