riscv: linux: vout: fix rgb2hdmi display problem
[platform/kernel/linux-starfive.git] / drivers / dma / txx9dmac.h
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 /*
3  * Driver for the TXx9 SoC DMA Controller
4  *
5  * Copyright (C) 2009 Atsushi Nemoto
6  */
7 #ifndef TXX9DMAC_H
8 #define TXX9DMAC_H
9
10 #include <linux/dmaengine.h>
11 #include <asm/txx9/dmac.h>
12
13 /*
14  * Design Notes:
15  *
16  * This DMAC have four channels and one FIFO buffer.  Each channel can
17  * be configured for memory-memory or device-memory transfer, but only
18  * one channel can do alignment-free memory-memory transfer at a time
19  * while the channel should occupy the FIFO buffer for effective
20  * transfers.
21  *
22  * Instead of dynamically assign the FIFO buffer to channels, I chose
23  * make one dedicated channel for memory-memory transfer.  The
24  * dedicated channel is public.  Other channels are private and used
25  * for slave transfer.  Some devices in the SoC are wired to certain
26  * DMA channel.
27  */
28
29 #ifdef CONFIG_MACH_TX49XX
30 static inline bool txx9_dma_have_SMPCHN(void)
31 {
32         return true;
33 }
34 #define TXX9_DMA_USE_SIMPLE_CHAIN
35 #else
36 static inline bool txx9_dma_have_SMPCHN(void)
37 {
38         return false;
39 }
40 #endif
41
42 #ifdef __LITTLE_ENDIAN
43 #ifdef CONFIG_MACH_TX49XX
44 #define CCR_LE  TXX9_DMA_CCR_LE
45 #define MCR_LE  0
46 #else
47 #define CCR_LE  0
48 #define MCR_LE  TXX9_DMA_MCR_LE
49 #endif
50 #else
51 #define CCR_LE  0
52 #define MCR_LE  0
53 #endif
54
55 /*
56  * Redefine this macro to handle differences between 32- and 64-bit
57  * addressing, big vs. little endian, etc.
58  */
59 #ifdef __BIG_ENDIAN
60 #define TXX9_DMA_REG32(name)            u32 __pad_##name; u32 name
61 #else
62 #define TXX9_DMA_REG32(name)            u32 name; u32 __pad_##name
63 #endif
64
65 /* Hardware register definitions. */
66 struct txx9dmac_cregs {
67 #if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
68         TXX9_DMA_REG32(CHAR);   /* Chain Address Register */
69 #else
70         u64 CHAR;               /* Chain Address Register */
71 #endif
72         u64 SAR;                /* Source Address Register */
73         u64 DAR;                /* Destination Address Register */
74         TXX9_DMA_REG32(CNTR);   /* Count Register */
75         TXX9_DMA_REG32(SAIR);   /* Source Address Increment Register */
76         TXX9_DMA_REG32(DAIR);   /* Destination Address Increment Register */
77         TXX9_DMA_REG32(CCR);    /* Channel Control Register */
78         TXX9_DMA_REG32(CSR);    /* Channel Status Register */
79 };
80 struct txx9dmac_cregs32 {
81         u32 CHAR;
82         u32 SAR;
83         u32 DAR;
84         u32 CNTR;
85         u32 SAIR;
86         u32 DAIR;
87         u32 CCR;
88         u32 CSR;
89 };
90
91 struct txx9dmac_regs {
92         /* per-channel registers */
93         struct txx9dmac_cregs   CHAN[TXX9_DMA_MAX_NR_CHANNELS];
94         u64     __pad[9];
95         u64     MFDR;           /* Memory Fill Data Register */
96         TXX9_DMA_REG32(MCR);    /* Master Control Register */
97 };
98 struct txx9dmac_regs32 {
99         struct txx9dmac_cregs32 CHAN[TXX9_DMA_MAX_NR_CHANNELS];
100         u32     __pad[9];
101         u32     MFDR;
102         u32     MCR;
103 };
104
105 /* bits for MCR */
106 #define TXX9_DMA_MCR_EIS(ch)    (0x10000000<<(ch))
107 #define TXX9_DMA_MCR_DIS(ch)    (0x01000000<<(ch))
108 #define TXX9_DMA_MCR_RSFIF      0x00000080
109 #define TXX9_DMA_MCR_FIFUM(ch)  (0x00000008<<(ch))
110 #define TXX9_DMA_MCR_LE         0x00000004
111 #define TXX9_DMA_MCR_RPRT       0x00000002
112 #define TXX9_DMA_MCR_MSTEN      0x00000001
113
114 /* bits for CCRn */
115 #define TXX9_DMA_CCR_IMMCHN     0x20000000
116 #define TXX9_DMA_CCR_USEXFSZ    0x10000000
117 #define TXX9_DMA_CCR_LE         0x08000000
118 #define TXX9_DMA_CCR_DBINH      0x04000000
119 #define TXX9_DMA_CCR_SBINH      0x02000000
120 #define TXX9_DMA_CCR_CHRST      0x01000000
121 #define TXX9_DMA_CCR_RVBYTE     0x00800000
122 #define TXX9_DMA_CCR_ACKPOL     0x00400000
123 #define TXX9_DMA_CCR_REQPL      0x00200000
124 #define TXX9_DMA_CCR_EGREQ      0x00100000
125 #define TXX9_DMA_CCR_CHDN       0x00080000
126 #define TXX9_DMA_CCR_DNCTL      0x00060000
127 #define TXX9_DMA_CCR_EXTRQ      0x00010000
128 #define TXX9_DMA_CCR_INTRQD     0x0000e000
129 #define TXX9_DMA_CCR_INTENE     0x00001000
130 #define TXX9_DMA_CCR_INTENC     0x00000800
131 #define TXX9_DMA_CCR_INTENT     0x00000400
132 #define TXX9_DMA_CCR_CHNEN      0x00000200
133 #define TXX9_DMA_CCR_XFACT      0x00000100
134 #define TXX9_DMA_CCR_SMPCHN     0x00000020
135 #define TXX9_DMA_CCR_XFSZ(order)        (((order) << 2) & 0x0000001c)
136 #define TXX9_DMA_CCR_XFSZ_1     TXX9_DMA_CCR_XFSZ(0)
137 #define TXX9_DMA_CCR_XFSZ_2     TXX9_DMA_CCR_XFSZ(1)
138 #define TXX9_DMA_CCR_XFSZ_4     TXX9_DMA_CCR_XFSZ(2)
139 #define TXX9_DMA_CCR_XFSZ_8     TXX9_DMA_CCR_XFSZ(3)
140 #define TXX9_DMA_CCR_XFSZ_X4    TXX9_DMA_CCR_XFSZ(4)
141 #define TXX9_DMA_CCR_XFSZ_X8    TXX9_DMA_CCR_XFSZ(5)
142 #define TXX9_DMA_CCR_XFSZ_X16   TXX9_DMA_CCR_XFSZ(6)
143 #define TXX9_DMA_CCR_XFSZ_X32   TXX9_DMA_CCR_XFSZ(7)
144 #define TXX9_DMA_CCR_MEMIO      0x00000002
145 #define TXX9_DMA_CCR_SNGAD      0x00000001
146
147 /* bits for CSRn */
148 #define TXX9_DMA_CSR_CHNEN      0x00000400
149 #define TXX9_DMA_CSR_STLXFER    0x00000200
150 #define TXX9_DMA_CSR_XFACT      0x00000100
151 #define TXX9_DMA_CSR_ABCHC      0x00000080
152 #define TXX9_DMA_CSR_NCHNC      0x00000040
153 #define TXX9_DMA_CSR_NTRNFC     0x00000020
154 #define TXX9_DMA_CSR_EXTDN      0x00000010
155 #define TXX9_DMA_CSR_CFERR      0x00000008
156 #define TXX9_DMA_CSR_CHERR      0x00000004
157 #define TXX9_DMA_CSR_DESERR     0x00000002
158 #define TXX9_DMA_CSR_SORERR     0x00000001
159
160 struct txx9dmac_chan {
161         struct dma_chan         chan;
162         struct dma_device       dma;
163         struct txx9dmac_dev     *ddev;
164         void __iomem            *ch_regs;
165         struct tasklet_struct   tasklet;
166         int                     irq;
167         u32                     ccr;
168
169         spinlock_t              lock;
170
171         /* these other elements are all protected by lock */
172         struct list_head        active_list;
173         struct list_head        queue;
174         struct list_head        free_list;
175
176         unsigned int            descs_allocated;
177 };
178
179 struct txx9dmac_dev {
180         void __iomem            *regs;
181         struct tasklet_struct   tasklet;
182         int                     irq;
183         struct txx9dmac_chan    *chan[TXX9_DMA_MAX_NR_CHANNELS];
184         bool                    have_64bit_regs;
185         unsigned int            descsize;
186 };
187
188 static inline bool __is_dmac64(const struct txx9dmac_dev *ddev)
189 {
190         return ddev->have_64bit_regs;
191 }
192
193 static inline bool is_dmac64(const struct txx9dmac_chan *dc)
194 {
195         return __is_dmac64(dc->ddev);
196 }
197
198 #ifdef TXX9_DMA_USE_SIMPLE_CHAIN
199 /* Hardware descriptor definition. (for simple-chain) */
200 struct txx9dmac_hwdesc {
201 #if defined(CONFIG_32BIT) && !defined(CONFIG_PHYS_ADDR_T_64BIT)
202         TXX9_DMA_REG32(CHAR);
203 #else
204         u64 CHAR;
205 #endif
206         u64 SAR;
207         u64 DAR;
208         TXX9_DMA_REG32(CNTR);
209 };
210 struct txx9dmac_hwdesc32 {
211         u32 CHAR;
212         u32 SAR;
213         u32 DAR;
214         u32 CNTR;
215 };
216 #else
217 #define txx9dmac_hwdesc txx9dmac_cregs
218 #define txx9dmac_hwdesc32 txx9dmac_cregs32
219 #endif
220
221 struct txx9dmac_desc {
222         /* FIRST values the hardware uses */
223         union {
224                 struct txx9dmac_hwdesc hwdesc;
225                 struct txx9dmac_hwdesc32 hwdesc32;
226         };
227
228         /* THEN values for driver housekeeping */
229         struct list_head                desc_node ____cacheline_aligned;
230         struct list_head                tx_list;
231         struct dma_async_tx_descriptor  txd;
232         size_t                          len;
233 };
234
235 #ifdef TXX9_DMA_USE_SIMPLE_CHAIN
236
237 static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)
238 {
239         return (dc->ccr & TXX9_DMA_CCR_INTENT) != 0;
240 }
241
242 static inline void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)
243 {
244         dc->ccr |= TXX9_DMA_CCR_INTENT;
245 }
246
247 static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,
248                                             struct txx9dmac_desc *desc)
249 {
250 }
251
252 static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)
253 {
254         dc->ccr |= TXX9_DMA_CCR_SMPCHN;
255 }
256
257 static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,
258                                               struct txx9dmac_desc *desc,
259                                               u32 sair, u32 dair, u32 ccr)
260 {
261 }
262
263 #else /* TXX9_DMA_USE_SIMPLE_CHAIN */
264
265 static inline bool txx9dmac_chan_INTENT(struct txx9dmac_chan *dc)
266 {
267         return true;
268 }
269
270 static void txx9dmac_chan_set_INTENT(struct txx9dmac_chan *dc)
271 {
272 }
273
274 static inline void txx9dmac_desc_set_INTENT(struct txx9dmac_dev *ddev,
275                                             struct txx9dmac_desc *desc)
276 {
277         if (__is_dmac64(ddev))
278                 desc->hwdesc.CCR |= TXX9_DMA_CCR_INTENT;
279         else
280                 desc->hwdesc32.CCR |= TXX9_DMA_CCR_INTENT;
281 }
282
283 static inline void txx9dmac_chan_set_SMPCHN(struct txx9dmac_chan *dc)
284 {
285 }
286
287 static inline void txx9dmac_desc_set_nosimple(struct txx9dmac_dev *ddev,
288                                               struct txx9dmac_desc *desc,
289                                               u32 sai, u32 dai, u32 ccr)
290 {
291         if (__is_dmac64(ddev)) {
292                 desc->hwdesc.SAIR = sai;
293                 desc->hwdesc.DAIR = dai;
294                 desc->hwdesc.CCR = ccr;
295         } else {
296                 desc->hwdesc32.SAIR = sai;
297                 desc->hwdesc32.DAIR = dai;
298                 desc->hwdesc32.CCR = ccr;
299         }
300 }
301
302 #endif /* TXX9_DMA_USE_SIMPLE_CHAIN */
303
304 #endif /* TXX9DMAC_H */