aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/layerscape/patches-5.4/806-dma-0008-MLK-15330-3-dma-fsl-edma-v3-add-dual-fifo-support.patch
blob: 36222efcb25ebae33a39a2ae31e25cebb15ee38b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
From 6c753f83ffc3fede13582f667a15e7f6e97f972c Mon Sep 17 00:00:00 2001
From: Robin Gong <yibin.gong@nxp.com>
Date: Tue, 4 Jul 2017 16:04:36 +0800
Subject: [PATCH] MLK-15330-3 dma: fsl-edma-v3: add dual fifo support

There is Audio dual fifo cause that fill fifo one by one and
loop back after every minor loop:
  -- fill the first 32bit width fifo
  -- fill the next 32bit width fifo
  -- +MLOFF signed offset after the above two FIFOs filled
  -- loop back to the first step to handle the next minor loop.

Signed-off-by: Robin Gong <yibin.gong@nxp.com>
(cherry picked from commit 5aa5e9663bb3a834444b75ea086bef8c37ecb636)
---
 .../devicetree/bindings/dma/fsl-edma-v3.txt        |  2 ++
 drivers/dma/fsl-edma-v3.c                          | 29 ++++++++++++++++++++--
 2 files changed, 29 insertions(+), 2 deletions(-)

--- a/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt
+++ b/Documentation/devicetree/bindings/dma/fsl-edma-v3.txt
@@ -22,6 +22,8 @@ Required properties:
 		0: transmit, 1: receive.
 	BIT(1): local or remote access:
 		0: local, 1: remote.
+	BIT(2): dualfifo case or not(only in Audio cyclic now):
+		0: not dual fifo case, 1: dualfifo case.
 	See the SoC's reference manual for all the supported request sources.
 - dma-channels : Number of channels supported by the controller
 
--- a/drivers/dma/fsl-edma-v3.c
+++ b/drivers/dma/fsl-edma-v3.c
@@ -78,6 +78,9 @@
 
 #define EDMA_TCD_SOFF_SOFF(x)		(x)
 #define EDMA_TCD_NBYTES_NBYTES(x)	(x)
+#define EDMA_TCD_NBYTES_MLOFF(x)	(x << 10)
+#define EDMA_TCD_NBYTES_DMLOE		(1 << 30)
+#define EDMA_TCD_NBYTES_SMLOE		(1 << 31)
 #define EDMA_TCD_SLAST_SLAST(x)		(x)
 #define EDMA_TCD_DADDR_DADDR(x)		(x)
 #define EDMA_TCD_CITER_CITER(x)		((x) & 0x7FFF)
@@ -102,6 +105,7 @@
 
 #define ARGS_RX				BIT(0)
 #define ARGS_REMOTE			BIT(1)
+#define ARGS_DFIFO			BIT(2)
 
 struct fsl_edma3_hw_tcd {
 	__le32	saddr;
@@ -143,6 +147,7 @@ struct fsl_edma3_chan {
 	int				priority;
 	int				is_rxchan;
 	int				is_remote;
+	int				is_dfifo;
 	struct dma_pool			*tcd_pool;
 	u32				chn_real_count;
 	char				txirq_name[32];
@@ -454,6 +459,19 @@ void fsl_edma3_fill_tcd(struct fsl_edma3
 
 	tcd->soff = cpu_to_le16(EDMA_TCD_SOFF_SOFF(soff));
 
+	if (fsl_chan->is_dfifo) {
+		/* set mloff as -8 */
+		nbytes |= EDMA_TCD_NBYTES_MLOFF(-8);
+		/* enable DMLOE/SMLOE */
+		if (fsl_chan->fsc.dir == DMA_MEM_TO_DEV) {
+			nbytes |= EDMA_TCD_NBYTES_DMLOE;
+			nbytes &= ~EDMA_TCD_NBYTES_SMLOE;
+		} else {
+			nbytes |= EDMA_TCD_NBYTES_SMLOE;
+			nbytes &= ~EDMA_TCD_NBYTES_DMLOE;
+		}
+	}
+
 	tcd->nbytes = cpu_to_le32(EDMA_TCD_NBYTES_NBYTES(nbytes));
 	tcd->slast = cpu_to_le32(EDMA_TCD_SLAST_SLAST(slast));
 
@@ -540,11 +558,17 @@ static struct dma_async_tx_descriptor *f
 			src_addr = dma_buf_next;
 			dst_addr = fsl_chan->fsc.dev_addr;
 			soff = fsl_chan->fsc.addr_width;
-			doff = 0;
+			if (fsl_chan->is_dfifo)
+				doff = 4;
+			else
+				doff = 0;
 		} else if (fsl_chan->fsc.dir == DMA_DEV_TO_MEM) {
 			src_addr = fsl_chan->fsc.dev_addr;
 			dst_addr = dma_buf_next;
-			soff = 0;
+			if (fsl_chan->is_dfifo)
+				soff = 4;
+			else
+				soff = 0;
 			doff = fsl_chan->fsc.addr_width;
 		} else {
 			/* DMA_DEV_TO_DEV */
@@ -715,6 +739,7 @@ static struct dma_chan *fsl_edma3_xlate(
 			fsl_chan->priority = dma_spec->args[1];
 			fsl_chan->is_rxchan = dma_spec->args[2] & ARGS_RX;
 			fsl_chan->is_remote = dma_spec->args[2] & ARGS_REMOTE;
+			fsl_chan->is_dfifo = dma_spec->args[2] & ARGS_DFIFO;
 			mutex_unlock(&fsl_edma3->fsl_edma3_mutex);
 			return chan;
 		}