hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/include/linux/dma/sprd-dma.h
....@@ -3,9 +3,65 @@
33 #ifndef _SPRD_DMA_H_
44 #define _SPRD_DMA_H_
55
6
-#define SPRD_DMA_REQ_SHIFT 16
7
-#define SPRD_DMA_FLAGS(req_mode, int_type) \
8
- ((req_mode) << SPRD_DMA_REQ_SHIFT | (int_type))
6
+#define SPRD_DMA_REQ_SHIFT 8
7
+#define SPRD_DMA_TRG_MODE_SHIFT 16
8
+#define SPRD_DMA_CHN_MODE_SHIFT 24
9
+#define SPRD_DMA_FLAGS(chn_mode, trg_mode, req_mode, int_type) \
10
+ ((chn_mode) << SPRD_DMA_CHN_MODE_SHIFT | \
11
+ (trg_mode) << SPRD_DMA_TRG_MODE_SHIFT | \
12
+ (req_mode) << SPRD_DMA_REQ_SHIFT | (int_type))
13
+
14
+/*
15
+ * The Spreadtrum DMA controller supports channel 2-stage tansfer, that means
16
+ * we can request 2 dma channels, one for source channel, and another one for
17
+ * destination channel. Each channel is independent, and has its own
18
+ * configurations. Once the source channel's transaction is done, it will
19
+ * trigger the destination channel's transaction automatically by hardware
20
+ * signal.
21
+ *
22
+ * To support 2-stage tansfer, we must configure the channel mode and trigger
23
+ * mode as below definition.
24
+ */
25
+
26
+/*
27
+ * enum sprd_dma_chn_mode: define the DMA channel mode for 2-stage transfer
28
+ * @SPRD_DMA_CHN_MODE_NONE: No channel mode setting which means channel doesn't
29
+ * support the 2-stage transfer.
30
+ * @SPRD_DMA_SRC_CHN0: Channel used as source channel 0.
31
+ * @SPRD_DMA_SRC_CHN1: Channel used as source channel 1.
32
+ * @SPRD_DMA_DST_CHN0: Channel used as destination channel 0.
33
+ * @SPRD_DMA_DST_CHN1: Channel used as destination channel 1.
34
+ *
35
+ * Now the DMA controller can supports 2 groups 2-stage transfer.
36
+ */
37
+enum sprd_dma_chn_mode {
38
+ SPRD_DMA_CHN_MODE_NONE,
39
+ SPRD_DMA_SRC_CHN0,
40
+ SPRD_DMA_SRC_CHN1,
41
+ SPRD_DMA_DST_CHN0,
42
+ SPRD_DMA_DST_CHN1,
43
+};
44
+
45
+/*
46
+ * enum sprd_dma_trg_mode: define the DMA channel trigger mode for 2-stage
47
+ * transfer
48
+ * @SPRD_DMA_NO_TRG: No trigger setting.
49
+ * @SPRD_DMA_FRAG_DONE_TRG: Trigger the transaction of destination channel
50
+ * automatically once the source channel's fragment request is done.
51
+ * @SPRD_DMA_BLOCK_DONE_TRG: Trigger the transaction of destination channel
52
+ * automatically once the source channel's block request is done.
53
+ * @SPRD_DMA_TRANS_DONE_TRG: Trigger the transaction of destination channel
54
+ * automatically once the source channel's transfer request is done.
55
+ * @SPRD_DMA_LIST_DONE_TRG: Trigger the transaction of destination channel
56
+ * automatically once the source channel's link-list request is done.
57
+ */
58
+enum sprd_dma_trg_mode {
59
+ SPRD_DMA_NO_TRG,
60
+ SPRD_DMA_FRAG_DONE_TRG,
61
+ SPRD_DMA_BLOCK_DONE_TRG,
62
+ SPRD_DMA_TRANS_DONE_TRG,
63
+ SPRD_DMA_LIST_DONE_TRG,
64
+};
965
1066 /*
1167 * enum sprd_dma_req_mode: define the DMA request mode
....@@ -58,4 +114,77 @@
58114 SPRD_DMA_CFGERR_INT,
59115 };
60116
117
+/*
118
+ * struct sprd_dma_linklist - DMA link-list address structure
119
+ * @virt_addr: link-list virtual address to configure link-list node
120
+ * @phy_addr: link-list physical address to link DMA transfer
121
+ * @wrap_addr: the wrap address for link-list mode, which means once the
122
+ * transfer address reaches the wrap address, the next transfer address
123
+ * will jump to the address specified by wrap_to register.
124
+ *
125
+ * The Spreadtrum DMA controller supports the link-list mode, that means slaves
126
+ * can supply several groups configurations (each configuration represents one
127
+ * DMA transfer) saved in memory, and DMA controller will link these groups
128
+ * configurations by writing the physical address of each configuration into the
129
+ * link-list register.
130
+ *
131
+ * Just as shown below, the link-list pointer register will be pointed to the
132
+ * physical address of 'configuration 1', and the 'configuration 1' link-list
133
+ * pointer will be pointed to 'configuration 2', and so on.
134
+ * Once trigger the DMA transfer, the DMA controller will load 'configuration
135
+ * 1' to its registers automatically, after 'configuration 1' transaction is
136
+ * done, DMA controller will load 'configuration 2' automatically, until all
137
+ * DMA transactions are done.
138
+ *
139
+ * Note: The last link-list pointer should point to the physical address
140
+ * of 'configuration 1', which can avoid DMA controller loads incorrect
141
+ * configuration when the last configuration transaction is done.
142
+ *
143
+ * DMA controller linklist memory
144
+ * ====================== -----------------------
145
+ *| | | configuration 1 |<---
146
+ *| DMA controller | ------->| | |
147
+ *| | | | | |
148
+ *| | | | | |
149
+ *| | | | | |
150
+ *| linklist pointer reg |---- ----| linklist pointer | |
151
+ * ====================== | ----------------------- |
152
+ * | |
153
+ * | ----------------------- |
154
+ * | | configuration 2 | |
155
+ * --->| | |
156
+ * | | |
157
+ * | | |
158
+ * | | |
159
+ * ----| linklist pointer | |
160
+ * | ----------------------- |
161
+ * | |
162
+ * | ----------------------- |
163
+ * | | configuration 3 | |
164
+ * --->| | |
165
+ * | | |
166
+ * | . | |
167
+ * . |
168
+ * . |
169
+ * . |
170
+ * | . |
171
+ * | ----------------------- |
172
+ * | | configuration n | |
173
+ * --->| | |
174
+ * | | |
175
+ * | | |
176
+ * | | |
177
+ * | linklist pointer |----
178
+ * -----------------------
179
+ *
180
+ * To support the link-list mode, DMA slaves should allocate one segment memory
181
+ * from always-on IRAM or dma coherent memory to store these groups of DMA
182
+ * configuration, and pass the virtual and physical address to DMA controller.
183
+ */
184
+struct sprd_dma_linklist {
185
+ unsigned long virt_addr;
186
+ phys_addr_t phy_addr;
187
+ phys_addr_t wrap_addr;
188
+};
189
+
61190 #endif