V4L/DVB (9720): cx18: Major rewrite of interrupt handling for incoming mailbox processing
[safe/jmp/linux-2.6] / drivers / media / video / cx18 / cx18-io.h
1 /*
2  *  cx18 driver PCI memory mapped IO access routines
3  *
4  *  Copyright (C) 2007  Hans Verkuil <hverkuil@xs4all.nl>
5  *  Copyright (C) 2008  Andy Walls <awalls@radix.net>
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20  *  02111-1307  USA
21  */
22
23 #ifndef CX18_IO_H
24 #define CX18_IO_H
25
26 #include "cx18-driver.h"
27
28 static inline void cx18_io_delay(struct cx18 *cx)
29 {
30         if (cx->options.mmio_ndelay)
31                 ndelay(cx->options.mmio_ndelay);
32 }
33
34 /*
35  * Readback and retry of MMIO access for reliability:
36  * The concept was suggested by Steve Toth <stoth@linuxtv.org>.
37  * The implmentation is the fault of Andy Walls <awalls@radix.net>.
38  */
39
40 /* Statistics gathering */
41 static inline
42 void cx18_log_write_retries(struct cx18 *cx, int i, const void __iomem *addr)
43 {
44         if (i > CX18_MAX_MMIO_WR_RETRIES)
45                 i = CX18_MAX_MMIO_WR_RETRIES;
46         atomic_inc(&cx->mmio_stats.retried_write[i]);
47         return;
48 }
49
50 static inline
51 void cx18_log_read_retries(struct cx18 *cx, int i, const void __iomem *addr)
52 {
53         if (i > CX18_MAX_MMIO_RD_RETRIES)
54                 i = CX18_MAX_MMIO_RD_RETRIES;
55         atomic_inc(&cx->mmio_stats.retried_read[i]);
56         return;
57 }
58
59 void cx18_log_statistics(struct cx18 *cx);
60
61 /* Non byteswapping memory mapped IO */
62 static inline
63 void cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
64 {
65         __raw_writel(val, addr);
66         cx18_io_delay(cx);
67 }
68
69 void cx18_raw_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr);
70
71 static inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr)
72 {
73         if (cx18_retry_mmio)
74                 cx18_raw_writel_retry(cx, val, addr);
75         else
76                 cx18_raw_writel_noretry(cx, val, addr);
77 }
78
79
80 static inline
81 u32 cx18_raw_readl_noretry(struct cx18 *cx, const void __iomem *addr)
82 {
83         u32 ret = __raw_readl(addr);
84         cx18_io_delay(cx);
85         return ret;
86 }
87
88 u32 cx18_raw_readl_retry(struct cx18 *cx, const void __iomem *addr);
89
90 static inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr)
91 {
92         if (cx18_retry_mmio)
93                 return cx18_raw_readl_retry(cx, addr);
94
95         return cx18_raw_readl_noretry(cx, addr);
96 }
97
98
99 static inline
100 u16 cx18_raw_readw_noretry(struct cx18 *cx, const void __iomem *addr)
101 {
102         u16 ret = __raw_readw(addr);
103         cx18_io_delay(cx);
104         return ret;
105 }
106
107 u16 cx18_raw_readw_retry(struct cx18 *cx, const void __iomem *addr);
108
109 static inline u16 cx18_raw_readw(struct cx18 *cx, const void __iomem *addr)
110 {
111         if (cx18_retry_mmio)
112                 return cx18_raw_readw_retry(cx, addr);
113
114         return cx18_raw_readw_noretry(cx, addr);
115 }
116
117
118 /* Normal memory mapped IO */
119 static inline
120 void cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
121 {
122         writel(val, addr);
123         cx18_io_delay(cx);
124 }
125
126 void cx18_writel_retry(struct cx18 *cx, u32 val, void __iomem *addr);
127
128 static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr)
129 {
130         if (cx18_retry_mmio)
131                 cx18_writel_retry(cx, val, addr);
132         else
133                 cx18_writel_noretry(cx, val, addr);
134 }
135
136 void _cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr,
137                          u32 eval, u32 mask);
138
139 static inline
140 void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr)
141 {
142         writew(val, addr);
143         cx18_io_delay(cx);
144 }
145
146 void cx18_writew_retry(struct cx18 *cx, u16 val, void __iomem *addr);
147
148 static inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr)
149 {
150         if (cx18_retry_mmio)
151                 cx18_writew_retry(cx, val, addr);
152         else
153                 cx18_writew_noretry(cx, val, addr);
154 }
155
156
157 static inline
158 void cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr)
159 {
160         writeb(val, addr);
161         cx18_io_delay(cx);
162 }
163
164 void cx18_writeb_retry(struct cx18 *cx, u8 val, void __iomem *addr);
165
166 static inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr)
167 {
168         if (cx18_retry_mmio)
169                 cx18_writeb_retry(cx, val, addr);
170         else
171                 cx18_writeb_noretry(cx, val, addr);
172 }
173
174
175 static inline u32 cx18_readl_noretry(struct cx18 *cx, const void __iomem *addr)
176 {
177         u32 ret = readl(addr);
178         cx18_io_delay(cx);
179         return ret;
180 }
181
182 u32 cx18_readl_retry(struct cx18 *cx, const void __iomem *addr);
183
184 static inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr)
185 {
186         if (cx18_retry_mmio)
187                 return cx18_readl_retry(cx, addr);
188
189         return cx18_readl_noretry(cx, addr);
190 }
191
192
193 static inline u16 cx18_readw_noretry(struct cx18 *cx, const void __iomem *addr)
194 {
195         u16 ret = readw(addr);
196         cx18_io_delay(cx);
197         return ret;
198 }
199
200 u16 cx18_readw_retry(struct cx18 *cx, const void __iomem *addr);
201
202 static inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr)
203 {
204         if (cx18_retry_mmio)
205                 return cx18_readw_retry(cx, addr);
206
207         return cx18_readw_noretry(cx, addr);
208 }
209
210
211 static inline u8 cx18_readb_noretry(struct cx18 *cx, const void __iomem *addr)
212 {
213         u8 ret = readb(addr);
214         cx18_io_delay(cx);
215         return ret;
216 }
217
218 u8 cx18_readb_retry(struct cx18 *cx, const void __iomem *addr);
219
220 static inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr)
221 {
222         if (cx18_retry_mmio)
223                 return cx18_readb_retry(cx, addr);
224
225         return cx18_readb_noretry(cx, addr);
226 }
227
228
229 static inline
230 u32 cx18_write_sync_noretry(struct cx18 *cx, u32 val, void __iomem *addr)
231 {
232         cx18_writel_noretry(cx, val, addr);
233         return cx18_readl_noretry(cx, addr);
234 }
235
236 static inline
237 u32 cx18_write_sync_retry(struct cx18 *cx, u32 val, void __iomem *addr)
238 {
239         cx18_writel_retry(cx, val, addr);
240         return cx18_readl_retry(cx, addr);
241 }
242
243 static inline u32 cx18_write_sync(struct cx18 *cx, u32 val, void __iomem *addr)
244 {
245         if (cx18_retry_mmio)
246                 return cx18_write_sync_retry(cx, val, addr);
247
248         return cx18_write_sync_noretry(cx, val, addr);
249 }
250
251
252 static inline
253 void cx18_memcpy_fromio(struct cx18 *cx, void *to,
254                         const void __iomem *from, unsigned int len)
255 {
256         memcpy_fromio(to, from, len);
257 }
258
259 void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count);
260
261
262 /* Access "register" region of CX23418 memory mapped I/O */
263 static inline void cx18_write_reg_noretry(struct cx18 *cx, u32 val, u32 reg)
264 {
265         cx18_writel_noretry(cx, val, cx->reg_mem + reg);
266 }
267
268 static inline void cx18_write_reg_retry(struct cx18 *cx, u32 val, u32 reg)
269 {
270         cx18_writel_retry(cx, val, cx->reg_mem + reg);
271 }
272
273 static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg)
274 {
275         if (cx18_retry_mmio)
276                 cx18_write_reg_retry(cx, val, reg);
277         else
278                 cx18_write_reg_noretry(cx, val, reg);
279 }
280
281 static inline void _cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg,
282                                           u32 eval, u32 mask)
283 {
284         _cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask);
285 }
286
287 static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg,
288                                          u32 eval, u32 mask)
289 {
290         if (cx18_retry_mmio)
291                 _cx18_write_reg_expect(cx, val, reg, eval, mask);
292         else
293                 cx18_write_reg_noretry(cx, val, reg);
294 }
295
296
297 static inline u32 cx18_read_reg_noretry(struct cx18 *cx, u32 reg)
298 {
299         return cx18_readl_noretry(cx, cx->reg_mem + reg);
300 }
301
302 static inline u32 cx18_read_reg_retry(struct cx18 *cx, u32 reg)
303 {
304         return cx18_readl_retry(cx, cx->reg_mem + reg);
305 }
306
307 static inline u32 cx18_read_reg(struct cx18 *cx, u32 reg)
308 {
309         if (cx18_retry_mmio)
310                 return cx18_read_reg_retry(cx, reg);
311
312         return cx18_read_reg_noretry(cx, reg);
313 }
314
315
316 static inline u32 cx18_write_reg_sync_noretry(struct cx18 *cx, u32 val, u32 reg)
317 {
318         return cx18_write_sync_noretry(cx, val, cx->reg_mem + reg);
319 }
320
321 static inline u32 cx18_write_reg_sync_retry(struct cx18 *cx, u32 val, u32 reg)
322 {
323         return cx18_write_sync_retry(cx, val, cx->reg_mem + reg);
324 }
325
326 static inline u32 cx18_write_reg_sync(struct cx18 *cx, u32 val, u32 reg)
327 {
328         if (cx18_retry_mmio)
329                 return cx18_write_reg_sync_retry(cx, val, reg);
330
331         return cx18_write_reg_sync_noretry(cx, val, reg);
332 }
333
334
335 /* Access "encoder memory" region of CX23418 memory mapped I/O */
336 static inline void cx18_write_enc_noretry(struct cx18 *cx, u32 val, u32 addr)
337 {
338         cx18_writel_noretry(cx, val, cx->enc_mem + addr);
339 }
340
341 static inline void cx18_write_enc_retry(struct cx18 *cx, u32 val, u32 addr)
342 {
343         cx18_writel_retry(cx, val, cx->enc_mem + addr);
344 }
345
346 static inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr)
347 {
348         if (cx18_retry_mmio)
349                 cx18_write_enc_retry(cx, val, addr);
350         else
351                 cx18_write_enc_noretry(cx, val, addr);
352 }
353
354
355 static inline u32 cx18_read_enc_noretry(struct cx18 *cx, u32 addr)
356 {
357         return cx18_readl_noretry(cx, cx->enc_mem + addr);
358 }
359
360 static inline u32 cx18_read_enc_retry(struct cx18 *cx, u32 addr)
361 {
362         return cx18_readl_retry(cx, cx->enc_mem + addr);
363 }
364
365 static inline u32 cx18_read_enc(struct cx18 *cx, u32 addr)
366 {
367         if (cx18_retry_mmio)
368                 return cx18_read_enc_retry(cx, addr);
369
370         return cx18_read_enc_noretry(cx, addr);
371 }
372
373 static inline
374 u32 cx18_write_enc_sync_noretry(struct cx18 *cx, u32 val, u32 addr)
375 {
376         return cx18_write_sync_noretry(cx, val, cx->enc_mem + addr);
377 }
378
379 static inline
380 u32 cx18_write_enc_sync_retry(struct cx18 *cx, u32 val, u32 addr)
381 {
382         return cx18_write_sync_retry(cx, val, cx->enc_mem + addr);
383 }
384
385 static inline
386 u32 cx18_write_enc_sync(struct cx18 *cx, u32 val, u32 addr)
387 {
388         if (cx18_retry_mmio)
389                 return cx18_write_enc_sync_retry(cx, val, addr);
390
391         return cx18_write_enc_sync_noretry(cx, val, addr);
392 }
393
394 void cx18_sw1_irq_enable(struct cx18 *cx, u32 val);
395 void cx18_sw1_irq_disable(struct cx18 *cx, u32 val);
396 void cx18_sw2_irq_enable(struct cx18 *cx, u32 val);
397 void cx18_sw2_irq_disable(struct cx18 *cx, u32 val);
398 void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val);
399 void cx18_setup_page(struct cx18 *cx, u32 addr);
400
401 #endif /* CX18_IO_H */