1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28
29#include <linux/module.h>
30#include <linux/init.h>
31#include <linux/slab.h>
32#include <linux/pci.h>
33#include <linux/vmalloc.h>
34#include <linux/interrupt.h>
35#include <asm/page.h>
36#include <asm/pgtable.h>
37#include <media/v4l2-ioctl.h>
38
39#include "bttvp.h"
40
41#define VCR_HACK_LINES 4
42
43
44
45
46int
47bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
48 struct scatterlist *sglist,
49 unsigned int offset, unsigned int bpl,
50 unsigned int padding, unsigned int skip_lines,
51 unsigned int store_lines)
52{
53 u32 instructions,line,todo;
54 struct scatterlist *sg;
55 __le32 *rp;
56 int rc;
57
58
59
60
61
62 instructions = skip_lines * 4;
63 instructions += (1 + ((bpl + padding) * store_lines)
64 / PAGE_SIZE + store_lines) * 8;
65 instructions += 2 * 8;
66 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions)) < 0)
67 return rc;
68
69
70 rp = risc->cpu;
71 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
72 *(rp++) = cpu_to_le32(0);
73
74 while (skip_lines-- > 0) {
75 *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
76 BT848_RISC_EOL | bpl);
77 }
78
79
80 sg = sglist;
81 for (line = 0; line < store_lines; line++) {
82 if ((btv->opt_vcr_hack) &&
83 (line >= (store_lines - VCR_HACK_LINES)))
84 continue;
85 while (offset && offset >= sg_dma_len(sg)) {
86 offset -= sg_dma_len(sg);
87 sg = sg_next(sg);
88 }
89 if (bpl <= sg_dma_len(sg)-offset) {
90
91 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
92 BT848_RISC_EOL|bpl);
93 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
94 offset+=bpl;
95 } else {
96
97 todo = bpl;
98 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
99 (sg_dma_len(sg)-offset));
100 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
101 todo -= (sg_dma_len(sg)-offset);
102 offset = 0;
103 sg = sg_next(sg);
104 while (todo > sg_dma_len(sg)) {
105 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
106 sg_dma_len(sg));
107 *(rp++)=cpu_to_le32(sg_dma_address(sg));
108 todo -= sg_dma_len(sg);
109 sg = sg_next(sg);
110 }
111 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
112 todo);
113 *(rp++)=cpu_to_le32(sg_dma_address(sg));
114 offset += todo;
115 }
116 offset += padding;
117 }
118
119
120 risc->jmp = rp;
121 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
122 return 0;
123}
124
125static int
126bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
127 struct scatterlist *sglist,
128 unsigned int yoffset, unsigned int ybpl,
129 unsigned int ypadding, unsigned int ylines,
130 unsigned int uoffset, unsigned int voffset,
131 unsigned int hshift, unsigned int vshift,
132 unsigned int cpadding)
133{
134 unsigned int instructions,line,todo,ylen,chroma;
135 __le32 *rp;
136 u32 ri;
137 struct scatterlist *ysg;
138 struct scatterlist *usg;
139 struct scatterlist *vsg;
140 int topfield = (0 == yoffset);
141 int rc;
142
143
144
145
146 instructions = ((3 + (ybpl + ypadding) * ylines * 2)
147 / PAGE_SIZE) + ylines;
148 instructions += 2;
149 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
150 return rc;
151
152
153 rp = risc->cpu;
154 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
155 *(rp++) = cpu_to_le32(0);
156
157
158 ysg = sglist;
159 usg = sglist;
160 vsg = sglist;
161 for (line = 0; line < ylines; line++) {
162 if ((btv->opt_vcr_hack) &&
163 (line >= (ylines - VCR_HACK_LINES)))
164 continue;
165 switch (vshift) {
166 case 0:
167 chroma = 1;
168 break;
169 case 1:
170 if (topfield)
171 chroma = ((line & 1) == 0);
172 else
173 chroma = ((line & 1) == 1);
174 break;
175 case 2:
176 if (topfield)
177 chroma = ((line & 3) == 0);
178 else
179 chroma = ((line & 3) == 2);
180 break;
181 default:
182 chroma = 0;
183 break;
184 }
185
186 for (todo = ybpl; todo > 0; todo -= ylen) {
187
188 while (yoffset && yoffset >= sg_dma_len(ysg)) {
189 yoffset -= sg_dma_len(ysg);
190 ysg = sg_next(ysg);
191 }
192
193
194 ylen = todo;
195 if (yoffset + ylen > sg_dma_len(ysg))
196 ylen = sg_dma_len(ysg) - yoffset;
197 if (chroma) {
198 while (uoffset && uoffset >= sg_dma_len(usg)) {
199 uoffset -= sg_dma_len(usg);
200 usg = sg_next(usg);
201 }
202 while (voffset && voffset >= sg_dma_len(vsg)) {
203 voffset -= sg_dma_len(vsg);
204 vsg = sg_next(vsg);
205 }
206
207 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
208 ylen = (sg_dma_len(usg) - uoffset) << hshift;
209 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
210 ylen = (sg_dma_len(vsg) - voffset) << hshift;
211 ri = BT848_RISC_WRITE123;
212 } else {
213 ri = BT848_RISC_WRITE1S23;
214 }
215 if (ybpl == todo)
216 ri |= BT848_RISC_SOL;
217 if (ylen == todo)
218 ri |= BT848_RISC_EOL;
219
220
221 *(rp++)=cpu_to_le32(ri | ylen);
222 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
223 (ylen >> hshift));
224 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
225 yoffset += ylen;
226 if (chroma) {
227 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
228 uoffset += ylen >> hshift;
229 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
230 voffset += ylen >> hshift;
231 }
232 }
233 yoffset += ypadding;
234 if (chroma) {
235 uoffset += cpadding;
236 voffset += cpadding;
237 }
238 }
239
240
241 risc->jmp = rp;
242 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
243 return 0;
244}
245
246static int
247bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
248 const struct bttv_format *fmt, struct bttv_overlay *ov,
249 int skip_even, int skip_odd)
250{
251 int dwords, rc, line, maxy, start, end;
252 unsigned skip, nskips;
253 struct btcx_skiplist *skips;
254 __le32 *rp;
255 u32 ri,ra;
256 u32 addr;
257
258
259 skips = kmalloc_array(ov->nclips, sizeof(*skips),GFP_KERNEL);
260 if (NULL == skips)
261 return -ENOMEM;
262
263
264
265 dwords = (3 * ov->nclips + 2) *
266 ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
267 dwords += 4;
268 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
269 kfree(skips);
270 return rc;
271 }
272
273
274 rp = risc->cpu;
275 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
276 *(rp++) = cpu_to_le32(0);
277
278 addr = (unsigned long)btv->fbuf.base;
279 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
280 addr += (fmt->depth >> 3) * ov->w.left;
281
282
283 for (maxy = -1, line = 0; line < ov->w.height;
284 line++, addr += btv->fbuf.fmt.bytesperline) {
285 if ((btv->opt_vcr_hack) &&
286 (line >= (ov->w.height - VCR_HACK_LINES)))
287 continue;
288 if ((line%2) == 0 && skip_even)
289 continue;
290 if ((line%2) == 1 && skip_odd)
291 continue;
292
293
294 if (line > maxy)
295 btcx_calc_skips(line, ov->w.width, &maxy,
296 skips, &nskips, ov->clips, ov->nclips);
297
298
299 for (start = 0, skip = 0; start < ov->w.width; start = end) {
300 if (skip >= nskips) {
301 ri = BT848_RISC_WRITE;
302 end = ov->w.width;
303 } else if (start < skips[skip].start) {
304 ri = BT848_RISC_WRITE;
305 end = skips[skip].start;
306 } else {
307 ri = BT848_RISC_SKIP;
308 end = skips[skip].end;
309 skip++;
310 }
311 if (BT848_RISC_WRITE == ri)
312 ra = addr + (fmt->depth>>3)*start;
313 else
314 ra = 0;
315
316 if (0 == start)
317 ri |= BT848_RISC_SOL;
318 if (ov->w.width == end)
319 ri |= BT848_RISC_EOL;
320 ri |= (fmt->depth>>3) * (end-start);
321
322 *(rp++)=cpu_to_le32(ri);
323 if (0 != ra)
324 *(rp++)=cpu_to_le32(ra);
325 }
326 }
327
328
329 risc->jmp = rp;
330 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
331 kfree(skips);
332 return 0;
333}
334
335
336
337static void
338bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
339 int width, int height, int interleaved,
340 const struct bttv_tvnorm *tvnorm)
341{
342 u32 xsf, sr;
343 int vdelay;
344
345 int swidth = tvnorm->swidth;
346 int totalwidth = tvnorm->totalwidth;
347 int scaledtwidth = tvnorm->scaledtwidth;
348
349 if (btv->input == btv->dig) {
350 swidth = 720;
351 totalwidth = 858;
352 scaledtwidth = 858;
353 }
354
355 vdelay = tvnorm->vdelay;
356
357 xsf = (width*scaledtwidth)/swidth;
358 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
359 geo->hdelay = tvnorm->hdelayx1;
360 geo->hdelay = (geo->hdelay*width)/swidth;
361 geo->hdelay &= 0x3fe;
362 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
363 geo->vscale = (0x10000UL-sr) & 0x1fff;
364 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
365 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
366 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
367 geo->vdelay = vdelay;
368 geo->width = width;
369 geo->sheight = tvnorm->sheight;
370 geo->vtotal = tvnorm->vtotal;
371
372 if (btv->opt_combfilter) {
373 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
374 geo->comb = (width < 769) ? 1 : 0;
375 } else {
376 geo->vtc = 0;
377 geo->comb = 0;
378 }
379}
380
381static void
382bttv_calc_geo (struct bttv * btv,
383 struct bttv_geometry * geo,
384 unsigned int width,
385 unsigned int height,
386 int both_fields,
387 const struct bttv_tvnorm * tvnorm,
388 const struct v4l2_rect * crop)
389{
390 unsigned int c_width;
391 unsigned int c_height;
392 u32 sr;
393
394 if ((crop->left == tvnorm->cropcap.defrect.left
395 && crop->top == tvnorm->cropcap.defrect.top
396 && crop->width == tvnorm->cropcap.defrect.width
397 && crop->height == tvnorm->cropcap.defrect.height
398 && width <= tvnorm->swidth )
399 || btv->input == btv->dig) {
400 bttv_calc_geo_old(btv, geo, width, height,
401 both_fields, tvnorm);
402 return;
403 }
404
405
406
407 c_width = min((unsigned int) crop->width, width * 16);
408 c_height = min((unsigned int) crop->height, height * 16);
409
410 geo->width = width;
411 geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
412
413 geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
414
415 geo->sheight = c_height;
416 geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
417 sr = c_height >> !both_fields;
418 sr = (sr * 512U + (height >> 1)) / height - 512;
419 geo->vscale = (0x10000UL - sr) & 0x1fff;
420 geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
421 geo->vtotal = tvnorm->vtotal;
422
423 geo->crop = (((geo->width >> 8) & 0x03) |
424 ((geo->hdelay >> 6) & 0x0c) |
425 ((geo->sheight >> 4) & 0x30) |
426 ((geo->vdelay >> 2) & 0xc0));
427
428 if (btv->opt_combfilter) {
429 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
430 geo->comb = (width < 769) ? 1 : 0;
431 } else {
432 geo->vtc = 0;
433 geo->comb = 0;
434 }
435}
436
437static void
438bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
439{
440 int off = odd ? 0x80 : 0x00;
441
442 if (geo->comb)
443 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
444 else
445 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
446
447 btwrite(geo->vtc, BT848_E_VTC+off);
448 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
449 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
450 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
451 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
452 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
453 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
454 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
455 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
456 btwrite(geo->crop, BT848_E_CROP+off);
457 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
458 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
459}
460
461
462
463
464void
465bttv_set_dma(struct bttv *btv, int override)
466{
467 unsigned long cmd;
468 int capctl;
469
470 btv->cap_ctl = 0;
471 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
472 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
473 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
474
475 capctl = 0;
476 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00;
477 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00;
478 capctl |= override;
479
480 d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n",
481 btv->c.nr,capctl,btv->loop_irq,
482 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
483 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
484 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
485 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
486
487 cmd = BT848_RISC_JUMP;
488 if (btv->loop_irq) {
489 cmd |= BT848_RISC_IRQ;
490 cmd |= (btv->loop_irq & 0x0f) << 16;
491 cmd |= (~btv->loop_irq & 0x0f) << 20;
492 }
493 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
494 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
495 } else {
496 del_timer(&btv->timeout);
497 }
498 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
499
500 btaor(capctl, ~0x0f, BT848_CAP_CTL);
501 if (capctl) {
502 if (btv->dma_on)
503 return;
504 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
505 btor(3, BT848_GPIO_DMA_CTL);
506 btv->dma_on = 1;
507 } else {
508 if (!btv->dma_on)
509 return;
510 btand(~3, BT848_GPIO_DMA_CTL);
511 btv->dma_on = 0;
512 }
513 return;
514}
515
516int
517bttv_risc_init_main(struct bttv *btv)
518{
519 int rc;
520
521 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
522 return rc;
523 dprintk("%d: risc main @ %08llx\n",
524 btv->c.nr, (unsigned long long)btv->main.dma);
525
526 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
527 BT848_FIFO_STATUS_VRE);
528 btv->main.cpu[1] = cpu_to_le32(0);
529 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
530 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
531
532
533 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
534 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
535 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
536 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
537
538 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
539 BT848_FIFO_STATUS_VRO);
540 btv->main.cpu[9] = cpu_to_le32(0);
541
542
543 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
544 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
545 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
546 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
547
548
549 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
550 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
551
552 return 0;
553}
554
555int
556bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
557 int irqflags)
558{
559 unsigned long cmd;
560 unsigned long next = btv->main.dma + ((slot+2) << 2);
561
562 if (NULL == risc) {
563 d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot);
564 btv->main.cpu[slot+1] = cpu_to_le32(next);
565 } else {
566 d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n",
567 btv->c.nr, risc, slot,
568 (unsigned long long)risc->dma, irqflags);
569 cmd = BT848_RISC_JUMP;
570 if (irqflags) {
571 cmd |= BT848_RISC_IRQ;
572 cmd |= (irqflags & 0x0f) << 16;
573 cmd |= (~irqflags & 0x0f) << 20;
574 }
575 risc->jmp[0] = cpu_to_le32(cmd);
576 risc->jmp[1] = cpu_to_le32(next);
577 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
578 }
579 return 0;
580}
581
582void
583bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
584{
585 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
586
587 BUG_ON(in_interrupt());
588 videobuf_waiton(q, &buf->vb, 0, 0);
589 videobuf_dma_unmap(q->dev, dma);
590 videobuf_dma_free(dma);
591 btcx_riscmem_free(btv->c.pci,&buf->bottom);
592 btcx_riscmem_free(btv->c.pci,&buf->top);
593 buf->vb.state = VIDEOBUF_NEEDS_INIT;
594}
595
596int
597bttv_buffer_activate_vbi(struct bttv *btv,
598 struct bttv_buffer *vbi)
599{
600 struct btcx_riscmem *top;
601 struct btcx_riscmem *bottom;
602 int top_irq_flags;
603 int bottom_irq_flags;
604
605 top = NULL;
606 bottom = NULL;
607 top_irq_flags = 0;
608 bottom_irq_flags = 0;
609
610 if (vbi) {
611 unsigned int crop, vdelay;
612
613 vbi->vb.state = VIDEOBUF_ACTIVE;
614 list_del(&vbi->vb.queue);
615
616
617 crop = btread(BT848_E_CROP);
618 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
619
620 if (vbi->geo.vdelay > vdelay) {
621 vdelay = vbi->geo.vdelay & 0xfe;
622 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
623
624 btwrite(vdelay, BT848_E_VDELAY_LO);
625 btwrite(crop, BT848_E_CROP);
626 btwrite(vdelay, BT848_O_VDELAY_LO);
627 btwrite(crop, BT848_O_CROP);
628 }
629
630 if (vbi->vbi_count[0] > 0) {
631 top = &vbi->top;
632 top_irq_flags = 4;
633 }
634
635 if (vbi->vbi_count[1] > 0) {
636 top_irq_flags = 0;
637 bottom = &vbi->bottom;
638 bottom_irq_flags = 4;
639 }
640 }
641
642 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
643 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
644
645 return 0;
646}
647
648int
649bttv_buffer_activate_video(struct bttv *btv,
650 struct bttv_buffer_set *set)
651{
652
653 if (NULL != set->top && NULL != set->bottom) {
654 if (set->top == set->bottom) {
655 set->top->vb.state = VIDEOBUF_ACTIVE;
656 if (set->top->vb.queue.next)
657 list_del(&set->top->vb.queue);
658 } else {
659 set->top->vb.state = VIDEOBUF_ACTIVE;
660 set->bottom->vb.state = VIDEOBUF_ACTIVE;
661 if (set->top->vb.queue.next)
662 list_del(&set->top->vb.queue);
663 if (set->bottom->vb.queue.next)
664 list_del(&set->bottom->vb.queue);
665 }
666 bttv_apply_geo(btv, &set->top->geo, 1);
667 bttv_apply_geo(btv, &set->bottom->geo,0);
668 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
669 set->top_irq);
670 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
671 set->frame_irq);
672 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
673 ~0xff, BT848_COLOR_FMT);
674 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
675 ~0x0f, BT848_COLOR_CTL);
676 } else if (NULL != set->top) {
677 set->top->vb.state = VIDEOBUF_ACTIVE;
678 if (set->top->vb.queue.next)
679 list_del(&set->top->vb.queue);
680 bttv_apply_geo(btv, &set->top->geo,1);
681 bttv_apply_geo(btv, &set->top->geo,0);
682 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
683 set->frame_irq);
684 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
685 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
686 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
687 } else if (NULL != set->bottom) {
688 set->bottom->vb.state = VIDEOBUF_ACTIVE;
689 if (set->bottom->vb.queue.next)
690 list_del(&set->bottom->vb.queue);
691 bttv_apply_geo(btv, &set->bottom->geo,1);
692 bttv_apply_geo(btv, &set->bottom->geo,0);
693 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
694 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
695 set->frame_irq);
696 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
697 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
698 } else {
699 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
700 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
701 }
702 return 0;
703}
704
705
706
707
708int
709bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
710{
711 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
712 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
713
714 dprintk("%d: buffer field: %s format: %s size: %dx%d\n",
715 btv->c.nr, v4l2_field_names[buf->vb.field],
716 buf->fmt->name, buf->vb.width, buf->vb.height);
717
718
719 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
720 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
721 int bpf = bpl * (buf->vb.height >> 1);
722
723 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
724 V4L2_FIELD_HAS_BOTH(buf->vb.field),
725 tvnorm,&buf->crop);
726
727 switch (buf->vb.field) {
728 case V4L2_FIELD_TOP:
729 bttv_risc_packed(btv,&buf->top,dma->sglist,
730 0,bpl,
731 0, 0,
732 buf->vb.height);
733 break;
734 case V4L2_FIELD_BOTTOM:
735 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
736 0,bpl,0,0,buf->vb.height);
737 break;
738 case V4L2_FIELD_INTERLACED:
739 bttv_risc_packed(btv,&buf->top,dma->sglist,
740 0,bpl,bpl,0,buf->vb.height >> 1);
741 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
742 bpl,bpl,bpl,0,buf->vb.height >> 1);
743 break;
744 case V4L2_FIELD_SEQ_TB:
745 bttv_risc_packed(btv,&buf->top,dma->sglist,
746 0,bpl,0,0,buf->vb.height >> 1);
747 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
748 bpf,bpl,0,0,buf->vb.height >> 1);
749 break;
750 default:
751 BUG();
752 }
753 }
754
755
756 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
757 int uoffset, voffset;
758 int ypadding, cpadding, lines;
759
760
761 uoffset = buf->vb.width * buf->vb.height;
762 voffset = buf->vb.width * buf->vb.height;
763 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
764
765 uoffset >>= buf->fmt->hshift;
766 uoffset >>= buf->fmt->vshift;
767 uoffset += voffset;
768 } else {
769
770 voffset >>= buf->fmt->hshift;
771 voffset >>= buf->fmt->vshift;
772 voffset += uoffset;
773 }
774
775 switch (buf->vb.field) {
776 case V4L2_FIELD_TOP:
777 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
778 buf->vb.height, 0,
779 tvnorm,&buf->crop);
780 bttv_risc_planar(btv, &buf->top, dma->sglist,
781 0,buf->vb.width,0,buf->vb.height,
782 uoffset,voffset,buf->fmt->hshift,
783 buf->fmt->vshift,0);
784 break;
785 case V4L2_FIELD_BOTTOM:
786 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
787 buf->vb.height,0,
788 tvnorm,&buf->crop);
789 bttv_risc_planar(btv, &buf->bottom, dma->sglist,
790 0,buf->vb.width,0,buf->vb.height,
791 uoffset,voffset,buf->fmt->hshift,
792 buf->fmt->vshift,0);
793 break;
794 case V4L2_FIELD_INTERLACED:
795 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
796 buf->vb.height,1,
797 tvnorm,&buf->crop);
798 lines = buf->vb.height >> 1;
799 ypadding = buf->vb.width;
800 cpadding = buf->vb.width >> buf->fmt->hshift;
801 bttv_risc_planar(btv,&buf->top,
802 dma->sglist,
803 0,buf->vb.width,ypadding,lines,
804 uoffset,voffset,
805 buf->fmt->hshift,
806 buf->fmt->vshift,
807 cpadding);
808 bttv_risc_planar(btv,&buf->bottom,
809 dma->sglist,
810 ypadding,buf->vb.width,ypadding,lines,
811 uoffset+cpadding,
812 voffset+cpadding,
813 buf->fmt->hshift,
814 buf->fmt->vshift,
815 cpadding);
816 break;
817 case V4L2_FIELD_SEQ_TB:
818 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
819 buf->vb.height,1,
820 tvnorm,&buf->crop);
821 lines = buf->vb.height >> 1;
822 ypadding = buf->vb.width;
823 cpadding = buf->vb.width >> buf->fmt->hshift;
824 bttv_risc_planar(btv,&buf->top,
825 dma->sglist,
826 0,buf->vb.width,0,lines,
827 uoffset >> 1,
828 voffset >> 1,
829 buf->fmt->hshift,
830 buf->fmt->vshift,
831 0);
832 bttv_risc_planar(btv,&buf->bottom,
833 dma->sglist,
834 lines * ypadding,buf->vb.width,0,lines,
835 lines * ypadding + (uoffset >> 1),
836 lines * ypadding + (voffset >> 1),
837 buf->fmt->hshift,
838 buf->fmt->vshift,
839 0);
840 break;
841 default:
842 BUG();
843 }
844 }
845
846
847 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
848
849 buf->vb.field = V4L2_FIELD_SEQ_TB;
850 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
851 1,tvnorm,&buf->crop);
852 bttv_risc_packed(btv, &buf->top, dma->sglist,
853 0, RAW_BPL, 0,
854 0, RAW_LINES);
855 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
856 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
857 }
858
859
860 buf->btformat = buf->fmt->btformat;
861 buf->btswap = buf->fmt->btswap;
862 return 0;
863}
864
865
866
867
868int
869bttv_overlay_risc(struct bttv *btv,
870 struct bttv_overlay *ov,
871 const struct bttv_format *fmt,
872 struct bttv_buffer *buf)
873{
874
875 dprintk("%d: overlay fields: %s format: %s size: %dx%d\n",
876 btv->c.nr, v4l2_field_names[buf->vb.field],
877 fmt->name, ov->w.width, ov->w.height);
878
879
880 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
881 V4L2_FIELD_HAS_BOTH(ov->field),
882 &bttv_tvnorms[ov->tvnorm],&buf->crop);
883
884
885 switch (ov->field) {
886 case V4L2_FIELD_TOP:
887 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
888 break;
889 case V4L2_FIELD_BOTTOM:
890 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
891 break;
892 case V4L2_FIELD_INTERLACED:
893 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
894 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
895 break;
896 default:
897 BUG();
898 }
899
900
901 buf->btformat = fmt->btformat;
902 buf->btswap = fmt->btswap;
903 buf->vb.field = ov->field;
904 return 0;
905}
906