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