xref: /linux/include/linux/dma/sprd-dma.h (revision 44f57d78)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 
3 #ifndef _SPRD_DMA_H_
4 #define _SPRD_DMA_H_
5 
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 };
65 
66 /*
67  * enum sprd_dma_req_mode: define the DMA request mode
68  * @SPRD_DMA_FRAG_REQ: fragment request mode
69  * @SPRD_DMA_BLK_REQ: block request mode
70  * @SPRD_DMA_TRANS_REQ: transaction request mode
71  * @SPRD_DMA_LIST_REQ: link-list request mode
72  *
73  * We have 4 types request mode: fragment mode, block mode, transaction mode
74  * and linklist mode. One transaction can contain several blocks, one block can
75  * contain several fragments. Link-list mode means we can save several DMA
76  * configuration into one reserved memory, then DMA can fetch each DMA
77  * configuration automatically to start transfer.
78  */
79 enum sprd_dma_req_mode {
80 	SPRD_DMA_FRAG_REQ,
81 	SPRD_DMA_BLK_REQ,
82 	SPRD_DMA_TRANS_REQ,
83 	SPRD_DMA_LIST_REQ,
84 };
85 
86 /*
87  * enum sprd_dma_int_type: define the DMA interrupt type
88  * @SPRD_DMA_NO_INT: do not need generate DMA interrupts.
89  * @SPRD_DMA_FRAG_INT: fragment done interrupt when one fragment request
90  * is done.
91  * @SPRD_DMA_BLK_INT: block done interrupt when one block request is done.
92  * @SPRD_DMA_BLK_FRAG_INT: block and fragment interrupt when one fragment
93  * or one block request is done.
94  * @SPRD_DMA_TRANS_INT: tansaction done interrupt when one transaction
95  * request is done.
96  * @SPRD_DMA_TRANS_FRAG_INT: transaction and fragment interrupt when one
97  * transaction request or fragment request is done.
98  * @SPRD_DMA_TRANS_BLK_INT: transaction and block interrupt when one
99  * transaction request or block request is done.
100  * @SPRD_DMA_LIST_INT: link-list done interrupt when one link-list request
101  * is done.
102  * @SPRD_DMA_CFGERR_INT: configure error interrupt when configuration is
103  * incorrect.
104  */
105 enum sprd_dma_int_type {
106 	SPRD_DMA_NO_INT,
107 	SPRD_DMA_FRAG_INT,
108 	SPRD_DMA_BLK_INT,
109 	SPRD_DMA_BLK_FRAG_INT,
110 	SPRD_DMA_TRANS_INT,
111 	SPRD_DMA_TRANS_FRAG_INT,
112 	SPRD_DMA_TRANS_BLK_INT,
113 	SPRD_DMA_LIST_INT,
114 	SPRD_DMA_CFGERR_INT,
115 };
116 
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  *
122  * The Spreadtrum DMA controller supports the link-list mode, that means slaves
123  * can supply several groups configurations (each configuration represents one
124  * DMA transfer) saved in memory, and DMA controller will link these groups
125  * configurations by writing the physical address of each configuration into the
126  * link-list register.
127  *
128  * Just as shown below, the link-list pointer register will be pointed to the
129  * physical address of 'configuration 1', and the 'configuration 1' link-list
130  * pointer will be pointed to 'configuration 2', and so on.
131  * Once trigger the DMA transfer, the DMA controller will load 'configuration
132  * 1' to its registers automatically, after 'configuration 1' transaction is
133  * done, DMA controller will load 'configuration 2' automatically, until all
134  * DMA transactions are done.
135  *
136  * Note: The last link-list pointer should point to the physical address
137  * of 'configuration 1', which can avoid DMA controller loads incorrect
138  * configuration when the last configuration transaction is done.
139  *
140  *     DMA controller                    linklist memory
141  * ======================             -----------------------
142  *|                      |           |    configuration 1    |<---
143  *|   DMA controller     |   ------->|                       |   |
144  *|                      |   |       |                       |   |
145  *|                      |   |       |                       |   |
146  *|                      |   |       |                       |   |
147  *| linklist pointer reg |----   ----|    linklist pointer   |   |
148  * ======================        |    -----------------------    |
149  *                               |                               |
150  *                               |    -----------------------    |
151  *                               |   |    configuration 2    |   |
152  *                               --->|                       |   |
153  *                                   |                       |   |
154  *                                   |                       |   |
155  *                                   |                       |   |
156  *                               ----|    linklist pointer   |   |
157  *                               |    -----------------------    |
158  *                               |                               |
159  *                               |    -----------------------    |
160  *                               |   |    configuration 3    |   |
161  *                               --->|                       |   |
162  *                                   |                       |   |
163  *                                   |           .           |   |
164  *                                               .               |
165  *                                               .               |
166  *                                               .               |
167  *                               |               .               |
168  *                               |    -----------------------    |
169  *                               |   |    configuration n    |   |
170  *                               --->|                       |   |
171  *                                   |                       |   |
172  *                                   |                       |   |
173  *                                   |                       |   |
174  *                                   |    linklist pointer   |----
175  *                                    -----------------------
176  *
177  * To support the link-list mode, DMA slaves should allocate one segment memory
178  * from always-on IRAM or dma coherent memory to store these groups of DMA
179  * configuration, and pass the virtual and physical address to DMA controller.
180  */
181 struct sprd_dma_linklist {
182 	unsigned long virt_addr;
183 	phys_addr_t phy_addr;
184 };
185 
186 #endif
187