devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] STM32 DMA Direct mode
@ 2020-04-22 10:29 Amelie Delaunay
  2020-04-22 10:29 ` [PATCH 1/2] dt-bindings: dma: add direct mode support through device tree in stm32-dma Amelie Delaunay
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Amelie Delaunay @ 2020-04-22 10:29 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Dan Williams, Maxime Coquelin, Alexandre Torgue
  Cc: dmaengine, devicetree, linux-stm32, linux-arm-kernel,
	linux-kernel, Amelie Delaunay, Pierre-Yves Mordret

By default, the driver compute if the FIFO must operate in direct mode or with
FIFO threshold. Direct mode is allowed only if computed source burst and
destination burst are disabled. But with memory source or destination, burst
is always > 0.
Direct mode is useful when the peripheral requires an immediate and single
transfer to or from the memory after each DMA request.
This patchset adds a way to force Direct mode through device tree.

Amelie Delaunay (2):
  dt-bindings: dma: add direct mode support through device tree in
    stm32-dma
  dmaengine: stm32-dma: direct mode support through device tree

 .../devicetree/bindings/dma/st,stm32-dma.yaml |  5 +++
 drivers/dma/stm32-dma.c                       | 41 ++++++++++++++-----
 2 files changed, 36 insertions(+), 10 deletions(-)

-- 
2.17.1


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

* [PATCH 1/2] dt-bindings: dma: add direct mode support through device tree in stm32-dma
  2020-04-22 10:29 [PATCH 0/2] STM32 DMA Direct mode Amelie Delaunay
@ 2020-04-22 10:29 ` Amelie Delaunay
  2020-04-22 10:29 ` [PATCH 2/2] dmaengine: stm32-dma: direct mode support through device tree Amelie Delaunay
  2020-04-27 16:10 ` [PATCH 0/2] STM32 DMA Direct mode Vinod Koul
  2 siblings, 0 replies; 4+ messages in thread
From: Amelie Delaunay @ 2020-04-22 10:29 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Dan Williams, Maxime Coquelin, Alexandre Torgue
  Cc: dmaengine, devicetree, linux-stm32, linux-arm-kernel,
	linux-kernel, Amelie Delaunay, Pierre-Yves Mordret

Direct mode or FIFO mode is computed by stm32-dma driver. Add a way for the
user to force direct mode, by setting bit 2 in the bitfield value
specifying DMA features in the device tree.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 Documentation/devicetree/bindings/dma/st,stm32-dma.yaml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/Documentation/devicetree/bindings/dma/st,stm32-dma.yaml b/Documentation/devicetree/bindings/dma/st,stm32-dma.yaml
index 0c0ac11ad55f..71987878e4ae 100644
--- a/Documentation/devicetree/bindings/dma/st,stm32-dma.yaml
+++ b/Documentation/devicetree/bindings/dma/st,stm32-dma.yaml
@@ -36,6 +36,11 @@ description: |
          0x1: 1/2 full FIFO
          0x2: 3/4 full FIFO
          0x3: full FIFO
+       -bit 2: DMA direct mode
+         0x0: FIFO mode with threshold selectable with bit 0-1
+         0x1: Direct mode: each DMA request immediately initiates a transfer
+              from/to the memory, FIFO is bypassed.
+
 
 maintainers:
   - Amelie Delaunay <amelie.delaunay@st.com>
-- 
2.17.1


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

* [PATCH 2/2] dmaengine: stm32-dma: direct mode support through device tree
  2020-04-22 10:29 [PATCH 0/2] STM32 DMA Direct mode Amelie Delaunay
  2020-04-22 10:29 ` [PATCH 1/2] dt-bindings: dma: add direct mode support through device tree in stm32-dma Amelie Delaunay
@ 2020-04-22 10:29 ` Amelie Delaunay
  2020-04-27 16:10 ` [PATCH 0/2] STM32 DMA Direct mode Vinod Koul
  2 siblings, 0 replies; 4+ messages in thread
From: Amelie Delaunay @ 2020-04-22 10:29 UTC (permalink / raw)
  To: Vinod Koul, Rob Herring, Dan Williams, Maxime Coquelin, Alexandre Torgue
  Cc: dmaengine, devicetree, linux-stm32, linux-arm-kernel,
	linux-kernel, Amelie Delaunay, Pierre-Yves Mordret

Direct mode or FIFO mode is computed by stm32-dma driver. Add a way for
the user to force direct mode, by setting bit 2 in the bitfield value
specifying DMA features in the device tree.

Signed-off-by: Amelie Delaunay <amelie.delaunay@st.com>
---
 drivers/dma/stm32-dma.c | 41 +++++++++++++++++++++++++++++++----------
 1 file changed, 31 insertions(+), 10 deletions(-)

diff --git a/drivers/dma/stm32-dma.c b/drivers/dma/stm32-dma.c
index 0ddbaa4b4f0b..96ad1b3d24c6 100644
--- a/drivers/dma/stm32-dma.c
+++ b/drivers/dma/stm32-dma.c
@@ -117,6 +117,7 @@
 #define STM32_DMA_FIFO_THRESHOLD_HALFFULL		0x01
 #define STM32_DMA_FIFO_THRESHOLD_3QUARTERSFULL		0x02
 #define STM32_DMA_FIFO_THRESHOLD_FULL			0x03
+#define STM32_DMA_FIFO_THRESHOLD_NONE			0x04
 
 #define STM32_DMA_MAX_DATA_ITEMS	0xffff
 /*
@@ -136,6 +137,9 @@
 /* DMA Features */
 #define STM32_DMA_THRESHOLD_FTR_MASK	GENMASK(1, 0)
 #define STM32_DMA_THRESHOLD_FTR_GET(n)	((n) & STM32_DMA_THRESHOLD_FTR_MASK)
+#define STM32_DMA_DIRECT_MODE_MASK	BIT(2)
+#define STM32_DMA_DIRECT_MODE_GET(n)	(((n) & STM32_DMA_DIRECT_MODE_MASK) \
+					 >> 2)
 
 enum stm32_dma_width {
 	STM32_DMA_BYTE,
@@ -281,6 +285,9 @@ static bool stm32_dma_fifo_threshold_is_allowed(u32 burst, u32 threshold,
 {
 	u32 remaining;
 
+	if (threshold == STM32_DMA_FIFO_THRESHOLD_NONE)
+		return false;
+
 	if (width != DMA_SLAVE_BUSWIDTH_UNDEFINED) {
 		if (burst != 0) {
 			/*
@@ -302,6 +309,10 @@ static bool stm32_dma_fifo_threshold_is_allowed(u32 burst, u32 threshold,
 
 static bool stm32_dma_is_burst_possible(u32 buf_len, u32 threshold)
 {
+	/* If FIFO direct mode, burst is not possible */
+	if (threshold == STM32_DMA_FIFO_THRESHOLD_NONE)
+		return false;
+
 	/*
 	 * Buffer or period length has to be aligned on FIFO depth.
 	 * Otherwise bytes may be stuck within FIFO at buffer or period
@@ -657,6 +668,12 @@ static irqreturn_t stm32_dma_chan_irq(int irq, void *devid)
 				dev_dbg(chan2dev(chan), "FIFO over/underrun\n");
 		}
 	}
+	if (status & STM32_DMA_DMEI) {
+		stm32_dma_irq_clear(chan, STM32_DMA_DMEI);
+		status &= ~STM32_DMA_DMEI;
+		if (sfcr & STM32_DMA_SCR_DMEIE)
+			dev_dbg(chan2dev(chan), "Direct mode overrun\n");
+	}
 	if (status) {
 		stm32_dma_irq_clear(chan, status);
 		dev_err(chan2dev(chan), "DMA error: status=0x%08x\n", status);
@@ -692,13 +709,13 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
 	int src_bus_width, dst_bus_width;
 	int src_burst_size, dst_burst_size;
 	u32 src_maxburst, dst_maxburst, src_best_burst, dst_best_burst;
-	u32 dma_scr, threshold;
+	u32 dma_scr, fifoth;
 
 	src_addr_width = chan->dma_sconfig.src_addr_width;
 	dst_addr_width = chan->dma_sconfig.dst_addr_width;
 	src_maxburst = chan->dma_sconfig.src_maxburst;
 	dst_maxburst = chan->dma_sconfig.dst_maxburst;
-	threshold = chan->threshold;
+	fifoth = chan->threshold;
 
 	switch (direction) {
 	case DMA_MEM_TO_DEV:
@@ -710,7 +727,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
 		/* Set device burst size */
 		dst_best_burst = stm32_dma_get_best_burst(buf_len,
 							  dst_maxburst,
-							  threshold,
+							  fifoth,
 							  dst_addr_width);
 
 		dst_burst_size = stm32_dma_get_burst(chan, dst_best_burst);
@@ -718,7 +735,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
 			return dst_burst_size;
 
 		/* Set memory data size */
-		src_addr_width = stm32_dma_get_max_width(buf_len, threshold);
+		src_addr_width = stm32_dma_get_max_width(buf_len, fifoth);
 		chan->mem_width = src_addr_width;
 		src_bus_width = stm32_dma_get_width(chan, src_addr_width);
 		if (src_bus_width < 0)
@@ -728,7 +745,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
 		src_maxburst = STM32_DMA_MAX_BURST;
 		src_best_burst = stm32_dma_get_best_burst(buf_len,
 							  src_maxburst,
-							  threshold,
+							  fifoth,
 							  src_addr_width);
 		src_burst_size = stm32_dma_get_burst(chan, src_best_burst);
 		if (src_burst_size < 0)
@@ -742,7 +759,8 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
 
 		/* Set FIFO threshold */
 		chan->chan_reg.dma_sfcr &= ~STM32_DMA_SFCR_FTH_MASK;
-		chan->chan_reg.dma_sfcr |= STM32_DMA_SFCR_FTH(threshold);
+		if (fifoth != STM32_DMA_FIFO_THRESHOLD_NONE)
+			chan->chan_reg.dma_sfcr |= STM32_DMA_SFCR_FTH(fifoth);
 
 		/* Set peripheral address */
 		chan->chan_reg.dma_spar = chan->dma_sconfig.dst_addr;
@@ -758,7 +776,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
 		/* Set device burst size */
 		src_best_burst = stm32_dma_get_best_burst(buf_len,
 							  src_maxburst,
-							  threshold,
+							  fifoth,
 							  src_addr_width);
 		chan->mem_burst = src_best_burst;
 		src_burst_size = stm32_dma_get_burst(chan, src_best_burst);
@@ -766,7 +784,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
 			return src_burst_size;
 
 		/* Set memory data size */
-		dst_addr_width = stm32_dma_get_max_width(buf_len, threshold);
+		dst_addr_width = stm32_dma_get_max_width(buf_len, fifoth);
 		chan->mem_width = dst_addr_width;
 		dst_bus_width = stm32_dma_get_width(chan, dst_addr_width);
 		if (dst_bus_width < 0)
@@ -776,7 +794,7 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
 		dst_maxburst = STM32_DMA_MAX_BURST;
 		dst_best_burst = stm32_dma_get_best_burst(buf_len,
 							  dst_maxburst,
-							  threshold,
+							  fifoth,
 							  dst_addr_width);
 		chan->mem_burst = dst_best_burst;
 		dst_burst_size = stm32_dma_get_burst(chan, dst_best_burst);
@@ -791,7 +809,8 @@ static int stm32_dma_set_xfer_param(struct stm32_dma_chan *chan,
 
 		/* Set FIFO threshold */
 		chan->chan_reg.dma_sfcr &= ~STM32_DMA_SFCR_FTH_MASK;
-		chan->chan_reg.dma_sfcr |= STM32_DMA_SFCR_FTH(threshold);
+		if (fifoth != STM32_DMA_FIFO_THRESHOLD_NONE)
+			chan->chan_reg.dma_sfcr |= STM32_DMA_SFCR_FTH(fifoth);
 
 		/* Set peripheral address */
 		chan->chan_reg.dma_spar = chan->dma_sconfig.src_addr;
@@ -1216,6 +1235,8 @@ static void stm32_dma_set_config(struct stm32_dma_chan *chan,
 	chan->chan_reg.dma_scr |= STM32_DMA_SCR_TEIE | STM32_DMA_SCR_TCIE;
 
 	chan->threshold = STM32_DMA_THRESHOLD_FTR_GET(cfg->features);
+	if (STM32_DMA_DIRECT_MODE_GET(cfg->features))
+		chan->threshold = STM32_DMA_FIFO_THRESHOLD_NONE;
 }
 
 static struct dma_chan *stm32_dma_of_xlate(struct of_phandle_args *dma_spec,
-- 
2.17.1


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

* Re: [PATCH 0/2] STM32 DMA Direct mode
  2020-04-22 10:29 [PATCH 0/2] STM32 DMA Direct mode Amelie Delaunay
  2020-04-22 10:29 ` [PATCH 1/2] dt-bindings: dma: add direct mode support through device tree in stm32-dma Amelie Delaunay
  2020-04-22 10:29 ` [PATCH 2/2] dmaengine: stm32-dma: direct mode support through device tree Amelie Delaunay
@ 2020-04-27 16:10 ` Vinod Koul
  2 siblings, 0 replies; 4+ messages in thread
From: Vinod Koul @ 2020-04-27 16:10 UTC (permalink / raw)
  To: Amelie Delaunay
  Cc: Rob Herring, Dan Williams, Maxime Coquelin, Alexandre Torgue,
	dmaengine, devicetree, linux-stm32, linux-arm-kernel,
	linux-kernel, Pierre-Yves Mordret

On 22-04-20, 12:29, Amelie Delaunay wrote:
> By default, the driver compute if the FIFO must operate in direct mode or with
> FIFO threshold. Direct mode is allowed only if computed source burst and
> destination burst are disabled. But with memory source or destination, burst
> is always > 0.
> Direct mode is useful when the peripheral requires an immediate and single
> transfer to or from the memory after each DMA request.
> This patchset adds a way to force Direct mode through device tree.

Applied, thanks

-- 
~Vinod

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

end of thread, other threads:[~2020-04-27 16:10 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-22 10:29 [PATCH 0/2] STM32 DMA Direct mode Amelie Delaunay
2020-04-22 10:29 ` [PATCH 1/2] dt-bindings: dma: add direct mode support through device tree in stm32-dma Amelie Delaunay
2020-04-22 10:29 ` [PATCH 2/2] dmaengine: stm32-dma: direct mode support through device tree Amelie Delaunay
2020-04-27 16:10 ` [PATCH 0/2] STM32 DMA Direct mode Vinod Koul

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).