All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/6] dmaengine: fsl-edma: integrate TCD64 support for 64bit physical address
@ 2023-11-27 22:55 Frank Li
  2023-11-27 22:55 ` [PATCH v3 1/6] dmaengine: fsl-edma: involve help macro fsl_edma_set(get)_tcd() Frank Li
                   ` (6 more replies)
  0 siblings, 7 replies; 10+ messages in thread
From: Frank Li @ 2023-11-27 22:55 UTC (permalink / raw)
  To: frank.li, vkoul
  Cc: devicetree, dmaengine, imx, joy.zou, krzysztof.kozlowski+dt,
	linux-kernel, peng.fan, robh+dt, shenwei.wang

Change from v2 to v3:
 - fix sparse build warning

Change from v1 to v2:
- fixed mcf-edma-main.c build error.
- fixed readq build error. readq actually is not atomic read in imx95.
So split to two ioread32\iowrite32.
  It needs read at least twice to avoid lower 32 bit part wrap during read
up 32bit part.

first 2 patch is prepare, No function change.
3rd patch is dt-bind doc
4rd patch is actuall support TCD64

Frank Li (6):
  dmaengine: fsl-edma: involve help macro fsl_edma_set(get)_tcd()
  dmaengine: fsl-edma: fix spare build warning
  dmaengine: fsl-edma: add address for channel mux register in
    fsl_edma_chan
  dmaengine: mcf-edma: utilize edma_write_tcdreg() macro for TCD Access
  dt-bindings: fsl-dma: fsl-edma: add fsl,imx95-edma5 compatible string
  dmaengine: fsl-edma: integrate TCD64 support for i.MX95

 .../devicetree/bindings/dma/fsl,edma.yaml     |   2 +
 drivers/dma/fsl-edma-common.c                 | 101 ++++++-----
 drivers/dma/fsl-edma-common.h                 | 161 ++++++++++++++++--
 drivers/dma/fsl-edma-main.c                   |  19 ++-
 drivers/dma/mcf-edma-main.c                   |   2 +-
 5 files changed, 223 insertions(+), 62 deletions(-)

-- 
2.34.1


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

* [PATCH v3 1/6] dmaengine: fsl-edma: involve help macro fsl_edma_set(get)_tcd()
  2023-11-27 22:55 [PATCH v3 0/6] dmaengine: fsl-edma: integrate TCD64 support for 64bit physical address Frank Li
@ 2023-11-27 22:55 ` Frank Li
  2023-11-27 22:55 ` [PATCH v3 2/6] dmaengine: fsl-edma: fix spare build warning Frank Li
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Frank Li @ 2023-11-27 22:55 UTC (permalink / raw)
  To: frank.li, vkoul
  Cc: devicetree, dmaengine, imx, joy.zou, krzysztof.kozlowski+dt,
	linux-kernel, peng.fan, robh+dt, shenwei.wang

Using help macro fsl_edma_set(get)_tcd() and edma_cp_tcd_to_reg() to handle
difference field size. This is not function change and prepare for 64bit
tcd in imx95.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/dma/fsl-edma-common.c | 61 ++++++++++++++++++-----------------
 drivers/dma/fsl-edma-common.h | 23 +++++++++++++
 2 files changed, 54 insertions(+), 30 deletions(-)

diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
index b53f46245c377..50f55d7566a33 100644
--- a/drivers/dma/fsl-edma-common.c
+++ b/drivers/dma/fsl-edma-common.c
@@ -358,10 +358,10 @@ static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
 
 	/* calculate the total size in this desc */
 	for (len = i = 0; i < fsl_chan->edesc->n_tcds; i++) {
-		nbytes = le32_to_cpu(edesc->tcd[i].vtcd->nbytes);
+		nbytes = fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->tcd[i].vtcd, nbytes);
 		if (nbytes & (EDMA_V3_TCD_NBYTES_DMLOE | EDMA_V3_TCD_NBYTES_SMLOE))
 			nbytes = EDMA_V3_TCD_NBYTES_MLOFF_NBYTES(nbytes);
-		len += nbytes * le16_to_cpu(edesc->tcd[i].vtcd->biter);
+		len += nbytes * fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->tcd[i].vtcd, biter);
 	}
 
 	if (!in_progress)
@@ -374,16 +374,16 @@ static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
 
 	/* figure out the finished and calculate the residue */
 	for (i = 0; i < fsl_chan->edesc->n_tcds; i++) {
-		nbytes = le32_to_cpu(edesc->tcd[i].vtcd->nbytes);
+		nbytes = fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->tcd[i].vtcd, nbytes);
 		if (nbytes & (EDMA_V3_TCD_NBYTES_DMLOE | EDMA_V3_TCD_NBYTES_SMLOE))
 			nbytes = EDMA_V3_TCD_NBYTES_MLOFF_NBYTES(nbytes);
 
-		size = nbytes * le16_to_cpu(edesc->tcd[i].vtcd->biter);
+		size = nbytes * fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->tcd[i].vtcd, biter);
 
 		if (dir == DMA_MEM_TO_DEV)
-			dma_addr = le32_to_cpu(edesc->tcd[i].vtcd->saddr);
+			dma_addr = fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->tcd[i].vtcd, saddr);
 		else
-			dma_addr = le32_to_cpu(edesc->tcd[i].vtcd->daddr);
+			dma_addr = fsl_edma_get_tcd_to_cpu(fsl_chan, edesc->tcd[i].vtcd, daddr);
 
 		len -= size;
 		if (cur_addr >= dma_addr && cur_addr < dma_addr + size) {
@@ -439,26 +439,26 @@ static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
 	 */
 	edma_write_tcdreg(fsl_chan, 0, csr);
 
-	edma_write_tcdreg(fsl_chan, tcd->saddr, saddr);
-	edma_write_tcdreg(fsl_chan, tcd->daddr, daddr);
+	edma_cp_tcd_to_reg(fsl_chan, tcd, saddr);
+	edma_cp_tcd_to_reg(fsl_chan, tcd, daddr);
 
-	edma_write_tcdreg(fsl_chan, tcd->attr, attr);
-	edma_write_tcdreg(fsl_chan, tcd->soff, soff);
+	edma_cp_tcd_to_reg(fsl_chan, tcd, attr);
+	edma_cp_tcd_to_reg(fsl_chan, tcd, soff);
 
-	edma_write_tcdreg(fsl_chan, tcd->nbytes, nbytes);
-	edma_write_tcdreg(fsl_chan, tcd->slast, slast);
+	edma_cp_tcd_to_reg(fsl_chan, tcd, nbytes);
+	edma_cp_tcd_to_reg(fsl_chan, tcd, slast);
 
-	edma_write_tcdreg(fsl_chan, tcd->citer, citer);
-	edma_write_tcdreg(fsl_chan, tcd->biter, biter);
-	edma_write_tcdreg(fsl_chan, tcd->doff, doff);
+	edma_cp_tcd_to_reg(fsl_chan, tcd, citer);
+	edma_cp_tcd_to_reg(fsl_chan, tcd, biter);
+	edma_cp_tcd_to_reg(fsl_chan, tcd, doff);
 
-	edma_write_tcdreg(fsl_chan, tcd->dlast_sga, dlast_sga);
+	edma_cp_tcd_to_reg(fsl_chan, tcd, dlast_sga);
 
-	csr = le16_to_cpu(tcd->csr);
+	csr = fsl_edma_get_tcd_to_cpu(fsl_chan, tcd, csr);
 
 	if (fsl_chan->is_sw) {
 		csr |= EDMA_TCD_CSR_START;
-		tcd->csr = cpu_to_le16(csr);
+		fsl_edma_set_tcd_to_le(fsl_chan, tcd, csr, csr);
 	}
 
 	/*
@@ -473,7 +473,7 @@ static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
 		edma_writel_chreg(fsl_chan, edma_readl_chreg(fsl_chan, ch_csr), ch_csr);
 
 
-	edma_write_tcdreg(fsl_chan, tcd->csr, csr);
+	edma_cp_tcd_to_reg(fsl_chan, tcd, csr);
 }
 
 static inline
@@ -493,12 +493,12 @@ void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan,
 	 * So we put the value in little endian in memory, waiting
 	 * for fsl_edma_set_tcd_regs doing the swap.
 	 */
-	tcd->saddr = cpu_to_le32(src);
-	tcd->daddr = cpu_to_le32(dst);
+	fsl_edma_set_tcd_to_le(fsl_chan, tcd, src, saddr);
+	fsl_edma_set_tcd_to_le(fsl_chan, tcd, dst, daddr);
 
-	tcd->attr = cpu_to_le16(attr);
+	fsl_edma_set_tcd_to_le(fsl_chan, tcd, attr, attr);
 
-	tcd->soff = cpu_to_le16(soff);
+	fsl_edma_set_tcd_to_le(fsl_chan, tcd, soff, soff);
 
 	if (fsl_chan->is_multi_fifo) {
 		/* set mloff to support multiple fifo */
@@ -515,15 +515,16 @@ void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan,
 		}
 	}
 
-	tcd->nbytes = cpu_to_le32(nbytes);
-	tcd->slast = cpu_to_le32(slast);
+	fsl_edma_set_tcd_to_le(fsl_chan, tcd, nbytes, nbytes);
+	fsl_edma_set_tcd_to_le(fsl_chan, tcd, slast, slast);
 
-	tcd->citer = cpu_to_le16(EDMA_TCD_CITER_CITER(citer));
-	tcd->doff = cpu_to_le16(doff);
+	fsl_edma_set_tcd_to_le(fsl_chan, tcd, EDMA_TCD_CITER_CITER(citer), citer);
+	fsl_edma_set_tcd_to_le(fsl_chan, tcd, doff, doff);
 
-	tcd->dlast_sga = cpu_to_le32(dlast_sga);
+	fsl_edma_set_tcd_to_le(fsl_chan, tcd, dlast_sga, dlast_sga);
+
+	fsl_edma_set_tcd_to_le(fsl_chan, tcd, EDMA_TCD_BITER_BITER(biter), biter);
 
-	tcd->biter = cpu_to_le16(EDMA_TCD_BITER_BITER(biter));
 	if (major_int)
 		csr |= EDMA_TCD_CSR_INT_MAJOR;
 
@@ -539,7 +540,7 @@ void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan,
 	if (fsl_chan->is_sw)
 		csr |= EDMA_TCD_CSR_START;
 
-	tcd->csr = cpu_to_le16(csr);
+	fsl_edma_set_tcd_to_le(fsl_chan, tcd, csr, csr);
 }
 
 static struct fsl_edma_desc *fsl_edma_alloc_desc(struct fsl_edma_chan *fsl_chan,
diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h
index bb5221158a770..ce779274d81e5 100644
--- a/drivers/dma/fsl-edma-common.h
+++ b/drivers/dma/fsl-edma-common.h
@@ -238,6 +238,9 @@ struct fsl_edma_engine {
 	edma_writel(chan->edma, (u32 __force)val, &chan->tcd->__name) :	\
 	edma_writew(chan->edma, (u16 __force)val, &chan->tcd->__name))
 
+#define edma_cp_tcd_to_reg(chan, __tcd, __name)			\
+	edma_write_tcdreg(chan, __tcd->__name, __name)
+
 #define edma_readl_chreg(chan, __name)				\
 	edma_readl(chan->edma,					\
 		   (void __iomem *)&(container_of(chan->tcd, struct fsl_edma3_ch_reg, tcd)->__name))
@@ -246,6 +249,26 @@ struct fsl_edma_engine {
 	edma_writel(chan->edma, val,				\
 		   (void __iomem *)&(container_of(chan->tcd, struct fsl_edma3_ch_reg, tcd)->__name))
 
+#define fsl_edma_get_tcd(_chan, _tcd, _field) ((_tcd)->_field)
+
+#define fsl_edma_le_to_cpu(x)					\
+(sizeof(x) == sizeof(u32) ? le32_to_cpu((__force __le32)(x)) : le16_to_cpu((__force __le16)(x)))
+
+#define fsl_edma_get_tcd_to_cpu(_chan, _tcd, _field)		\
+fsl_edma_le_to_cpu(fsl_edma_get_tcd(_chan, _tcd, _field))
+
+#define fsl_edma_set_tcd_to_le(_fsl_chan, _tcd, _val, _field)			\
+do {										\
+	switch (sizeof((_tcd)->_field)) {					\
+	case sizeof(u32):							\
+		*(__force __le32 *)(&((_tcd)->_field)) = cpu_to_le32(_val);	\
+		break;								\
+	case sizeof(u16):							\
+		*(__force __le16 *)(&((_tcd)->_field)) = cpu_to_le16(_val);	\
+		break;								\
+	}									\
+} while (0)
+
 /*
  * R/W functions for big- or little-endian registers:
  * The eDMA controller's endian is independent of the CPU core's endian.
-- 
2.34.1


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

* [PATCH v3 2/6] dmaengine: fsl-edma: fix spare build warning
  2023-11-27 22:55 [PATCH v3 0/6] dmaengine: fsl-edma: integrate TCD64 support for 64bit physical address Frank Li
  2023-11-27 22:55 ` [PATCH v3 1/6] dmaengine: fsl-edma: involve help macro fsl_edma_set(get)_tcd() Frank Li
@ 2023-11-27 22:55 ` Frank Li
  2023-11-27 22:55 ` [PATCH v3 3/6] dmaengine: fsl-edma: add address for channel mux register in fsl_edma_chan Frank Li
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Frank Li @ 2023-11-27 22:55 UTC (permalink / raw)
  To: frank.li, vkoul
  Cc: devicetree, dmaengine, imx, joy.zou, krzysztof.kozlowski+dt,
	linux-kernel, peng.fan, robh+dt, shenwei.wang

../drivers/dma/fsl-edma-common.c:93:9: sparse: warning: cast removes address space '__iomem' of expression
../drivers/dma/fsl-edma-common.c:101:25: sparse: warning: cast removes address space '__iomem' of expression
...
../drivers/dma/fsl-edma-main.c:557:17: sparse:    got restricted __le32 [usertype]

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/dma/fsl-edma-common.h | 6 ++++--
 drivers/dma/fsl-edma-main.c   | 2 +-
 2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h
index ce779274d81e5..fb45c7d4c1f4c 100644
--- a/drivers/dma/fsl-edma-common.h
+++ b/drivers/dma/fsl-edma-common.h
@@ -243,11 +243,13 @@ struct fsl_edma_engine {
 
 #define edma_readl_chreg(chan, __name)				\
 	edma_readl(chan->edma,					\
-		   (void __iomem *)&(container_of(chan->tcd, struct fsl_edma3_ch_reg, tcd)->__name))
+		   (void __iomem *)&(container_of(((__force void *)chan->tcd),\
+						  struct fsl_edma3_ch_reg, tcd)->__name))
 
 #define edma_writel_chreg(chan, val,  __name)			\
 	edma_writel(chan->edma, val,				\
-		   (void __iomem *)&(container_of(chan->tcd, struct fsl_edma3_ch_reg, tcd)->__name))
+		   (void __iomem *)&(container_of(((__force void *)chan->tcd),\
+						  struct fsl_edma3_ch_reg, tcd)->__name))
 
 #define fsl_edma_get_tcd(_chan, _tcd, _field) ((_tcd)->_field)
 
diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
index f53b0ec17bcbc..86b293eba27c2 100644
--- a/drivers/dma/fsl-edma-main.c
+++ b/drivers/dma/fsl-edma-main.c
@@ -537,7 +537,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
 		fsl_chan->pdev = pdev;
 		vchan_init(&fsl_chan->vchan, &fsl_edma->dma_dev);
 
-		edma_write_tcdreg(fsl_chan, 0, csr);
+		edma_write_tcdreg(fsl_chan, cpu_to_le32(0), csr);
 		fsl_edma_chan_mux(fsl_chan, 0, false);
 	}
 
-- 
2.34.1


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

* [PATCH v3 3/6] dmaengine: fsl-edma: add address for channel mux register in fsl_edma_chan
  2023-11-27 22:55 [PATCH v3 0/6] dmaengine: fsl-edma: integrate TCD64 support for 64bit physical address Frank Li
  2023-11-27 22:55 ` [PATCH v3 1/6] dmaengine: fsl-edma: involve help macro fsl_edma_set(get)_tcd() Frank Li
  2023-11-27 22:55 ` [PATCH v3 2/6] dmaengine: fsl-edma: fix spare build warning Frank Li
@ 2023-11-27 22:55 ` Frank Li
  2023-11-27 22:55 ` [PATCH v3 4/6] dmaengine: mcf-edma: utilize edma_write_tcdreg() macro for TCD Access Frank Li
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Frank Li @ 2023-11-27 22:55 UTC (permalink / raw)
  To: frank.li, vkoul
  Cc: devicetree, dmaengine, imx, joy.zou, krzysztof.kozlowski+dt,
	linux-kernel, peng.fan, robh+dt, shenwei.wang

iMX95 move channel mux register to management page address space. This
prepare to support iMX95.

Add mux_addr in struct fsl_edma_chan. No function change.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/dma/fsl-edma-common.c | 6 +++---
 drivers/dma/fsl-edma-common.h | 3 +++
 drivers/dma/fsl-edma-main.c   | 3 +++
 3 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
index 50f55d7566a33..65f466ab9d4da 100644
--- a/drivers/dma/fsl-edma-common.c
+++ b/drivers/dma/fsl-edma-common.c
@@ -97,8 +97,8 @@ static void fsl_edma3_enable_request(struct fsl_edma_chan *fsl_chan)
 		 * ch_mux: With the exception of 0, attempts to write a value
 		 * already in use will be forced to 0.
 		 */
-		if (!edma_readl_chreg(fsl_chan, ch_mux))
-			edma_writel_chreg(fsl_chan, fsl_chan->srcid, ch_mux);
+		if (!edma_readl(fsl_chan->edma, fsl_chan->mux_addr))
+			edma_writel(fsl_chan->edma, fsl_chan->srcid, fsl_chan->mux_addr);
 	}
 
 	val = edma_readl_chreg(fsl_chan, ch_csr);
@@ -134,7 +134,7 @@ static void fsl_edma3_disable_request(struct fsl_edma_chan *fsl_chan)
 	flags = fsl_edma_drvflags(fsl_chan);
 
 	if (flags & FSL_EDMA_DRV_HAS_CHMUX)
-		edma_writel_chreg(fsl_chan, 0, ch_mux);
+		edma_writel(fsl_chan->edma, 0, fsl_chan->mux_addr);
 
 	val &= ~EDMA_V3_CH_CSR_ERQ;
 	edma_writel_chreg(fsl_chan, val, ch_csr);
diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h
index fb45c7d4c1f4c..4f39a548547a6 100644
--- a/drivers/dma/fsl-edma-common.h
+++ b/drivers/dma/fsl-edma-common.h
@@ -145,6 +145,7 @@ struct fsl_edma_chan {
 	enum dma_data_direction		dma_dir;
 	char				chan_name[32];
 	struct fsl_edma_hw_tcd __iomem *tcd;
+	void __iomem			*mux_addr;
 	u32				real_count;
 	struct work_struct		issue_worker;
 	struct platform_device		*pdev;
@@ -206,6 +207,8 @@ struct fsl_edma_drvdata {
 	u32			chreg_off;
 	u32			chreg_space_sz;
 	u32			flags;
+	u32			mux_off;	/* channel mux register offset */
+	u32			mux_skip;	/* how much skip for each channel */
 	int			(*setup_irq)(struct platform_device *pdev,
 					     struct fsl_edma_engine *fsl_edma);
 };
diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
index 86b293eba27c2..d767c89973b69 100644
--- a/drivers/dma/fsl-edma-main.c
+++ b/drivers/dma/fsl-edma-main.c
@@ -359,6 +359,8 @@ static struct fsl_edma_drvdata imx93_data4 = {
 	.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA4,
 	.chreg_space_sz = 0x8000,
 	.chreg_off = 0x10000,
+	.mux_off = 0x10000 + offsetof(struct fsl_edma3_ch_reg, ch_mux),
+	.mux_skip = 0x8000,
 	.setup_irq = fsl_edma3_irq_init,
 };
 
@@ -533,6 +535,7 @@ static int fsl_edma_probe(struct platform_device *pdev)
 				offsetof(struct fsl_edma3_ch_reg, tcd) : 0;
 		fsl_chan->tcd = fsl_edma->membase
 				+ i * drvdata->chreg_space_sz + drvdata->chreg_off + len;
+		fsl_chan->mux_addr = fsl_edma->membase + drvdata->mux_off + i * drvdata->mux_skip;
 
 		fsl_chan->pdev = pdev;
 		vchan_init(&fsl_chan->vchan, &fsl_edma->dma_dev);
-- 
2.34.1


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

* [PATCH v3 4/6] dmaengine: mcf-edma: utilize edma_write_tcdreg() macro for TCD Access
  2023-11-27 22:55 [PATCH v3 0/6] dmaengine: fsl-edma: integrate TCD64 support for 64bit physical address Frank Li
                   ` (2 preceding siblings ...)
  2023-11-27 22:55 ` [PATCH v3 3/6] dmaengine: fsl-edma: add address for channel mux register in fsl_edma_chan Frank Li
@ 2023-11-27 22:55 ` Frank Li
  2023-11-27 22:55 ` [PATCH v3 5/6] dt-bindings: fsl-dma: fsl-edma: add fsl,imx95-edma5 compatible string Frank Li
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 10+ messages in thread
From: Frank Li @ 2023-11-27 22:55 UTC (permalink / raw)
  To: frank.li, vkoul
  Cc: devicetree, dmaengine, imx, joy.zou, krzysztof.kozlowski+dt,
	linux-kernel, peng.fan, robh+dt, shenwei.wang

The TCD structure has undergone modifications, incorporating fields
extended to 64 bits. When TCD64 is enabled, the TCD type shifts to
'void *'. Use of the edma_write_tcdreg() macro to facilitate TCD register
access.

Add cpu_to_le32(0) to ensure little-endian compatibility with TCD
registers and avoid a build warning.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/dma/mcf-edma-main.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/dma/mcf-edma-main.c b/drivers/dma/mcf-edma-main.c
index ab21455d9c3a4..dba6317838767 100644
--- a/drivers/dma/mcf-edma-main.c
+++ b/drivers/dma/mcf-edma-main.c
@@ -202,7 +202,7 @@ static int mcf_edma_probe(struct platform_device *pdev)
 		vchan_init(&mcf_chan->vchan, &mcf_edma->dma_dev);
 		mcf_chan->tcd = mcf_edma->membase + EDMA_TCD
 				+ i * sizeof(struct fsl_edma_hw_tcd);
-		iowrite32(0x0, &mcf_chan->tcd->csr);
+		edma_write_tcdreg(mcf_chan, cpu_to_le32(0), csr);
 	}
 
 	iowrite32(~0, regs->inth);
-- 
2.34.1


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

* [PATCH v3 5/6] dt-bindings: fsl-dma: fsl-edma: add fsl,imx95-edma5 compatible string
  2023-11-27 22:55 [PATCH v3 0/6] dmaengine: fsl-edma: integrate TCD64 support for 64bit physical address Frank Li
                   ` (3 preceding siblings ...)
  2023-11-27 22:55 ` [PATCH v3 4/6] dmaengine: mcf-edma: utilize edma_write_tcdreg() macro for TCD Access Frank Li
@ 2023-11-27 22:55 ` Frank Li
  2023-11-27 22:55 ` [PATCH v3 6/6] dmaengine: fsl-edma: integrate TCD64 support for i.MX95 Frank Li
  2023-12-12 16:19 ` [PATCH v3 0/6] dmaengine: fsl-edma: integrate TCD64 support for 64bit physical address Frank Li
  6 siblings, 0 replies; 10+ messages in thread
From: Frank Li @ 2023-11-27 22:55 UTC (permalink / raw)
  To: frank.li, vkoul
  Cc: devicetree, dmaengine, imx, joy.zou, krzysztof.kozlowski+dt,
	linux-kernel, peng.fan, robh+dt, shenwei.wang

Add the compatible string 'fsl,imx95-edma5' to support the i.MX95's eDMA,
which features 64-bit physical address support.

Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 Documentation/devicetree/bindings/dma/fsl,edma.yaml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/dma/fsl,edma.yaml b/Documentation/devicetree/bindings/dma/fsl,edma.yaml
index 437db0c62339f..aa51d278cb67b 100644
--- a/Documentation/devicetree/bindings/dma/fsl,edma.yaml
+++ b/Documentation/devicetree/bindings/dma/fsl,edma.yaml
@@ -25,6 +25,7 @@ properties:
           - fsl,imx8qm-edma
           - fsl,imx93-edma3
           - fsl,imx93-edma4
+          - fsl,imx95-edma5
       - items:
           - const: fsl,ls1028a-edma
           - const: fsl,vf610-edma
@@ -83,6 +84,7 @@ allOf:
               - fsl,imx8qm-edma
               - fsl,imx93-edma3
               - fsl,imx93-edma4
+              - fsl,imx95-edma5
     then:
       properties:
         "#dma-cells":
-- 
2.34.1


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

* [PATCH v3 6/6] dmaengine: fsl-edma: integrate TCD64 support for i.MX95
  2023-11-27 22:55 [PATCH v3 0/6] dmaengine: fsl-edma: integrate TCD64 support for 64bit physical address Frank Li
                   ` (4 preceding siblings ...)
  2023-11-27 22:55 ` [PATCH v3 5/6] dt-bindings: fsl-dma: fsl-edma: add fsl,imx95-edma5 compatible string Frank Li
@ 2023-11-27 22:55 ` Frank Li
  2023-12-21  7:47   ` Joy Zou
  2023-12-12 16:19 ` [PATCH v3 0/6] dmaengine: fsl-edma: integrate TCD64 support for 64bit physical address Frank Li
  6 siblings, 1 reply; 10+ messages in thread
From: Frank Li @ 2023-11-27 22:55 UTC (permalink / raw)
  To: frank.li, vkoul
  Cc: devicetree, dmaengine, imx, joy.zou, krzysztof.kozlowski+dt,
	linux-kernel, peng.fan, robh+dt, shenwei.wang

In i.MX95's edma version 5, the TCD structure is extended to support 64-bit
addresses for fields like saddr and daddr. To prevent code duplication,
employ help macros to handle the fields, as the field names remain the same
between TCD and TCD64.

Change local variables related to TCD addresses from 'u32' to 'dma_addr_t'
to accept 64-bit DMA addresses.

Change 'vtcd' type to 'void *' to avoid direct use. Use helper macros to
access the TCD fields correctly.

Call 'dma_set_mask_and_coherent(64)' when TCD64 is supported.

Signed-off-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/dma/fsl-edma-common.c |  34 ++++---
 drivers/dma/fsl-edma-common.h | 165 +++++++++++++++++++++++++++-------
 drivers/dma/fsl-edma-main.c   |  14 +++
 3 files changed, 170 insertions(+), 43 deletions(-)

diff --git a/drivers/dma/fsl-edma-common.c b/drivers/dma/fsl-edma-common.c
index 65f466ab9d4da..c8acff09308fd 100644
--- a/drivers/dma/fsl-edma-common.c
+++ b/drivers/dma/fsl-edma-common.c
@@ -351,7 +351,7 @@ static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
 {
 	struct fsl_edma_desc *edesc = fsl_chan->edesc;
 	enum dma_transfer_direction dir = edesc->dirn;
-	dma_addr_t cur_addr, dma_addr;
+	dma_addr_t cur_addr, dma_addr, old_addr;
 	size_t len, size;
 	u32 nbytes = 0;
 	int i;
@@ -367,10 +367,16 @@ static size_t fsl_edma_desc_residue(struct fsl_edma_chan *fsl_chan,
 	if (!in_progress)
 		return len;
 
-	if (dir == DMA_MEM_TO_DEV)
-		cur_addr = edma_read_tcdreg(fsl_chan, saddr);
-	else
-		cur_addr = edma_read_tcdreg(fsl_chan, daddr);
+	/* 64bit read is not atomic, need read retry when high 32bit changed */
+	do {
+		if (dir == DMA_MEM_TO_DEV) {
+			old_addr = edma_read_tcdreg(fsl_chan, saddr);
+			cur_addr = edma_read_tcdreg(fsl_chan, saddr);
+		} else {
+			old_addr = edma_read_tcdreg(fsl_chan, daddr);
+			cur_addr = edma_read_tcdreg(fsl_chan, daddr);
+		}
+	} while (upper_32_bits(cur_addr) != upper_32_bits(old_addr));
 
 	/* figure out the finished and calculate the residue */
 	for (i = 0; i < fsl_chan->edesc->n_tcds; i++) {
@@ -426,8 +432,7 @@ enum dma_status fsl_edma_tx_status(struct dma_chan *chan,
 	return fsl_chan->status;
 }
 
-static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
-				  struct fsl_edma_hw_tcd *tcd)
+static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan, void *tcd)
 {
 	u16 csr = 0;
 
@@ -478,9 +483,9 @@ static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
 
 static inline
 void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan,
-		       struct fsl_edma_hw_tcd *tcd, u32 src, u32 dst,
-		       u16 attr, u16 soff, u32 nbytes, u32 slast, u16 citer,
-		       u16 biter, u16 doff, u32 dlast_sga, bool major_int,
+		       struct fsl_edma_hw_tcd *tcd, dma_addr_t src, dma_addr_t dst,
+		       u16 attr, u16 soff, u32 nbytes, dma_addr_t slast, u16 citer,
+		       u16 biter, u16 doff, dma_addr_t dlast_sga, bool major_int,
 		       bool disable_req, bool enable_sg)
 {
 	struct dma_slave_config *cfg = &fsl_chan->cfg;
@@ -581,8 +586,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
 	dma_addr_t dma_buf_next;
 	bool major_int = true;
 	int sg_len, i;
-	u32 src_addr, dst_addr, last_sg, nbytes;
+	dma_addr_t src_addr, dst_addr, last_sg;
 	u16 soff, doff, iter;
+	u32 nbytes;
 
 	if (!is_slave_direction(direction))
 		return NULL;
@@ -654,8 +660,9 @@ struct dma_async_tx_descriptor *fsl_edma_prep_slave_sg(
 	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
 	struct fsl_edma_desc *fsl_desc;
 	struct scatterlist *sg;
-	u32 src_addr, dst_addr, last_sg, nbytes;
+	dma_addr_t src_addr, dst_addr, last_sg;
 	u16 soff, doff, iter;
+	u32 nbytes;
 	int i;
 
 	if (!is_slave_direction(direction))
@@ -804,7 +811,8 @@ int fsl_edma_alloc_chan_resources(struct dma_chan *chan)
 	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
 
 	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
-				sizeof(struct fsl_edma_hw_tcd),
+				fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_TCD64 ?
+				sizeof(struct fsl_edma_hw_tcd64) : sizeof(struct fsl_edma_hw_tcd),
 				32, 0);
 	return 0;
 }
diff --git a/drivers/dma/fsl-edma-common.h b/drivers/dma/fsl-edma-common.h
index 4f39a548547a6..6afceb9fded1b 100644
--- a/drivers/dma/fsl-edma-common.h
+++ b/drivers/dma/fsl-edma-common.h
@@ -87,6 +87,20 @@ struct fsl_edma_hw_tcd {
 	__le16	biter;
 };
 
+struct fsl_edma_hw_tcd64 {
+	__le64  saddr;
+	__le16  soff;
+	__le16  attr;
+	__le32  nbytes;
+	__le64  slast;
+	__le64  daddr;
+	__le64  dlast_sga;
+	__le16  doff;
+	__le16  citer;
+	__le16  csr;
+	__le16  biter;
+} __packed;
+
 struct fsl_edma3_ch_reg {
 	__le32	ch_csr;
 	__le32	ch_es;
@@ -96,7 +110,10 @@ struct fsl_edma3_ch_reg {
 	__le32	ch_mux;
 	__le32  ch_mattr; /* edma4, reserved for edma3 */
 	__le32  ch_reserved;
-	struct fsl_edma_hw_tcd tcd;
+	union {
+		struct fsl_edma_hw_tcd tcd;
+		struct fsl_edma_hw_tcd tcd64;
+	};
 } __packed;
 
 /*
@@ -125,7 +142,7 @@ struct edma_regs {
 
 struct fsl_edma_sw_tcd {
 	dma_addr_t			ptcd;
-	struct fsl_edma_hw_tcd		*vtcd;
+	void				*vtcd;
 };
 
 struct fsl_edma_chan {
@@ -144,7 +161,7 @@ struct fsl_edma_chan {
 	u32				dma_dev_size;
 	enum dma_data_direction		dma_dir;
 	char				chan_name[32];
-	struct fsl_edma_hw_tcd __iomem *tcd;
+	void __iomem			*tcd;
 	void __iomem			*mux_addr;
 	u32				real_count;
 	struct work_struct		issue_worker;
@@ -188,6 +205,7 @@ struct fsl_edma_desc {
 #define FSL_EDMA_DRV_CLEAR_DONE_E_SG	BIT(13)
 /* Need clean CHn_CSR DONE before enable TCD's MAJORELINK */
 #define FSL_EDMA_DRV_CLEAR_DONE_E_LINK	BIT(14)
+#define FSL_EDMA_DRV_TCD64		BIT(15)
 
 #define FSL_EDMA_DRV_EDMA3	(FSL_EDMA_DRV_SPLIT_REG |	\
 				 FSL_EDMA_DRV_BUS_8BYTE |	\
@@ -231,18 +249,61 @@ struct fsl_edma_engine {
 	struct fsl_edma_chan	chans[] __counted_by(n_chans);
 };
 
-#define edma_read_tcdreg(chan, __name)				\
-(sizeof(chan->tcd->__name) == sizeof(u32) ?			\
-	edma_readl(chan->edma, &chan->tcd->__name) :		\
-	edma_readw(chan->edma, &chan->tcd->__name))
+#define edma_read_tcdreg_c(chan, _tcd,  __name)				\
+(sizeof((_tcd)->__name) == sizeof(u64) ?				\
+	edma_readq(chan->edma, &(_tcd)->__name) :			\
+		((sizeof((_tcd)->__name) == sizeof(u32)) ?		\
+			edma_readl(chan->edma, &(_tcd)->__name) :	\
+			edma_readw(chan->edma, &(_tcd)->__name)		\
+		))
+
+#define edma_read_tcdreg(chan, __name)								\
+((fsl_edma_drvflags(chan) & FSL_EDMA_DRV_TCD64) ?						\
+	edma_read_tcdreg_c(chan, ((struct fsl_edma_hw_tcd64 __iomem *)chan->tcd), __name) :	\
+	edma_read_tcdreg_c(chan, ((struct fsl_edma_hw_tcd __iomem *)chan->tcd), __name)		\
+)
+
+#define edma_write_tcdreg_c(chan, _tcd, _val, __name)				\
+do {										\
+	switch (sizeof(_tcd->__name)) {						\
+	case sizeof(u64):							\
+		edma_writeq(chan->edma, (u64 __force)_val, &_tcd->__name);	\
+		break;								\
+	case sizeof(u32):							\
+		edma_writel(chan->edma, (u32 __force)_val, &_tcd->__name);	\
+		break;								\
+	case sizeof(u16):							\
+		edma_writew(chan->edma, (u16 __force)_val, &_tcd->__name);	\
+		break;								\
+	case sizeof(u8):							\
+		edma_writeb(chan->edma, (u8 __force)_val, &_tcd->__name);	\
+		break;								\
+	}									\
+} while (0)
 
-#define edma_write_tcdreg(chan, val, __name)			\
-(sizeof(chan->tcd->__name) == sizeof(u32) ?			\
-	edma_writel(chan->edma, (u32 __force)val, &chan->tcd->__name) :	\
-	edma_writew(chan->edma, (u16 __force)val, &chan->tcd->__name))
+#define edma_write_tcdreg(chan, val, __name)							   \
+do {												   \
+	struct fsl_edma_hw_tcd64 __iomem *tcd64_r = (struct fsl_edma_hw_tcd64 __iomem *)chan->tcd; \
+	struct fsl_edma_hw_tcd __iomem *tcd_r = (struct fsl_edma_hw_tcd __iomem *)chan->tcd;	   \
+												   \
+	if (fsl_edma_drvflags(chan) & FSL_EDMA_DRV_TCD64)					   \
+		edma_write_tcdreg_c(chan, tcd64_r, val, __name);				   \
+	else											   \
+		edma_write_tcdreg_c(chan, tcd_r, val, __name);					   \
+} while (0)
 
-#define edma_cp_tcd_to_reg(chan, __tcd, __name)			\
-	edma_write_tcdreg(chan, __tcd->__name, __name)
+#define edma_cp_tcd_to_reg(chan, __tcd, __name)							   \
+do {	\
+	struct fsl_edma_hw_tcd64 __iomem *tcd64_r = (struct fsl_edma_hw_tcd64 __iomem *)chan->tcd; \
+	struct fsl_edma_hw_tcd __iomem *tcd_r = (struct fsl_edma_hw_tcd __iomem *)chan->tcd;	   \
+	struct fsl_edma_hw_tcd64 *tcd64_m = (struct fsl_edma_hw_tcd64 *)__tcd;			   \
+	struct fsl_edma_hw_tcd *tcd_m = (struct fsl_edma_hw_tcd *)__tcd;			   \
+												   \
+	if (fsl_edma_drvflags(chan) & FSL_EDMA_DRV_TCD64)					   \
+		edma_write_tcdreg_c(chan, tcd64_r,  tcd64_m->__name, __name);			   \
+	else											   \
+		edma_write_tcdreg_c(chan, tcd_r, tcd_m->__name, __name);			   \
+} while (0)
 
 #define edma_readl_chreg(chan, __name)				\
 	edma_readl(chan->edma,					\
@@ -254,24 +315,41 @@ struct fsl_edma_engine {
 		   (void __iomem *)&(container_of(((__force void *)chan->tcd),\
 						  struct fsl_edma3_ch_reg, tcd)->__name))
 
-#define fsl_edma_get_tcd(_chan, _tcd, _field) ((_tcd)->_field)
-
-#define fsl_edma_le_to_cpu(x)					\
-(sizeof(x) == sizeof(u32) ? le32_to_cpu((__force __le32)(x)) : le16_to_cpu((__force __le16)(x)))
-
-#define fsl_edma_get_tcd_to_cpu(_chan, _tcd, _field)		\
-fsl_edma_le_to_cpu(fsl_edma_get_tcd(_chan, _tcd, _field))
+#define fsl_edma_get_tcd(_chan, _tcd, _field)			\
+(fsl_edma_drvflags(_chan) & FSL_EDMA_DRV_TCD64 ? (((struct fsl_edma_hw_tcd64 *)_tcd)->_field) : \
+						 (((struct fsl_edma_hw_tcd *)_tcd)->_field))
+
+#define fsl_edma_le_to_cpu(x)						\
+(sizeof(x) == sizeof(u64) ? le64_to_cpu((__force __le64)(x)) :		\
+	(sizeof(x) == sizeof(u32) ? le32_to_cpu((__force __le32)(x)) :	\
+				    le16_to_cpu((__force __le16)(x))))
+
+#define fsl_edma_get_tcd_to_cpu(_chan, _tcd, _field)				\
+(fsl_edma_drvflags(_chan) & FSL_EDMA_DRV_TCD64 ?				\
+	fsl_edma_le_to_cpu(((struct fsl_edma_hw_tcd64 *)_tcd)->_field) :	\
+	fsl_edma_le_to_cpu(((struct fsl_edma_hw_tcd *)_tcd)->_field))
+
+#define fsl_edma_set_tcd_to_le_c(_tcd, _val, _field)					\
+do {											\
+	switch (sizeof((_tcd)->_field)) {						\
+	case sizeof(u64):								\
+		*(__force __le64 *)(&((_tcd)->_field)) = cpu_to_le64(_val);		\
+		break;									\
+	case sizeof(u32):								\
+		*(__force __le32 *)(&((_tcd)->_field)) = cpu_to_le32(_val);		\
+		break;									\
+	case sizeof(u16):								\
+		*(__force __le16 *)(&((_tcd)->_field)) = cpu_to_le16(_val);		\
+		break;									\
+	}										\
+} while (0)
 
-#define fsl_edma_set_tcd_to_le(_fsl_chan, _tcd, _val, _field)			\
-do {										\
-	switch (sizeof((_tcd)->_field)) {					\
-	case sizeof(u32):							\
-		*(__force __le32 *)(&((_tcd)->_field)) = cpu_to_le32(_val);	\
-		break;								\
-	case sizeof(u16):							\
-		*(__force __le16 *)(&((_tcd)->_field)) = cpu_to_le16(_val);	\
-		break;								\
-	}									\
+#define fsl_edma_set_tcd_to_le(_chan, _tcd, _val, _field)	\
+do {								\
+	if (fsl_edma_drvflags(_chan) & FSL_EDMA_DRV_TCD64)	\
+		fsl_edma_set_tcd_to_le_c((struct fsl_edma_hw_tcd64 *)_tcd, _val, _field);	\
+	else											\
+		fsl_edma_set_tcd_to_le_c((struct fsl_edma_hw_tcd *)_tcd, _val, _field);		\
 } while (0)
 
 /*
@@ -280,6 +358,21 @@ do {										\
  * For the big-endian IP module, the offset for 8-bit or 16-bit registers
  * should also be swapped opposite to that in little-endian IP.
  */
+static inline u64 edma_readq(struct fsl_edma_engine *edma, void __iomem *addr)
+{
+	u64 l, h;
+
+	if (edma->big_endian) {
+		l = ioread32be(addr);
+		h = ioread32be(addr + 4);
+	} else {
+		l = ioread32(addr);
+		h = ioread32(addr + 4);
+	}
+
+	return (h << 32) | l;
+}
+
 static inline u32 edma_readl(struct fsl_edma_engine *edma, void __iomem *addr)
 {
 	if (edma->big_endian)
@@ -325,6 +418,18 @@ static inline void edma_writel(struct fsl_edma_engine *edma,
 		iowrite32(val, addr);
 }
 
+static inline void edma_writeq(struct fsl_edma_engine *edma,
+			       u64 val, void __iomem *addr)
+{
+	if (edma->big_endian) {
+		iowrite32be(val & 0xFFFFFFFF, addr);
+		iowrite32be(val >> 32, addr + 4);
+	} else {
+		iowrite32(val & 0xFFFFFFFF, addr);
+		iowrite32(val >> 32, addr + 4);
+	}
+}
+
 static inline struct fsl_edma_chan *to_fsl_edma_chan(struct dma_chan *chan)
 {
 	return container_of(chan, struct fsl_edma_chan, vchan.chan);
diff --git a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c
index d767c89973b69..c2c0c3effc8cb 100644
--- a/drivers/dma/fsl-edma-main.c
+++ b/drivers/dma/fsl-edma-main.c
@@ -364,6 +364,16 @@ static struct fsl_edma_drvdata imx93_data4 = {
 	.setup_irq = fsl_edma3_irq_init,
 };
 
+static struct fsl_edma_drvdata imx95_data5 = {
+	.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK | FSL_EDMA_DRV_EDMA4 |
+		 FSL_EDMA_DRV_TCD64,
+	.chreg_space_sz = 0x8000,
+	.chreg_off = 0x10000,
+	.mux_off = 0x200,
+	.mux_skip = sizeof(u32),
+	.setup_irq = fsl_edma3_irq_init,
+};
+
 static const struct of_device_id fsl_edma_dt_ids[] = {
 	{ .compatible = "fsl,vf610-edma", .data = &vf610_data},
 	{ .compatible = "fsl,ls1028a-edma", .data = &ls1028a_data},
@@ -372,6 +382,7 @@ static const struct of_device_id fsl_edma_dt_ids[] = {
 	{ .compatible = "fsl,imx8qm-adma", .data = &imx8qm_audio_data},
 	{ .compatible = "fsl,imx93-edma3", .data = &imx93_data3},
 	{ .compatible = "fsl,imx93-edma4", .data = &imx93_data4},
+	{ .compatible = "fsl,imx95-edma5", .data = &imx95_data5},
 	{ /* sentinel */ }
 };
 MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids);
@@ -513,6 +524,9 @@ static int fsl_edma_probe(struct platform_device *pdev)
 			return ret;
 	}
 
+	if (drvdata->flags & FSL_EDMA_DRV_TCD64)
+		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
+
 	INIT_LIST_HEAD(&fsl_edma->dma_dev.channels);
 	for (i = 0; i < fsl_edma->n_chans; i++) {
 		struct fsl_edma_chan *fsl_chan = &fsl_edma->chans[i];
-- 
2.34.1


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

* Re: [PATCH v3 0/6] dmaengine: fsl-edma: integrate TCD64 support for 64bit physical address
  2023-11-27 22:55 [PATCH v3 0/6] dmaengine: fsl-edma: integrate TCD64 support for 64bit physical address Frank Li
                   ` (5 preceding siblings ...)
  2023-11-27 22:55 ` [PATCH v3 6/6] dmaengine: fsl-edma: integrate TCD64 support for i.MX95 Frank Li
@ 2023-12-12 16:19 ` Frank Li
  6 siblings, 0 replies; 10+ messages in thread
From: Frank Li @ 2023-12-12 16:19 UTC (permalink / raw)
  To: vkoul
  Cc: devicetree, dmaengine, imx, joy.zou, krzysztof.kozlowski+dt,
	linux-kernel, peng.fan, robh+dt, shenwei.wang

On Mon, Nov 27, 2023 at 05:55:36PM -0500, Frank Li wrote:
> Change from v2 to v3:
>  - fix sparse build warning
> 
> Change from v1 to v2:
> - fixed mcf-edma-main.c build error.
> - fixed readq build error. readq actually is not atomic read in imx95.
> So split to two ioread32\iowrite32.
>   It needs read at least twice to avoid lower 32 bit part wrap during read
> up 32bit part.
> 
> first 2 patch is prepare, No function change.
> 3rd patch is dt-bind doc
> 4rd patch is actuall support TCD64

@vnod:
	Do you have chance to look at these patches?

Frank

> 
> Frank Li (6):
>   dmaengine: fsl-edma: involve help macro fsl_edma_set(get)_tcd()
>   dmaengine: fsl-edma: fix spare build warning
>   dmaengine: fsl-edma: add address for channel mux register in
>     fsl_edma_chan
>   dmaengine: mcf-edma: utilize edma_write_tcdreg() macro for TCD Access
>   dt-bindings: fsl-dma: fsl-edma: add fsl,imx95-edma5 compatible string
>   dmaengine: fsl-edma: integrate TCD64 support for i.MX95
> 
>  .../devicetree/bindings/dma/fsl,edma.yaml     |   2 +
>  drivers/dma/fsl-edma-common.c                 | 101 ++++++-----
>  drivers/dma/fsl-edma-common.h                 | 161 ++++++++++++++++--
>  drivers/dma/fsl-edma-main.c                   |  19 ++-
>  drivers/dma/mcf-edma-main.c                   |   2 +-
>  5 files changed, 223 insertions(+), 62 deletions(-)
> 
> -- 
> 2.34.1
> 

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

* RE: [PATCH v3 6/6] dmaengine: fsl-edma: integrate TCD64 support for i.MX95
  2023-11-27 22:55 ` [PATCH v3 6/6] dmaengine: fsl-edma: integrate TCD64 support for i.MX95 Frank Li
@ 2023-12-21  7:47   ` Joy Zou
  2023-12-21 15:14     ` Frank Li
  0 siblings, 1 reply; 10+ messages in thread
From: Joy Zou @ 2023-12-21  7:47 UTC (permalink / raw)
  To: Frank Li, vkoul
  Cc: devicetree, dmaengine, imx, krzysztof.kozlowski+dt, linux-kernel,
	Peng Fan, robh+dt, Shenwei Wang

Hi frank,
> -----Original Message-----
> From: Frank Li <frank.li@nxp.com>
> Sent: 2023年11月28日 6:56
> To: Frank Li <frank.li@nxp.com>; vkoul@kernel.org
> Cc: devicetree@vger.kernel.org; dmaengine@vger.kernel.org;
> imx@lists.linux.dev; Joy Zou <joy.zou@nxp.com>;
> krzysztof.kozlowski+dt@linaro.org; linux-kernel@vger.kernel.org; Peng Fan
> <peng.fan@nxp.com>; robh+dt@kernel.org; Shenwei Wang
> <shenwei.wang@nxp.com>
> Subject: [PATCH v3 6/6] dmaengine: fsl-edma: integrate TCD64 support for
> i.MX95
> 
> In i.MX95's edma version 5, the TCD structure is extended to support 64-bit
> addresses for fields like saddr and daddr. To prevent code duplication, employ
> help macros to handle the fields, as the field names remain the same between
> TCD and TCD64.
> 
> Change local variables related to TCD addresses from 'u32' to 'dma_addr_t'
> to accept 64-bit DMA addresses.
> 
> Change 'vtcd' type to 'void *' to avoid direct use. Use helper macros to access
> the TCD fields correctly.
> 
> Call 'dma_set_mask_and_coherent(64)' when TCD64 is supported.
> 
> Signed-off-by: Frank Li <Frank.Li@nxp.com>
> ---
>  drivers/dma/fsl-edma-common.c |  34 ++++---
> drivers/dma/fsl-edma-common.h | 165
> +++++++++++++++++++++++++++-------
>  drivers/dma/fsl-edma-main.c   |  14 +++
>  3 files changed, 170 insertions(+), 43 deletions(-)
> 
> diff --git a/drivers/dma/fsl-edma-common.c
> b/drivers/dma/fsl-edma-common.c index 65f466ab9d4da..c8acff09308fd
> 100644
> --- a/drivers/dma/fsl-edma-common.c
> +++ b/drivers/dma/fsl-edma-common.c
> @@ -351,7 +351,7 @@ static size_t fsl_edma_desc_residue(struct
> fsl_edma_chan *fsl_chan,  {
>  	struct fsl_edma_desc *edesc = fsl_chan->edesc;
>  	enum dma_transfer_direction dir = edesc->dirn;
> -	dma_addr_t cur_addr, dma_addr;
> +	dma_addr_t cur_addr, dma_addr, old_addr;
>  	size_t len, size;
>  	u32 nbytes = 0;
>  	int i;
> @@ -367,10 +367,16 @@ static size_t fsl_edma_desc_residue(struct
> fsl_edma_chan *fsl_chan,
>  	if (!in_progress)
>  		return len;
> 
> -	if (dir == DMA_MEM_TO_DEV)
> -		cur_addr = edma_read_tcdreg(fsl_chan, saddr);
> -	else
> -		cur_addr = edma_read_tcdreg(fsl_chan, daddr);
> +	/* 64bit read is not atomic, need read retry when high 32bit changed */
> +	do {
> +		if (dir == DMA_MEM_TO_DEV) {
> +			old_addr = edma_read_tcdreg(fsl_chan, saddr);
> +			cur_addr = edma_read_tcdreg(fsl_chan, saddr);
> +		} else {
> +			old_addr = edma_read_tcdreg(fsl_chan, daddr);
> +			cur_addr = edma_read_tcdreg(fsl_chan, daddr);
> +		}
> +	} while (upper_32_bits(cur_addr) != upper_32_bits(old_addr));
> 
>  	/* figure out the finished and calculate the residue */
>  	for (i = 0; i < fsl_chan->edesc->n_tcds; i++) { @@ -426,8 +432,7 @@
> enum dma_status fsl_edma_tx_status(struct dma_chan *chan,
>  	return fsl_chan->status;
>  }
> 
> -static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
> -				  struct fsl_edma_hw_tcd *tcd)
> +static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan, void
> +*tcd)
>  {
>  	u16 csr = 0;
> 
> @@ -478,9 +483,9 @@ static void fsl_edma_set_tcd_regs(struct
> fsl_edma_chan *fsl_chan,
> 
>  static inline
>  void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan,
> -		       struct fsl_edma_hw_tcd *tcd, u32 src, u32 dst,
> -		       u16 attr, u16 soff, u32 nbytes, u32 slast, u16 citer,
> -		       u16 biter, u16 doff, u32 dlast_sga, bool major_int,
> +		       struct fsl_edma_hw_tcd *tcd, dma_addr_t src, dma_addr_t
> dst,
> +		       u16 attr, u16 soff, u32 nbytes, dma_addr_t slast, u16 citer,
> +		       u16 biter, u16 doff, dma_addr_t dlast_sga, bool major_int,
>  		       bool disable_req, bool enable_sg)  {
>  	struct dma_slave_config *cfg = &fsl_chan->cfg; @@ -581,8 +586,9 @@
> struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
>  	dma_addr_t dma_buf_next;
>  	bool major_int = true;
>  	int sg_len, i;
> -	u32 src_addr, dst_addr, last_sg, nbytes;
> +	dma_addr_t src_addr, dst_addr, last_sg;
>  	u16 soff, doff, iter;
> +	u32 nbytes;
> 
>  	if (!is_slave_direction(direction))
>  		return NULL;
> @@ -654,8 +660,9 @@ struct dma_async_tx_descriptor
> *fsl_edma_prep_slave_sg(
>  	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
>  	struct fsl_edma_desc *fsl_desc;
>  	struct scatterlist *sg;
> -	u32 src_addr, dst_addr, last_sg, nbytes;
> +	dma_addr_t src_addr, dst_addr, last_sg;
>  	u16 soff, doff, iter;
> +	u32 nbytes;
>  	int i;
> 
>  	if (!is_slave_direction(direction))
> @@ -804,7 +811,8 @@ int fsl_edma_alloc_chan_resources(struct dma_chan
> *chan)
>  	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> 
>  	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
> -				sizeof(struct fsl_edma_hw_tcd),
> +				fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_TCD64 ?
> +				sizeof(struct fsl_edma_hw_tcd64) : sizeof(struct
> fsl_edma_hw_tcd),
>  				32, 0);
>  	return 0;
>  }
> diff --git a/drivers/dma/fsl-edma-common.h
> b/drivers/dma/fsl-edma-common.h index 4f39a548547a6..6afceb9fded1b
> 100644
> --- a/drivers/dma/fsl-edma-common.h
> +++ b/drivers/dma/fsl-edma-common.h
> @@ -87,6 +87,20 @@ struct fsl_edma_hw_tcd {
>  	__le16	biter;
>  };
> 
> +struct fsl_edma_hw_tcd64 {
> +	__le64  saddr;
> +	__le16  soff;
> +	__le16  attr;
> +	__le32  nbytes;
> +	__le64  slast;
> +	__le64  daddr;
> +	__le64  dlast_sga;
> +	__le16  doff;
> +	__le16  citer;
> +	__le16  csr;
> +	__le16  biter;
> +} __packed;
> +
>  struct fsl_edma3_ch_reg {
>  	__le32	ch_csr;
>  	__le32	ch_es;
> @@ -96,7 +110,10 @@ struct fsl_edma3_ch_reg {
>  	__le32	ch_mux;
>  	__le32  ch_mattr; /* edma4, reserved for edma3 */
>  	__le32  ch_reserved;
> -	struct fsl_edma_hw_tcd tcd;
> +	union {
> +		struct fsl_edma_hw_tcd tcd;
> +		struct fsl_edma_hw_tcd tcd64;
> +	};
>  } __packed; 
The tcd64 should be fsl_edma_hw_tcd64?
BR
Joy Zou 
> 
>  /*
> @@ -125,7 +142,7 @@ struct edma_regs {
> 
>  struct fsl_edma_sw_tcd {
>  	dma_addr_t			ptcd;
> -	struct fsl_edma_hw_tcd		*vtcd;
> +	void				*vtcd;
>  };
> 
>  struct fsl_edma_chan {
> @@ -144,7 +161,7 @@ struct fsl_edma_chan {
>  	u32				dma_dev_size;
>  	enum dma_data_direction		dma_dir;
>  	char				chan_name[32];
> -	struct fsl_edma_hw_tcd __iomem *tcd;
> +	void __iomem			*tcd;
>  	void __iomem			*mux_addr;
>  	u32				real_count;
>  	struct work_struct		issue_worker;
> @@ -188,6 +205,7 @@ struct fsl_edma_desc {
>  #define FSL_EDMA_DRV_CLEAR_DONE_E_SG	BIT(13)
>  /* Need clean CHn_CSR DONE before enable TCD's MAJORELINK */
>  #define FSL_EDMA_DRV_CLEAR_DONE_E_LINK	BIT(14)
> +#define FSL_EDMA_DRV_TCD64		BIT(15)
> 
>  #define FSL_EDMA_DRV_EDMA3	(FSL_EDMA_DRV_SPLIT_REG |	\
>  				 FSL_EDMA_DRV_BUS_8BYTE |	\
> @@ -231,18 +249,61 @@ struct fsl_edma_engine {
>  	struct fsl_edma_chan	chans[] __counted_by(n_chans);
>  };
> 
> -#define edma_read_tcdreg(chan, __name)				\
> -(sizeof(chan->tcd->__name) == sizeof(u32) ?			\
> -	edma_readl(chan->edma, &chan->tcd->__name) :		\
> -	edma_readw(chan->edma, &chan->tcd->__name))
> +#define edma_read_tcdreg_c(chan, _tcd,  __name)				\
> +(sizeof((_tcd)->__name) == sizeof(u64) ?				\
> +	edma_readq(chan->edma, &(_tcd)->__name) :			\
> +		((sizeof((_tcd)->__name) == sizeof(u32)) ?		\
> +			edma_readl(chan->edma, &(_tcd)->__name) :	\
> +			edma_readw(chan->edma, &(_tcd)->__name)		\
> +		))
> +
> +#define edma_read_tcdreg(chan, __name)
> 	\
> +((fsl_edma_drvflags(chan) & FSL_EDMA_DRV_TCD64) ?
> 	\
> +	edma_read_tcdreg_c(chan, ((struct fsl_edma_hw_tcd64 __iomem
> *)chan->tcd), __name) :	\
> +	edma_read_tcdreg_c(chan, ((struct fsl_edma_hw_tcd __iomem
> *)chan->tcd), __name)		\
> +)
> +
> +#define edma_write_tcdreg_c(chan, _tcd, _val, __name)				\
> +do {										\
> +	switch (sizeof(_tcd->__name)) {						\
> +	case sizeof(u64):							\
> +		edma_writeq(chan->edma, (u64 __force)_val, &_tcd->__name);	\
> +		break;								\
> +	case sizeof(u32):							\
> +		edma_writel(chan->edma, (u32 __force)_val, &_tcd->__name);	\
> +		break;								\
> +	case sizeof(u16):							\
> +		edma_writew(chan->edma, (u16 __force)_val, &_tcd->__name);	\
> +		break;								\
> +	case sizeof(u8):							\
> +		edma_writeb(chan->edma, (u8 __force)_val, &_tcd->__name);	\
> +		break;								\
> +	}									\
> +} while (0)
> 
> -#define edma_write_tcdreg(chan, val, __name)			\
> -(sizeof(chan->tcd->__name) == sizeof(u32) ?			\
> -	edma_writel(chan->edma, (u32 __force)val, &chan->tcd->__name) :	\
> -	edma_writew(chan->edma, (u16 __force)val, &chan->tcd->__name))
> +#define edma_write_tcdreg(chan, val, __name)
> \
> +do {												   \
> +	struct fsl_edma_hw_tcd64 __iomem *tcd64_r = (struct
> fsl_edma_hw_tcd64 __iomem *)chan->tcd; \
> +	struct fsl_edma_hw_tcd __iomem *tcd_r = (struct fsl_edma_hw_tcd
> __iomem *)chan->tcd;	   \
> +												   \
> +	if (fsl_edma_drvflags(chan) & FSL_EDMA_DRV_TCD64)
> 	   \
> +		edma_write_tcdreg_c(chan, tcd64_r, val, __name);
> \
> +	else											   \
> +		edma_write_tcdreg_c(chan, tcd_r, val, __name);
> \
> +} while (0)
> 
> -#define edma_cp_tcd_to_reg(chan, __tcd, __name)			\
> -	edma_write_tcdreg(chan, __tcd->__name, __name)
> +#define edma_cp_tcd_to_reg(chan, __tcd, __name)
> 	   \
> +do {	\
> +	struct fsl_edma_hw_tcd64 __iomem *tcd64_r = (struct
> fsl_edma_hw_tcd64 __iomem *)chan->tcd; \
> +	struct fsl_edma_hw_tcd __iomem *tcd_r = (struct fsl_edma_hw_tcd
> __iomem *)chan->tcd;	   \
> +	struct fsl_edma_hw_tcd64 *tcd64_m = (struct fsl_edma_hw_tcd64
> *)__tcd;			   \
> +	struct fsl_edma_hw_tcd *tcd_m = (struct fsl_edma_hw_tcd *)__tcd;
> 	   \
> +												   \
> +	if (fsl_edma_drvflags(chan) & FSL_EDMA_DRV_TCD64)
> 	   \
> +		edma_write_tcdreg_c(chan, tcd64_r,  tcd64_m->__name, __name);
> 		   \
> +	else											   \
> +		edma_write_tcdreg_c(chan, tcd_r, tcd_m->__name, __name);
> 	   \
> +} while (0)
> 
>  #define edma_readl_chreg(chan, __name)				\
>  	edma_readl(chan->edma,					\
> @@ -254,24 +315,41 @@ struct fsl_edma_engine {
>  		   (void __iomem *)&(container_of(((__force void *)chan->tcd),\
>  						  struct fsl_edma3_ch_reg, tcd)->__name))
> 
> -#define fsl_edma_get_tcd(_chan, _tcd, _field) ((_tcd)->_field)
> -
> -#define fsl_edma_le_to_cpu(x)					\
> -(sizeof(x) == sizeof(u32) ? le32_to_cpu((__force __le32)(x)) :
> le16_to_cpu((__force __le16)(x)))
> -
> -#define fsl_edma_get_tcd_to_cpu(_chan, _tcd, _field)		\
> -fsl_edma_le_to_cpu(fsl_edma_get_tcd(_chan, _tcd, _field))
> +#define fsl_edma_get_tcd(_chan, _tcd, _field)			\
> +(fsl_edma_drvflags(_chan) & FSL_EDMA_DRV_TCD64 ? (((struct
> fsl_edma_hw_tcd64 *)_tcd)->_field) : \
> +						 (((struct fsl_edma_hw_tcd *)_tcd)->_field))
> +
> +#define fsl_edma_le_to_cpu(x)						\
> +(sizeof(x) == sizeof(u64) ? le64_to_cpu((__force __le64)(x)) :		\
> +	(sizeof(x) == sizeof(u32) ? le32_to_cpu((__force __le32)(x)) :	\
> +				    le16_to_cpu((__force __le16)(x))))
> +
> +#define fsl_edma_get_tcd_to_cpu(_chan, _tcd, _field)				\
> +(fsl_edma_drvflags(_chan) & FSL_EDMA_DRV_TCD64 ?				\
> +	fsl_edma_le_to_cpu(((struct fsl_edma_hw_tcd64 *)_tcd)->_field) :	\
> +	fsl_edma_le_to_cpu(((struct fsl_edma_hw_tcd *)_tcd)->_field))
> +
> +#define fsl_edma_set_tcd_to_le_c(_tcd, _val, _field)					\
> +do {											\
> +	switch (sizeof((_tcd)->_field)) {						\
> +	case sizeof(u64):								\
> +		*(__force __le64 *)(&((_tcd)->_field)) = cpu_to_le64(_val);		\
> +		break;									\
> +	case sizeof(u32):								\
> +		*(__force __le32 *)(&((_tcd)->_field)) = cpu_to_le32(_val);		\
> +		break;									\
> +	case sizeof(u16):								\
> +		*(__force __le16 *)(&((_tcd)->_field)) = cpu_to_le16(_val);		\
> +		break;									\
> +	}										\
> +} while (0)
> 
> -#define fsl_edma_set_tcd_to_le(_fsl_chan, _tcd, _val, _field)			\
> -do {										\
> -	switch (sizeof((_tcd)->_field)) {					\
> -	case sizeof(u32):							\
> -		*(__force __le32 *)(&((_tcd)->_field)) = cpu_to_le32(_val);	\
> -		break;								\
> -	case sizeof(u16):							\
> -		*(__force __le16 *)(&((_tcd)->_field)) = cpu_to_le16(_val);	\
> -		break;								\
> -	}									\
> +#define fsl_edma_set_tcd_to_le(_chan, _tcd, _val, _field)	\
> +do {								\
> +	if (fsl_edma_drvflags(_chan) & FSL_EDMA_DRV_TCD64)	\
> +		fsl_edma_set_tcd_to_le_c((struct fsl_edma_hw_tcd64 *)_tcd, _val,
> _field);	\
> +	else											\
> +		fsl_edma_set_tcd_to_le_c((struct fsl_edma_hw_tcd *)_tcd, _val,
> _field);		\
>  } while (0)
> 
>  /*
> @@ -280,6 +358,21 @@ do {
> 	\
>   * For the big-endian IP module, the offset for 8-bit or 16-bit registers
>   * should also be swapped opposite to that in little-endian IP.
>   */
> +static inline u64 edma_readq(struct fsl_edma_engine *edma, void __iomem
> +*addr) {
> +	u64 l, h;
> +
> +	if (edma->big_endian) {
> +		l = ioread32be(addr);
> +		h = ioread32be(addr + 4);
> +	} else {
> +		l = ioread32(addr);
> +		h = ioread32(addr + 4);
> +	}
> +
> +	return (h << 32) | l;
> +}
> +
>  static inline u32 edma_readl(struct fsl_edma_engine *edma, void __iomem
> *addr)  {
>  	if (edma->big_endian)
> @@ -325,6 +418,18 @@ static inline void edma_writel(struct
> fsl_edma_engine *edma,
>  		iowrite32(val, addr);
>  }
> 
> +static inline void edma_writeq(struct fsl_edma_engine *edma,
> +			       u64 val, void __iomem *addr)
> +{
> +	if (edma->big_endian) {
> +		iowrite32be(val & 0xFFFFFFFF, addr);
> +		iowrite32be(val >> 32, addr + 4);
> +	} else {
> +		iowrite32(val & 0xFFFFFFFF, addr);
> +		iowrite32(val >> 32, addr + 4);
> +	}
> +}
> +
>  static inline struct fsl_edma_chan *to_fsl_edma_chan(struct dma_chan *chan)
> {
>  	return container_of(chan, struct fsl_edma_chan, vchan.chan); diff --git
> a/drivers/dma/fsl-edma-main.c b/drivers/dma/fsl-edma-main.c index
> d767c89973b69..c2c0c3effc8cb 100644
> --- a/drivers/dma/fsl-edma-main.c
> +++ b/drivers/dma/fsl-edma-main.c
> @@ -364,6 +364,16 @@ static struct fsl_edma_drvdata imx93_data4 = {
>  	.setup_irq = fsl_edma3_irq_init,
>  };
> 
> +static struct fsl_edma_drvdata imx95_data5 = {
> +	.flags = FSL_EDMA_DRV_HAS_CHMUX | FSL_EDMA_DRV_HAS_DMACLK |
> FSL_EDMA_DRV_EDMA4 |
> +		 FSL_EDMA_DRV_TCD64,
> +	.chreg_space_sz = 0x8000,
> +	.chreg_off = 0x10000,
> +	.mux_off = 0x200,
> +	.mux_skip = sizeof(u32),
> +	.setup_irq = fsl_edma3_irq_init,
> +};
> +
>  static const struct of_device_id fsl_edma_dt_ids[] = {
>  	{ .compatible = "fsl,vf610-edma", .data = &vf610_data},
>  	{ .compatible = "fsl,ls1028a-edma", .data = &ls1028a_data}, @@ -372,6
> +382,7 @@ static const struct of_device_id fsl_edma_dt_ids[] = {
>  	{ .compatible = "fsl,imx8qm-adma", .data = &imx8qm_audio_data},
>  	{ .compatible = "fsl,imx93-edma3", .data = &imx93_data3},
>  	{ .compatible = "fsl,imx93-edma4", .data = &imx93_data4},
> +	{ .compatible = "fsl,imx95-edma5", .data = &imx95_data5},
>  	{ /* sentinel */ }
>  };
>  MODULE_DEVICE_TABLE(of, fsl_edma_dt_ids); @@ -513,6 +524,9 @@ static
> int fsl_edma_probe(struct platform_device *pdev)
>  			return ret;
>  	}
> 
> +	if (drvdata->flags & FSL_EDMA_DRV_TCD64)
> +		dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
> +
>  	INIT_LIST_HEAD(&fsl_edma->dma_dev.channels);
>  	for (i = 0; i < fsl_edma->n_chans; i++) {
>  		struct fsl_edma_chan *fsl_chan = &fsl_edma->chans[i];
> --
> 2.34.1


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

* Re: [PATCH v3 6/6] dmaengine: fsl-edma: integrate TCD64 support for i.MX95
  2023-12-21  7:47   ` Joy Zou
@ 2023-12-21 15:14     ` Frank Li
  0 siblings, 0 replies; 10+ messages in thread
From: Frank Li @ 2023-12-21 15:14 UTC (permalink / raw)
  To: Joy Zou
  Cc: vkoul, devicetree, dmaengine, imx, krzysztof.kozlowski+dt,
	linux-kernel, Peng Fan, robh+dt, Shenwei Wang

On Thu, Dec 21, 2023 at 07:47:19AM +0000, Joy Zou wrote:
> Hi frank,
> > -----Original Message-----
> > From: Frank Li <frank.li@nxp.com>
> > Sent: 2023年11月28日 6:56
> > To: Frank Li <frank.li@nxp.com>; vkoul@kernel.org
> > Cc: devicetree@vger.kernel.org; dmaengine@vger.kernel.org;
> > imx@lists.linux.dev; Joy Zou <joy.zou@nxp.com>;
> > krzysztof.kozlowski+dt@linaro.org; linux-kernel@vger.kernel.org; Peng Fan
> > <peng.fan@nxp.com>; robh+dt@kernel.org; Shenwei Wang
> > <shenwei.wang@nxp.com>
> > Subject: [PATCH v3 6/6] dmaengine: fsl-edma: integrate TCD64 support for
> > i.MX95
> > 
> > In i.MX95's edma version 5, the TCD structure is extended to support 64-bit
> > addresses for fields like saddr and daddr. To prevent code duplication, employ
> > help macros to handle the fields, as the field names remain the same between
> > TCD and TCD64.
> > 
> > Change local variables related to TCD addresses from 'u32' to 'dma_addr_t'
> > to accept 64-bit DMA addresses.
> > 
> > Change 'vtcd' type to 'void *' to avoid direct use. Use helper macros to access
> > the TCD fields correctly.
> > 
> > Call 'dma_set_mask_and_coherent(64)' when TCD64 is supported.
> > 
> > Signed-off-by: Frank Li <Frank.Li@nxp.com>
> > ---
> >  drivers/dma/fsl-edma-common.c |  34 ++++---
> > drivers/dma/fsl-edma-common.h | 165
> > +++++++++++++++++++++++++++-------
> >  drivers/dma/fsl-edma-main.c   |  14 +++
> >  3 files changed, 170 insertions(+), 43 deletions(-)
> > 
> > diff --git a/drivers/dma/fsl-edma-common.c
> > b/drivers/dma/fsl-edma-common.c index 65f466ab9d4da..c8acff09308fd
> > 100644
> > --- a/drivers/dma/fsl-edma-common.c
> > +++ b/drivers/dma/fsl-edma-common.c
> > @@ -351,7 +351,7 @@ static size_t fsl_edma_desc_residue(struct
> > fsl_edma_chan *fsl_chan,  {
> >  	struct fsl_edma_desc *edesc = fsl_chan->edesc;
> >  	enum dma_transfer_direction dir = edesc->dirn;
> > -	dma_addr_t cur_addr, dma_addr;
> > +	dma_addr_t cur_addr, dma_addr, old_addr;
> >  	size_t len, size;
> >  	u32 nbytes = 0;
> >  	int i;
> > @@ -367,10 +367,16 @@ static size_t fsl_edma_desc_residue(struct
> > fsl_edma_chan *fsl_chan,
> >  	if (!in_progress)
> >  		return len;
> > 
> > -	if (dir == DMA_MEM_TO_DEV)
> > -		cur_addr = edma_read_tcdreg(fsl_chan, saddr);
> > -	else
> > -		cur_addr = edma_read_tcdreg(fsl_chan, daddr);
> > +	/* 64bit read is not atomic, need read retry when high 32bit changed */
> > +	do {
> > +		if (dir == DMA_MEM_TO_DEV) {
> > +			old_addr = edma_read_tcdreg(fsl_chan, saddr);
> > +			cur_addr = edma_read_tcdreg(fsl_chan, saddr);
> > +		} else {
> > +			old_addr = edma_read_tcdreg(fsl_chan, daddr);
> > +			cur_addr = edma_read_tcdreg(fsl_chan, daddr);
> > +		}
> > +	} while (upper_32_bits(cur_addr) != upper_32_bits(old_addr));
> > 
> >  	/* figure out the finished and calculate the residue */
> >  	for (i = 0; i < fsl_chan->edesc->n_tcds; i++) { @@ -426,8 +432,7 @@
> > enum dma_status fsl_edma_tx_status(struct dma_chan *chan,
> >  	return fsl_chan->status;
> >  }
> > 
> > -static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan,
> > -				  struct fsl_edma_hw_tcd *tcd)
> > +static void fsl_edma_set_tcd_regs(struct fsl_edma_chan *fsl_chan, void
> > +*tcd)
> >  {
> >  	u16 csr = 0;
> > 
> > @@ -478,9 +483,9 @@ static void fsl_edma_set_tcd_regs(struct
> > fsl_edma_chan *fsl_chan,
> > 
> >  static inline
> >  void fsl_edma_fill_tcd(struct fsl_edma_chan *fsl_chan,
> > -		       struct fsl_edma_hw_tcd *tcd, u32 src, u32 dst,
> > -		       u16 attr, u16 soff, u32 nbytes, u32 slast, u16 citer,
> > -		       u16 biter, u16 doff, u32 dlast_sga, bool major_int,
> > +		       struct fsl_edma_hw_tcd *tcd, dma_addr_t src, dma_addr_t
> > dst,
> > +		       u16 attr, u16 soff, u32 nbytes, dma_addr_t slast, u16 citer,
> > +		       u16 biter, u16 doff, dma_addr_t dlast_sga, bool major_int,
> >  		       bool disable_req, bool enable_sg)  {
> >  	struct dma_slave_config *cfg = &fsl_chan->cfg; @@ -581,8 +586,9 @@
> > struct dma_async_tx_descriptor *fsl_edma_prep_dma_cyclic(
> >  	dma_addr_t dma_buf_next;
> >  	bool major_int = true;
> >  	int sg_len, i;
> > -	u32 src_addr, dst_addr, last_sg, nbytes;
> > +	dma_addr_t src_addr, dst_addr, last_sg;
> >  	u16 soff, doff, iter;
> > +	u32 nbytes;
> > 
> >  	if (!is_slave_direction(direction))
> >  		return NULL;
> > @@ -654,8 +660,9 @@ struct dma_async_tx_descriptor
> > *fsl_edma_prep_slave_sg(
> >  	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> >  	struct fsl_edma_desc *fsl_desc;
> >  	struct scatterlist *sg;
> > -	u32 src_addr, dst_addr, last_sg, nbytes;
> > +	dma_addr_t src_addr, dst_addr, last_sg;
> >  	u16 soff, doff, iter;
> > +	u32 nbytes;
> >  	int i;
> > 
> >  	if (!is_slave_direction(direction))
> > @@ -804,7 +811,8 @@ int fsl_edma_alloc_chan_resources(struct dma_chan
> > *chan)
> >  	struct fsl_edma_chan *fsl_chan = to_fsl_edma_chan(chan);
> > 
> >  	fsl_chan->tcd_pool = dma_pool_create("tcd_pool", chan->device->dev,
> > -				sizeof(struct fsl_edma_hw_tcd),
> > +				fsl_edma_drvflags(fsl_chan) & FSL_EDMA_DRV_TCD64 ?
> > +				sizeof(struct fsl_edma_hw_tcd64) : sizeof(struct
> > fsl_edma_hw_tcd),
> >  				32, 0);
> >  	return 0;
> >  }
> > diff --git a/drivers/dma/fsl-edma-common.h
> > b/drivers/dma/fsl-edma-common.h index 4f39a548547a6..6afceb9fded1b
> > 100644
> > --- a/drivers/dma/fsl-edma-common.h
> > +++ b/drivers/dma/fsl-edma-common.h
> > @@ -87,6 +87,20 @@ struct fsl_edma_hw_tcd {
> >  	__le16	biter;
> >  };
> > 
> > +struct fsl_edma_hw_tcd64 {
> > +	__le64  saddr;
> > +	__le16  soff;
> > +	__le16  attr;
> > +	__le32  nbytes;
> > +	__le64  slast;
> > +	__le64  daddr;
> > +	__le64  dlast_sga;
> > +	__le16  doff;
> > +	__le16  citer;
> > +	__le16  csr;
> > +	__le16  biter;
> > +} __packed;
> > +
> >  struct fsl_edma3_ch_reg {
> >  	__le32	ch_csr;
> >  	__le32	ch_es;
> > @@ -96,7 +110,10 @@ struct fsl_edma3_ch_reg {
> >  	__le32	ch_mux;
> >  	__le32  ch_mattr; /* edma4, reserved for edma3 */
> >  	__le32  ch_reserved;
> > -	struct fsl_edma_hw_tcd tcd;
> > +	union {
> > +		struct fsl_edma_hw_tcd tcd;
> > +		struct fsl_edma_hw_tcd tcd64;
> > +	};
> >  } __packed; 
> The tcd64 should be fsl_edma_hw_tcd64?
> BR

With help macro, it is not imporant, only used to caculate ch_reg address
from tcd address.

Anyway, it should change to fsl_edma_hw_tcd64 for better maintaince. 

Frank

> Joy Zou 
> > 
> >  /*
> > @@ -125,7 +142,7 @@ struct edma_regs {
> > 
> >  struct fsl_edma_sw_tcd {
> >  	dma_addr_t			ptcd;
> > -	struct fsl_edma_hw_tcd		*vtcd;
> > +	void				*vtcd;
> 

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

end of thread, other threads:[~2023-12-21 15:14 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-11-27 22:55 [PATCH v3 0/6] dmaengine: fsl-edma: integrate TCD64 support for 64bit physical address Frank Li
2023-11-27 22:55 ` [PATCH v3 1/6] dmaengine: fsl-edma: involve help macro fsl_edma_set(get)_tcd() Frank Li
2023-11-27 22:55 ` [PATCH v3 2/6] dmaengine: fsl-edma: fix spare build warning Frank Li
2023-11-27 22:55 ` [PATCH v3 3/6] dmaengine: fsl-edma: add address for channel mux register in fsl_edma_chan Frank Li
2023-11-27 22:55 ` [PATCH v3 4/6] dmaengine: mcf-edma: utilize edma_write_tcdreg() macro for TCD Access Frank Li
2023-11-27 22:55 ` [PATCH v3 5/6] dt-bindings: fsl-dma: fsl-edma: add fsl,imx95-edma5 compatible string Frank Li
2023-11-27 22:55 ` [PATCH v3 6/6] dmaengine: fsl-edma: integrate TCD64 support for i.MX95 Frank Li
2023-12-21  7:47   ` Joy Zou
2023-12-21 15:14     ` Frank Li
2023-12-12 16:19 ` [PATCH v3 0/6] dmaengine: fsl-edma: integrate TCD64 support for 64bit physical address Frank Li

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.