3 bttv-risc.c -- interfaces to other kernel modules
5 bttv risc code handling
9 (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/pci.h>
30 #include <linux/vmalloc.h>
31 #include <linux/interrupt.h>
33 #include <asm/pgtable.h>
37 #define VCR_HACK_LINES 4
39 /* ---------------------------------------------------------- */
40 /* risc code generators */
43 bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
44 struct scatterlist *sglist,
45 unsigned int offset, unsigned int bpl,
46 unsigned int padding, unsigned int lines)
48 u32 instructions,line,todo;
49 struct scatterlist *sg;
53 /* estimate risc mem: worst case is one write per page border +
54 one write per scan line + sync + jump (all 2 dwords). padding
55 can cause next bpl to start close to a page border. First DMA
56 region may be smaller than PAGE_SIZE */
57 instructions = 1 + ((bpl + padding) * lines) / PAGE_SIZE + lines;
59 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 0)
62 /* sync instruction */
64 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
65 *(rp++) = cpu_to_le32(0);
69 for (line = 0; line < lines; line++) {
70 if ((btv->opt_vcr_hack) &&
71 (line >= (lines - VCR_HACK_LINES)))
73 while (offset && offset >= sg_dma_len(sg)) {
74 offset -= sg_dma_len(sg);
77 if (bpl <= sg_dma_len(sg)-offset) {
78 /* fits into current chunk */
79 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
81 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
84 /* scanline needs to be splitted */
86 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
87 (sg_dma_len(sg)-offset));
88 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
89 todo -= (sg_dma_len(sg)-offset);
92 while (todo > sg_dma_len(sg)) {
93 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
95 *(rp++)=cpu_to_le32(sg_dma_address(sg));
96 todo -= sg_dma_len(sg);
99 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
101 *(rp++)=cpu_to_le32(sg_dma_address(sg));
107 /* save pointer to jmp instruction address */
109 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
114 bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
115 struct scatterlist *sglist,
116 unsigned int yoffset, unsigned int ybpl,
117 unsigned int ypadding, unsigned int ylines,
118 unsigned int uoffset, unsigned int voffset,
119 unsigned int hshift, unsigned int vshift,
120 unsigned int cpadding)
122 unsigned int instructions,line,todo,ylen,chroma;
124 struct scatterlist *ysg;
125 struct scatterlist *usg;
126 struct scatterlist *vsg;
127 int topfield = (0 == yoffset);
130 /* estimate risc mem: worst case is one write per page border +
131 one write per scan line (5 dwords)
132 plus sync + jump (2 dwords) */
133 instructions = (ybpl * ylines * 2) / PAGE_SIZE + ylines;
135 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
138 /* sync instruction */
140 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
141 *(rp++) = cpu_to_le32(0);
147 for (line = 0; line < ylines; line++) {
148 if ((btv->opt_vcr_hack) &&
149 (line >= (ylines - VCR_HACK_LINES)))
157 chroma = ((line & 1) == 0);
159 chroma = ((line & 1) == 1);
163 chroma = ((line & 3) == 0);
165 chroma = ((line & 3) == 2);
172 for (todo = ybpl; todo > 0; todo -= ylen) {
173 /* go to next sg entry if needed */
174 while (yoffset && yoffset >= sg_dma_len(ysg)) {
175 yoffset -= sg_dma_len(ysg);
178 while (uoffset && uoffset >= sg_dma_len(usg)) {
179 uoffset -= sg_dma_len(usg);
182 while (voffset && voffset >= sg_dma_len(vsg)) {
183 voffset -= sg_dma_len(vsg);
187 /* calculate max number of bytes we can write */
189 if (yoffset + ylen > sg_dma_len(ysg))
190 ylen = sg_dma_len(ysg) - yoffset;
192 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
193 ylen = (sg_dma_len(usg) - uoffset) << hshift;
194 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
195 ylen = (sg_dma_len(vsg) - voffset) << hshift;
196 ri = BT848_RISC_WRITE123;
198 ri = BT848_RISC_WRITE1S23;
201 ri |= BT848_RISC_SOL;
203 ri |= BT848_RISC_EOL;
205 /* write risc instruction */
206 *(rp++)=cpu_to_le32(ri | ylen);
207 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
209 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
212 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
213 uoffset += ylen >> hshift;
214 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
215 voffset += ylen >> hshift;
225 /* save pointer to jmp instruction address */
227 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
232 bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
233 const struct bttv_format *fmt, struct bttv_overlay *ov,
234 int skip_even, int skip_odd)
236 int dwords,rc,line,maxy,start,end,skip,nskips;
237 struct btcx_skiplist *skips;
241 /* skip list for window clipping */
242 if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
245 /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
246 + sync + jump (all 2 dwords) */
247 dwords = (3 * ov->nclips + 2) *
248 ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
250 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
255 /* sync instruction */
257 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
258 *(rp++) = cpu_to_le32(0);
260 addr = (unsigned long)btv->fbuf.base;
261 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
262 addr += (fmt->depth >> 3) * ov->w.left;
265 for (maxy = -1, line = 0; line < ov->w.height;
266 line++, addr += btv->fbuf.fmt.bytesperline) {
267 if ((btv->opt_vcr_hack) &&
268 (line >= (ov->w.height - VCR_HACK_LINES)))
270 if ((line%2) == 0 && skip_even)
272 if ((line%2) == 1 && skip_odd)
275 /* calculate clipping */
277 btcx_calc_skips(line, ov->w.width, &maxy,
278 skips, &nskips, ov->clips, ov->nclips);
280 /* write out risc code */
281 for (start = 0, skip = 0; start < ov->w.width; start = end) {
282 if (skip >= nskips) {
283 ri = BT848_RISC_WRITE;
285 } else if (start < skips[skip].start) {
286 ri = BT848_RISC_WRITE;
287 end = skips[skip].start;
289 ri = BT848_RISC_SKIP;
290 end = skips[skip].end;
293 if (BT848_RISC_WRITE == ri)
294 ra = addr + (fmt->depth>>3)*start;
299 ri |= BT848_RISC_SOL;
300 if (ov->w.width == end)
301 ri |= BT848_RISC_EOL;
302 ri |= (fmt->depth>>3) * (end-start);
304 *(rp++)=cpu_to_le32(ri);
306 *(rp++)=cpu_to_le32(ra);
310 /* save pointer to jmp instruction address */
312 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
317 /* ---------------------------------------------------------- */
320 bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
321 int width, int height, int interleaved, int norm)
323 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
327 int swidth = tvnorm->swidth;
328 int totalwidth = tvnorm->totalwidth;
329 int scaledtwidth = tvnorm->scaledtwidth;
331 if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
337 vdelay = tvnorm->vdelay;
339 xsf = (width*scaledtwidth)/swidth;
340 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
341 geo->hdelay = tvnorm->hdelayx1;
342 geo->hdelay = (geo->hdelay*width)/swidth;
343 geo->hdelay &= 0x3fe;
344 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
345 geo->vscale = (0x10000UL-sr) & 0x1fff;
346 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
347 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
348 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
349 geo->vdelay = vdelay;
351 geo->sheight = tvnorm->sheight;
352 geo->vtotal = tvnorm->vtotal;
354 if (btv->opt_combfilter) {
355 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
356 geo->comb = (width < 769) ? 1 : 0;
364 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
366 int off = odd ? 0x80 : 0x00;
369 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
371 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
373 btwrite(geo->vtc, BT848_E_VTC+off);
374 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
375 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
376 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
377 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
378 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
379 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
380 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
381 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
382 btwrite(geo->crop, BT848_E_CROP+off);
383 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
384 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
387 /* ---------------------------------------------------------- */
388 /* risc group / risc main loop / dma management */
391 bttv_set_dma(struct bttv *btv, int override)
397 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
398 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
399 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
402 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
403 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
407 "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
408 btv->c.nr,capctl,btv->loop_irq,
409 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
410 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
411 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
412 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
414 cmd = BT848_RISC_JUMP;
416 cmd |= BT848_RISC_IRQ;
417 cmd |= (btv->loop_irq & 0x0f) << 16;
418 cmd |= (~btv->loop_irq & 0x0f) << 20;
420 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
421 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
423 del_timer(&btv->timeout);
425 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
427 btaor(capctl, ~0x0f, BT848_CAP_CTL);
431 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
432 btor(3, BT848_GPIO_DMA_CTL);
437 btand(~3, BT848_GPIO_DMA_CTL);
444 bttv_risc_init_main(struct bttv *btv)
448 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
450 dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
451 btv->c.nr,(unsigned long long)btv->main.dma);
453 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
454 BT848_FIFO_STATUS_VRE);
455 btv->main.cpu[1] = cpu_to_le32(0);
456 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
457 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
460 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
461 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
462 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
463 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
465 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
466 BT848_FIFO_STATUS_VRO);
467 btv->main.cpu[9] = cpu_to_le32(0);
470 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
471 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
472 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
473 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
475 /* jump back to top field */
476 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
477 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
483 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
487 unsigned long next = btv->main.dma + ((slot+2) << 2);
490 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
491 btv->c.nr,risc,slot);
492 btv->main.cpu[slot+1] = cpu_to_le32(next);
494 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
495 btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
496 cmd = BT848_RISC_JUMP;
498 cmd |= BT848_RISC_IRQ;
499 cmd |= (irqflags & 0x0f) << 16;
500 cmd |= (~irqflags & 0x0f) << 20;
502 risc->jmp[0] = cpu_to_le32(cmd);
503 risc->jmp[1] = cpu_to_le32(next);
504 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
510 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
512 BUG_ON(in_interrupt());
513 videobuf_waiton(&buf->vb,0,0);
514 videobuf_dma_unmap(q, &buf->vb.dma);
515 videobuf_dma_free(&buf->vb.dma);
516 btcx_riscmem_free(btv->c.pci,&buf->bottom);
517 btcx_riscmem_free(btv->c.pci,&buf->top);
518 buf->vb.state = STATE_NEEDS_INIT;
522 bttv_buffer_activate_vbi(struct bttv *btv,
523 struct bttv_buffer *vbi)
527 vbi->vb.state = STATE_ACTIVE;
528 list_del(&vbi->vb.queue);
529 bttv_risc_hook(btv, RISC_SLOT_O_VBI, &vbi->top, 0);
530 bttv_risc_hook(btv, RISC_SLOT_E_VBI, &vbi->bottom, 4);
532 bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
533 bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
539 bttv_buffer_activate_video(struct bttv *btv,
540 struct bttv_buffer_set *set)
543 if (NULL != set->top && NULL != set->bottom) {
544 if (set->top == set->bottom) {
545 set->top->vb.state = STATE_ACTIVE;
546 if (set->top->vb.queue.next)
547 list_del(&set->top->vb.queue);
549 set->top->vb.state = STATE_ACTIVE;
550 set->bottom->vb.state = STATE_ACTIVE;
551 if (set->top->vb.queue.next)
552 list_del(&set->top->vb.queue);
553 if (set->bottom->vb.queue.next)
554 list_del(&set->bottom->vb.queue);
556 bttv_apply_geo(btv, &set->top->geo, 1);
557 bttv_apply_geo(btv, &set->bottom->geo,0);
558 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
560 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
562 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
563 ~0xff, BT848_COLOR_FMT);
564 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
565 ~0x0f, BT848_COLOR_CTL);
566 } else if (NULL != set->top) {
567 set->top->vb.state = STATE_ACTIVE;
568 if (set->top->vb.queue.next)
569 list_del(&set->top->vb.queue);
570 bttv_apply_geo(btv, &set->top->geo,1);
571 bttv_apply_geo(btv, &set->top->geo,0);
572 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
574 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
575 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
576 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
577 } else if (NULL != set->bottom) {
578 set->bottom->vb.state = STATE_ACTIVE;
579 if (set->bottom->vb.queue.next)
580 list_del(&set->bottom->vb.queue);
581 bttv_apply_geo(btv, &set->bottom->geo,1);
582 bttv_apply_geo(btv, &set->bottom->geo,0);
583 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
584 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
586 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
587 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
589 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
590 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
595 /* ---------------------------------------------------------- */
597 /* calculate geometry, build risc code */
599 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
601 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
604 "bttv%d: buffer field: %s format: %s size: %dx%d\n",
605 btv->c.nr, v4l2_field_names[buf->vb.field],
606 buf->fmt->name, buf->vb.width, buf->vb.height);
608 /* packed pixel modes */
609 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
610 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
611 int bpf = bpl * (buf->vb.height >> 1);
613 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
614 V4L2_FIELD_HAS_BOTH(buf->vb.field),buf->tvnorm);
616 switch (buf->vb.field) {
618 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
619 0,bpl,0,buf->vb.height);
621 case V4L2_FIELD_BOTTOM:
622 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
623 0,bpl,0,buf->vb.height);
625 case V4L2_FIELD_INTERLACED:
626 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
627 0,bpl,bpl,buf->vb.height >> 1);
628 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
629 bpl,bpl,bpl,buf->vb.height >> 1);
631 case V4L2_FIELD_SEQ_TB:
632 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
633 0,bpl,0,buf->vb.height >> 1);
634 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
635 bpf,bpl,0,buf->vb.height >> 1);
643 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
644 int uoffset, voffset;
645 int ypadding, cpadding, lines;
647 /* calculate chroma offsets */
648 uoffset = buf->vb.width * buf->vb.height;
649 voffset = buf->vb.width * buf->vb.height;
650 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
651 /* Y-Cr-Cb plane order */
652 uoffset >>= buf->fmt->hshift;
653 uoffset >>= buf->fmt->vshift;
656 /* Y-Cb-Cr plane order */
657 voffset >>= buf->fmt->hshift;
658 voffset >>= buf->fmt->vshift;
662 switch (buf->vb.field) {
664 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
665 buf->vb.height,0,buf->tvnorm);
666 bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist,
667 0,buf->vb.width,0,buf->vb.height,
668 uoffset,voffset,buf->fmt->hshift,
671 case V4L2_FIELD_BOTTOM:
672 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
673 buf->vb.height,0,buf->tvnorm);
674 bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist,
675 0,buf->vb.width,0,buf->vb.height,
676 uoffset,voffset,buf->fmt->hshift,
679 case V4L2_FIELD_INTERLACED:
680 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
681 buf->vb.height,1,buf->tvnorm);
682 lines = buf->vb.height >> 1;
683 ypadding = buf->vb.width;
684 cpadding = buf->vb.width >> buf->fmt->hshift;
685 bttv_risc_planar(btv,&buf->top,
687 0,buf->vb.width,ypadding,lines,
692 bttv_risc_planar(btv,&buf->bottom,
694 ypadding,buf->vb.width,ypadding,lines,
701 case V4L2_FIELD_SEQ_TB:
702 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
703 buf->vb.height,1,buf->tvnorm);
704 lines = buf->vb.height >> 1;
705 ypadding = buf->vb.width;
706 cpadding = buf->vb.width >> buf->fmt->hshift;
707 bttv_risc_planar(btv,&buf->top,
709 0,buf->vb.width,0,lines,
715 bttv_risc_planar(btv,&buf->bottom,
717 lines * ypadding,buf->vb.width,0,lines,
718 lines * ypadding + (uoffset >> 1),
719 lines * ypadding + (voffset >> 1),
730 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
731 /* build risc code */
732 buf->vb.field = V4L2_FIELD_SEQ_TB;
733 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
735 bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
736 0, RAW_BPL, 0, RAW_LINES);
737 bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
738 buf->vb.size/2 , RAW_BPL, 0, RAW_LINES);
741 /* copy format info */
742 buf->btformat = buf->fmt->btformat;
743 buf->btswap = buf->fmt->btswap;
747 /* ---------------------------------------------------------- */
749 /* calculate geometry, build risc code */
751 bttv_overlay_risc(struct bttv *btv,
752 struct bttv_overlay *ov,
753 const struct bttv_format *fmt,
754 struct bttv_buffer *buf)
756 /* check interleave, bottom+top fields */
758 "bttv%d: overlay fields: %s format: %s size: %dx%d\n",
759 btv->c.nr, v4l2_field_names[buf->vb.field],
760 fmt->name,ov->w.width,ov->w.height);
762 /* calculate geometry */
763 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
764 V4L2_FIELD_HAS_BOTH(ov->field), ov->tvnorm);
766 /* build risc code */
769 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
771 case V4L2_FIELD_BOTTOM:
772 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
774 case V4L2_FIELD_INTERLACED:
775 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
776 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
782 /* copy format info */
783 buf->btformat = fmt->btformat;
784 buf->btswap = fmt->btswap;
785 buf->vb.field = ov->field;