1
2
3
4
5
6
7
8#include <linux/slab.h>
9
10#include "saa7164.h"
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55void saa7164_buffer_display(struct saa7164_buffer *buf)
56{
57 struct saa7164_dev *dev = buf->port->dev;
58 int i;
59
60 dprintk(DBGLVL_BUF, "%s() buffer @ 0x%p nr=%d\n",
61 __func__, buf, buf->idx);
62 dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08llx len = 0x%x\n",
63 buf->cpu, (long long)buf->dma, buf->pci_size);
64 dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08llx len = 0x%x\n",
65 buf->pt_cpu, (long long)buf->pt_dma, buf->pt_size);
66
67
68 for (i = 0 ; i < SAA7164_PT_ENTRIES; i++) {
69
70 dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n",
71 i, buf->pt_cpu, (u64)*(buf->pt_cpu));
72
73 }
74}
75
76
77
78struct saa7164_buffer *saa7164_buffer_alloc(struct saa7164_port *port,
79 u32 len)
80{
81 struct tmHWStreamParameters *params = &port->hw_streamingparams;
82 struct saa7164_buffer *buf = NULL;
83 struct saa7164_dev *dev = port->dev;
84 int i;
85
86 if ((len == 0) || (len >= 65536) || (len % sizeof(u64))) {
87 log_warn("%s() SAA_ERR_BAD_PARAMETER\n", __func__);
88 goto ret;
89 }
90
91 buf = kzalloc(sizeof(*buf), GFP_KERNEL);
92 if (!buf)
93 goto ret;
94
95 buf->idx = -1;
96 buf->port = port;
97 buf->flags = SAA7164_BUFFER_FREE;
98 buf->pos = 0;
99 buf->actual_size = params->pitch * params->numberoflines;
100 buf->crc = 0;
101
102 buf->pci_size = SAA7164_PT_ENTRIES * 0x1000;
103 buf->pt_size = (SAA7164_PT_ENTRIES * sizeof(u64)) + 0x1000;
104
105
106 buf->cpu = dma_alloc_coherent(&port->dev->pci->dev, buf->pci_size,
107 &buf->dma, GFP_KERNEL);
108 if (!buf->cpu)
109 goto fail1;
110
111 buf->pt_cpu = dma_alloc_coherent(&port->dev->pci->dev, buf->pt_size,
112 &buf->pt_dma, GFP_KERNEL);
113 if (!buf->pt_cpu)
114 goto fail2;
115
116
117 memset(buf->cpu, 0xff, buf->pci_size);
118 buf->crc = crc32(0, buf->cpu, buf->actual_size);
119 memset(buf->pt_cpu, 0xff, buf->pt_size);
120
121 dprintk(DBGLVL_BUF, "%s() allocated buffer @ 0x%p (%d pageptrs)\n",
122 __func__, buf, params->numpagetables);
123 dprintk(DBGLVL_BUF, " pci_cpu @ 0x%p dma @ 0x%08lx len = 0x%x\n",
124 buf->cpu, (long)buf->dma, buf->pci_size);
125 dprintk(DBGLVL_BUF, " pt_cpu @ 0x%p pt_dma @ 0x%08lx len = 0x%x\n",
126 buf->pt_cpu, (long)buf->pt_dma, buf->pt_size);
127
128
129 for (i = 0 ; i < params->numpagetables; i++) {
130
131 *(buf->pt_cpu + i) = buf->dma + (i * 0x1000);
132 dprintk(DBGLVL_BUF, " pt[%02d] = 0x%p -> 0x%llx\n",
133 i, buf->pt_cpu, (u64)*(buf->pt_cpu));
134
135 }
136
137 goto ret;
138
139fail2:
140 dma_free_coherent(&port->dev->pci->dev, buf->pci_size, buf->cpu,
141 buf->dma);
142fail1:
143 kfree(buf);
144
145 buf = NULL;
146ret:
147 return buf;
148}
149
150int saa7164_buffer_dealloc(struct saa7164_buffer *buf)
151{
152 struct saa7164_dev *dev;
153
154 if (!buf || !buf->port)
155 return SAA_ERR_BAD_PARAMETER;
156 dev = buf->port->dev;
157
158 dprintk(DBGLVL_BUF, "%s() deallocating buffer @ 0x%p\n",
159 __func__, buf);
160
161 if (buf->flags != SAA7164_BUFFER_FREE)
162 log_warn(" freeing a non-free buffer\n");
163
164 dma_free_coherent(&dev->pci->dev, buf->pci_size, buf->cpu, buf->dma);
165 dma_free_coherent(&dev->pci->dev, buf->pt_size, buf->pt_cpu,
166 buf->pt_dma);
167
168 kfree(buf);
169
170 return SAA_OK;
171}
172
173int saa7164_buffer_zero_offsets(struct saa7164_port *port, int i)
174{
175 struct saa7164_dev *dev = port->dev;
176
177 if ((i < 0) || (i >= port->hwcfg.buffercount))
178 return -EINVAL;
179
180 dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i);
181
182 saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
183
184 return 0;
185}
186
187
188int saa7164_buffer_activate(struct saa7164_buffer *buf, int i)
189{
190 struct saa7164_port *port = buf->port;
191 struct saa7164_dev *dev = port->dev;
192
193 if ((i < 0) || (i >= port->hwcfg.buffercount))
194 return -EINVAL;
195
196 dprintk(DBGLVL_BUF, "%s(idx = %d)\n", __func__, i);
197
198 buf->idx = i;
199 buf->flags = SAA7164_BUFFER_BUSY;
200 buf->pos = 0;
201
202
203 saa7164_writel(port->bufoffset + (sizeof(u32) * i), 0);
204 saa7164_writel(port->bufptr32h + ((sizeof(u32) * 2) * i), buf->pt_dma);
205 saa7164_writel(port->bufptr32l + ((sizeof(u32) * 2) * i), 0);
206
207 dprintk(DBGLVL_BUF, " buf[%d] offset 0x%llx (0x%x) buf 0x%llx/%llx (0x%x/%x) nr=%d\n",
208 buf->idx,
209 (u64)port->bufoffset + (i * sizeof(u32)),
210 saa7164_readl(port->bufoffset + (sizeof(u32) * i)),
211 (u64)port->bufptr32h + ((sizeof(u32) * 2) * i),
212 (u64)port->bufptr32l + ((sizeof(u32) * 2) * i),
213 saa7164_readl(port->bufptr32h + ((sizeof(u32) * i) * 2)),
214 saa7164_readl(port->bufptr32l + ((sizeof(u32) * i) * 2)),
215 buf->idx);
216
217 return 0;
218}
219
220int saa7164_buffer_cfg_port(struct saa7164_port *port)
221{
222 struct tmHWStreamParameters *params = &port->hw_streamingparams;
223 struct saa7164_dev *dev = port->dev;
224 struct saa7164_buffer *buf;
225 struct list_head *c, *n;
226 int i = 0;
227
228 dprintk(DBGLVL_BUF, "%s(port=%d)\n", __func__, port->nr);
229
230 saa7164_writel(port->bufcounter, 0);
231 saa7164_writel(port->pitch, params->pitch);
232 saa7164_writel(port->bufsize, params->pitch * params->numberoflines);
233
234 dprintk(DBGLVL_BUF, " configured:\n");
235 dprintk(DBGLVL_BUF, " lmmio 0x%p\n", dev->lmmio);
236 dprintk(DBGLVL_BUF, " bufcounter 0x%x = 0x%x\n", port->bufcounter,
237 saa7164_readl(port->bufcounter));
238
239 dprintk(DBGLVL_BUF, " pitch 0x%x = %d\n", port->pitch,
240 saa7164_readl(port->pitch));
241
242 dprintk(DBGLVL_BUF, " bufsize 0x%x = %d\n", port->bufsize,
243 saa7164_readl(port->bufsize));
244
245 dprintk(DBGLVL_BUF, " buffercount = %d\n", port->hwcfg.buffercount);
246 dprintk(DBGLVL_BUF, " bufoffset = 0x%x\n", port->bufoffset);
247 dprintk(DBGLVL_BUF, " bufptr32h = 0x%x\n", port->bufptr32h);
248 dprintk(DBGLVL_BUF, " bufptr32l = 0x%x\n", port->bufptr32l);
249
250
251 mutex_lock(&port->dmaqueue_lock);
252 list_for_each_safe(c, n, &port->dmaqueue.list) {
253 buf = list_entry(c, struct saa7164_buffer, list);
254
255 BUG_ON(buf->flags != SAA7164_BUFFER_FREE);
256
257
258 saa7164_buffer_activate(buf, i);
259
260
261 BUG_ON(i > port->hwcfg.buffercount);
262 i++;
263
264 }
265 mutex_unlock(&port->dmaqueue_lock);
266
267 return 0;
268}
269
270struct saa7164_user_buffer *saa7164_buffer_alloc_user(struct saa7164_dev *dev,
271 u32 len)
272{
273 struct saa7164_user_buffer *buf;
274
275 buf = kzalloc(sizeof(*buf), GFP_KERNEL);
276 if (!buf)
277 return NULL;
278
279 buf->data = kzalloc(len, GFP_KERNEL);
280
281 if (!buf->data) {
282 kfree(buf);
283 return NULL;
284 }
285
286 buf->actual_size = len;
287 buf->pos = 0;
288 buf->crc = 0;
289
290 dprintk(DBGLVL_BUF, "%s() allocated user buffer @ 0x%p\n",
291 __func__, buf);
292
293 return buf;
294}
295
296void saa7164_buffer_dealloc_user(struct saa7164_user_buffer *buf)
297{
298 if (!buf)
299 return;
300
301 kfree(buf->data);
302 buf->data = NULL;
303
304 kfree(buf);
305}
306