DMA Engine development
 help / color / mirror / Atom feed
* [PATCH 2/2] dmaengine: axi-dmac: assign `copy_align` property
From: Alexandru Ardelean @ 2019-05-21 11:23 UTC (permalink / raw)
  To: dmaengine; +Cc: Alexandru Ardelean
In-Reply-To: <20190521112331.32424-1-alexandru.ardelean@analog.com>

The `copy_align` property is a generic property that describes alignment
for DMA memcpy & sg ops.
It serves mostly an informational purpose, and can be used in DMA tests, to
pass the info to know what alignment to expect.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
 drivers/dma/dma-axi-dmac.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
index edd81ceeeb33..eea994d827ba 100644
--- a/drivers/dma/dma-axi-dmac.c
+++ b/drivers/dma/dma-axi-dmac.c
@@ -763,6 +763,8 @@ static int axi_dmac_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_clk_disable;
 
+	dma_dev->copy_align = (dmac->chan.address_align_mask + 1);
+
 	axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_MASK, 0x00);
 
 	ret = dma_async_device_register(dma_dev);
-- 
2.17.1


^ permalink raw reply related

* [PATCH 1/2] dmaengine: axi-dmac: Discover length alignment requirement
From: Alexandru Ardelean @ 2019-05-21 11:23 UTC (permalink / raw)
  To: dmaengine; +Cc: Lars-Peter Clausen

From: Lars-Peter Clausen <lars@metafoo.de>

Starting with version 4.1.a the AXI-DMAC is capable of reporting the
required length alignment.

The LSBs that are required to be set for alignment will always read back as
set from the transfer length register. It is not possible to clear them by
writing a 0. This means the driver can discover the length alignment
requirement by writing 0 to that register and reading back the value.

Since the DMA will support length alignment requirements that are different
from the address alignment requirement track both of them independently.

For older versions of the peripheral assume that the length alignment
requirement is equal to the address alignment requirement.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
---
 drivers/dma/dma-axi-dmac.c | 23 ++++++++++++++++++-----
 1 file changed, 18 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
index 0984ae6eb155..edd81ceeeb33 100644
--- a/drivers/dma/dma-axi-dmac.c
+++ b/drivers/dma/dma-axi-dmac.c
@@ -44,6 +44,8 @@
  * there is no address than can or needs to be configured for the device side.
  */
 
+#define AXI_DMAC_REG_VERSION		0x00
+
 #define AXI_DMAC_REG_IRQ_MASK		0x80
 #define AXI_DMAC_REG_IRQ_PENDING	0x84
 #define AXI_DMAC_REG_IRQ_SOURCE		0x88
@@ -110,7 +112,8 @@ struct axi_dmac_chan {
 	unsigned int dest_type;
 
 	unsigned int max_length;
-	unsigned int align_mask;
+	unsigned int address_align_mask;
+	unsigned int length_align_mask;
 
 	bool hw_cyclic;
 	bool hw_2d;
@@ -169,14 +172,14 @@ static bool axi_dmac_check_len(struct axi_dmac_chan *chan, unsigned int len)
 {
 	if (len == 0)
 		return false;
-	if ((len & chan->align_mask) != 0) /* Not aligned */
+	if ((len & chan->length_align_mask) != 0) /* Not aligned */
 		return false;
 	return true;
 }
 
 static bool axi_dmac_check_addr(struct axi_dmac_chan *chan, dma_addr_t addr)
 {
-	if ((addr & chan->align_mask) != 0) /* Not aligned */
+	if ((addr & chan->address_align_mask) != 0) /* Not aligned */
 		return false;
 	return true;
 }
@@ -394,7 +397,7 @@ static struct axi_dmac_sg *axi_dmac_fill_linear_sg(struct axi_dmac_chan *chan,
 	num_segments = DIV_ROUND_UP(period_len, chan->max_length);
 	segment_size = DIV_ROUND_UP(period_len, num_segments);
 	/* Take care of alignment */
-	segment_size = ((segment_size - 1) | chan->align_mask) + 1;
+	segment_size = ((segment_size - 1) | chan->length_align_mask) + 1;
 
 	for (i = 0; i < num_periods; i++) {
 		len = period_len;
@@ -623,7 +626,7 @@ static int axi_dmac_parse_chan_dt(struct device_node *of_chan,
 		return ret;
 	chan->dest_width = val / 8;
 
-	chan->align_mask = max(chan->dest_width, chan->src_width) - 1;
+	chan->address_align_mask = max(chan->dest_width, chan->src_width) - 1;
 
 	if (axi_dmac_dest_is_mem(chan) && axi_dmac_src_is_mem(chan))
 		chan->direction = DMA_MEM_TO_MEM;
@@ -640,6 +643,9 @@ static int axi_dmac_parse_chan_dt(struct device_node *of_chan,
 static int axi_dmac_detect_caps(struct axi_dmac *dmac)
 {
 	struct axi_dmac_chan *chan = &dmac->chan;
+	unsigned int version;
+
+	version = axi_dmac_read(dmac, AXI_DMAC_REG_VERSION);
 
 	axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, AXI_DMAC_FLAG_CYCLIC);
 	if (axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS) == AXI_DMAC_FLAG_CYCLIC)
@@ -670,6 +676,13 @@ static int axi_dmac_detect_caps(struct axi_dmac *dmac)
 		return -ENODEV;
 	}
 
+	if ((version & 0xff00) >= 0x0100) {
+		axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, 0x00);
+		chan->length_align_mask = axi_dmac_read(dmac, AXI_DMAC_REG_X_LENGTH);
+	} else {
+		chan->length_align_mask = chan->address_align_mask;
+	}
+
 	return 0;
 }
 
-- 
2.17.1


^ permalink raw reply related

* Re: [PATCH 1/2] dmaengine: axi-dmac: Discover length alignment requirement
From: Vinod Koul @ 2019-05-21  9:00 UTC (permalink / raw)
  To: Alexandru Ardelean; +Cc: dmaengine, Lars-Peter Clausen
In-Reply-To: <20190521112331.32424-1-alexandru.ardelean@analog.com>

On 21-05-19, 14:23, Alexandru Ardelean wrote:
> From: Lars-Peter Clausen <lars@metafoo.de>
> 
> Starting with version 4.1.a the AXI-DMAC is capable of reporting the
> required length alignment.
> 
> The LSBs that are required to be set for alignment will always read back as
> set from the transfer length register. It is not possible to clear them by
> writing a 0. This means the driver can discover the length alignment
> requirement by writing 0 to that register and reading back the value.
> 
> Since the DMA will support length alignment requirements that are different
> from the address alignment requirement track both of them independently.
> 
> For older versions of the peripheral assume that the length alignment
> requirement is equal to the address alignment requirement.
> 
> Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>

You need to sign off the patch before sending. Please reread Documentation/process/submitting-patches.rst

>  	axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, AXI_DMAC_FLAG_CYCLIC);
>  	if (axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS) == AXI_DMAC_FLAG_CYCLIC)
> @@ -670,6 +676,13 @@ static int axi_dmac_detect_caps(struct axi_dmac *dmac)
>  		return -ENODEV;
>  	}
>  
> +	if ((version & 0xff00) >= 0x0100) {

magic numbers yaay

-- 
~Vinod

^ permalink raw reply

* [PATCH v3 0/2] dmaengine: ti: edma: Polled completion support
From: Peter Ujfalusi @ 2019-05-21  9:36 UTC (permalink / raw)
  To: vkoul; +Cc: dan.j.williams, dmaengine, linux-arm-kernel, linux-omap

Hi,

Changes since v2:
- Fix typo in the comment for patch 0

Changes since v1:
- Cleanup patch for the array register handling
- typo fixed in patch2 commit message

The code around the array register access was pretty confusing for the first
look, so clean them up first then use the cleaner way in the polled handling.

When a DMA client driver decides that it is not providing callback for
completion of a transfer (and/or does not set the DMA_PREP_INTERRUPT) but
it will poll the status of the transfer (in case of short memcpy for
example) we will not get interrupt for the completion of the transfer and
will not mark the transaction as done.

Check the event registers (ER and EER) and if the channel is inactive then
return wioth DMA_COMPLETE to let the client know that the transfer is
completed.

Regards,
Peter
---
Peter Ujfalusi (2):
  dmaengine: ti: edma: Clean up the 2x32bit array register accesses
  dmaengine: ti: edma: Enable support for polled (memcpy) completion

 drivers/dma/ti/edma.c | 129 ++++++++++++++++++++++++++----------------
 1 file changed, 81 insertions(+), 48 deletions(-)

-- 
Peter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply

* [PATCH v3 1/2] dmaengine: ti: edma: Clean up the 2x32bit array register accesses
From: Peter Ujfalusi @ 2019-05-21  9:36 UTC (permalink / raw)
  To: vkoul; +Cc: dan.j.williams, dmaengine, linux-arm-kernel, linux-omap
In-Reply-To: <20190521093646.21836-1-peter.ujfalusi@ti.com>

Introduce defines for getting the array index and the bit number within the
64bit array register pairs.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/ti/edma.c | 106 ++++++++++++++++++++++++------------------
 1 file changed, 61 insertions(+), 45 deletions(-)

diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c
index ceabdea40ae0..a39f817b3888 100644
--- a/drivers/dma/ti/edma.c
+++ b/drivers/dma/ti/edma.c
@@ -133,6 +133,17 @@
 #define EDMA_CONT_PARAMS_FIXED_EXACT	 1002
 #define EDMA_CONT_PARAMS_FIXED_NOT_EXACT 1003
 
+/*
+ * 64bit array registers are split into two 32bit registers:
+ * reg0: channel/event 0-31
+ * reg1: channel/event 32-63
+ *
+ * bit 5 in the channel number tells the array index (0/1)
+ * bit 0-4 (0x1f) is the bit offset within the register
+ */
+#define EDMA_REG_ARRAY_INDEX(channel)	((channel) >> 5)
+#define EDMA_CHANNEL_BIT(channel)	(BIT((channel) & 0x1f))
+
 /* PaRAM slots are laid out like this */
 struct edmacc_param {
 	u32 opt;
@@ -441,15 +452,14 @@ static void edma_setup_interrupt(struct edma_chan *echan, bool enable)
 {
 	struct edma_cc *ecc = echan->ecc;
 	int channel = EDMA_CHAN_SLOT(echan->ch_num);
+	int idx = EDMA_REG_ARRAY_INDEX(channel);
+	int ch_bit = EDMA_CHANNEL_BIT(channel);
 
 	if (enable) {
-		edma_shadow0_write_array(ecc, SH_ICR, channel >> 5,
-					 BIT(channel & 0x1f));
-		edma_shadow0_write_array(ecc, SH_IESR, channel >> 5,
-					 BIT(channel & 0x1f));
+		edma_shadow0_write_array(ecc, SH_ICR, idx, ch_bit);
+		edma_shadow0_write_array(ecc, SH_IESR, idx, ch_bit);
 	} else {
-		edma_shadow0_write_array(ecc, SH_IECR, channel >> 5,
-					 BIT(channel & 0x1f));
+		edma_shadow0_write_array(ecc, SH_IECR, idx, ch_bit);
 	}
 }
 
@@ -587,26 +597,26 @@ static void edma_start(struct edma_chan *echan)
 {
 	struct edma_cc *ecc = echan->ecc;
 	int channel = EDMA_CHAN_SLOT(echan->ch_num);
-	int j = (channel >> 5);
-	unsigned int mask = BIT(channel & 0x1f);
+	int idx = EDMA_REG_ARRAY_INDEX(channel);
+	int ch_bit = EDMA_CHANNEL_BIT(channel);
 
 	if (!echan->hw_triggered) {
 		/* EDMA channels without event association */
-		dev_dbg(ecc->dev, "ESR%d %08x\n", j,
-			edma_shadow0_read_array(ecc, SH_ESR, j));
-		edma_shadow0_write_array(ecc, SH_ESR, j, mask);
+		dev_dbg(ecc->dev, "ESR%d %08x\n", idx,
+			edma_shadow0_read_array(ecc, SH_ESR, idx));
+		edma_shadow0_write_array(ecc, SH_ESR, idx, ch_bit);
 	} else {
 		/* EDMA channel with event association */
-		dev_dbg(ecc->dev, "ER%d %08x\n", j,
-			edma_shadow0_read_array(ecc, SH_ER, j));
+		dev_dbg(ecc->dev, "ER%d %08x\n", idx,
+			edma_shadow0_read_array(ecc, SH_ER, idx));
 		/* Clear any pending event or error */
-		edma_write_array(ecc, EDMA_ECR, j, mask);
-		edma_write_array(ecc, EDMA_EMCR, j, mask);
+		edma_write_array(ecc, EDMA_ECR, idx, ch_bit);
+		edma_write_array(ecc, EDMA_EMCR, idx, ch_bit);
 		/* Clear any SER */
-		edma_shadow0_write_array(ecc, SH_SECR, j, mask);
-		edma_shadow0_write_array(ecc, SH_EESR, j, mask);
-		dev_dbg(ecc->dev, "EER%d %08x\n", j,
-			edma_shadow0_read_array(ecc, SH_EER, j));
+		edma_shadow0_write_array(ecc, SH_SECR, idx, ch_bit);
+		edma_shadow0_write_array(ecc, SH_EESR, idx, ch_bit);
+		dev_dbg(ecc->dev, "EER%d %08x\n", idx,
+			edma_shadow0_read_array(ecc, SH_EER, idx));
 	}
 }
 
@@ -614,19 +624,19 @@ static void edma_stop(struct edma_chan *echan)
 {
 	struct edma_cc *ecc = echan->ecc;
 	int channel = EDMA_CHAN_SLOT(echan->ch_num);
-	int j = (channel >> 5);
-	unsigned int mask = BIT(channel & 0x1f);
+	int idx = EDMA_REG_ARRAY_INDEX(channel);
+	int ch_bit = EDMA_CHANNEL_BIT(channel);
 
-	edma_shadow0_write_array(ecc, SH_EECR, j, mask);
-	edma_shadow0_write_array(ecc, SH_ECR, j, mask);
-	edma_shadow0_write_array(ecc, SH_SECR, j, mask);
-	edma_write_array(ecc, EDMA_EMCR, j, mask);
+	edma_shadow0_write_array(ecc, SH_EECR, idx, ch_bit);
+	edma_shadow0_write_array(ecc, SH_ECR, idx, ch_bit);
+	edma_shadow0_write_array(ecc, SH_SECR, idx, ch_bit);
+	edma_write_array(ecc, EDMA_EMCR, idx, ch_bit);
 
 	/* clear possibly pending completion interrupt */
-	edma_shadow0_write_array(ecc, SH_ICR, j, mask);
+	edma_shadow0_write_array(ecc, SH_ICR, idx, ch_bit);
 
-	dev_dbg(ecc->dev, "EER%d %08x\n", j,
-		edma_shadow0_read_array(ecc, SH_EER, j));
+	dev_dbg(ecc->dev, "EER%d %08x\n", idx,
+		edma_shadow0_read_array(ecc, SH_EER, idx));
 
 	/* REVISIT:  consider guarding against inappropriate event
 	 * chaining by overwriting with dummy_paramset.
@@ -640,45 +650,49 @@ static void edma_stop(struct edma_chan *echan)
 static void edma_pause(struct edma_chan *echan)
 {
 	int channel = EDMA_CHAN_SLOT(echan->ch_num);
-	unsigned int mask = BIT(channel & 0x1f);
 
-	edma_shadow0_write_array(echan->ecc, SH_EECR, channel >> 5, mask);
+	edma_shadow0_write_array(echan->ecc, SH_EECR,
+				 EDMA_REG_ARRAY_INDEX(channel),
+				 EDMA_CHANNEL_BIT(channel));
 }
 
 /* Re-enable EDMA hardware events on the specified channel.  */
 static void edma_resume(struct edma_chan *echan)
 {
 	int channel = EDMA_CHAN_SLOT(echan->ch_num);
-	unsigned int mask = BIT(channel & 0x1f);
 
-	edma_shadow0_write_array(echan->ecc, SH_EESR, channel >> 5, mask);
+	edma_shadow0_write_array(echan->ecc, SH_EESR,
+				 EDMA_REG_ARRAY_INDEX(channel),
+				 EDMA_CHANNEL_BIT(channel));
 }
 
 static void edma_trigger_channel(struct edma_chan *echan)
 {
 	struct edma_cc *ecc = echan->ecc;
 	int channel = EDMA_CHAN_SLOT(echan->ch_num);
-	unsigned int mask = BIT(channel & 0x1f);
+	int idx = EDMA_REG_ARRAY_INDEX(channel);
+	int ch_bit = EDMA_CHANNEL_BIT(channel);
 
-	edma_shadow0_write_array(ecc, SH_ESR, (channel >> 5), mask);
+	edma_shadow0_write_array(ecc, SH_ESR, idx, ch_bit);
 
-	dev_dbg(ecc->dev, "ESR%d %08x\n", (channel >> 5),
-		edma_shadow0_read_array(ecc, SH_ESR, (channel >> 5)));
+	dev_dbg(ecc->dev, "ESR%d %08x\n", idx,
+		edma_shadow0_read_array(ecc, SH_ESR, idx));
 }
 
 static void edma_clean_channel(struct edma_chan *echan)
 {
 	struct edma_cc *ecc = echan->ecc;
 	int channel = EDMA_CHAN_SLOT(echan->ch_num);
-	int j = (channel >> 5);
-	unsigned int mask = BIT(channel & 0x1f);
+	int idx = EDMA_REG_ARRAY_INDEX(channel);
+	int ch_bit = EDMA_CHANNEL_BIT(channel);
 
-	dev_dbg(ecc->dev, "EMR%d %08x\n", j, edma_read_array(ecc, EDMA_EMR, j));
-	edma_shadow0_write_array(ecc, SH_ECR, j, mask);
+	dev_dbg(ecc->dev, "EMR%d %08x\n", idx,
+		edma_read_array(ecc, EDMA_EMR, idx));
+	edma_shadow0_write_array(ecc, SH_ECR, idx, ch_bit);
 	/* Clear the corresponding EMR bits */
-	edma_write_array(ecc, EDMA_EMCR, j, mask);
+	edma_write_array(ecc, EDMA_EMCR, idx, ch_bit);
 	/* Clear any SER */
-	edma_shadow0_write_array(ecc, SH_SECR, j, mask);
+	edma_shadow0_write_array(ecc, SH_SECR, idx, ch_bit);
 	edma_write(ecc, EDMA_CCERRCLR, BIT(16) | BIT(1) | BIT(0));
 }
 
@@ -708,7 +722,8 @@ static int edma_alloc_channel(struct edma_chan *echan,
 	int channel = EDMA_CHAN_SLOT(echan->ch_num);
 
 	/* ensure access through shadow region 0 */
-	edma_or_array2(ecc, EDMA_DRAE, 0, channel >> 5, BIT(channel & 0x1f));
+	edma_or_array2(ecc, EDMA_DRAE, 0, EDMA_REG_ARRAY_INDEX(channel),
+		       EDMA_CHANNEL_BIT(channel));
 
 	/* ensure no events are pending */
 	edma_stop(echan);
@@ -2482,8 +2497,9 @@ static int edma_pm_resume(struct device *dev)
 	for (i = 0; i < ecc->num_channels; i++) {
 		if (echan[i].alloced) {
 			/* ensure access through shadow region 0 */
-			edma_or_array2(ecc, EDMA_DRAE, 0, i >> 5,
-				       BIT(i & 0x1f));
+			edma_or_array2(ecc, EDMA_DRAE, 0,
+				       EDMA_REG_ARRAY_INDEX(i),
+				       EDMA_CHANNEL_BIT(i));
 
 			edma_setup_interrupt(&echan[i], true);
 
-- 
Peter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related

* [PATCH v3 2/2] dmaengine: ti: edma: Enable support for polled (memcpy) completion
From: Peter Ujfalusi @ 2019-05-21  9:36 UTC (permalink / raw)
  To: vkoul; +Cc: dan.j.williams, dmaengine, linux-arm-kernel, linux-omap
In-Reply-To: <20190521093646.21836-1-peter.ujfalusi@ti.com>

When a DMA client driver decides that it is not providing callback for
completion of a transfer (and/or does not set the DMA_PREP_INTERRUPT) but
it will poll the status of the transfer (in case of short memcpy for
example) we will not get interrupt for the completion of the transfer and
will not mark the transaction as done.

Check the event registers (ER and EER) and if the channel is inactive then
return with DMA_COMPLETE to let the client know that the transfer is
completed.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/dma/ti/edma.c | 23 ++++++++++++++++++++---
 1 file changed, 20 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/ti/edma.c b/drivers/dma/ti/edma.c
index a39f817b3888..1ad539c38468 100644
--- a/drivers/dma/ti/edma.c
+++ b/drivers/dma/ti/edma.c
@@ -1226,8 +1226,9 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
 
 	edesc->pset[0].param.opt |= ITCCHEN;
 	if (nslots == 1) {
-		/* Enable transfer complete interrupt */
-		edesc->pset[0].param.opt |= TCINTEN;
+		/* Enable transfer complete interrupt if requested */
+		if (tx_flags & DMA_PREP_INTERRUPT)
+			edesc->pset[0].param.opt |= TCINTEN;
 	} else {
 		/* Enable transfer complete chaining for the first slot */
 		edesc->pset[0].param.opt |= TCCHEN;
@@ -1254,7 +1255,9 @@ static struct dma_async_tx_descriptor *edma_prep_dma_memcpy(
 		}
 
 		edesc->pset[1].param.opt |= ITCCHEN;
-		edesc->pset[1].param.opt |= TCINTEN;
+		/* Enable transfer complete interrupt if requested */
+		if (tx_flags & DMA_PREP_INTERRUPT)
+			edesc->pset[1].param.opt |= TCINTEN;
 	}
 
 	return vchan_tx_prep(&echan->vchan, &edesc->vdesc, tx_flags);
@@ -1816,6 +1819,20 @@ static enum dma_status edma_tx_status(struct dma_chan *chan,
 	unsigned long flags;
 
 	ret = dma_cookie_status(chan, cookie, txstate);
+
+	if (ret != DMA_COMPLETE && echan->edesc && !echan->edesc->cyclic) {
+		struct edma_cc *ecc = echan->ecc;
+		int channel = EDMA_CHAN_SLOT(echan->ch_num);
+		int idx = EDMA_REG_ARRAY_INDEX(channel);
+		int ch_bit = EDMA_CHANNEL_BIT(channel);
+		unsigned int sh_er = edma_shadow0_read_array(ecc, SH_ER, idx);
+		unsigned int sh_eer = edma_shadow0_read_array(ecc, SH_EER, idx);
+
+		/* The channel is no longer active */
+		if (!(sh_er & ch_bit) && !(sh_eer & ch_bit))
+			ret = DMA_COMPLETE;
+	}
+
 	if (ret == DMA_COMPLETE || !txstate)
 		return ret;
 
-- 
Peter

Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki.
Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki


^ permalink raw reply related

* Re: [PATCH 1/2] dmaengine: axi-dmac: Discover length alignment requirement
From: Ardelean, Alexandru @ 2019-05-21 10:13 UTC (permalink / raw)
  To: vkoul@kernel.org; +Cc: dmaengine@vger.kernel.org, lars@metafoo.de
In-Reply-To: <20190521090042.GC15118@vkoul-mobl>

On Tue, 2019-05-21 at 14:30 +0530, Vinod Koul wrote:
> [External]
> 
> 
> On 21-05-19, 14:23, Alexandru Ardelean wrote:
> > From: Lars-Peter Clausen <lars@metafoo.de>
> > 
> > Starting with version 4.1.a the AXI-DMAC is capable of reporting the
> > required length alignment.
> > 
> > The LSBs that are required to be set for alignment will always read back as
> > set from the transfer length register. It is not possible to clear them by
> > writing a 0. This means the driver can discover the length alignment
> > requirement by writing 0 to that register and reading back the value.
> > 
> > Since the DMA will support length alignment requirements that are different
> > from the address alignment requirement track both of them independently.
> > 
> > For older versions of the peripheral assume that the length alignment
> > requirement is equal to the address alignment requirement.
> > 
> > Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
> 
> You need to sign off the patch before sending. Please reread Documentation/process/submitting-patches.rst

Ack.

Sorry for forgetting this one.

> 
> >       axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, AXI_DMAC_FLAG_CYCLIC);
> >       if (axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS) == AXI_DMAC_FLAG_CYCLIC)
> > @@ -670,6 +676,13 @@ static int axi_dmac_detect_caps(struct axi_dmac *dmac)
> >               return -ENODEV;
> >       }
> > 
> > +     if ((version & 0xff00) >= 0x0100) {
> 
> magic numbers yaay

Good point.
Will fix.

> 
> --
> ~Vinod

^ permalink raw reply

* Re: [PATCH v1] dmaengine: tegra-apb: Handle DMA_PREP_INTERRUPT flag properly
From: Dmitry Osipenko @ 2019-05-21 13:46 UTC (permalink / raw)
  To: Vinod Koul, Jon Hunter
  Cc: Laxman Dewangan, Thierry Reding, Ben Dooks, dmaengine,
	linux-tegra, linux-kernel
In-Reply-To: <20190521045545.GP15118@vkoul-mobl>

21.05.2019 7:55, Vinod Koul пишет:
> On 08-05-19, 10:24, Jon Hunter wrote:
>>
>> On 05/05/2019 19:12, Dmitry Osipenko wrote:
>>> The DMA_PREP_INTERRUPT flag means that descriptor's callback should be
>>> invoked upon transfer completion and that's it. For some reason driver
>>> completely disables the hardware interrupt handling, leaving channel in
>>> unusable state if transfer is issued with the flag being unset. Note
>>> that there are no occurrences in the relevant drivers that do not set
>>> the flag, hence this patch doesn't fix any actual bug and merely fixes
>>> potential problem.
>>>
>>> Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
>>
>> >From having a look at this, I am guessing that we have never really
>> tested the case where DMA_PREP_INTERRUPT flag is not set because as you
>> mentioned it does not look like this will work at all!
> 
> That is a fair argument
>>
>> Is there are use-case you are looking at where you don't set the
>> DMA_PREP_INTERRUPT flag?
>>
>> If not I am wondering if we should even bother supporting this and warn
>> if it is not set. AFAICT it does not appear to be mandatory, but maybe
>> Vinod can comment more on this.
> 
> This is supposed to be used in the cases where you submit a bunch of
> descriptors and selectively dont want an interrupt in few cases...
> 
> Is this such a case?

The flag is set by device drivers. AFAIK, none of the drivers that are
used on Tegra SoC's make a use of that flag, at least not in upstream.

^ permalink raw reply

* Re: [PATCH v2 0/6] Fix some bugs and add new feature for Spreadtrum DMA engine
From: Vinod Koul @ 2019-05-21 13:54 UTC (permalink / raw)
  To: Baolin Wang
  Cc: dan.j.williams, eric.long, orsonzhai, zhang.lyra, vincent.guittot,
	dmaengine, linux-kernel
In-Reply-To: <cover.1557127239.git.baolin.wang@linaro.org>

On 06-05-19, 15:28, Baolin Wang wrote:
> Hi,
> 
> This patch set fixes some DMA engine bugs and adds interrupt support
> for 2-stage transfer.

Applied all, thanks
-- 
~Vinod

^ permalink raw reply

* Re: [PATCH 4/4] serial: 8250-mtk: modify uart DMA rx
From: Vinod Koul @ 2019-05-21 13:57 UTC (permalink / raw)
  To: Long Cheng
  Cc: Randy Dunlap, Rob Herring, Mark Rutland, Ryder Lee, Sean Wang,
	Nicolas Boichat, Matthias Brugger, Dan Williams,
	Greg Kroah-Hartman, Jiri Slaby, Sean Wang, dmaengine, devicetree,
	linux-arm-kernel, linux-mediatek, linux-kernel, linux-serial,
	srv_heupstream, Yingjoe Chen, YT Shen, Zhenbao Liu
In-Reply-To: <1556336193-15198-5-git-send-email-long.cheng@mediatek.com>

On 27-04-19, 11:36, Long Cheng wrote:
> Modify uart rx and complete for DMA.
> 
> Signed-off-by: Long Cheng <long.cheng@mediatek.com>
> ---
>  drivers/tty/serial/8250/8250_mtk.c |   53 ++++++++++++++++--------------------
>  1 file changed, 23 insertions(+), 30 deletions(-)
> 
> diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c
> index c1fdbc0..04081a6 100644
> --- a/drivers/tty/serial/8250/8250_mtk.c
> +++ b/drivers/tty/serial/8250/8250_mtk.c
> @@ -30,7 +30,6 @@
>  #define MTK_UART_DMA_EN_TX	0x2
>  #define MTK_UART_DMA_EN_RX	0x5
>  
> -#define MTK_UART_TX_SIZE	UART_XMIT_SIZE
>  #define MTK_UART_RX_SIZE	0x8000
>  #define MTK_UART_TX_TRIGGER	1
>  #define MTK_UART_RX_TRIGGER	MTK_UART_RX_SIZE
> @@ -64,28 +63,30 @@ static void mtk8250_dma_rx_complete(void *param)
>  	struct mtk8250_data *data = up->port.private_data;
>  	struct tty_port *tty_port = &up->port.state->port;
>  	struct dma_tx_state state;
> +	int copied, cnt, tmp;
>  	unsigned char *ptr;
> -	int copied;
>  
> -	dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
> -				dma->rx_size, DMA_FROM_DEVICE);
> +	if (data->rx_status == DMA_RX_SHUTDOWN)
> +		return;
>  
>  	dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
> +	cnt = dma->rx_size - state.residue;
> +	tmp = cnt;
>  
> -	if (data->rx_status == DMA_RX_SHUTDOWN)
> -		return;
> +	if ((data->rx_pos + cnt) > dma->rx_size)
> +		tmp = dma->rx_size - data->rx_pos;
>  
> -	if ((data->rx_pos + state.residue) <= dma->rx_size) {
> -		ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> -		copied = tty_insert_flip_string(tty_port, ptr, state.residue);
> -	} else {
> -		ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> -		copied = tty_insert_flip_string(tty_port, ptr,
> -						dma->rx_size - data->rx_pos);
> +	ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> +	copied = tty_insert_flip_string(tty_port, ptr, tmp);
> +	data->rx_pos += tmp;
> +
> +	if (cnt > tmp) {
>  		ptr = (unsigned char *)(dma->rx_buf);
> -		copied += tty_insert_flip_string(tty_port, ptr,
> -				data->rx_pos + state.residue - dma->rx_size);
> +		tmp = cnt - tmp;
> +		copied += tty_insert_flip_string(tty_port, ptr, tmp);
> +		data->rx_pos = tmp;
>  	}
> +
>  	up->port.icount.rx += copied;
>  
>  	tty_flip_buffer_push(tty_port);
> @@ -96,9 +97,7 @@ static void mtk8250_dma_rx_complete(void *param)
>  static void mtk8250_rx_dma(struct uart_8250_port *up)
>  {
>  	struct uart_8250_dma *dma = up->dma;
> -	struct mtk8250_data *data = up->port.private_data;
>  	struct dma_async_tx_descriptor	*desc;
> -	struct dma_tx_state	 state;
>  
>  	desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
>  					   dma->rx_size, DMA_DEV_TO_MEM,
> @@ -113,12 +112,6 @@ static void mtk8250_rx_dma(struct uart_8250_port *up)
>  
>  	dma->rx_cookie = dmaengine_submit(desc);
>  
> -	dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
> -	data->rx_pos = state.residue;
> -
> -	dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
> -				   dma->rx_size, DMA_FROM_DEVICE);
> -
>  	dma_async_issue_pending(dma->rxchan);
>  }
>  
> @@ -131,13 +124,13 @@ static void mtk8250_dma_enable(struct uart_8250_port *up)
>  	if (data->rx_status != DMA_RX_START)
>  		return;
>  
> -	dma->rxconf.direction		= DMA_DEV_TO_MEM;
> -	dma->rxconf.src_addr_width	= dma->rx_size / 1024;
> -	dma->rxconf.src_addr		= dma->rx_addr;
> +	dma->rxconf.direction				= DMA_DEV_TO_MEM;

Direction field is deprecated, please do not use this anymore...

> +	dma->rxconf.src_port_window_size	= dma->rx_size;
> +	dma->rxconf.src_addr				= dma->rx_addr;
>  
> -	dma->txconf.direction		= DMA_MEM_TO_DEV;
> -	dma->txconf.dst_addr_width	= MTK_UART_TX_SIZE / 1024;
> -	dma->txconf.dst_addr		= dma->tx_addr;
> +	dma->txconf.direction				= DMA_MEM_TO_DEV;
> +	dma->txconf.dst_port_window_size	= UART_XMIT_SIZE;
> +	dma->txconf.dst_addr				= dma->tx_addr;
>  
>  	serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
>  		UART_FCR_CLEAR_XMIT);
> @@ -217,7 +210,7 @@ static void mtk8250_shutdown(struct uart_port *port)
>  	 * Mediatek UARTs use an extra highspeed register (UART_MTK_HIGHS)
>  	 *
>  	 * We need to recalcualte the quot register, as the claculation depends
> -	 * on the vaule in the highspeed register.
> +	 * on the value in the highspeed register.
>  	 *
>  	 * Some baudrates are not supported by the chip, so we use the next
>  	 * lower rate supported and update termios c_flag.
> -- 
> 1.7.9.5

-- 
~Vinod

^ permalink raw reply

* Re: [PATCH 1/4] dmaengine: mediatek: Add MediaTek UART APDMA support
From: Vinod Koul @ 2019-05-21 14:00 UTC (permalink / raw)
  To: Long Cheng
  Cc: Randy Dunlap, Rob Herring, Mark Rutland, Ryder Lee, Sean Wang,
	Nicolas Boichat, Matthias Brugger, Dan Williams,
	Greg Kroah-Hartman, Jiri Slaby, Sean Wang, dmaengine, devicetree,
	linux-arm-kernel, linux-mediatek, linux-kernel, linux-serial,
	srv_heupstream, Yingjoe Chen, YT Shen, Zhenbao Liu
In-Reply-To: <1556336193-15198-2-git-send-email-long.cheng@mediatek.com>

On 27-04-19, 11:36, Long Cheng wrote:
> Add 8250 UART APDMA to support MediaTek UART. If MediaTek UART is
> enabled by SERIAL_8250_MT6577, and we can enable this driver to offload
> the UART device moving bytes.

Applied, thanks

-- 
~Vinod

^ permalink raw reply

* Re: [PATCH 3/4] dt-bindings: dma: uart: rename binding
From: Vinod Koul @ 2019-05-21 14:01 UTC (permalink / raw)
  To: Long Cheng
  Cc: Randy Dunlap, Rob Herring, Mark Rutland, Ryder Lee, Sean Wang,
	Nicolas Boichat, Matthias Brugger, Dan Williams,
	Greg Kroah-Hartman, Jiri Slaby, Sean Wang, dmaengine, devicetree,
	linux-arm-kernel, linux-mediatek, linux-kernel, linux-serial,
	srv_heupstream, Yingjoe Chen, YT Shen, Zhenbao Liu
In-Reply-To: <1556336193-15198-4-git-send-email-long.cheng@mediatek.com>

On 27-04-19, 11:36, Long Cheng wrote:
> The filename matches mtk-uart-apdma.c.
> So using "mtk-uart-apdma.txt" should be better.
> And add some property.

Applied with Robs r-b tag in last version, thanks
Also fixed a trailing line in patch :(

-- 
~Vinod

^ permalink raw reply

* [PATCH] dmaengine: xilinx_dma: Remove set but unused ‘tail_desc’
From: Vinod Koul @ 2019-05-21 14:10 UTC (permalink / raw)
  To: dmaengine
  Cc: Vinod Koul, Michal Simek, Radhey Shyam Pandey, Andrea Merello,
	Appana Durga Kedareswara Rao

We get a compiler warn about variable ‘tail_desc’ set but not used

drivers/dma/xilinx/xilinx_dma.c:1102:42: warning:
	variable ‘tail_desc’ set but not used [-Wunused-but-set-variable]
  struct xilinx_dma_tx_descriptor *desc, *tail_desc;

So remove it.

Signed-off-by: Vinod Koul <vkoul@kernel.org>
---
 drivers/dma/xilinx/xilinx_dma.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
index c43c1a154604..34564224e675 100644
--- a/drivers/dma/xilinx/xilinx_dma.c
+++ b/drivers/dma/xilinx/xilinx_dma.c
@@ -1099,7 +1099,7 @@ static void xilinx_dma_start(struct xilinx_dma_chan *chan)
 static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
 {
 	struct xilinx_vdma_config *config = &chan->config;
-	struct xilinx_dma_tx_descriptor *desc, *tail_desc;
+	struct xilinx_dma_tx_descriptor *desc;
 	u32 reg, j;
 	struct xilinx_vdma_tx_segment *segment, *last = NULL;
 	int i = 0;
@@ -1116,8 +1116,6 @@ static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
 
 	desc = list_first_entry(&chan->pending_list,
 				struct xilinx_dma_tx_descriptor, node);
-	tail_desc = list_last_entry(&chan->pending_list,
-				    struct xilinx_dma_tx_descriptor, node);
 
 	/* Configure the hardware using info in the config structure */
 	if (chan->has_vflip) {
-- 
2.20.1


^ permalink raw reply related

* [PATCH 1/3][V2] include: fpga: adi-axi-common.h: add common regs & defs header
From: Alexandru Ardelean @ 2019-05-21 14:14 UTC (permalink / raw)
  To: dmaengine; +Cc: Alexandru Ardelean

The AXI HDL cores provided for Analog Devices reference designs all share
some common base registers (e.g. version register at address 0x00).

To reduce duplication for this, a common header is added to define these
registers as well as bitfields & macros to work with these registers.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
 include/linux/fpga/adi-axi-common.h | 19 +++++++++++++++++++
 1 file changed, 19 insertions(+)
 create mode 100644 include/linux/fpga/adi-axi-common.h

diff --git a/include/linux/fpga/adi-axi-common.h b/include/linux/fpga/adi-axi-common.h
new file mode 100644
index 000000000000..7966c89561b1
--- /dev/null
+++ b/include/linux/fpga/adi-axi-common.h
@@ -0,0 +1,19 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Analog Devices AXI common registers & definitions
+ *
+ * Copyright 2019 Analog Devices Inc.
+ *
+ * https://wiki.analog.com/resources/fpga/docs/axi_ip
+ * https://wiki.analog.com/resources/fpga/docs/hdl/regmap
+ */
+
+#ifndef ADI_AXI_COMMON_H_
+#define ADI_AXI_COMMON_H_
+
+#define	ADI_AXI_REG_VERSION			0x0000
+
+#define ADI_AXI_PCORE_VER(major, minor, patch)	\
+	(((major) << 16) | ((minor) << 8) | (patch))
+
+#endif /* ADI_AXI_COMMON_H_ */
-- 
2.17.1


^ permalink raw reply related

* [PATCH 3/3][V2] dmaengine: axi-dmac: assign `copy_align` property
From: Alexandru Ardelean @ 2019-05-21 14:14 UTC (permalink / raw)
  To: dmaengine; +Cc: Alexandru Ardelean
In-Reply-To: <20190521141425.26176-1-alexandru.ardelean@analog.com>

The `copy_align` property is a generic property that describes alignment
for DMA memcpy & sg ops.
It serves mostly an informational purpose, and can be used in DMA tests, to
pass the info to know what alignment to expect.

Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
 drivers/dma/dma-axi-dmac.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
index 196e6c429182..88f9986e0e14 100644
--- a/drivers/dma/dma-axi-dmac.c
+++ b/drivers/dma/dma-axi-dmac.c
@@ -762,6 +762,8 @@ static int axi_dmac_probe(struct platform_device *pdev)
 	if (ret)
 		goto err_clk_disable;
 
+	dma_dev->copy_align = (dmac->chan.address_align_mask + 1);
+
 	axi_dmac_write(dmac, AXI_DMAC_REG_IRQ_MASK, 0x00);
 
 	ret = dma_async_device_register(dma_dev);
-- 
2.17.1


^ permalink raw reply related

* [PATCH 2/3][V2] dmaengine: axi-dmac: Discover length alignment requirement
From: Alexandru Ardelean @ 2019-05-21 14:14 UTC (permalink / raw)
  To: dmaengine; +Cc: Lars-Peter Clausen, Alexandru Ardelean
In-Reply-To: <20190521141425.26176-1-alexandru.ardelean@analog.com>

From: Lars-Peter Clausen <lars@metafoo.de>

Starting with version 4.1.a the AXI-DMAC is capable of reporting the
required length alignment.

The LSBs that are required to be set for alignment will always read back as
set from the transfer length register. It is not possible to clear them by
writing a 0. This means the driver can discover the length alignment
requirement by writing 0 to that register and reading back the value.

Since the DMA will support length alignment requirements that are different
from the address alignment requirement track both of them independently.

For older versions of the peripheral assume that the length alignment
requirement is equal to the address alignment requirement.

Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
---
 drivers/dma/dma-axi-dmac.c | 22 +++++++++++++++++-----
 1 file changed, 17 insertions(+), 5 deletions(-)

diff --git a/drivers/dma/dma-axi-dmac.c b/drivers/dma/dma-axi-dmac.c
index 0984ae6eb155..196e6c429182 100644
--- a/drivers/dma/dma-axi-dmac.c
+++ b/drivers/dma/dma-axi-dmac.c
@@ -20,6 +20,7 @@
 #include <linux/of_dma.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/fpga/adi-axi-common.h>
 
 #include <dt-bindings/dma/axi-dmac.h>
 
@@ -110,7 +111,8 @@ struct axi_dmac_chan {
 	unsigned int dest_type;
 
 	unsigned int max_length;
-	unsigned int align_mask;
+	unsigned int address_align_mask;
+	unsigned int length_align_mask;
 
 	bool hw_cyclic;
 	bool hw_2d;
@@ -169,14 +171,14 @@ static bool axi_dmac_check_len(struct axi_dmac_chan *chan, unsigned int len)
 {
 	if (len == 0)
 		return false;
-	if ((len & chan->align_mask) != 0) /* Not aligned */
+	if ((len & chan->length_align_mask) != 0) /* Not aligned */
 		return false;
 	return true;
 }
 
 static bool axi_dmac_check_addr(struct axi_dmac_chan *chan, dma_addr_t addr)
 {
-	if ((addr & chan->align_mask) != 0) /* Not aligned */
+	if ((addr & chan->address_align_mask) != 0) /* Not aligned */
 		return false;
 	return true;
 }
@@ -394,7 +396,7 @@ static struct axi_dmac_sg *axi_dmac_fill_linear_sg(struct axi_dmac_chan *chan,
 	num_segments = DIV_ROUND_UP(period_len, chan->max_length);
 	segment_size = DIV_ROUND_UP(period_len, num_segments);
 	/* Take care of alignment */
-	segment_size = ((segment_size - 1) | chan->align_mask) + 1;
+	segment_size = ((segment_size - 1) | chan->length_align_mask) + 1;
 
 	for (i = 0; i < num_periods; i++) {
 		len = period_len;
@@ -623,7 +625,7 @@ static int axi_dmac_parse_chan_dt(struct device_node *of_chan,
 		return ret;
 	chan->dest_width = val / 8;
 
-	chan->align_mask = max(chan->dest_width, chan->src_width) - 1;
+	chan->address_align_mask = max(chan->dest_width, chan->src_width) - 1;
 
 	if (axi_dmac_dest_is_mem(chan) && axi_dmac_src_is_mem(chan))
 		chan->direction = DMA_MEM_TO_MEM;
@@ -640,6 +642,9 @@ static int axi_dmac_parse_chan_dt(struct device_node *of_chan,
 static int axi_dmac_detect_caps(struct axi_dmac *dmac)
 {
 	struct axi_dmac_chan *chan = &dmac->chan;
+	unsigned int version;
+
+	version = axi_dmac_read(dmac, ADI_AXI_REG_VERSION);
 
 	axi_dmac_write(dmac, AXI_DMAC_REG_FLAGS, AXI_DMAC_FLAG_CYCLIC);
 	if (axi_dmac_read(dmac, AXI_DMAC_REG_FLAGS) == AXI_DMAC_FLAG_CYCLIC)
@@ -670,6 +675,13 @@ static int axi_dmac_detect_caps(struct axi_dmac *dmac)
 		return -ENODEV;
 	}
 
+	if (version >= ADI_AXI_PCORE_VER(4, 1, 'a')) {
+		axi_dmac_write(dmac, AXI_DMAC_REG_X_LENGTH, 0x00);
+		chan->length_align_mask = axi_dmac_read(dmac, AXI_DMAC_REG_X_LENGTH);
+	} else {
+		chan->length_align_mask = chan->address_align_mask;
+	}
+
 	return 0;
 }
 
-- 
2.17.1


^ permalink raw reply related

* Re: [PATCH 1/3][V2] include: fpga: adi-axi-common.h: add common regs & defs header
From: Ardelean, Alexandru @ 2019-05-21 14:18 UTC (permalink / raw)
  To: dmaengine@vger.kernel.org
In-Reply-To: <20190521141425.26176-1-alexandru.ardelean@analog.com>

On Tue, 2019-05-21 at 17:14 +0300, Alexandru Ardelean wrote:
> The AXI HDL cores provided for Analog Devices reference designs all share
> some common base registers (e.g. version register at address 0x00).
> 
> To reduce duplication for this, a common header is added to define these
> registers as well as bitfields & macros to work with these registers.
> 
> Signed-off-by: Alexandru Ardelean <alexandru.ardelean@analog.com>
> ---

I forgot to add a changelog for this series when writing the patches.

Changelog v1 -> v2:
* add common `include/linux/fpga/adi-axi-common.h` with reg version; more regs will be added
* use macro to check version of HDL core from common header
* add my S-o-B to patch `dmaengine: axi-dmac: Discover length alignment requirement`


>  include/linux/fpga/adi-axi-common.h | 19 +++++++++++++++++++
>  1 file changed, 19 insertions(+)
>  create mode 100644 include/linux/fpga/adi-axi-common.h
> 
> diff --git a/include/linux/fpga/adi-axi-common.h b/include/linux/fpga/adi-axi-common.h
> new file mode 100644
> index 000000000000..7966c89561b1
> --- /dev/null
> +++ b/include/linux/fpga/adi-axi-common.h
> @@ -0,0 +1,19 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Analog Devices AXI common registers & definitions
> + *
> + * Copyright 2019 Analog Devices Inc.
> + *
> + * https://wiki.analog.com/resources/fpga/docs/axi_ip
> + * https://wiki.analog.com/resources/fpga/docs/hdl/regmap
> + */
> +
> +#ifndef ADI_AXI_COMMON_H_
> +#define ADI_AXI_COMMON_H_
> +
> +#define	ADI_AXI_REG_VERSION			0x0000
> +
> +#define ADI_AXI_PCORE_VER(major, minor, patch)	\
> +	(((major) << 16) | ((minor) << 8) | (patch))
> +
> +#endif /* ADI_AXI_COMMON_H_ */

^ permalink raw reply

* RE: [PATCH] dmaengine: xilinx_dma: Remove set but unused ‘tail_desc’
From: Radhey Shyam Pandey @ 2019-05-21 14:20 UTC (permalink / raw)
  To: Vinod Koul, dmaengine@vger.kernel.org
  Cc: Michal Simek, Andrea Merello, Appana Durga Kedareswara Rao
In-Reply-To: <20190521141034.8808-1-vkoul@kernel.org>

> -----Original Message-----
> From: Vinod Koul <vkoul@kernel.org>
> Sent: Tuesday, May 21, 2019 7:41 PM
> To: dmaengine@vger.kernel.org
> Cc: Vinod Koul <vkoul@kernel.org>; Michal Simek <michals@xilinx.com>;
> Radhey Shyam Pandey <radheys@xilinx.com>; Andrea Merello
> <andrea.merello@gmail.com>; Appana Durga Kedareswara Rao
> <appanad@xilinx.com>
> Subject: [PATCH] dmaengine: xilinx_dma: Remove set but unused ‘tail_desc’
> 
> We get a compiler warn about variable ‘tail_desc’ set but not used
> 
> drivers/dma/xilinx/xilinx_dma.c:1102:42: warning:
> 	variable ‘tail_desc’ set but not used [-Wunused-but-set-variable]
>   struct xilinx_dma_tx_descriptor *desc, *tail_desc;
> 
> So remove it.
> 
> Signed-off-by: Vinod Koul <vkoul@kernel.org>

Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>
Thanks!

> ---
>  drivers/dma/xilinx/xilinx_dma.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
> 
> diff --git a/drivers/dma/xilinx/xilinx_dma.c b/drivers/dma/xilinx/xilinx_dma.c
> index c43c1a154604..34564224e675 100644
> --- a/drivers/dma/xilinx/xilinx_dma.c
> +++ b/drivers/dma/xilinx/xilinx_dma.c
> @@ -1099,7 +1099,7 @@ static void xilinx_dma_start(struct xilinx_dma_chan
> *chan)
>  static void xilinx_vdma_start_transfer(struct xilinx_dma_chan *chan)
>  {
>  	struct xilinx_vdma_config *config = &chan->config;
> -	struct xilinx_dma_tx_descriptor *desc, *tail_desc;
> +	struct xilinx_dma_tx_descriptor *desc;
>  	u32 reg, j;
>  	struct xilinx_vdma_tx_segment *segment, *last = NULL;
>  	int i = 0;
> @@ -1116,8 +1116,6 @@ static void xilinx_vdma_start_transfer(struct
> xilinx_dma_chan *chan)
> 
>  	desc = list_first_entry(&chan->pending_list,
>  				struct xilinx_dma_tx_descriptor, node);
> -	tail_desc = list_last_entry(&chan->pending_list,
> -				    struct xilinx_dma_tx_descriptor, node);
> 
>  	/* Configure the hardware using info in the config structure */
>  	if (chan->has_vflip) {
> --
> 2.20.1


^ permalink raw reply

* [V3 1/2] dmaengine: fsl-qdma: fixed the source/destination descriptor format
From: Peng Ma @ 2019-05-22  3:21 UTC (permalink / raw)
  To: vkoul, dan.j.williams; +Cc: dmaengine, linux-kernel, Peng Ma

CMD of Source/Destination descriptor format should be lower of
struct fsl_qdma_engine number data address.

Signed-off-by: Peng Ma <peng.ma@nxp.com>
---
changed for V3:
	- Delete macro to simplify code.

 drivers/dma/fsl-qdma.c |   18 ++++++++++--------
 1 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c
index aa1d0ae..da8fdf5 100644
--- a/drivers/dma/fsl-qdma.c
+++ b/drivers/dma/fsl-qdma.c
@@ -113,6 +113,7 @@
 /* Field definition for Descriptor offset */
 #define QDMA_CCDF_STATUS		20
 #define QDMA_CCDF_OFFSET		20
+#define QDMA_SDDF_CMD(x)		(((u64)(x)) << 32)
 
 /* Field definition for safe loop count*/
 #define FSL_QDMA_HALT_COUNT		1500
@@ -341,6 +342,7 @@ static void fsl_qdma_free_chan_resources(struct dma_chan *chan)
 static void fsl_qdma_comp_fill_memcpy(struct fsl_qdma_comp *fsl_comp,
 				      dma_addr_t dst, dma_addr_t src, u32 len)
 {
+	u32 cmd;
 	struct fsl_qdma_format *sdf, *ddf;
 	struct fsl_qdma_format *ccdf, *csgf_desc, *csgf_src, *csgf_dest;
 
@@ -369,14 +371,14 @@ static void fsl_qdma_comp_fill_memcpy(struct fsl_qdma_comp *fsl_comp,
 	/* This entry is the last entry. */
 	qdma_csgf_set_f(csgf_dest, len);
 	/* Descriptor Buffer */
-	sdf->data =
-		cpu_to_le64(FSL_QDMA_CMD_RWTTYPE <<
-			    FSL_QDMA_CMD_RWTTYPE_OFFSET);
-	ddf->data =
-		cpu_to_le64(FSL_QDMA_CMD_RWTTYPE <<
-			    FSL_QDMA_CMD_RWTTYPE_OFFSET);
-	ddf->data |=
-		cpu_to_le64(FSL_QDMA_CMD_LWC << FSL_QDMA_CMD_LWC_OFFSET);
+	cmd = cpu_to_le32(FSL_QDMA_CMD_RWTTYPE <<
+			  FSL_QDMA_CMD_RWTTYPE_OFFSET);
+	sdf->data = QDMA_SDDF_CMD(cmd);
+
+	cmd = cpu_to_le32(FSL_QDMA_CMD_RWTTYPE <<
+			  FSL_QDMA_CMD_RWTTYPE_OFFSET);
+	cmd |= cpu_to_le32(FSL_QDMA_CMD_LWC << FSL_QDMA_CMD_LWC_OFFSET);
+	ddf->data = QDMA_SDDF_CMD(cmd);
 }
 
 /*
-- 
1.7.1


^ permalink raw reply related

* [V3 2/2] dmaengine: fsl-qdma: Add improvement
From: Peng Ma @ 2019-05-22  3:21 UTC (permalink / raw)
  To: vkoul, dan.j.williams; +Cc: dmaengine, linux-kernel, Peng Ma
In-Reply-To: <20190522032103.13713-1-peng.ma@nxp.com>

When an error occurs we should clean the error register then to return

Signed-off-by: Peng Ma <peng.ma@nxp.com>
---
changed for V3:
	- no changed.

 drivers/dma/fsl-qdma.c |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/fsl-qdma.c b/drivers/dma/fsl-qdma.c
index da8fdf5..8e341c0 100644
--- a/drivers/dma/fsl-qdma.c
+++ b/drivers/dma/fsl-qdma.c
@@ -703,10 +703,8 @@ static irqreturn_t fsl_qdma_error_handler(int irq, void *dev_id)
 
 	intr = qdma_readl(fsl_qdma, status + FSL_QDMA_DEDR);
 
-	if (intr) {
+	if (intr)
 		dev_err(fsl_qdma->dma_dev.dev, "DMA transaction error!\n");
-		return IRQ_NONE;
-	}
 
 	qdma_writel(fsl_qdma, FSL_QDMA_DEDR_CLEAR, status + FSL_QDMA_DEDR);
 	return IRQ_HANDLED;
-- 
1.7.1


^ permalink raw reply related

* Re: [PATCH] dmaengine: xilinx_dma: Remove set but unused ‘tail_desc’
From: Vinod Koul @ 2019-05-22  5:15 UTC (permalink / raw)
  To: Radhey Shyam Pandey
  Cc: dmaengine@vger.kernel.org, Michal Simek, Andrea Merello,
	Appana Durga Kedareswara Rao
In-Reply-To: <CH2PR02MB61980091BB537AC704B1F333C7070@CH2PR02MB6198.namprd02.prod.outlook.com>

On 21-05-19, 14:20, Radhey Shyam Pandey wrote:
> > -----Original Message-----
> > From: Vinod Koul <vkoul@kernel.org>
> > Sent: Tuesday, May 21, 2019 7:41 PM
> > To: dmaengine@vger.kernel.org
> > Cc: Vinod Koul <vkoul@kernel.org>; Michal Simek <michals@xilinx.com>;
> > Radhey Shyam Pandey <radheys@xilinx.com>; Andrea Merello
> > <andrea.merello@gmail.com>; Appana Durga Kedareswara Rao
> > <appanad@xilinx.com>
> > Subject: [PATCH] dmaengine: xilinx_dma: Remove set but unused ‘tail_desc’
> > 
> > We get a compiler warn about variable ‘tail_desc’ set but not used
> > 
> > drivers/dma/xilinx/xilinx_dma.c:1102:42: warning:
> > 	variable ‘tail_desc’ set but not used [-Wunused-but-set-variable]
> >   struct xilinx_dma_tx_descriptor *desc, *tail_desc;
> > 
> > So remove it.
> > 
> > Signed-off-by: Vinod Koul <vkoul@kernel.org>
> 
> Reviewed-by: Radhey Shyam Pandey <radhey.shyam.pandey@xilinx.com>

Thanks applied now

-- 
~Vinod

^ permalink raw reply

* Re: [PATCH 4/4] serial: 8250-mtk: modify uart DMA rx
From: Long Cheng @ 2019-05-22  5:24 UTC (permalink / raw)
  To: Nicolas Boichat
  Cc: Vinod Koul, Randy Dunlap, Rob Herring, Mark Rutland, Ryder Lee,
	Sean Wang, Matthias Brugger, Dan Williams, Greg Kroah-Hartman,
	Jiri Slaby, Sean Wang, dmaengine, devicetree,
	linux-arm Mailing List, moderated list:ARM/Mediatek SoC support,
	lkml, linux-serial, srv_heupstream, Yingjoe Chen, YT Shen,
	Zhenbao Liu, Long Cheng
In-Reply-To: <1558078602.14150.27.camel@mhfsdcap03>

On Fri, 2019-05-17 at 15:36 +0800, Long Cheng wrote:
> On Wed, 2019-05-15 at 21:48 +0800, Nicolas Boichat wrote:
> > On Sat, Apr 27, 2019 at 11:36 AM Long Cheng <long.cheng@mediatek.com> wrote:
> > >
> > > Modify uart rx and complete for DMA.
> > 
> > I don't know much about the DMA framework, but can you please explain
> > why you are making the changes in this CL? I see that you are dropping
> > dma_sync_single_for_device calls, for example, why?
> > 
> 
> the rx buffer is create by 'dma_alloc_coherent'. in the function, the
> buffer is uncache. We don't need to sync between CPU and DMA. So I
> remove it.
> 
> > >
> > > Signed-off-by: Long Cheng <long.cheng@mediatek.com>
> > > ---
> > >  drivers/tty/serial/8250/8250_mtk.c |   53 ++++++++++++++++--------------------
> > >  1 file changed, 23 insertions(+), 30 deletions(-)
> > >
> > > diff --git a/drivers/tty/serial/8250/8250_mtk.c b/drivers/tty/serial/8250/8250_mtk.c
> > > index c1fdbc0..04081a6 100644
> > > --- a/drivers/tty/serial/8250/8250_mtk.c
> > > +++ b/drivers/tty/serial/8250/8250_mtk.c
> > > @@ -30,7 +30,6 @@
> > >  #define MTK_UART_DMA_EN_TX     0x2
> > >  #define MTK_UART_DMA_EN_RX     0x5
> > >
> > > -#define MTK_UART_TX_SIZE       UART_XMIT_SIZE
> > >  #define MTK_UART_RX_SIZE       0x8000
> > >  #define MTK_UART_TX_TRIGGER    1
> > >  #define MTK_UART_RX_TRIGGER    MTK_UART_RX_SIZE
> > > @@ -64,28 +63,30 @@ static void mtk8250_dma_rx_complete(void *param)
> > >         struct mtk8250_data *data = up->port.private_data;
> > >         struct tty_port *tty_port = &up->port.state->port;
> > >         struct dma_tx_state state;
> > > +       int copied, cnt, tmp;
> > >         unsigned char *ptr;
> > > -       int copied;
> > >
> > > -       dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
> > > -                               dma->rx_size, DMA_FROM_DEVICE);
> > > +       if (data->rx_status == DMA_RX_SHUTDOWN)
> > > +               return;
> > >
> > >         dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
> > > +       cnt = dma->rx_size - state.residue;
> > > +       tmp = cnt;
> > 
> > I ponder, maybe we should rename cnt to left? (like, how many bytes
> > are left to transfer, in total) Or maybe "total"
> > Then maybe rename tmp to cnt.
> > 
> like better.
> 
> > >
> > > -       if (data->rx_status == DMA_RX_SHUTDOWN)
> > > -               return;
> > > +       if ((data->rx_pos + cnt) > dma->rx_size)
> > > +               tmp = dma->rx_size - data->rx_pos;
> > 
> > Maybe replace this and the line above:
> > tmp = max_t(int, cnt, dma->rx_size - data->rx_pos);
> > 
> Yes. It's better.
> 

can't replace by 'max_t'. So I will keep original code.

> > >
> > > -       if ((data->rx_pos + state.residue) <= dma->rx_size) {
> > > -               ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> > > -               copied = tty_insert_flip_string(tty_port, ptr, state.residue);
> > > -       } else {
> > > -               ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> > > -               copied = tty_insert_flip_string(tty_port, ptr,
> > > -                                               dma->rx_size - data->rx_pos);
> > > +       ptr = (unsigned char *)(data->rx_pos + dma->rx_buf);
> > > +       copied = tty_insert_flip_string(tty_port, ptr, tmp);
> > > +       data->rx_pos += tmp;
> > > +
> > > +       if (cnt > tmp) {
> > >                 ptr = (unsigned char *)(dma->rx_buf);
> > > -               copied += tty_insert_flip_string(tty_port, ptr,
> > > -                               data->rx_pos + state.residue - dma->rx_size);
> > > +               tmp = cnt - tmp;
> > > +               copied += tty_insert_flip_string(tty_port, ptr, tmp);
> > > +               data->rx_pos = tmp;
> > >         }
> > > +
> > >         up->port.icount.rx += copied;
> > >
> > >         tty_flip_buffer_push(tty_port);
> > > @@ -96,9 +97,7 @@ static void mtk8250_dma_rx_complete(void *param)
> > >  static void mtk8250_rx_dma(struct uart_8250_port *up)
> > >  {
> > >         struct uart_8250_dma *dma = up->dma;
> > > -       struct mtk8250_data *data = up->port.private_data;
> > >         struct dma_async_tx_descriptor  *desc;
> > > -       struct dma_tx_state      state;
> > >
> > >         desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
> > >                                            dma->rx_size, DMA_DEV_TO_MEM,
> > > @@ -113,12 +112,6 @@ static void mtk8250_rx_dma(struct uart_8250_port *up)
> > >
> > >         dma->rx_cookie = dmaengine_submit(desc);
> > >
> > > -       dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
> > > -       data->rx_pos = state.residue;
> > > -
> > > -       dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
> > > -                                  dma->rx_size, DMA_FROM_DEVICE);
> > > -
> > >         dma_async_issue_pending(dma->rxchan);
> > >  }
> > >
> > > @@ -131,13 +124,13 @@ static void mtk8250_dma_enable(struct uart_8250_port *up)
> > >         if (data->rx_status != DMA_RX_START)
> > >                 return;
> > >
> > > -       dma->rxconf.direction           = DMA_DEV_TO_MEM;
> > > -       dma->rxconf.src_addr_width      = dma->rx_size / 1024;
> > > -       dma->rxconf.src_addr            = dma->rx_addr;
> > > +       dma->rxconf.direction                           = DMA_DEV_TO_MEM;
> > > +       dma->rxconf.src_port_window_size        = dma->rx_size;
> > > +       dma->rxconf.src_addr                            = dma->rx_addr;
> > >
> > > -       dma->txconf.direction           = DMA_MEM_TO_DEV;
> > > -       dma->txconf.dst_addr_width      = MTK_UART_TX_SIZE / 1024;
> > > -       dma->txconf.dst_addr            = dma->tx_addr;
> > > +       dma->txconf.direction                           = DMA_MEM_TO_DEV;
> > > +       dma->txconf.dst_port_window_size        = UART_XMIT_SIZE;
> > > +       dma->txconf.dst_addr                            = dma->tx_addr;
> > >
> > >         serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR_CLEAR_RCVR |
> > >                 UART_FCR_CLEAR_XMIT);
> > > @@ -217,7 +210,7 @@ static void mtk8250_shutdown(struct uart_port *port)
> > >          * Mediatek UARTs use an extra highspeed register (UART_MTK_HIGHS)
> > >          *
> > >          * We need to recalcualte the quot register, as the claculation depends
> > > -        * on the vaule in the highspeed register.
> > > +        * on the value in the highspeed register.
> > 
> > Since you're doing some cosmetic changes here, you might as well fix
> > recalcualte => recalculate and claculation => calculation on the line
> > above.
> > 
> 
> I see.
> 
> > But technically, this should belong in another patch...
> > 
> > >          *
> > >          * Some baudrates are not supported by the chip, so we use the next
> > >          * lower rate supported and update termios c_flag.
> > > --
> > > 1.7.9.5
> > >
> 



^ permalink raw reply

* RE: [EXT] Re: [PATCH 3/4] dmaengine: fsl-edma: support little endian for edma driver
From: Peng Ma @ 2019-05-22  6:33 UTC (permalink / raw)
  To: Vinod Koul
  Cc: robh+dt@kernel.org, shawnguo@kernel.org, mark.rutland@arm.com,
	Leo Li, dan.j.williams@intel.com, dmaengine@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org
In-Reply-To: <20190521043807.GN15118@vkoul-mobl>

Hi Vinod,

Thank for you reply.
the registers (CHCFG0 - CHCFG15) on big endian socs as fallows:
CHCFG0		0x0
CHCFG1		0x1
CHCFG2		0x2
CHCFG3		0x3
......
CHCFG12		0xC
CHCFG13		0xD
CHCFG14		0xE
CHCFG15		0xF

On little endian socs as fallows:
CHCFG3		0x0
CHCFG2		0x1
CHCFG1		0x2
CHCFG0		0x3
......
CHCFG15		0xC
CHCFG14		0xD
CHCFG13		0xE
CHCFG12		0xF

To fit this map we should add this patch.

Best Regards,
Peng
>-----Original Message-----
>From: Vinod Koul <vkoul@kernel.org>
>Sent: 2019年5月21日 12:38
>To: Peng Ma <peng.ma@nxp.com>
>Cc: robh+dt@kernel.org; shawnguo@kernel.org; mark.rutland@arm.com; Leo
>Li <leoyang.li@nxp.com>; dan.j.williams@intel.com;
>dmaengine@vger.kernel.org; devicetree@vger.kernel.org;
>linux-kernel@vger.kernel.org; linux-arm-kernel@lists.infradead.org
>Subject: [EXT] Re: [PATCH 3/4] dmaengine: fsl-edma: support little endian for
>edma driver
>
>Caution: EXT Email
>
>On 06-05-19, 09:03, Peng Ma wrote:
>> improve edma driver to support little endian.
>
>Can you explain a bit more how adding the below lines adds little endian
>support...
>
>>
>> Signed-off-by: Peng Ma <peng.ma@nxp.com>
>> ---
>>  drivers/dma/fsl-edma-common.c |    5 +++++
>>  1 files changed, 5 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/dma/fsl-edma-common.c
>> b/drivers/dma/fsl-edma-common.c index 680b2a0..6bf238e 100644
>> --- a/drivers/dma/fsl-edma-common.c
>> +++ b/drivers/dma/fsl-edma-common.c
>> @@ -83,9 +83,14 @@ void fsl_edma_chan_mux(struct fsl_edma_chan
>*fsl_chan,
>>       u32 ch = fsl_chan->vchan.chan.chan_id;
>>       void __iomem *muxaddr;
>>       unsigned int chans_per_mux, ch_off;
>> +     int endian_diff[4] = {3, 1, -1, -3};
>>
>>       chans_per_mux = fsl_chan->edma->n_chans / DMAMUX_NR;
>>       ch_off = fsl_chan->vchan.chan.chan_id % chans_per_mux;
>> +
>> +     if (!fsl_chan->edma->big_endian)
>> +             ch_off += endian_diff[ch_off % 4];
>> +
>>       muxaddr = fsl_chan->edma->muxbase[ch / chans_per_mux];
>>       slot = EDMAMUX_CHCFG_SOURCE(slot);
>>
>> --
>> 1.7.1
>
>--
>~Vinod

^ permalink raw reply

* [PATCH v4 00/14] add ecspi ERR009165 for i.mx6/7 soc family
From: Robin Gong @ 2019-05-22  9:59 UTC (permalink / raw)
  To: robh@kernel.org, broonie@kernel.org, shawnguo@kernel.org,
	s.hauer@pengutronix.de, festevam@gmail.com, mark.rutland@arm.com,
	vkoul@kernel.org, dan.j.williams@intel.com,
	u.kleine-koenig@pengutronix.de, plyatov@gmail.com,
	catalin.marinas@arm.com, l.stach@pengutronix.de
  Cc: linux-spi@vger.kernel.org, dl-linux-imx,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org,
	devicetree@vger.kernel.org, kernel@pengutronix.de

  There is ecspi ERR009165 on i.mx6/7 soc family, which cause FIFO
transfer to be send twice in DMA mode. Please get more information from:
https://www.nxp.com/docs/en/errata/IMX6DQCE.pdf. The workaround is adding
new sdma ram script which works in XCH  mode as PIO inside sdma instead
of SMC mode, meanwhile, 'TX_THRESHOLD' should be 0. The issue should be
exist on all legacy i.mx6/7 soc family before i.mx6ul.
NXP fix this design issue from i.mx6ul, so newer chips including i.mx6ul/
6ull/6sll do not need this workaroud anymore. All other i.mx6/7/8 chips
still need this workaroud. This patch set add new 'fsl,imx6ul-ecspi'
for ecspi driver and 'ecspi_fixed' in sdma driver to choose if need errata
or not.
  The first two reverted patches should be the same issue, though, it
seems 'fixed' by changing to other shp script. Hope Sean or Sascha could
have the chance to test this patch set if could fix their issues.
  Besides, enable sdma support for i.mx8mm/8mq and fix ecspi1 not work
on i.mx8mm because the event id is zero.

PS:
  Please get sdma firmware from below linux-firmware and copy it to your
local rootfs /lib/firmware/imx/sdma.
https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/tree/imx/sdma

v2:
  1. add commit log for reverted patches.
  2. add comment for 'ecspi_fixed' in sdma driver.
  3. add 'fsl,imx6sll-ecspi' compatible instead of 'fsl,imx6ul-ecspi'
     rather than remove.
v3:
  1. confirm with design team make sure ERR009165 fixed on i.mx6ul/i.mx6ull
  /i.mx6sll, not fixed on i.mx8m/8mm and other i.mx6/7 legacy chips.
  Correct dts related dts patch in v2.
  2. clean eratta information in binding doc and new 'tx_glitch_fixed' flag
  in spi-imx driver to state ERR009165 fixed or not.
  3. Enlarge burst size to fifo size for tx since tx_wml set to 0 in the
  errata workaroud, thus improve performance as possible.
v4:
  1. add Ack tag from Mark and Vinod
  2. remove checking 'event_id1' zero as 'event_id0'.

Robin Gong (14):
  Revert "ARM: dts: imx6q: Use correct SDMA script for SPI5 core"
  Revert "ARM: dts: imx6: Use correct SDMA script for SPI cores"
  Revert "dmaengine: imx-sdma: refine to load context only once"
  dmaengine: imx-sdma: remove dupilicated sdma_load_context
  dmaengine: imx-sdma: add mcu_2_ecspi script
  spi: imx: fix ERR009165
  spi: imx: remove ERR009165 workaround on i.mx6ul
  dt-bindings: spi: imx: add new i.mx6ul compatible name
  dmaengine: imx-sdma: remove ERR009165 on i.mx6ul
  dt-bindings: dma: imx-sdma: add i.mx6ul/6sx compatible name
  dmaengine: imx-sdma: fix ecspi1 rx dma not work on i.mx8mm
  ARM: dts: imx6ul: add dma support on ecspi
  ARM: dts: imx6sll: correct sdma compatible
  arm64: defconfig: Enable SDMA on i.mx8mq/8mm

 .../devicetree/bindings/dma/fsl-imx-sdma.txt       |  2 +
 .../devicetree/bindings/spi/fsl-imx-cspi.txt       |  1 +
 arch/arm/boot/dts/imx6q.dtsi                       |  2 +-
 arch/arm/boot/dts/imx6qdl.dtsi                     |  8 +--
 arch/arm/boot/dts/imx6sll.dtsi                     |  2 +-
 arch/arm/boot/dts/imx6ul.dtsi                      |  8 +++
 arch/arm64/configs/defconfig                       |  3 +
 drivers/dma/imx-sdma.c                             | 78 ++++++++++++++++------
 drivers/spi/spi-imx.c                              | 61 ++++++++++++++---
 include/linux/platform_data/dma-imx-sdma.h         |  1 +
 10 files changed, 132 insertions(+), 34 deletions(-)

-- 
2.7.4


^ permalink raw reply

* [PATCH v4 01/14] Revert "ARM: dts: imx6q: Use correct SDMA script for SPI5 core"
From: Robin Gong @ 2019-05-22  9:59 UTC (permalink / raw)
  To: robh@kernel.org, broonie@kernel.org, shawnguo@kernel.org,
	s.hauer@pengutronix.de, festevam@gmail.com, mark.rutland@arm.com,
	vkoul@kernel.org, dan.j.williams@intel.com,
	u.kleine-koenig@pengutronix.de, plyatov@gmail.com,
	catalin.marinas@arm.com, l.stach@pengutronix.de
  Cc: linux-spi@vger.kernel.org, dl-linux-imx,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, dmaengine@vger.kernel.org,
	devicetree@vger.kernel.org, kernel@pengutronix.de
In-Reply-To: <1558548188-1155-1-git-send-email-yibin.gong@nxp.com>

  There are two ways for SDMA accessing SPBA devices: one is SDMA->AIPS
->SPBA(masterA port), another is SDMA->SPBA(masterC port). Please refer
to the 'Figure 58-1. i.MX 6Dual/6Quad SPBA connectivity' of i.mx6DQ
Reference Manual. SDMA provide the corresponding app_2_mcu/mcu_2_app and
shp_2_mcu/mcu_2_shp script for such two options. So both AIPS and SPBA
scripts should keep the same behaviour, the issue only caught in AIPS
script sounds not solide.
  The issue is more likely as the ecspi errata
ERR009165(http://www.nxp.com/docs/en/errata/IMX6DQCE.pdf):
eCSPI: TXFIFO empty flag glitch can cause the current FIFO transfer to
       be sent twice
So revert commit 'df07101e1c4a' firstly.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
---
 arch/arm/boot/dts/imx6q.dtsi | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index d038f41..7175898 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -172,7 +172,7 @@
 					clocks = <&clks IMX6Q_CLK_ECSPI5>,
 						 <&clks IMX6Q_CLK_ECSPI5>;
 					clock-names = "ipg", "per";
-					dmas = <&sdma 11 8 1>, <&sdma 12 8 2>;
+					dmas = <&sdma 11 7 1>, <&sdma 12 7 2>;
 					dma-names = "rx", "tx";
 					status = "disabled";
 				};
-- 
2.7.4


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox