Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
awilliam
GitHub Repository: awilliam/linux-vfio
Path: blob/master/drivers/media/common/saa7146_vbi.c
15112 views
1
#include <media/saa7146_vv.h>
2
3
static int vbi_pixel_to_capture = 720 * 2;
4
5
static int vbi_workaround(struct saa7146_dev *dev)
6
{
7
struct saa7146_vv *vv = dev->vv_data;
8
9
u32 *cpu;
10
dma_addr_t dma_addr;
11
12
int count = 0;
13
int i;
14
15
DECLARE_WAITQUEUE(wait, current);
16
17
DEB_VBI(("dev:%p\n",dev));
18
19
/* once again, a bug in the saa7146: the brs acquisition
20
is buggy and especially the BXO-counter does not work
21
as specified. there is this workaround, but please
22
don't let me explain it. ;-) */
23
24
cpu = pci_alloc_consistent(dev->pci, 4096, &dma_addr);
25
if (NULL == cpu)
26
return -ENOMEM;
27
28
/* setup some basic programming, just for the workaround */
29
saa7146_write(dev, BASE_EVEN3, dma_addr);
30
saa7146_write(dev, BASE_ODD3, dma_addr+vbi_pixel_to_capture);
31
saa7146_write(dev, PROT_ADDR3, dma_addr+4096);
32
saa7146_write(dev, PITCH3, vbi_pixel_to_capture);
33
saa7146_write(dev, BASE_PAGE3, 0x0);
34
saa7146_write(dev, NUM_LINE_BYTE3, (2<<16)|((vbi_pixel_to_capture)<<0));
35
saa7146_write(dev, MC2, MASK_04|MASK_20);
36
37
/* load brs-control register */
38
WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
39
/* BXO = 1h, BRS to outbound */
40
WRITE_RPS1(0xc000008c);
41
/* wait for vbi_a or vbi_b*/
42
if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
43
DEB_D(("...using port b\n"));
44
WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_E_FID_B);
45
WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | CMD_O_FID_B);
46
/*
47
WRITE_RPS1(CMD_PAUSE | MASK_09);
48
*/
49
} else {
50
DEB_D(("...using port a\n"));
51
WRITE_RPS1(CMD_PAUSE | MASK_10);
52
}
53
/* upload brs */
54
WRITE_RPS1(CMD_UPLOAD | MASK_08);
55
/* load brs-control register */
56
WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
57
/* BYO = 1, BXO = NQBIL (=1728 for PAL, for NTSC this is 858*2) - NumByte3 (=1440) = 288 */
58
WRITE_RPS1(((1728-(vbi_pixel_to_capture)) << 7) | MASK_19);
59
/* wait for brs_done */
60
WRITE_RPS1(CMD_PAUSE | MASK_08);
61
/* upload brs */
62
WRITE_RPS1(CMD_UPLOAD | MASK_08);
63
/* load video-dma3 NumLines3 and NumBytes3 */
64
WRITE_RPS1(CMD_WR_REG | (1 << 8) | (NUM_LINE_BYTE3/4));
65
/* dev->vbi_count*2 lines, 720 pixel (= 1440 Bytes) */
66
WRITE_RPS1((2 << 16) | (vbi_pixel_to_capture));
67
/* load brs-control register */
68
WRITE_RPS1(CMD_WR_REG | (1 << 8) | (BRS_CTRL/4));
69
/* Set BRS right: note: this is an experimental value for BXO (=> PAL!) */
70
WRITE_RPS1((540 << 7) | (5 << 19)); // 5 == vbi_start
71
/* wait for brs_done */
72
WRITE_RPS1(CMD_PAUSE | MASK_08);
73
/* upload brs and video-dma3*/
74
WRITE_RPS1(CMD_UPLOAD | MASK_08 | MASK_04);
75
/* load mc2 register: enable dma3 */
76
WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC1/4));
77
WRITE_RPS1(MASK_20 | MASK_04);
78
/* generate interrupt */
79
WRITE_RPS1(CMD_INTERRUPT);
80
/* stop rps1 */
81
WRITE_RPS1(CMD_STOP);
82
83
/* we have to do the workaround twice to be sure that
84
everything is ok */
85
for(i = 0; i < 2; i++) {
86
87
/* indicate to the irq handler that we do the workaround */
88
saa7146_write(dev, MC2, MASK_31|MASK_15);
89
90
saa7146_write(dev, NUM_LINE_BYTE3, (1<<16)|(2<<0));
91
saa7146_write(dev, MC2, MASK_04|MASK_20);
92
93
/* enable rps1 irqs */
94
SAA7146_IER_ENABLE(dev,MASK_28);
95
96
/* prepare to wait to be woken up by the irq-handler */
97
add_wait_queue(&vv->vbi_wq, &wait);
98
current->state = TASK_INTERRUPTIBLE;
99
100
/* start rps1 to enable workaround */
101
saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
102
saa7146_write(dev, MC1, (MASK_13 | MASK_29));
103
104
schedule();
105
106
DEB_VBI(("brs bug workaround %d/1.\n",i));
107
108
remove_wait_queue(&vv->vbi_wq, &wait);
109
current->state = TASK_RUNNING;
110
111
/* disable rps1 irqs */
112
SAA7146_IER_DISABLE(dev,MASK_28);
113
114
/* stop video-dma3 */
115
saa7146_write(dev, MC1, MASK_20);
116
117
if(signal_pending(current)) {
118
119
DEB_VBI(("aborted (rps:0x%08x).\n",saa7146_read(dev,RPS_ADDR1)));
120
121
/* stop rps1 for sure */
122
saa7146_write(dev, MC1, MASK_29);
123
124
pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
125
return -EINTR;
126
}
127
}
128
129
pci_free_consistent(dev->pci, 4096, cpu, dma_addr);
130
return 0;
131
}
132
133
static void saa7146_set_vbi_capture(struct saa7146_dev *dev, struct saa7146_buf *buf, struct saa7146_buf *next)
134
{
135
struct saa7146_vv *vv = dev->vv_data;
136
137
struct saa7146_video_dma vdma3;
138
139
int count = 0;
140
unsigned long e_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_E_FID_A : CMD_E_FID_B;
141
unsigned long o_wait = vv->current_hps_sync == SAA7146_HPS_SYNC_PORT_A ? CMD_O_FID_A : CMD_O_FID_B;
142
143
/*
144
vdma3.base_even = 0xc8000000+2560*70;
145
vdma3.base_odd = 0xc8000000;
146
vdma3.prot_addr = 0xc8000000+2560*164;
147
vdma3.pitch = 2560;
148
vdma3.base_page = 0;
149
vdma3.num_line_byte = (64<<16)|((vbi_pixel_to_capture)<<0); // set above!
150
*/
151
vdma3.base_even = buf->pt[2].offset;
152
vdma3.base_odd = buf->pt[2].offset + 16 * vbi_pixel_to_capture;
153
vdma3.prot_addr = buf->pt[2].offset + 16 * 2 * vbi_pixel_to_capture;
154
vdma3.pitch = vbi_pixel_to_capture;
155
vdma3.base_page = buf->pt[2].dma | ME1;
156
vdma3.num_line_byte = (16 << 16) | vbi_pixel_to_capture;
157
158
saa7146_write_out_dma(dev, 3, &vdma3);
159
160
/* write beginning of rps-program */
161
count = 0;
162
163
/* wait for o_fid_a/b / e_fid_a/b toggle only if bit 1 is not set */
164
165
/* we don't wait here for the first field anymore. this is different from the video
166
capture and might cause that the first buffer is only half filled (with only
167
one field). but since this is some sort of streaming data, this is not that negative.
168
but by doing this, we can use the whole engine from videobuf-dma-sg.c... */
169
170
/*
171
WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | e_wait);
172
WRITE_RPS1(CMD_PAUSE | CMD_OAN | CMD_SIG1 | o_wait);
173
*/
174
/* set bit 1 */
175
WRITE_RPS1(CMD_WR_REG | (1 << 8) | (MC2/4));
176
WRITE_RPS1(MASK_28 | MASK_12);
177
178
/* turn on video-dma3 */
179
WRITE_RPS1(CMD_WR_REG_MASK | (MC1/4));
180
WRITE_RPS1(MASK_04 | MASK_20); /* => mask */
181
WRITE_RPS1(MASK_04 | MASK_20); /* => values */
182
183
/* wait for o_fid_a/b / e_fid_a/b toggle */
184
WRITE_RPS1(CMD_PAUSE | o_wait);
185
WRITE_RPS1(CMD_PAUSE | e_wait);
186
187
/* generate interrupt */
188
WRITE_RPS1(CMD_INTERRUPT);
189
190
/* stop */
191
WRITE_RPS1(CMD_STOP);
192
193
/* enable rps1 irqs */
194
SAA7146_IER_ENABLE(dev, MASK_28);
195
196
/* write the address of the rps-program */
197
saa7146_write(dev, RPS_ADDR1, dev->d_rps1.dma_handle);
198
199
/* turn on rps */
200
saa7146_write(dev, MC1, (MASK_13 | MASK_29));
201
}
202
203
static int buffer_activate(struct saa7146_dev *dev,
204
struct saa7146_buf *buf,
205
struct saa7146_buf *next)
206
{
207
struct saa7146_vv *vv = dev->vv_data;
208
buf->vb.state = VIDEOBUF_ACTIVE;
209
210
DEB_VBI(("dev:%p, buf:%p, next:%p\n",dev,buf,next));
211
saa7146_set_vbi_capture(dev,buf,next);
212
213
mod_timer(&vv->vbi_q.timeout, jiffies+BUFFER_TIMEOUT);
214
return 0;
215
}
216
217
static int buffer_prepare(struct videobuf_queue *q, struct videobuf_buffer *vb,enum v4l2_field field)
218
{
219
struct file *file = q->priv_data;
220
struct saa7146_fh *fh = file->private_data;
221
struct saa7146_dev *dev = fh->dev;
222
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
223
224
int err = 0;
225
int lines, llength, size;
226
227
lines = 16 * 2 ; /* 2 fields */
228
llength = vbi_pixel_to_capture;
229
size = lines * llength;
230
231
DEB_VBI(("vb:%p\n",vb));
232
233
if (0 != buf->vb.baddr && buf->vb.bsize < size) {
234
DEB_VBI(("size mismatch.\n"));
235
return -EINVAL;
236
}
237
238
if (buf->vb.size != size)
239
saa7146_dma_free(dev,q,buf);
240
241
if (VIDEOBUF_NEEDS_INIT == buf->vb.state) {
242
struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
243
244
buf->vb.width = llength;
245
buf->vb.height = lines;
246
buf->vb.size = size;
247
buf->vb.field = field; // FIXME: check this
248
249
saa7146_pgtable_free(dev->pci, &buf->pt[2]);
250
saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
251
252
err = videobuf_iolock(q,&buf->vb, NULL);
253
if (err)
254
goto oops;
255
err = saa7146_pgtable_build_single(dev->pci, &buf->pt[2],
256
dma->sglist, dma->sglen);
257
if (0 != err)
258
return err;
259
}
260
buf->vb.state = VIDEOBUF_PREPARED;
261
buf->activate = buffer_activate;
262
263
return 0;
264
265
oops:
266
DEB_VBI(("error out.\n"));
267
saa7146_dma_free(dev,q,buf);
268
269
return err;
270
}
271
272
static int buffer_setup(struct videobuf_queue *q, unsigned int *count, unsigned int *size)
273
{
274
int llength,lines;
275
276
lines = 16 * 2 ; /* 2 fields */
277
llength = vbi_pixel_to_capture;
278
279
*size = lines * llength;
280
*count = 2;
281
282
DEB_VBI(("count:%d, size:%d\n",*count,*size));
283
284
return 0;
285
}
286
287
static void buffer_queue(struct videobuf_queue *q, struct videobuf_buffer *vb)
288
{
289
struct file *file = q->priv_data;
290
struct saa7146_fh *fh = file->private_data;
291
struct saa7146_dev *dev = fh->dev;
292
struct saa7146_vv *vv = dev->vv_data;
293
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
294
295
DEB_VBI(("vb:%p\n",vb));
296
saa7146_buffer_queue(dev,&vv->vbi_q,buf);
297
}
298
299
static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
300
{
301
struct file *file = q->priv_data;
302
struct saa7146_fh *fh = file->private_data;
303
struct saa7146_dev *dev = fh->dev;
304
struct saa7146_buf *buf = (struct saa7146_buf *)vb;
305
306
DEB_VBI(("vb:%p\n",vb));
307
saa7146_dma_free(dev,q,buf);
308
}
309
310
static struct videobuf_queue_ops vbi_qops = {
311
.buf_setup = buffer_setup,
312
.buf_prepare = buffer_prepare,
313
.buf_queue = buffer_queue,
314
.buf_release = buffer_release,
315
};
316
317
/* ------------------------------------------------------------------ */
318
319
static void vbi_stop(struct saa7146_fh *fh, struct file *file)
320
{
321
struct saa7146_dev *dev = fh->dev;
322
struct saa7146_vv *vv = dev->vv_data;
323
unsigned long flags;
324
DEB_VBI(("dev:%p, fh:%p\n",dev, fh));
325
326
spin_lock_irqsave(&dev->slock,flags);
327
328
/* disable rps1 */
329
saa7146_write(dev, MC1, MASK_29);
330
331
/* disable rps1 irqs */
332
SAA7146_IER_DISABLE(dev, MASK_28);
333
334
/* shut down dma 3 transfers */
335
saa7146_write(dev, MC1, MASK_20);
336
337
if (vv->vbi_q.curr) {
338
saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE);
339
}
340
341
videobuf_queue_cancel(&fh->vbi_q);
342
343
vv->vbi_streaming = NULL;
344
345
del_timer(&vv->vbi_q.timeout);
346
del_timer(&fh->vbi_read_timeout);
347
348
spin_unlock_irqrestore(&dev->slock, flags);
349
}
350
351
static void vbi_read_timeout(unsigned long data)
352
{
353
struct file *file = (struct file*)data;
354
struct saa7146_fh *fh = file->private_data;
355
struct saa7146_dev *dev = fh->dev;
356
357
DEB_VBI(("dev:%p, fh:%p\n",dev, fh));
358
359
vbi_stop(fh, file);
360
}
361
362
static void vbi_init(struct saa7146_dev *dev, struct saa7146_vv *vv)
363
{
364
DEB_VBI(("dev:%p\n",dev));
365
366
INIT_LIST_HEAD(&vv->vbi_q.queue);
367
368
init_timer(&vv->vbi_q.timeout);
369
vv->vbi_q.timeout.function = saa7146_buffer_timeout;
370
vv->vbi_q.timeout.data = (unsigned long)(&vv->vbi_q);
371
vv->vbi_q.dev = dev;
372
373
init_waitqueue_head(&vv->vbi_wq);
374
}
375
376
static int vbi_open(struct saa7146_dev *dev, struct file *file)
377
{
378
struct saa7146_fh *fh = file->private_data;
379
380
u32 arbtr_ctrl = saa7146_read(dev, PCI_BT_V1);
381
int ret = 0;
382
383
DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
384
385
ret = saa7146_res_get(fh, RESOURCE_DMA3_BRS);
386
if (0 == ret) {
387
DEB_S(("cannot get vbi RESOURCE_DMA3_BRS resource\n"));
388
return -EBUSY;
389
}
390
391
/* adjust arbitrition control for video dma 3 */
392
arbtr_ctrl &= ~0x1f0000;
393
arbtr_ctrl |= 0x1d0000;
394
saa7146_write(dev, PCI_BT_V1, arbtr_ctrl);
395
saa7146_write(dev, MC2, (MASK_04|MASK_20));
396
397
memset(&fh->vbi_fmt,0,sizeof(fh->vbi_fmt));
398
399
fh->vbi_fmt.sampling_rate = 27000000;
400
fh->vbi_fmt.offset = 248; /* todo */
401
fh->vbi_fmt.samples_per_line = vbi_pixel_to_capture;
402
fh->vbi_fmt.sample_format = V4L2_PIX_FMT_GREY;
403
404
/* fixme: this only works for PAL */
405
fh->vbi_fmt.start[0] = 5;
406
fh->vbi_fmt.count[0] = 16;
407
fh->vbi_fmt.start[1] = 312;
408
fh->vbi_fmt.count[1] = 16;
409
410
videobuf_queue_sg_init(&fh->vbi_q, &vbi_qops,
411
&dev->pci->dev, &dev->slock,
412
V4L2_BUF_TYPE_VBI_CAPTURE,
413
V4L2_FIELD_SEQ_TB, // FIXME: does this really work?
414
sizeof(struct saa7146_buf),
415
file, &dev->v4l2_lock);
416
417
init_timer(&fh->vbi_read_timeout);
418
fh->vbi_read_timeout.function = vbi_read_timeout;
419
fh->vbi_read_timeout.data = (unsigned long)file;
420
421
/* initialize the brs */
422
if ( 0 != (SAA7146_USE_PORT_B_FOR_VBI & dev->ext_vv_data->flags)) {
423
saa7146_write(dev, BRS_CTRL, MASK_30|MASK_29 | (7 << 19));
424
} else {
425
saa7146_write(dev, BRS_CTRL, 0x00000001);
426
427
if (0 != (ret = vbi_workaround(dev))) {
428
DEB_VBI(("vbi workaround failed!\n"));
429
/* return ret;*/
430
}
431
}
432
433
/* upload brs register */
434
saa7146_write(dev, MC2, (MASK_08|MASK_24));
435
return 0;
436
}
437
438
static void vbi_close(struct saa7146_dev *dev, struct file *file)
439
{
440
struct saa7146_fh *fh = file->private_data;
441
struct saa7146_vv *vv = dev->vv_data;
442
DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
443
444
if( fh == vv->vbi_streaming ) {
445
vbi_stop(fh, file);
446
}
447
saa7146_res_free(fh, RESOURCE_DMA3_BRS);
448
}
449
450
static void vbi_irq_done(struct saa7146_dev *dev, unsigned long status)
451
{
452
struct saa7146_vv *vv = dev->vv_data;
453
spin_lock(&dev->slock);
454
455
if (vv->vbi_q.curr) {
456
DEB_VBI(("dev:%p, curr:%p\n",dev,vv->vbi_q.curr));
457
/* this must be += 2, one count for each field */
458
vv->vbi_fieldcount+=2;
459
vv->vbi_q.curr->vb.field_count = vv->vbi_fieldcount;
460
saa7146_buffer_finish(dev,&vv->vbi_q,VIDEOBUF_DONE);
461
} else {
462
DEB_VBI(("dev:%p\n",dev));
463
}
464
saa7146_buffer_next(dev,&vv->vbi_q,1);
465
466
spin_unlock(&dev->slock);
467
}
468
469
static ssize_t vbi_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
470
{
471
struct saa7146_fh *fh = file->private_data;
472
struct saa7146_dev *dev = fh->dev;
473
struct saa7146_vv *vv = dev->vv_data;
474
ssize_t ret = 0;
475
476
DEB_VBI(("dev:%p, fh:%p\n",dev,fh));
477
478
if( NULL == vv->vbi_streaming ) {
479
// fixme: check if dma3 is available
480
// fixme: activate vbi engine here if necessary. (really?)
481
vv->vbi_streaming = fh;
482
}
483
484
if( fh != vv->vbi_streaming ) {
485
DEB_VBI(("open %p is already using vbi capture.",vv->vbi_streaming));
486
return -EBUSY;
487
}
488
489
mod_timer(&fh->vbi_read_timeout, jiffies+BUFFER_TIMEOUT);
490
ret = videobuf_read_stream(&fh->vbi_q, data, count, ppos, 1,
491
file->f_flags & O_NONBLOCK);
492
/*
493
printk("BASE_ODD3: 0x%08x\n", saa7146_read(dev, BASE_ODD3));
494
printk("BASE_EVEN3: 0x%08x\n", saa7146_read(dev, BASE_EVEN3));
495
printk("PROT_ADDR3: 0x%08x\n", saa7146_read(dev, PROT_ADDR3));
496
printk("PITCH3: 0x%08x\n", saa7146_read(dev, PITCH3));
497
printk("BASE_PAGE3: 0x%08x\n", saa7146_read(dev, BASE_PAGE3));
498
printk("NUM_LINE_BYTE3: 0x%08x\n", saa7146_read(dev, NUM_LINE_BYTE3));
499
printk("BRS_CTRL: 0x%08x\n", saa7146_read(dev, BRS_CTRL));
500
*/
501
return ret;
502
}
503
504
struct saa7146_use_ops saa7146_vbi_uops = {
505
.init = vbi_init,
506
.open = vbi_open,
507
.release = vbi_close,
508
.irq_done = vbi_irq_done,
509
.read = vbi_read,
510
};
511
512