All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v3 0/4] dmaengine: sun6i: Allwinner D1 support
@ 2022-04-24 17:27 ` Samuel Holland
  0 siblings, 0 replies; 14+ messages in thread
From: Samuel Holland @ 2022-04-24 17:27 UTC (permalink / raw)
  To: Vinod Koul, dmaengine
  Cc: Samuel Holland, Chen-Yu Tsai, Jernej Skrabec,
	Krzysztof Kozlowski, Maxime Ripard, Rob Herring, devicetree,
	linux-arm-kernel, linux-kernel, linux-sunxi

D1 is a new RISC-V SoC that uses mostly the same peripherals as
existing ARM-based sunxi SoCs. This series adds dmaengine support for
D1, after fixing an issue where the driver depended on architecture-
specific behavior (patch 2) and resolving a TODO item (patch 3).

Changes in v3:
 - Fix format warnings
 - Fix shift warnings for 32-bit dma_addr_t and 32-bit phys_addr_t
 - Make explicit that v_lli->src/dst only hold the low 32 bits

Changes in v2:
 - Fix `checkpatch.pl --strict` style issues (missing spaces)

Samuel Holland (4):
  dt-bindings: dma: sun50i-a64: Add compatible for D1
  dmaengine: sun6i: Do not use virt_to_phys
  dmaengine: sun6i: Add support for 34-bit physical addresses
  dmaengine: sun6i: Add support for the D1 variant

 .../dma/allwinner,sun50i-a64-dma.yaml         |  9 +-
 drivers/dma/Kconfig                           |  2 +-
 drivers/dma/sun6i-dma.c                       | 92 ++++++++++++-------
 3 files changed, 65 insertions(+), 38 deletions(-)

-- 
2.35.1


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

* [PATCH v3 0/4] dmaengine: sun6i: Allwinner D1 support
@ 2022-04-24 17:27 ` Samuel Holland
  0 siblings, 0 replies; 14+ messages in thread
From: Samuel Holland @ 2022-04-24 17:27 UTC (permalink / raw)
  To: Vinod Koul, dmaengine
  Cc: Samuel Holland, Chen-Yu Tsai, Jernej Skrabec,
	Krzysztof Kozlowski, Maxime Ripard, Rob Herring, devicetree,
	linux-arm-kernel, linux-kernel, linux-sunxi

D1 is a new RISC-V SoC that uses mostly the same peripherals as
existing ARM-based sunxi SoCs. This series adds dmaengine support for
D1, after fixing an issue where the driver depended on architecture-
specific behavior (patch 2) and resolving a TODO item (patch 3).

Changes in v3:
 - Fix format warnings
 - Fix shift warnings for 32-bit dma_addr_t and 32-bit phys_addr_t
 - Make explicit that v_lli->src/dst only hold the low 32 bits

Changes in v2:
 - Fix `checkpatch.pl --strict` style issues (missing spaces)

Samuel Holland (4):
  dt-bindings: dma: sun50i-a64: Add compatible for D1
  dmaengine: sun6i: Do not use virt_to_phys
  dmaengine: sun6i: Add support for 34-bit physical addresses
  dmaengine: sun6i: Add support for the D1 variant

 .../dma/allwinner,sun50i-a64-dma.yaml         |  9 +-
 drivers/dma/Kconfig                           |  2 +-
 drivers/dma/sun6i-dma.c                       | 92 ++++++++++++-------
 3 files changed, 65 insertions(+), 38 deletions(-)

-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 1/4] dt-bindings: dma: sun50i-a64: Add compatible for D1
  2022-04-24 17:27 ` Samuel Holland
@ 2022-04-24 17:27   ` Samuel Holland
  -1 siblings, 0 replies; 14+ messages in thread
From: Samuel Holland @ 2022-04-24 17:27 UTC (permalink / raw)
  To: Vinod Koul, dmaengine
  Cc: Samuel Holland, Chen-Yu Tsai, Jernej Skrabec,
	Krzysztof Kozlowski, Maxime Ripard, Rob Herring, devicetree,
	linux-arm-kernel, linux-kernel, linux-sunxi, Rob Herring,
	Maxime Ripard

D1 has a DMA controller similar to the one in other Allwinner SoCs.
Add its compatible, and include it in the list of variants with a
separate MBUS clock gate.

Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Maxime Ripard <maxime@cerno.tech>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

(no changes since v1)

 .../bindings/dma/allwinner,sun50i-a64-dma.yaml           | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml b/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
index b6e1ebfaf366..ff0a5c58d78c 100644
--- a/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
+++ b/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
@@ -20,9 +20,11 @@ properties:
 
   compatible:
     oneOf:
-      - const: allwinner,sun50i-a64-dma
-      - const: allwinner,sun50i-a100-dma
-      - const: allwinner,sun50i-h6-dma
+      - enum:
+          - allwinner,sun20i-d1-dma
+          - allwinner,sun50i-a64-dma
+          - allwinner,sun50i-a100-dma
+          - allwinner,sun50i-h6-dma
       - items:
           - const: allwinner,sun8i-r40-dma
           - const: allwinner,sun50i-a64-dma
@@ -58,6 +60,7 @@ if:
   properties:
     compatible:
       enum:
+        - allwinner,sun20i-d1-dma
         - allwinner,sun50i-a100-dma
         - allwinner,sun50i-h6-dma
 
-- 
2.35.1


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

* [PATCH v3 1/4] dt-bindings: dma: sun50i-a64: Add compatible for D1
@ 2022-04-24 17:27   ` Samuel Holland
  0 siblings, 0 replies; 14+ messages in thread
From: Samuel Holland @ 2022-04-24 17:27 UTC (permalink / raw)
  To: Vinod Koul, dmaengine
  Cc: Samuel Holland, Chen-Yu Tsai, Jernej Skrabec,
	Krzysztof Kozlowski, Maxime Ripard, Rob Herring, devicetree,
	linux-arm-kernel, linux-kernel, linux-sunxi, Rob Herring,
	Maxime Ripard

D1 has a DMA controller similar to the one in other Allwinner SoCs.
Add its compatible, and include it in the list of variants with a
separate MBUS clock gate.

Acked-by: Rob Herring <robh@kernel.org>
Acked-by: Maxime Ripard <maxime@cerno.tech>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

(no changes since v1)

 .../bindings/dma/allwinner,sun50i-a64-dma.yaml           | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml b/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
index b6e1ebfaf366..ff0a5c58d78c 100644
--- a/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
+++ b/Documentation/devicetree/bindings/dma/allwinner,sun50i-a64-dma.yaml
@@ -20,9 +20,11 @@ properties:
 
   compatible:
     oneOf:
-      - const: allwinner,sun50i-a64-dma
-      - const: allwinner,sun50i-a100-dma
-      - const: allwinner,sun50i-h6-dma
+      - enum:
+          - allwinner,sun20i-d1-dma
+          - allwinner,sun50i-a64-dma
+          - allwinner,sun50i-a100-dma
+          - allwinner,sun50i-h6-dma
       - items:
           - const: allwinner,sun8i-r40-dma
           - const: allwinner,sun50i-a64-dma
@@ -58,6 +60,7 @@ if:
   properties:
     compatible:
       enum:
+        - allwinner,sun20i-d1-dma
         - allwinner,sun50i-a100-dma
         - allwinner,sun50i-h6-dma
 
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 2/4] dmaengine: sun6i: Do not use virt_to_phys
  2022-04-24 17:27 ` Samuel Holland
@ 2022-04-24 17:27   ` Samuel Holland
  -1 siblings, 0 replies; 14+ messages in thread
From: Samuel Holland @ 2022-04-24 17:27 UTC (permalink / raw)
  To: Vinod Koul, dmaengine
  Cc: Samuel Holland, Chen-Yu Tsai, Jernej Skrabec,
	Krzysztof Kozlowski, Maxime Ripard, Rob Herring, devicetree,
	linux-arm-kernel, linux-kernel, linux-sunxi, Maxime Ripard

This breaks on RISC-V, because dma_pool_alloc returns addresses which
are not in the linear map. Instead, plumb through the physical address
which is already known anyway.

Acked-by: Maxime Ripard <maxime@cerno.tech>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v3:
 - Fix format warnings

 drivers/dma/sun6i-dma.c | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 5cadd4d2b824..4436fbd70445 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -241,9 +241,7 @@ static inline void sun6i_dma_dump_com_regs(struct sun6i_dma_dev *sdev)
 static inline void sun6i_dma_dump_chan_regs(struct sun6i_dma_dev *sdev,
 					    struct sun6i_pchan *pchan)
 {
-	phys_addr_t reg = virt_to_phys(pchan->base);
-
-	dev_dbg(sdev->slave.dev, "Chan %d reg: %pa\n"
+	dev_dbg(sdev->slave.dev, "Chan %d reg:\n"
 		"\t___en(%04x): \t0x%08x\n"
 		"\tpause(%04x): \t0x%08x\n"
 		"\tstart(%04x): \t0x%08x\n"
@@ -252,7 +250,7 @@ static inline void sun6i_dma_dump_chan_regs(struct sun6i_dma_dev *sdev,
 		"\t__dst(%04x): \t0x%08x\n"
 		"\tcount(%04x): \t0x%08x\n"
 		"\t_para(%04x): \t0x%08x\n\n",
-		pchan->idx, &reg,
+		pchan->idx,
 		DMA_CHAN_ENABLE,
 		readl(pchan->base + DMA_CHAN_ENABLE),
 		DMA_CHAN_PAUSE,
@@ -385,17 +383,16 @@ static void *sun6i_dma_lli_add(struct sun6i_dma_lli *prev,
 }
 
 static inline void sun6i_dma_dump_lli(struct sun6i_vchan *vchan,
-				      struct sun6i_dma_lli *lli)
+				      struct sun6i_dma_lli *v_lli,
+				      dma_addr_t p_lli)
 {
-	phys_addr_t p_lli = virt_to_phys(lli);
-
 	dev_dbg(chan2dev(&vchan->vc.chan),
-		"\n\tdesc:   p - %pa v - 0x%p\n"
+		"\n\tdesc:\tp - %pad v - 0x%p\n"
 		"\t\tc - 0x%08x s - 0x%08x d - 0x%08x\n"
 		"\t\tl - 0x%08x p - 0x%08x n - 0x%08x\n",
-		&p_lli, lli,
-		lli->cfg, lli->src, lli->dst,
-		lli->len, lli->para, lli->p_lli_next);
+		&p_lli, v_lli,
+		v_lli->cfg, v_lli->src, v_lli->dst,
+		v_lli->len, v_lli->para, v_lli->p_lli_next);
 }
 
 static void sun6i_dma_free_desc(struct virt_dma_desc *vd)
@@ -445,7 +442,7 @@ static int sun6i_dma_start_desc(struct sun6i_vchan *vchan)
 	pchan->desc = to_sun6i_desc(&desc->tx);
 	pchan->done = NULL;
 
-	sun6i_dma_dump_lli(vchan, pchan->desc->v_lli);
+	sun6i_dma_dump_lli(vchan, pchan->desc->v_lli, pchan->desc->p_lli);
 
 	irq_reg = pchan->idx / DMA_IRQ_CHAN_NR;
 	irq_offset = pchan->idx % DMA_IRQ_CHAN_NR;
@@ -670,7 +667,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
 
 	sun6i_dma_lli_add(NULL, v_lli, p_lli, txd);
 
-	sun6i_dma_dump_lli(vchan, v_lli);
+	sun6i_dma_dump_lli(vchan, v_lli, p_lli);
 
 	return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
 
@@ -746,14 +743,16 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 	}
 
 	dev_dbg(chan2dev(chan), "First: %pad\n", &txd->p_lli);
-	for (prev = txd->v_lli; prev; prev = prev->v_lli_next)
-		sun6i_dma_dump_lli(vchan, prev);
+	for (p_lli = txd->p_lli, v_lli = txd->v_lli; v_lli;
+	     p_lli = v_lli->p_lli_next, v_lli = v_lli->v_lli_next)
+		sun6i_dma_dump_lli(vchan, v_lli, p_lli);
 
 	return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
 
 err_lli_free:
-	for (prev = txd->v_lli; prev; prev = prev->v_lli_next)
-		dma_pool_free(sdev->pool, prev, virt_to_phys(prev));
+	for (p_lli = txd->p_lli, v_lli = txd->v_lli; v_lli;
+	     p_lli = v_lli->p_lli_next, v_lli = v_lli->v_lli_next)
+		dma_pool_free(sdev->pool, v_lli, p_lli);
 	kfree(txd);
 	return NULL;
 }
@@ -820,8 +819,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
 	return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
 
 err_lli_free:
-	for (prev = txd->v_lli; prev; prev = prev->v_lli_next)
-		dma_pool_free(sdev->pool, prev, virt_to_phys(prev));
+	for (p_lli = txd->p_lli, v_lli = txd->v_lli; v_lli;
+	     p_lli = v_lli->p_lli_next, v_lli = v_lli->v_lli_next)
+		dma_pool_free(sdev->pool, v_lli, p_lli);
 	kfree(txd);
 	return NULL;
 }
-- 
2.35.1


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

* [PATCH v3 2/4] dmaengine: sun6i: Do not use virt_to_phys
@ 2022-04-24 17:27   ` Samuel Holland
  0 siblings, 0 replies; 14+ messages in thread
From: Samuel Holland @ 2022-04-24 17:27 UTC (permalink / raw)
  To: Vinod Koul, dmaengine
  Cc: Samuel Holland, Chen-Yu Tsai, Jernej Skrabec,
	Krzysztof Kozlowski, Maxime Ripard, Rob Herring, devicetree,
	linux-arm-kernel, linux-kernel, linux-sunxi, Maxime Ripard

This breaks on RISC-V, because dma_pool_alloc returns addresses which
are not in the linear map. Instead, plumb through the physical address
which is already known anyway.

Acked-by: Maxime Ripard <maxime@cerno.tech>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v3:
 - Fix format warnings

 drivers/dma/sun6i-dma.c | 38 +++++++++++++++++++-------------------
 1 file changed, 19 insertions(+), 19 deletions(-)

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 5cadd4d2b824..4436fbd70445 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -241,9 +241,7 @@ static inline void sun6i_dma_dump_com_regs(struct sun6i_dma_dev *sdev)
 static inline void sun6i_dma_dump_chan_regs(struct sun6i_dma_dev *sdev,
 					    struct sun6i_pchan *pchan)
 {
-	phys_addr_t reg = virt_to_phys(pchan->base);
-
-	dev_dbg(sdev->slave.dev, "Chan %d reg: %pa\n"
+	dev_dbg(sdev->slave.dev, "Chan %d reg:\n"
 		"\t___en(%04x): \t0x%08x\n"
 		"\tpause(%04x): \t0x%08x\n"
 		"\tstart(%04x): \t0x%08x\n"
@@ -252,7 +250,7 @@ static inline void sun6i_dma_dump_chan_regs(struct sun6i_dma_dev *sdev,
 		"\t__dst(%04x): \t0x%08x\n"
 		"\tcount(%04x): \t0x%08x\n"
 		"\t_para(%04x): \t0x%08x\n\n",
-		pchan->idx, &reg,
+		pchan->idx,
 		DMA_CHAN_ENABLE,
 		readl(pchan->base + DMA_CHAN_ENABLE),
 		DMA_CHAN_PAUSE,
@@ -385,17 +383,16 @@ static void *sun6i_dma_lli_add(struct sun6i_dma_lli *prev,
 }
 
 static inline void sun6i_dma_dump_lli(struct sun6i_vchan *vchan,
-				      struct sun6i_dma_lli *lli)
+				      struct sun6i_dma_lli *v_lli,
+				      dma_addr_t p_lli)
 {
-	phys_addr_t p_lli = virt_to_phys(lli);
-
 	dev_dbg(chan2dev(&vchan->vc.chan),
-		"\n\tdesc:   p - %pa v - 0x%p\n"
+		"\n\tdesc:\tp - %pad v - 0x%p\n"
 		"\t\tc - 0x%08x s - 0x%08x d - 0x%08x\n"
 		"\t\tl - 0x%08x p - 0x%08x n - 0x%08x\n",
-		&p_lli, lli,
-		lli->cfg, lli->src, lli->dst,
-		lli->len, lli->para, lli->p_lli_next);
+		&p_lli, v_lli,
+		v_lli->cfg, v_lli->src, v_lli->dst,
+		v_lli->len, v_lli->para, v_lli->p_lli_next);
 }
 
 static void sun6i_dma_free_desc(struct virt_dma_desc *vd)
@@ -445,7 +442,7 @@ static int sun6i_dma_start_desc(struct sun6i_vchan *vchan)
 	pchan->desc = to_sun6i_desc(&desc->tx);
 	pchan->done = NULL;
 
-	sun6i_dma_dump_lli(vchan, pchan->desc->v_lli);
+	sun6i_dma_dump_lli(vchan, pchan->desc->v_lli, pchan->desc->p_lli);
 
 	irq_reg = pchan->idx / DMA_IRQ_CHAN_NR;
 	irq_offset = pchan->idx % DMA_IRQ_CHAN_NR;
@@ -670,7 +667,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
 
 	sun6i_dma_lli_add(NULL, v_lli, p_lli, txd);
 
-	sun6i_dma_dump_lli(vchan, v_lli);
+	sun6i_dma_dump_lli(vchan, v_lli, p_lli);
 
 	return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
 
@@ -746,14 +743,16 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 	}
 
 	dev_dbg(chan2dev(chan), "First: %pad\n", &txd->p_lli);
-	for (prev = txd->v_lli; prev; prev = prev->v_lli_next)
-		sun6i_dma_dump_lli(vchan, prev);
+	for (p_lli = txd->p_lli, v_lli = txd->v_lli; v_lli;
+	     p_lli = v_lli->p_lli_next, v_lli = v_lli->v_lli_next)
+		sun6i_dma_dump_lli(vchan, v_lli, p_lli);
 
 	return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
 
 err_lli_free:
-	for (prev = txd->v_lli; prev; prev = prev->v_lli_next)
-		dma_pool_free(sdev->pool, prev, virt_to_phys(prev));
+	for (p_lli = txd->p_lli, v_lli = txd->v_lli; v_lli;
+	     p_lli = v_lli->p_lli_next, v_lli = v_lli->v_lli_next)
+		dma_pool_free(sdev->pool, v_lli, p_lli);
 	kfree(txd);
 	return NULL;
 }
@@ -820,8 +819,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
 	return vchan_tx_prep(&vchan->vc, &txd->vd, flags);
 
 err_lli_free:
-	for (prev = txd->v_lli; prev; prev = prev->v_lli_next)
-		dma_pool_free(sdev->pool, prev, virt_to_phys(prev));
+	for (p_lli = txd->p_lli, v_lli = txd->v_lli; v_lli;
+	     p_lli = v_lli->p_lli_next, v_lli = v_lli->v_lli_next)
+		dma_pool_free(sdev->pool, v_lli, p_lli);
 	kfree(txd);
 	return NULL;
 }
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 3/4] dmaengine: sun6i: Add support for 34-bit physical addresses
  2022-04-24 17:27 ` Samuel Holland
@ 2022-04-24 17:27   ` Samuel Holland
  -1 siblings, 0 replies; 14+ messages in thread
From: Samuel Holland @ 2022-04-24 17:27 UTC (permalink / raw)
  To: Vinod Koul, dmaengine
  Cc: Samuel Holland, Chen-Yu Tsai, Jernej Skrabec,
	Krzysztof Kozlowski, Maxime Ripard, Rob Herring, devicetree,
	linux-arm-kernel, linux-kernel, linux-sunxi

Recent Allwinner SoCs support >4 GiB of DRAM, so those variants of the
DMA engine support >32 bit physical addresses. This is accomplished by
placing the high bits in the "para" word in the DMA descriptor.

DMA descriptors themselves can be located at >32 bit addresses by
putting the high bits in the LSBs of the descriptor address register,
taking advantage of the required DMA descriptor alignment. However,
support for this is not really necessary, so we can avoid the
complication by allocating them from the DMA_32 zone.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v3:
 - Fix shift warnings for 32-bit dma_addr_t and 32-bit phys_addr_t
 - Make explicit that v_lli->src/dst only hold the low 32 bits

Changes in v2:
 - Fix `checkpatch.pl --strict` style issues (missing spaces)

 drivers/dma/sun6i-dma.c | 53 +++++++++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 15 deletions(-)

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 4436fbd70445..1eb3bafa7324 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -90,6 +90,14 @@
 
 #define DMA_CHAN_CUR_PARA	0x1c
 
+/*
+ * LLI address mangling
+ *
+ * The LLI link physical address is also mangled, but we avoid dealing
+ * with that by allocating LLIs from the DMA32 zone.
+ */
+#define SRC_HIGH_ADDR(x)		(((x) & 0x3U) << 16)
+#define DST_HIGH_ADDR(x)		(((x) & 0x3U) << 18)
 
 /*
  * Various hardware related defines
@@ -132,6 +140,7 @@ struct sun6i_dma_config {
 	u32 dst_burst_lengths;
 	u32 src_addr_widths;
 	u32 dst_addr_widths;
+	bool has_high_addr;
 	bool has_mbus_clk;
 };
 
@@ -623,6 +632,18 @@ static int set_config(struct sun6i_dma_dev *sdev,
 	return 0;
 }
 
+static inline void sun6i_dma_set_addr(struct sun6i_dma_dev *sdev,
+				      struct sun6i_dma_lli *v_lli,
+				      dma_addr_t src, dma_addr_t dst)
+{
+	v_lli->src = lower_32_bits(src);
+	v_lli->dst = lower_32_bits(dst);
+
+	if (sdev->cfg->has_high_addr)
+		v_lli->para |= SRC_HIGH_ADDR(upper_32_bits(src)) |
+			       DST_HIGH_ADDR(upper_32_bits(dst));
+}
+
 static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
 		struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 		size_t len, unsigned long flags)
@@ -645,16 +666,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
 	if (!txd)
 		return NULL;
 
-	v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
+	v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | GFP_NOWAIT, &p_lli);
 	if (!v_lli) {
 		dev_err(sdev->slave.dev, "Failed to alloc lli memory\n");
 		goto err_txd_free;
 	}
 
-	v_lli->src = src;
-	v_lli->dst = dest;
 	v_lli->len = len;
 	v_lli->para = NORMAL_WAIT;
+	sun6i_dma_set_addr(sdev, v_lli, src, dest);
 
 	burst = convert_burst(8);
 	width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES);
@@ -705,7 +725,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 		return NULL;
 
 	for_each_sg(sgl, sg, sg_len, i) {
-		v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
+		v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | GFP_NOWAIT, &p_lli);
 		if (!v_lli)
 			goto err_lli_free;
 
@@ -713,8 +733,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 		v_lli->para = NORMAL_WAIT;
 
 		if (dir == DMA_MEM_TO_DEV) {
-			v_lli->src = sg_dma_address(sg);
-			v_lli->dst = sconfig->dst_addr;
+			sun6i_dma_set_addr(sdev, v_lli,
+					   sg_dma_address(sg),
+					   sconfig->dst_addr);
 			v_lli->cfg = lli_cfg;
 			sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port);
 			sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE);
@@ -726,8 +747,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 				sg_dma_len(sg), flags);
 
 		} else {
-			v_lli->src = sconfig->src_addr;
-			v_lli->dst = sg_dma_address(sg);
+			sun6i_dma_set_addr(sdev, v_lli,
+					   sconfig->src_addr,
+					   sg_dma_address(sg));
 			v_lli->cfg = lli_cfg;
 			sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM);
 			sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE);
@@ -786,7 +808,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
 		return NULL;
 
 	for (i = 0; i < periods; i++) {
-		v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
+		v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | GFP_NOWAIT, &p_lli);
 		if (!v_lli) {
 			dev_err(sdev->slave.dev, "Failed to alloc lli memory\n");
 			goto err_lli_free;
@@ -796,14 +818,16 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
 		v_lli->para = NORMAL_WAIT;
 
 		if (dir == DMA_MEM_TO_DEV) {
-			v_lli->src = buf_addr + period_len * i;
-			v_lli->dst = sconfig->dst_addr;
+			sun6i_dma_set_addr(sdev, v_lli,
+					   buf_addr + period_len * i,
+					   sconfig->dst_addr);
 			v_lli->cfg = lli_cfg;
 			sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port);
 			sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE);
 		} else {
-			v_lli->src = sconfig->src_addr;
-			v_lli->dst = buf_addr + period_len * i;
+			sun6i_dma_set_addr(sdev, v_lli,
+					   sconfig->src_addr,
+					   buf_addr + period_len * i);
 			v_lli->cfg = lli_cfg;
 			sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM);
 			sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE);
@@ -1174,8 +1198,6 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = {
 };
 
 /*
- * TODO: Add support for more than 4g physical addressing.
- *
  * The A100 binding uses the number of dma channels from the
  * device tree node.
  */
@@ -1194,6 +1216,7 @@ static struct sun6i_dma_config sun50i_a100_dma_cfg = {
 			     BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
 			     BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
 			     BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
+	.has_high_addr = true,
 	.has_mbus_clk = true,
 };
 
-- 
2.35.1


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

* [PATCH v3 3/4] dmaengine: sun6i: Add support for 34-bit physical addresses
@ 2022-04-24 17:27   ` Samuel Holland
  0 siblings, 0 replies; 14+ messages in thread
From: Samuel Holland @ 2022-04-24 17:27 UTC (permalink / raw)
  To: Vinod Koul, dmaengine
  Cc: Samuel Holland, Chen-Yu Tsai, Jernej Skrabec,
	Krzysztof Kozlowski, Maxime Ripard, Rob Herring, devicetree,
	linux-arm-kernel, linux-kernel, linux-sunxi

Recent Allwinner SoCs support >4 GiB of DRAM, so those variants of the
DMA engine support >32 bit physical addresses. This is accomplished by
placing the high bits in the "para" word in the DMA descriptor.

DMA descriptors themselves can be located at >32 bit addresses by
putting the high bits in the LSBs of the descriptor address register,
taking advantage of the required DMA descriptor alignment. However,
support for this is not really necessary, so we can avoid the
complication by allocating them from the DMA_32 zone.

Signed-off-by: Samuel Holland <samuel@sholland.org>
---

Changes in v3:
 - Fix shift warnings for 32-bit dma_addr_t and 32-bit phys_addr_t
 - Make explicit that v_lli->src/dst only hold the low 32 bits

Changes in v2:
 - Fix `checkpatch.pl --strict` style issues (missing spaces)

 drivers/dma/sun6i-dma.c | 53 +++++++++++++++++++++++++++++------------
 1 file changed, 38 insertions(+), 15 deletions(-)

diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 4436fbd70445..1eb3bafa7324 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -90,6 +90,14 @@
 
 #define DMA_CHAN_CUR_PARA	0x1c
 
+/*
+ * LLI address mangling
+ *
+ * The LLI link physical address is also mangled, but we avoid dealing
+ * with that by allocating LLIs from the DMA32 zone.
+ */
+#define SRC_HIGH_ADDR(x)		(((x) & 0x3U) << 16)
+#define DST_HIGH_ADDR(x)		(((x) & 0x3U) << 18)
 
 /*
  * Various hardware related defines
@@ -132,6 +140,7 @@ struct sun6i_dma_config {
 	u32 dst_burst_lengths;
 	u32 src_addr_widths;
 	u32 dst_addr_widths;
+	bool has_high_addr;
 	bool has_mbus_clk;
 };
 
@@ -623,6 +632,18 @@ static int set_config(struct sun6i_dma_dev *sdev,
 	return 0;
 }
 
+static inline void sun6i_dma_set_addr(struct sun6i_dma_dev *sdev,
+				      struct sun6i_dma_lli *v_lli,
+				      dma_addr_t src, dma_addr_t dst)
+{
+	v_lli->src = lower_32_bits(src);
+	v_lli->dst = lower_32_bits(dst);
+
+	if (sdev->cfg->has_high_addr)
+		v_lli->para |= SRC_HIGH_ADDR(upper_32_bits(src)) |
+			       DST_HIGH_ADDR(upper_32_bits(dst));
+}
+
 static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
 		struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 		size_t len, unsigned long flags)
@@ -645,16 +666,15 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
 	if (!txd)
 		return NULL;
 
-	v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
+	v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | GFP_NOWAIT, &p_lli);
 	if (!v_lli) {
 		dev_err(sdev->slave.dev, "Failed to alloc lli memory\n");
 		goto err_txd_free;
 	}
 
-	v_lli->src = src;
-	v_lli->dst = dest;
 	v_lli->len = len;
 	v_lli->para = NORMAL_WAIT;
+	sun6i_dma_set_addr(sdev, v_lli, src, dest);
 
 	burst = convert_burst(8);
 	width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES);
@@ -705,7 +725,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 		return NULL;
 
 	for_each_sg(sgl, sg, sg_len, i) {
-		v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
+		v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | GFP_NOWAIT, &p_lli);
 		if (!v_lli)
 			goto err_lli_free;
 
@@ -713,8 +733,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 		v_lli->para = NORMAL_WAIT;
 
 		if (dir == DMA_MEM_TO_DEV) {
-			v_lli->src = sg_dma_address(sg);
-			v_lli->dst = sconfig->dst_addr;
+			sun6i_dma_set_addr(sdev, v_lli,
+					   sg_dma_address(sg),
+					   sconfig->dst_addr);
 			v_lli->cfg = lli_cfg;
 			sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port);
 			sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE);
@@ -726,8 +747,9 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_slave_sg(
 				sg_dma_len(sg), flags);
 
 		} else {
-			v_lli->src = sconfig->src_addr;
-			v_lli->dst = sg_dma_address(sg);
+			sun6i_dma_set_addr(sdev, v_lli,
+					   sconfig->src_addr,
+					   sg_dma_address(sg));
 			v_lli->cfg = lli_cfg;
 			sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM);
 			sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE);
@@ -786,7 +808,7 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
 		return NULL;
 
 	for (i = 0; i < periods; i++) {
-		v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
+		v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | GFP_NOWAIT, &p_lli);
 		if (!v_lli) {
 			dev_err(sdev->slave.dev, "Failed to alloc lli memory\n");
 			goto err_lli_free;
@@ -796,14 +818,16 @@ static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_cyclic(
 		v_lli->para = NORMAL_WAIT;
 
 		if (dir == DMA_MEM_TO_DEV) {
-			v_lli->src = buf_addr + period_len * i;
-			v_lli->dst = sconfig->dst_addr;
+			sun6i_dma_set_addr(sdev, v_lli,
+					   buf_addr + period_len * i,
+					   sconfig->dst_addr);
 			v_lli->cfg = lli_cfg;
 			sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, vchan->port);
 			sdev->cfg->set_mode(&v_lli->cfg, LINEAR_MODE, IO_MODE);
 		} else {
-			v_lli->src = sconfig->src_addr;
-			v_lli->dst = buf_addr + period_len * i;
+			sun6i_dma_set_addr(sdev, v_lli,
+					   sconfig->src_addr,
+					   buf_addr + period_len * i);
 			v_lli->cfg = lli_cfg;
 			sdev->cfg->set_drq(&v_lli->cfg, vchan->port, DRQ_SDRAM);
 			sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, LINEAR_MODE);
@@ -1174,8 +1198,6 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = {
 };
 
 /*
- * TODO: Add support for more than 4g physical addressing.
- *
  * The A100 binding uses the number of dma channels from the
  * device tree node.
  */
@@ -1194,6 +1216,7 @@ static struct sun6i_dma_config sun50i_a100_dma_cfg = {
 			     BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
 			     BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
 			     BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
+	.has_high_addr = true,
 	.has_mbus_clk = true,
 };
 
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH v3 4/4] dmaengine: sun6i: Add support for the D1 variant
  2022-04-24 17:27 ` Samuel Holland
@ 2022-04-24 17:27   ` Samuel Holland
  -1 siblings, 0 replies; 14+ messages in thread
From: Samuel Holland @ 2022-04-24 17:27 UTC (permalink / raw)
  To: Vinod Koul, dmaengine
  Cc: Samuel Holland, Chen-Yu Tsai, Jernej Skrabec,
	Krzysztof Kozlowski, Maxime Ripard, Rob Herring, devicetree,
	linux-arm-kernel, linux-kernel, linux-sunxi, Maxime Ripard

So far it appears to match the configuration of the A100 variant.

Since D1 is a RISC-V chip, it does not meet any of the existing
dependencies for this driver, so relax the dependency somewhat.

Acked-by: Maxime Ripard <maxime@cerno.tech>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

(no changes since v1)

 drivers/dma/Kconfig     | 2 +-
 drivers/dma/sun6i-dma.c | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index d5de3f77d3aa..b6845303cf7e 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -163,7 +163,7 @@ config DMA_SUN4I
 
 config DMA_SUN6I
 	tristate "Allwinner A31 SoCs DMA support"
-	depends on MACH_SUN6I || MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST
+	depends on ARCH_SUNXI || COMPILE_TEST
 	depends on RESET_CONTROLLER
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 1eb3bafa7324..b7557f437936 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -1271,6 +1271,7 @@ static const struct of_device_id sun6i_dma_match[] = {
 	{ .compatible = "allwinner,sun8i-a83t-dma", .data = &sun8i_a83t_dma_cfg },
 	{ .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg },
 	{ .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg },
+	{ .compatible = "allwinner,sun20i-d1-dma", .data = &sun50i_a100_dma_cfg },
 	{ .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg },
 	{ .compatible = "allwinner,sun50i-a100-dma", .data = &sun50i_a100_dma_cfg },
 	{ .compatible = "allwinner,sun50i-h6-dma", .data = &sun50i_h6_dma_cfg },
-- 
2.35.1


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

* [PATCH v3 4/4] dmaengine: sun6i: Add support for the D1 variant
@ 2022-04-24 17:27   ` Samuel Holland
  0 siblings, 0 replies; 14+ messages in thread
From: Samuel Holland @ 2022-04-24 17:27 UTC (permalink / raw)
  To: Vinod Koul, dmaengine
  Cc: Samuel Holland, Chen-Yu Tsai, Jernej Skrabec,
	Krzysztof Kozlowski, Maxime Ripard, Rob Herring, devicetree,
	linux-arm-kernel, linux-kernel, linux-sunxi, Maxime Ripard

So far it appears to match the configuration of the A100 variant.

Since D1 is a RISC-V chip, it does not meet any of the existing
dependencies for this driver, so relax the dependency somewhat.

Acked-by: Maxime Ripard <maxime@cerno.tech>
Signed-off-by: Samuel Holland <samuel@sholland.org>
---

(no changes since v1)

 drivers/dma/Kconfig     | 2 +-
 drivers/dma/sun6i-dma.c | 1 +
 2 files changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index d5de3f77d3aa..b6845303cf7e 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -163,7 +163,7 @@ config DMA_SUN4I
 
 config DMA_SUN6I
 	tristate "Allwinner A31 SoCs DMA support"
-	depends on MACH_SUN6I || MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST
+	depends on ARCH_SUNXI || COMPILE_TEST
 	depends on RESET_CONTROLLER
 	select DMA_ENGINE
 	select DMA_VIRTUAL_CHANNELS
diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
index 1eb3bafa7324..b7557f437936 100644
--- a/drivers/dma/sun6i-dma.c
+++ b/drivers/dma/sun6i-dma.c
@@ -1271,6 +1271,7 @@ static const struct of_device_id sun6i_dma_match[] = {
 	{ .compatible = "allwinner,sun8i-a83t-dma", .data = &sun8i_a83t_dma_cfg },
 	{ .compatible = "allwinner,sun8i-h3-dma", .data = &sun8i_h3_dma_cfg },
 	{ .compatible = "allwinner,sun8i-v3s-dma", .data = &sun8i_v3s_dma_cfg },
+	{ .compatible = "allwinner,sun20i-d1-dma", .data = &sun50i_a100_dma_cfg },
 	{ .compatible = "allwinner,sun50i-a64-dma", .data = &sun50i_a64_dma_cfg },
 	{ .compatible = "allwinner,sun50i-a100-dma", .data = &sun50i_a100_dma_cfg },
 	{ .compatible = "allwinner,sun50i-h6-dma", .data = &sun50i_h6_dma_cfg },
-- 
2.35.1


_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 3/4] dmaengine: sun6i: Add support for 34-bit physical addresses
  2022-04-24 17:27   ` Samuel Holland
@ 2022-04-24 20:17     ` Jernej Škrabec
  -1 siblings, 0 replies; 14+ messages in thread
From: Jernej Škrabec @ 2022-04-24 20:17 UTC (permalink / raw)
  To: Vinod Koul, dmaengine, Samuel Holland
  Cc: Samuel Holland, Chen-Yu Tsai, Krzysztof Kozlowski, Maxime Ripard,
	Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-sunxi

Dne nedelja, 24. april 2022 ob 19:27:57 CEST je Samuel Holland napisal(a):
> Recent Allwinner SoCs support >4 GiB of DRAM, so those variants of the
> DMA engine support >32 bit physical addresses. This is accomplished by
> placing the high bits in the "para" word in the DMA descriptor.
> 
> DMA descriptors themselves can be located at >32 bit addresses by
> putting the high bits in the LSBs of the descriptor address register,
> taking advantage of the required DMA descriptor alignment. However,
> support for this is not really necessary, so we can avoid the
> complication by allocating them from the DMA_32 zone.
> 
> Signed-off-by: Samuel Holland <samuel@sholland.org>

Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>

Best regards,
Jernej Skrabec

> ---
> 
> Changes in v3:
>  - Fix shift warnings for 32-bit dma_addr_t and 32-bit phys_addr_t
>  - Make explicit that v_lli->src/dst only hold the low 32 bits
> 
> Changes in v2:
>  - Fix `checkpatch.pl --strict` style issues (missing spaces)
> 
>  drivers/dma/sun6i-dma.c | 53 +++++++++++++++++++++++++++++------------
>  1 file changed, 38 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index 4436fbd70445..1eb3bafa7324 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -90,6 +90,14 @@
>  
>  #define DMA_CHAN_CUR_PARA	0x1c
>  
> +/*
> + * LLI address mangling
> + *
> + * The LLI link physical address is also mangled, but we avoid dealing
> + * with that by allocating LLIs from the DMA32 zone.
> + */
> +#define SRC_HIGH_ADDR(x)		(((x) & 0x3U) << 16)
> +#define DST_HIGH_ADDR(x)		(((x) & 0x3U) << 18)
>  
>  /*
>   * Various hardware related defines
> @@ -132,6 +140,7 @@ struct sun6i_dma_config {
>  	u32 dst_burst_lengths;
>  	u32 src_addr_widths;
>  	u32 dst_addr_widths;
> +	bool has_high_addr;
>  	bool has_mbus_clk;
>  };
>  
> @@ -623,6 +632,18 @@ static int set_config(struct sun6i_dma_dev *sdev,
>  	return 0;
>  }
>  
> +static inline void sun6i_dma_set_addr(struct sun6i_dma_dev *sdev,
> +				      struct sun6i_dma_lli *v_lli,
> +				      dma_addr_t src, dma_addr_t 
dst)
> +{
> +	v_lli->src = lower_32_bits(src);
> +	v_lli->dst = lower_32_bits(dst);
> +
> +	if (sdev->cfg->has_high_addr)
> +		v_lli->para |= SRC_HIGH_ADDR(upper_32_bits(src)) |
> +			       DST_HIGH_ADDR(upper_32_bits(dst));
> +}
> +
>  static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
>  		struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
>  		size_t len, unsigned long flags)
> @@ -645,16 +666,15 @@ static struct dma_async_tx_descriptor 
*sun6i_dma_prep_dma_memcpy(
>  	if (!txd)
>  		return NULL;
>  
> -	v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
> +	v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | GFP_NOWAIT, &p_lli);
>  	if (!v_lli) {
>  		dev_err(sdev->slave.dev, "Failed to alloc lli 
memory\n");
>  		goto err_txd_free;
>  	}
>  
> -	v_lli->src = src;
> -	v_lli->dst = dest;
>  	v_lli->len = len;
>  	v_lli->para = NORMAL_WAIT;
> +	sun6i_dma_set_addr(sdev, v_lli, src, dest);
>  
>  	burst = convert_burst(8);
>  	width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES);
> @@ -705,7 +725,7 @@ static struct dma_async_tx_descriptor 
*sun6i_dma_prep_slave_sg(
>  		return NULL;
>  
>  	for_each_sg(sgl, sg, sg_len, i) {
> -		v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
> +		v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | 
GFP_NOWAIT, &p_lli);
>  		if (!v_lli)
>  			goto err_lli_free;
>  
> @@ -713,8 +733,9 @@ static struct dma_async_tx_descriptor 
*sun6i_dma_prep_slave_sg(
>  		v_lli->para = NORMAL_WAIT;
>  
>  		if (dir == DMA_MEM_TO_DEV) {
> -			v_lli->src = sg_dma_address(sg);
> -			v_lli->dst = sconfig->dst_addr;
> +			sun6i_dma_set_addr(sdev, v_lli,
> +					   sg_dma_address(sg),
> +					   sconfig->dst_addr);
>  			v_lli->cfg = lli_cfg;
>  			sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, 
vchan->port);
>  			sdev->cfg->set_mode(&v_lli->cfg, 
LINEAR_MODE, IO_MODE);
> @@ -726,8 +747,9 @@ static struct dma_async_tx_descriptor 
*sun6i_dma_prep_slave_sg(
>  				sg_dma_len(sg), flags);
>  
>  		} else {
> -			v_lli->src = sconfig->src_addr;
> -			v_lli->dst = sg_dma_address(sg);
> +			sun6i_dma_set_addr(sdev, v_lli,
> +					   sconfig->src_addr,
> +					   sg_dma_address(sg));
>  			v_lli->cfg = lli_cfg;
>  			sdev->cfg->set_drq(&v_lli->cfg, vchan->port, 
DRQ_SDRAM);
>  			sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, 
LINEAR_MODE);
> @@ -786,7 +808,7 @@ static struct dma_async_tx_descriptor 
*sun6i_dma_prep_dma_cyclic(
>  		return NULL;
>  
>  	for (i = 0; i < periods; i++) {
> -		v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
> +		v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | 
GFP_NOWAIT, &p_lli);
>  		if (!v_lli) {
>  			dev_err(sdev->slave.dev, "Failed to alloc 
lli memory\n");
>  			goto err_lli_free;
> @@ -796,14 +818,16 @@ static struct dma_async_tx_descriptor 
*sun6i_dma_prep_dma_cyclic(
>  		v_lli->para = NORMAL_WAIT;
>  
>  		if (dir == DMA_MEM_TO_DEV) {
> -			v_lli->src = buf_addr + period_len * i;
> -			v_lli->dst = sconfig->dst_addr;
> +			sun6i_dma_set_addr(sdev, v_lli,
> +					   buf_addr + 
period_len * i,
> +					   sconfig->dst_addr);
>  			v_lli->cfg = lli_cfg;
>  			sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, 
vchan->port);
>  			sdev->cfg->set_mode(&v_lli->cfg, 
LINEAR_MODE, IO_MODE);
>  		} else {
> -			v_lli->src = sconfig->src_addr;
> -			v_lli->dst = buf_addr + period_len * i;
> +			sun6i_dma_set_addr(sdev, v_lli,
> +					   sconfig->src_addr,
> +					   buf_addr + 
period_len * i);
>  			v_lli->cfg = lli_cfg;
>  			sdev->cfg->set_drq(&v_lli->cfg, vchan->port, 
DRQ_SDRAM);
>  			sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, 
LINEAR_MODE);
> @@ -1174,8 +1198,6 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = {
>  };
>  
>  /*
> - * TODO: Add support for more than 4g physical addressing.
> - *
>   * The A100 binding uses the number of dma channels from the
>   * device tree node.
>   */
> @@ -1194,6 +1216,7 @@ static struct sun6i_dma_config sun50i_a100_dma_cfg = {
>  			     BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
>  			     BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
>  			     BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
> +	.has_high_addr = true,
>  	.has_mbus_clk = true,
>  };
>  
> -- 
> 2.35.1
> 
> 



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

* Re: [PATCH v3 3/4] dmaengine: sun6i: Add support for 34-bit physical addresses
@ 2022-04-24 20:17     ` Jernej Škrabec
  0 siblings, 0 replies; 14+ messages in thread
From: Jernej Škrabec @ 2022-04-24 20:17 UTC (permalink / raw)
  To: Vinod Koul, dmaengine, Samuel Holland
  Cc: Samuel Holland, Chen-Yu Tsai, Krzysztof Kozlowski, Maxime Ripard,
	Rob Herring, devicetree, linux-arm-kernel, linux-kernel,
	linux-sunxi

Dne nedelja, 24. april 2022 ob 19:27:57 CEST je Samuel Holland napisal(a):
> Recent Allwinner SoCs support >4 GiB of DRAM, so those variants of the
> DMA engine support >32 bit physical addresses. This is accomplished by
> placing the high bits in the "para" word in the DMA descriptor.
> 
> DMA descriptors themselves can be located at >32 bit addresses by
> putting the high bits in the LSBs of the descriptor address register,
> taking advantage of the required DMA descriptor alignment. However,
> support for this is not really necessary, so we can avoid the
> complication by allocating them from the DMA_32 zone.
> 
> Signed-off-by: Samuel Holland <samuel@sholland.org>

Acked-by: Jernej Skrabec <jernej.skrabec@gmail.com>

Best regards,
Jernej Skrabec

> ---
> 
> Changes in v3:
>  - Fix shift warnings for 32-bit dma_addr_t and 32-bit phys_addr_t
>  - Make explicit that v_lli->src/dst only hold the low 32 bits
> 
> Changes in v2:
>  - Fix `checkpatch.pl --strict` style issues (missing spaces)
> 
>  drivers/dma/sun6i-dma.c | 53 +++++++++++++++++++++++++++++------------
>  1 file changed, 38 insertions(+), 15 deletions(-)
> 
> diff --git a/drivers/dma/sun6i-dma.c b/drivers/dma/sun6i-dma.c
> index 4436fbd70445..1eb3bafa7324 100644
> --- a/drivers/dma/sun6i-dma.c
> +++ b/drivers/dma/sun6i-dma.c
> @@ -90,6 +90,14 @@
>  
>  #define DMA_CHAN_CUR_PARA	0x1c
>  
> +/*
> + * LLI address mangling
> + *
> + * The LLI link physical address is also mangled, but we avoid dealing
> + * with that by allocating LLIs from the DMA32 zone.
> + */
> +#define SRC_HIGH_ADDR(x)		(((x) & 0x3U) << 16)
> +#define DST_HIGH_ADDR(x)		(((x) & 0x3U) << 18)
>  
>  /*
>   * Various hardware related defines
> @@ -132,6 +140,7 @@ struct sun6i_dma_config {
>  	u32 dst_burst_lengths;
>  	u32 src_addr_widths;
>  	u32 dst_addr_widths;
> +	bool has_high_addr;
>  	bool has_mbus_clk;
>  };
>  
> @@ -623,6 +632,18 @@ static int set_config(struct sun6i_dma_dev *sdev,
>  	return 0;
>  }
>  
> +static inline void sun6i_dma_set_addr(struct sun6i_dma_dev *sdev,
> +				      struct sun6i_dma_lli *v_lli,
> +				      dma_addr_t src, dma_addr_t 
dst)
> +{
> +	v_lli->src = lower_32_bits(src);
> +	v_lli->dst = lower_32_bits(dst);
> +
> +	if (sdev->cfg->has_high_addr)
> +		v_lli->para |= SRC_HIGH_ADDR(upper_32_bits(src)) |
> +			       DST_HIGH_ADDR(upper_32_bits(dst));
> +}
> +
>  static struct dma_async_tx_descriptor *sun6i_dma_prep_dma_memcpy(
>  		struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
>  		size_t len, unsigned long flags)
> @@ -645,16 +666,15 @@ static struct dma_async_tx_descriptor 
*sun6i_dma_prep_dma_memcpy(
>  	if (!txd)
>  		return NULL;
>  
> -	v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
> +	v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | GFP_NOWAIT, &p_lli);
>  	if (!v_lli) {
>  		dev_err(sdev->slave.dev, "Failed to alloc lli 
memory\n");
>  		goto err_txd_free;
>  	}
>  
> -	v_lli->src = src;
> -	v_lli->dst = dest;
>  	v_lli->len = len;
>  	v_lli->para = NORMAL_WAIT;
> +	sun6i_dma_set_addr(sdev, v_lli, src, dest);
>  
>  	burst = convert_burst(8);
>  	width = convert_buswidth(DMA_SLAVE_BUSWIDTH_4_BYTES);
> @@ -705,7 +725,7 @@ static struct dma_async_tx_descriptor 
*sun6i_dma_prep_slave_sg(
>  		return NULL;
>  
>  	for_each_sg(sgl, sg, sg_len, i) {
> -		v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
> +		v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | 
GFP_NOWAIT, &p_lli);
>  		if (!v_lli)
>  			goto err_lli_free;
>  
> @@ -713,8 +733,9 @@ static struct dma_async_tx_descriptor 
*sun6i_dma_prep_slave_sg(
>  		v_lli->para = NORMAL_WAIT;
>  
>  		if (dir == DMA_MEM_TO_DEV) {
> -			v_lli->src = sg_dma_address(sg);
> -			v_lli->dst = sconfig->dst_addr;
> +			sun6i_dma_set_addr(sdev, v_lli,
> +					   sg_dma_address(sg),
> +					   sconfig->dst_addr);
>  			v_lli->cfg = lli_cfg;
>  			sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, 
vchan->port);
>  			sdev->cfg->set_mode(&v_lli->cfg, 
LINEAR_MODE, IO_MODE);
> @@ -726,8 +747,9 @@ static struct dma_async_tx_descriptor 
*sun6i_dma_prep_slave_sg(
>  				sg_dma_len(sg), flags);
>  
>  		} else {
> -			v_lli->src = sconfig->src_addr;
> -			v_lli->dst = sg_dma_address(sg);
> +			sun6i_dma_set_addr(sdev, v_lli,
> +					   sconfig->src_addr,
> +					   sg_dma_address(sg));
>  			v_lli->cfg = lli_cfg;
>  			sdev->cfg->set_drq(&v_lli->cfg, vchan->port, 
DRQ_SDRAM);
>  			sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, 
LINEAR_MODE);
> @@ -786,7 +808,7 @@ static struct dma_async_tx_descriptor 
*sun6i_dma_prep_dma_cyclic(
>  		return NULL;
>  
>  	for (i = 0; i < periods; i++) {
> -		v_lli = dma_pool_alloc(sdev->pool, GFP_NOWAIT, &p_lli);
> +		v_lli = dma_pool_alloc(sdev->pool, GFP_DMA32 | 
GFP_NOWAIT, &p_lli);
>  		if (!v_lli) {
>  			dev_err(sdev->slave.dev, "Failed to alloc 
lli memory\n");
>  			goto err_lli_free;
> @@ -796,14 +818,16 @@ static struct dma_async_tx_descriptor 
*sun6i_dma_prep_dma_cyclic(
>  		v_lli->para = NORMAL_WAIT;
>  
>  		if (dir == DMA_MEM_TO_DEV) {
> -			v_lli->src = buf_addr + period_len * i;
> -			v_lli->dst = sconfig->dst_addr;
> +			sun6i_dma_set_addr(sdev, v_lli,
> +					   buf_addr + 
period_len * i,
> +					   sconfig->dst_addr);
>  			v_lli->cfg = lli_cfg;
>  			sdev->cfg->set_drq(&v_lli->cfg, DRQ_SDRAM, 
vchan->port);
>  			sdev->cfg->set_mode(&v_lli->cfg, 
LINEAR_MODE, IO_MODE);
>  		} else {
> -			v_lli->src = sconfig->src_addr;
> -			v_lli->dst = buf_addr + period_len * i;
> +			sun6i_dma_set_addr(sdev, v_lli,
> +					   sconfig->src_addr,
> +					   buf_addr + 
period_len * i);
>  			v_lli->cfg = lli_cfg;
>  			sdev->cfg->set_drq(&v_lli->cfg, vchan->port, 
DRQ_SDRAM);
>  			sdev->cfg->set_mode(&v_lli->cfg, IO_MODE, 
LINEAR_MODE);
> @@ -1174,8 +1198,6 @@ static struct sun6i_dma_config sun50i_a64_dma_cfg = {
>  };
>  
>  /*
> - * TODO: Add support for more than 4g physical addressing.
> - *
>   * The A100 binding uses the number of dma channels from the
>   * device tree node.
>   */
> @@ -1194,6 +1216,7 @@ static struct sun6i_dma_config sun50i_a100_dma_cfg = {
>  			     BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) |
>  			     BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) |
>  			     BIT(DMA_SLAVE_BUSWIDTH_8_BYTES),
> +	.has_high_addr = true,
>  	.has_mbus_clk = true,
>  };
>  
> -- 
> 2.35.1
> 
> 



_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* Re: [PATCH v3 0/4] dmaengine: sun6i: Allwinner D1 support
  2022-04-24 17:27 ` Samuel Holland
@ 2022-05-19 17:55   ` Vinod Koul
  -1 siblings, 0 replies; 14+ messages in thread
From: Vinod Koul @ 2022-05-19 17:55 UTC (permalink / raw)
  To: Samuel Holland
  Cc: dmaengine, Chen-Yu Tsai, Jernej Skrabec, Krzysztof Kozlowski,
	Maxime Ripard, Rob Herring, devicetree, linux-arm-kernel,
	linux-kernel, linux-sunxi

On 24-04-22, 12:27, Samuel Holland wrote:
> D1 is a new RISC-V SoC that uses mostly the same peripherals as
> existing ARM-based sunxi SoCs. This series adds dmaengine support for
> D1, after fixing an issue where the driver depended on architecture-
> specific behavior (patch 2) and resolving a TODO item (patch 3).

Applied, thanks

-- 
~Vinod

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

* Re: [PATCH v3 0/4] dmaengine: sun6i: Allwinner D1 support
@ 2022-05-19 17:55   ` Vinod Koul
  0 siblings, 0 replies; 14+ messages in thread
From: Vinod Koul @ 2022-05-19 17:55 UTC (permalink / raw)
  To: Samuel Holland
  Cc: dmaengine, Chen-Yu Tsai, Jernej Skrabec, Krzysztof Kozlowski,
	Maxime Ripard, Rob Herring, devicetree, linux-arm-kernel,
	linux-kernel, linux-sunxi

On 24-04-22, 12:27, Samuel Holland wrote:
> D1 is a new RISC-V SoC that uses mostly the same peripherals as
> existing ARM-based sunxi SoCs. This series adds dmaengine support for
> D1, after fixing an issue where the driver depended on architecture-
> specific behavior (patch 2) and resolving a TODO item (patch 3).

Applied, thanks

-- 
~Vinod

_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

end of thread, other threads:[~2022-05-19 17:56 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-04-24 17:27 [PATCH v3 0/4] dmaengine: sun6i: Allwinner D1 support Samuel Holland
2022-04-24 17:27 ` Samuel Holland
2022-04-24 17:27 ` [PATCH v3 1/4] dt-bindings: dma: sun50i-a64: Add compatible for D1 Samuel Holland
2022-04-24 17:27   ` Samuel Holland
2022-04-24 17:27 ` [PATCH v3 2/4] dmaengine: sun6i: Do not use virt_to_phys Samuel Holland
2022-04-24 17:27   ` Samuel Holland
2022-04-24 17:27 ` [PATCH v3 3/4] dmaengine: sun6i: Add support for 34-bit physical addresses Samuel Holland
2022-04-24 17:27   ` Samuel Holland
2022-04-24 20:17   ` Jernej Škrabec
2022-04-24 20:17     ` Jernej Škrabec
2022-04-24 17:27 ` [PATCH v3 4/4] dmaengine: sun6i: Add support for the D1 variant Samuel Holland
2022-04-24 17:27   ` Samuel Holland
2022-05-19 17:55 ` [PATCH v3 0/4] dmaengine: sun6i: Allwinner D1 support Vinod Koul
2022-05-19 17:55   ` Vinod Koul

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.