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