dmaengine Archive on lore.kernel.org
 help / color / Atom feed
* [PATCH -next 0/2] dmaengine: xilinx_dma: In dma channel probe fix node order dependency
@ 2020-01-30 12:54 Radhey Shyam Pandey
  2020-01-30 12:54 ` [PATCH -next 1/2] dmaengine: xilinx_dma: Extend dma_config structure to store max channel count Radhey Shyam Pandey
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Radhey Shyam Pandey @ 2020-01-30 12:54 UTC (permalink / raw)
  To: vkoul, dan.j.williams, michal.simek, nick.graumann,
	andrea.merello, appana.durga.rao, mcgrof
  Cc: dmaengine, linux-kernel, git, Radhey Shyam Pandey

In overlay application[1] we noticed that channel DT nodes are inverted and
as a sideffect of this behaviour the axidmatest client fails.

In general driver should not assume specific DT probe order. So to fix this
failure remove channel node ordering restriction from the xilinx dma driver.

[1]: https://github.com/raspberrypi/linux/issues/2416

Radhey Shyam Pandey (2):
  dmaengine: xilinx_dma: Extend dma_config structure to store max
    channel count
  dmaengine: xilinx_dma: In dma channel probe fix node order dependency

 drivers/dma/xilinx/xilinx_dma.c | 48 +++++++++++++++++++++--------------------
 1 file changed, 25 insertions(+), 23 deletions(-)

-- 
2.7.4


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

* [PATCH -next 1/2] dmaengine: xilinx_dma: Extend dma_config structure to store max channel count
  2020-01-30 12:54 [PATCH -next 0/2] dmaengine: xilinx_dma: In dma channel probe fix node order dependency Radhey Shyam Pandey
@ 2020-01-30 12:54 ` Radhey Shyam Pandey
  2020-01-30 12:54 ` [PATCH -next 2/2] dmaengine: xilinx_dma: In dma channel probe fix node order dependency Radhey Shyam Pandey
  2020-02-25  5:48 ` [PATCH -next 0/2] " Vinod Koul
  2 siblings, 0 replies; 4+ messages in thread
From: Radhey Shyam Pandey @ 2020-01-30 12:54 UTC (permalink / raw)
  To: vkoul, dan.j.williams, michal.simek, nick.graumann,
	andrea.merello, appana.durga.rao, mcgrof
  Cc: dmaengine, linux-kernel, git, Radhey Shyam Pandey

Extend dma_config structure to store the max channel count. This input is
used to populate dma device channel nodes at the fixed offset. It serves
as a preparatory patch for removing dma channel DT node order dependency,
added in the subsequent commit.

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
---
 drivers/dma/xilinx/xilinx_dma.c | 9 ++++++++-
 1 file changed, 8 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 6f1539c..2281af3 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -125,7 +125,9 @@
 #define XILINX_VDMA_ENABLE_VERTICAL_FLIP	BIT(0)
 
 /* HW specific definitions */
-#define XILINX_DMA_MAX_CHANS_PER_DEVICE	0x20
+#define XILINX_MCDMA_MAX_CHANS_PER_DEVICE	0x20
+#define XILINX_DMA_MAX_CHANS_PER_DEVICE		0x2
+#define XILINX_CDMA_MAX_CHANS_PER_DEVICE	0x1
 
 #define XILINX_DMA_DMAXR_ALL_IRQ_MASK	\
 		(XILINX_DMA_DMASR_FRM_CNT_IRQ | \
@@ -468,6 +470,7 @@ struct xilinx_dma_config {
 			struct clk **tx_clk, struct clk **txs_clk,
 			struct clk **rx_clk, struct clk **rxs_clk);
 	irqreturn_t (*irq_handler)(int irq, void *data);
+	const int max_channels;
 };
 
 /**
@@ -2939,23 +2942,27 @@ static const struct xilinx_dma_config axidma_config = {
 	.dmatype = XDMA_TYPE_AXIDMA,
 	.clk_init = axidma_clk_init,
 	.irq_handler = xilinx_dma_irq_handler,
+	.max_channels = XILINX_DMA_MAX_CHANS_PER_DEVICE,
 };
 
 static const struct xilinx_dma_config aximcdma_config = {
 	.dmatype = XDMA_TYPE_AXIMCDMA,
 	.clk_init = axidma_clk_init,
 	.irq_handler = xilinx_mcdma_irq_handler,
+	.max_channels = XILINX_MCDMA_MAX_CHANS_PER_DEVICE,
 };
 static const struct xilinx_dma_config axicdma_config = {
 	.dmatype = XDMA_TYPE_CDMA,
 	.clk_init = axicdma_clk_init,
 	.irq_handler = xilinx_dma_irq_handler,
+	.max_channels = XILINX_CDMA_MAX_CHANS_PER_DEVICE,
 };
 
 static const struct xilinx_dma_config axivdma_config = {
 	.dmatype = XDMA_TYPE_VDMA,
 	.clk_init = axivdma_clk_init,
 	.irq_handler = xilinx_dma_irq_handler,
+	.max_channels = XILINX_DMA_MAX_CHANS_PER_DEVICE,
 };
 
 static const struct of_device_id xilinx_dma_of_ids[] = {
-- 
2.7.4


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

* [PATCH -next 2/2] dmaengine: xilinx_dma: In dma channel probe fix node order dependency
  2020-01-30 12:54 [PATCH -next 0/2] dmaengine: xilinx_dma: In dma channel probe fix node order dependency Radhey Shyam Pandey
  2020-01-30 12:54 ` [PATCH -next 1/2] dmaengine: xilinx_dma: Extend dma_config structure to store max channel count Radhey Shyam Pandey
@ 2020-01-30 12:54 ` Radhey Shyam Pandey
  2020-02-25  5:48 ` [PATCH -next 0/2] " Vinod Koul
  2 siblings, 0 replies; 4+ messages in thread
From: Radhey Shyam Pandey @ 2020-01-30 12:54 UTC (permalink / raw)
  To: vkoul, dan.j.williams, michal.simek, nick.graumann,
	andrea.merello, appana.durga.rao, mcgrof
  Cc: dmaengine, linux-kernel, git, Radhey Shyam Pandey

In overlay application we noticed that dma channel node probe order is
inverted i.e s2mm channel is probed first followed by mm2s channel. The
reason for this inversion is fdtoverlay utility which uses a function
called fdt_add_subnode(*). It stores the subnodes after the properties,
this has the effect of inserting the new subnode before any others and
the end result is a reversal.

Because of this inverted channel probe order, the node probed first is
assigned a '0' index instead of Channel ID should be '0' for tx and '1'
for rx and dmatest client using the DT convention fails in dma transfer
as channel are swapped.

To fix above behavior and make channel assignment index independent
of probe order, always assign mm2s channel at '0' index and the s2mm
channel at IP specific fixed offset derived from the max_channels
count.

Signed-off-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
---
 drivers/dma/xilinx/xilinx_dma.c | 39 +++++++++++++++++----------------------
 1 file changed, 17 insertions(+), 22 deletions(-)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index 2281af3..aecd5a3 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -488,16 +488,15 @@ struct xilinx_dma_config {
  * @txs_clk: DMA mm2s stream clock
  * @rx_clk: DMA s2mm clock
  * @rxs_clk: DMA s2mm stream clock
- * @nr_channels: Number of channels DMA device supports
- * @chan_id: DMA channel identifier
+ * @s2mm_chan_id: DMA s2mm channel identifier
+ * @mm2s_chan_id: DMA mm2s channel identifier
  * @max_buffer_len: Max buffer length
- * @s2mm_index: S2MM channel index
  */
 struct xilinx_dma_device {
 	void __iomem *regs;
 	struct device *dev;
 	struct dma_device common;
-	struct xilinx_dma_chan *chan[XILINX_DMA_MAX_CHANS_PER_DEVICE];
+	struct xilinx_dma_chan *chan[XILINX_MCDMA_MAX_CHANS_PER_DEVICE];
 	u32 flush_on_fsync;
 	bool ext_addr;
 	struct platform_device  *pdev;
@@ -507,10 +506,9 @@ struct xilinx_dma_device {
 	struct clk *txs_clk;
 	struct clk *rx_clk;
 	struct clk *rxs_clk;
-	u32 nr_channels;
-	u32 chan_id;
+	u32 s2mm_chan_id;
+	u32 mm2s_chan_id;
 	u32 max_buffer_len;
-	u32 s2mm_index;
 };
 
 /* Macros */
@@ -1748,7 +1746,7 @@ static irqreturn_t xilinx_mcdma_irq_handler(int irq, void *data)
 		return IRQ_NONE;
 
 	if (chan->direction == DMA_DEV_TO_MEM)
-		chan_offset = chan->xdev->s2mm_index;
+		chan_offset = chan->xdev->dma_config->max_channels / 2;
 
 	chan_offset = chan_offset + (chan_id - 1);
 	chan = chan->xdev->chan[chan_offset];
@@ -2734,12 +2732,11 @@ static void xdma_disable_allclks(struct xilinx_dma_device *xdev)
  *
  * @xdev: Driver specific device structure
  * @node: Device node
- * @chan_id: DMA Channel id
  *
  * Return: '0' on success and failure value on error
  */
 static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
-				  struct device_node *node, int chan_id)
+				  struct device_node *node)
 {
 	struct xilinx_dma_chan *chan;
 	bool has_dre = false;
@@ -2791,8 +2788,8 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
 	    of_device_is_compatible(node, "xlnx,axi-dma-mm2s-channel") ||
 	    of_device_is_compatible(node, "xlnx,axi-cdma-channel")) {
 		chan->direction = DMA_MEM_TO_DEV;
-		chan->id = chan_id;
-		chan->tdest = chan_id;
+		chan->id = xdev->mm2s_chan_id++;
+		chan->tdest = chan->id;
 
 		chan->ctrl_offset = XILINX_DMA_MM2S_CTRL_OFFSET;
 		if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {
@@ -2808,9 +2805,8 @@ static int xilinx_dma_chan_probe(struct xilinx_dma_device *xdev,
 		   of_device_is_compatible(node,
 					   "xlnx,axi-dma-s2mm-channel")) {
 		chan->direction = DMA_DEV_TO_MEM;
-		chan->id = chan_id;
-		xdev->s2mm_index = xdev->nr_channels;
-		chan->tdest = chan_id - xdev->nr_channels;
+		chan->id = xdev->s2mm_chan_id++;
+		chan->tdest = chan->id - xdev->dma_config->max_channels / 2;
 		chan->has_vflip = of_property_read_bool(node,
 					"xlnx,enable-vert-flip");
 		if (chan->has_vflip) {
@@ -2912,9 +2908,7 @@ static int xilinx_dma_child_probe(struct xilinx_dma_device *xdev,
 		dev_warn(xdev->dev, "missing dma-channels property\n");
 
 	for (i = 0; i < nr_channels; i++)
-		xilinx_dma_chan_probe(xdev, node, xdev->chan_id++);
-
-	xdev->nr_channels += nr_channels;
+		xilinx_dma_chan_probe(xdev, node);
 
 	return 0;
 }
@@ -2932,7 +2926,7 @@ static struct dma_chan *of_dma_xilinx_xlate(struct of_phandle_args *dma_spec,
 	struct xilinx_dma_device *xdev = ofdma->of_dma_data;
 	int chan_id = dma_spec->args[0];
 
-	if (chan_id >= xdev->nr_channels || !xdev->chan[chan_id])
+	if (chan_id >= xdev->dma_config->max_channels || !xdev->chan[chan_id])
 		return NULL;
 
 	return dma_get_slave_channel(&xdev->chan[chan_id]->common);
@@ -3019,6 +3013,7 @@ static int xilinx_dma_probe(struct platform_device *pdev)
 
 	/* Retrieve the DMA engine properties from the device tree */
 	xdev->max_buffer_len = GENMASK(XILINX_DMA_MAX_TRANS_LEN_MAX - 1, 0);
+	xdev->s2mm_chan_id = xdev->dma_config->max_channels / 2;
 
 	if (xdev->dma_config->dmatype == XDMA_TYPE_AXIDMA ||
 	    xdev->dma_config->dmatype == XDMA_TYPE_AXIMCDMA) {
@@ -3112,7 +3107,7 @@ static int xilinx_dma_probe(struct platform_device *pdev)
 	}
 
 	if (xdev->dma_config->dmatype == XDMA_TYPE_VDMA) {
-		for (i = 0; i < xdev->nr_channels; i++)
+		for (i = 0; i < xdev->dma_config->max_channels; i++)
 			if (xdev->chan[i])
 				xdev->chan[i]->num_frms = num_frames;
 	}
@@ -3142,7 +3137,7 @@ static int xilinx_dma_probe(struct platform_device *pdev)
 disable_clks:
 	xdma_disable_allclks(xdev);
 error:
-	for (i = 0; i < xdev->nr_channels; i++)
+	for (i = 0; i < xdev->dma_config->max_channels; i++)
 		if (xdev->chan[i])
 			xilinx_dma_chan_remove(xdev->chan[i]);
 
@@ -3164,7 +3159,7 @@ static int xilinx_dma_remove(struct platform_device *pdev)
 
 	dma_async_device_unregister(&xdev->common);
 
-	for (i = 0; i < xdev->nr_channels; i++)
+	for (i = 0; i < xdev->dma_config->max_channels; i++)
 		if (xdev->chan[i])
 			xilinx_dma_chan_remove(xdev->chan[i]);
 
-- 
2.7.4


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

* Re: [PATCH -next 0/2] dmaengine: xilinx_dma: In dma channel probe fix node order dependency
  2020-01-30 12:54 [PATCH -next 0/2] dmaengine: xilinx_dma: In dma channel probe fix node order dependency Radhey Shyam Pandey
  2020-01-30 12:54 ` [PATCH -next 1/2] dmaengine: xilinx_dma: Extend dma_config structure to store max channel count Radhey Shyam Pandey
  2020-01-30 12:54 ` [PATCH -next 2/2] dmaengine: xilinx_dma: In dma channel probe fix node order dependency Radhey Shyam Pandey
@ 2020-02-25  5:48 ` " Vinod Koul
  2 siblings, 0 replies; 4+ messages in thread
From: Vinod Koul @ 2020-02-25  5:48 UTC (permalink / raw)
  To: Radhey Shyam Pandey
  Cc: dan.j.williams, michal.simek, nick.graumann, andrea.merello,
	appana.durga.rao, mcgrof, dmaengine, linux-kernel, git

On 30-01-20, 18:24, Radhey Shyam Pandey wrote:
> In overlay application[1] we noticed that channel DT nodes are inverted and
> as a sideffect of this behaviour the axidmatest client fails.
> 
> In general driver should not assume specific DT probe order. So to fix this
> failure remove channel node ordering restriction from the xilinx dma driver.

Applied, thanks

-- 
~Vinod

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

end of thread, back to index

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-01-30 12:54 [PATCH -next 0/2] dmaengine: xilinx_dma: In dma channel probe fix node order dependency Radhey Shyam Pandey
2020-01-30 12:54 ` [PATCH -next 1/2] dmaengine: xilinx_dma: Extend dma_config structure to store max channel count Radhey Shyam Pandey
2020-01-30 12:54 ` [PATCH -next 2/2] dmaengine: xilinx_dma: In dma channel probe fix node order dependency Radhey Shyam Pandey
2020-02-25  5:48 ` [PATCH -next 0/2] " Vinod Koul

dmaengine Archive on lore.kernel.org

Archives are clonable:
	git clone --mirror https://lore.kernel.org/dmaengine/0 dmaengine/git/0.git

	# If you have public-inbox 1.1+ installed, you may
	# initialize and index your mirror using the following commands:
	public-inbox-init -V2 dmaengine dmaengine/ https://lore.kernel.org/dmaengine \
		dmaengine@vger.kernel.org
	public-inbox-index dmaengine

Example config snippet for mirrors

Newsgroup available over NNTP:
	nntp://nntp.lore.kernel.org/org.kernel.vger.dmaengine


AGPL code for this site: git clone https://public-inbox.org/public-inbox.git