]>
Commit | Line | Data |
---|---|---|
c942fddf | 1 | /* SPDX-License-Identifier: GPL-2.0-or-later */ |
b1526421 AW |
2 | /* |
3 | * cx18 driver PCI memory mapped IO access routines | |
4 | * | |
5 | * Copyright (C) 2007 Hans Verkuil <hverkuil@xs4all.nl> | |
6afdeaf8 | 6 | * Copyright (C) 2008 Andy Walls <awalls@md.metrocast.net> |
b1526421 AW |
7 | */ |
8 | ||
9 | #ifndef CX18_IO_H | |
10 | #define CX18_IO_H | |
11 | ||
12 | #include "cx18-driver.h" | |
13 | ||
d267d851 AW |
14 | /* |
15 | * Readback and retry of MMIO access for reliability: | |
16 | * The concept was suggested by Steve Toth <stoth@linuxtv.org>. | |
16790554 | 17 | * The implementation is the fault of Andy Walls <awalls@md.metrocast.net>. |
3f75c616 AW |
18 | * |
19 | * *write* functions are implied to retry the mmio unless suffixed with _noretry | |
20 | * *read* functions never retry the mmio (it never helps to do so) | |
d267d851 AW |
21 | */ |
22 | ||
c641d09c | 23 | /* Non byteswapping memory mapped IO */ |
3f75c616 AW |
24 | static inline u32 cx18_raw_readl(struct cx18 *cx, const void __iomem *addr) |
25 | { | |
26 | return __raw_readl(addr); | |
27 | } | |
28 | ||
d267d851 AW |
29 | static inline |
30 | void cx18_raw_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr) | |
c641d09c AW |
31 | { |
32 | __raw_writel(val, addr); | |
c641d09c | 33 | } |
b1526421 | 34 | |
d267d851 AW |
35 | static inline void cx18_raw_writel(struct cx18 *cx, u32 val, void __iomem *addr) |
36 | { | |
3f75c616 AW |
37 | int i; |
38 | for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { | |
d267d851 | 39 | cx18_raw_writel_noretry(cx, val, addr); |
3f75c616 AW |
40 | if (val == cx18_raw_readl(cx, addr)) |
41 | break; | |
42 | } | |
d267d851 AW |
43 | } |
44 | ||
3f75c616 AW |
45 | /* Normal memory mapped IO */ |
46 | static inline u32 cx18_readl(struct cx18 *cx, const void __iomem *addr) | |
d267d851 | 47 | { |
3f75c616 | 48 | return readl(addr); |
d267d851 AW |
49 | } |
50 | ||
d267d851 | 51 | static inline |
3f75c616 | 52 | void cx18_writel_noretry(struct cx18 *cx, u32 val, void __iomem *addr) |
c641d09c | 53 | { |
3f75c616 | 54 | writel(val, addr); |
c641d09c | 55 | } |
b1526421 | 56 | |
3f75c616 | 57 | static inline void cx18_writel(struct cx18 *cx, u32 val, void __iomem *addr) |
d267d851 | 58 | { |
3f75c616 AW |
59 | int i; |
60 | for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { | |
61 | cx18_writel_noretry(cx, val, addr); | |
62 | if (val == cx18_readl(cx, addr)) | |
63 | break; | |
64 | } | |
d267d851 AW |
65 | } |
66 | ||
d267d851 | 67 | static inline |
3f75c616 AW |
68 | void cx18_writel_expect(struct cx18 *cx, u32 val, void __iomem *addr, |
69 | u32 eval, u32 mask) | |
c641d09c | 70 | { |
3f75c616 | 71 | int i; |
daa1c164 | 72 | u32 r; |
3f75c616 AW |
73 | eval &= mask; |
74 | for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { | |
75 | cx18_writel_noretry(cx, val, addr); | |
daa1c164 AW |
76 | r = cx18_readl(cx, addr); |
77 | if (r == 0xffffffff && eval != 0xffffffff) | |
78 | continue; | |
79 | if (eval == (r & mask)) | |
3f75c616 AW |
80 | break; |
81 | } | |
c641d09c | 82 | } |
b1526421 | 83 | |
3f75c616 | 84 | static inline u16 cx18_readw(struct cx18 *cx, const void __iomem *addr) |
d267d851 | 85 | { |
3f75c616 | 86 | return readw(addr); |
d267d851 AW |
87 | } |
88 | ||
d267d851 AW |
89 | static inline |
90 | void cx18_writew_noretry(struct cx18 *cx, u16 val, void __iomem *addr) | |
c641d09c AW |
91 | { |
92 | writew(val, addr); | |
c641d09c AW |
93 | } |
94 | ||
d267d851 AW |
95 | static inline void cx18_writew(struct cx18 *cx, u16 val, void __iomem *addr) |
96 | { | |
3f75c616 AW |
97 | int i; |
98 | for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { | |
d267d851 | 99 | cx18_writew_noretry(cx, val, addr); |
3f75c616 AW |
100 | if (val == cx18_readw(cx, addr)) |
101 | break; | |
102 | } | |
d267d851 AW |
103 | } |
104 | ||
3f75c616 AW |
105 | static inline u8 cx18_readb(struct cx18 *cx, const void __iomem *addr) |
106 | { | |
107 | return readb(addr); | |
108 | } | |
d267d851 AW |
109 | |
110 | static inline | |
111 | void cx18_writeb_noretry(struct cx18 *cx, u8 val, void __iomem *addr) | |
c641d09c AW |
112 | { |
113 | writeb(val, addr); | |
c641d09c AW |
114 | } |
115 | ||
d267d851 AW |
116 | static inline void cx18_writeb(struct cx18 *cx, u8 val, void __iomem *addr) |
117 | { | |
3f75c616 AW |
118 | int i; |
119 | for (i = 0; i < CX18_MAX_MMIO_WR_RETRIES; i++) { | |
d267d851 | 120 | cx18_writeb_noretry(cx, val, addr); |
3f75c616 AW |
121 | if (val == cx18_readb(cx, addr)) |
122 | break; | |
123 | } | |
d267d851 AW |
124 | } |
125 | ||
ee2d64f5 | 126 | static inline |
b1526421 | 127 | void cx18_memcpy_fromio(struct cx18 *cx, void *to, |
ee2d64f5 AW |
128 | const void __iomem *from, unsigned int len) |
129 | { | |
130 | memcpy_fromio(to, from, len); | |
131 | } | |
132 | ||
b1526421 AW |
133 | void cx18_memset_io(struct cx18 *cx, void __iomem *addr, int val, size_t count); |
134 | ||
d267d851 | 135 | |
c641d09c | 136 | /* Access "register" region of CX23418 memory mapped I/O */ |
d267d851 AW |
137 | static inline void cx18_write_reg_noretry(struct cx18 *cx, u32 val, u32 reg) |
138 | { | |
139 | cx18_writel_noretry(cx, val, cx->reg_mem + reg); | |
140 | } | |
141 | ||
c641d09c AW |
142 | static inline void cx18_write_reg(struct cx18 *cx, u32 val, u32 reg) |
143 | { | |
3f75c616 | 144 | cx18_writel(cx, val, cx->reg_mem + reg); |
f056d29e AW |
145 | } |
146 | ||
147 | static inline void cx18_write_reg_expect(struct cx18 *cx, u32 val, u32 reg, | |
148 | u32 eval, u32 mask) | |
149 | { | |
3f75c616 | 150 | cx18_writel_expect(cx, val, cx->reg_mem + reg, eval, mask); |
c641d09c AW |
151 | } |
152 | ||
153 | static inline u32 cx18_read_reg(struct cx18 *cx, u32 reg) | |
154 | { | |
3f75c616 | 155 | return cx18_readl(cx, cx->reg_mem + reg); |
c641d09c AW |
156 | } |
157 | ||
d267d851 | 158 | |
c641d09c AW |
159 | /* Access "encoder memory" region of CX23418 memory mapped I/O */ |
160 | static inline void cx18_write_enc(struct cx18 *cx, u32 val, u32 addr) | |
161 | { | |
3f75c616 | 162 | cx18_writel(cx, val, cx->enc_mem + addr); |
c641d09c AW |
163 | } |
164 | ||
165 | static inline u32 cx18_read_enc(struct cx18 *cx, u32 addr) | |
166 | { | |
3f75c616 | 167 | return cx18_readl(cx, cx->enc_mem + addr); |
d267d851 | 168 | } |
c641d09c | 169 | |
b1526421 AW |
170 | void cx18_sw1_irq_enable(struct cx18 *cx, u32 val); |
171 | void cx18_sw1_irq_disable(struct cx18 *cx, u32 val); | |
172 | void cx18_sw2_irq_enable(struct cx18 *cx, u32 val); | |
173 | void cx18_sw2_irq_disable(struct cx18 *cx, u32 val); | |
d20ceecd | 174 | void cx18_sw2_irq_disable_cpu(struct cx18 *cx, u32 val); |
b1526421 AW |
175 | void cx18_setup_page(struct cx18 *cx, u32 addr); |
176 | ||
b1526421 | 177 | #endif /* CX18_IO_H */ |