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 instructions,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 (clip+1) * lines instructions
246 + sync + jump (all 2 dwords) */
247 instructions = (ov->nclips + 1) *
248 ((skip_even || skip_odd) ? ov->w.height>>1 : ov->w.height);
250 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*8)) < 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);
282 /* write out risc code */
283 for (start = 0, skip = 0; start < ov->w.width; start = end) {
284 if (skip >= nskips) {
285 ri = BT848_RISC_WRITE;
287 } else if (start < skips[skip].start) {
288 ri = BT848_RISC_WRITE;
289 end = skips[skip].start;
291 ri = BT848_RISC_SKIP;
292 end = skips[skip].end;
295 if (BT848_RISC_WRITE == ri)
296 ra = addr + (fmt->depth>>3)*start;
301 ri |= BT848_RISC_SOL;
302 if (ov->w.width == end)
303 ri |= BT848_RISC_EOL;
304 ri |= (fmt->depth>>3) * (end-start);
306 *(rp++)=cpu_to_le32(ri);
308 *(rp++)=cpu_to_le32(ra);
312 /* save pointer to jmp instruction address */
314 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
319 /* ---------------------------------------------------------- */
322 bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
323 int width, int height, int interleaved, int norm)
325 const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
329 int swidth = tvnorm->swidth;
330 int totalwidth = tvnorm->totalwidth;
331 int scaledtwidth = tvnorm->scaledtwidth;
333 if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
339 vdelay = tvnorm->vdelay;
341 xsf = (width*scaledtwidth)/swidth;
342 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
343 geo->hdelay = tvnorm->hdelayx1;
344 geo->hdelay = (geo->hdelay*width)/swidth;
345 geo->hdelay &= 0x3fe;
346 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
347 geo->vscale = (0x10000UL-sr) & 0x1fff;
348 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
349 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
350 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
351 geo->vdelay = vdelay;
353 geo->sheight = tvnorm->sheight;
354 geo->vtotal = tvnorm->vtotal;
356 if (btv->opt_combfilter) {
357 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
358 geo->comb = (width < 769) ? 1 : 0;
366 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
368 int off = odd ? 0x80 : 0x00;
371 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
373 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
375 btwrite(geo->vtc, BT848_E_VTC+off);
376 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
377 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
378 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
379 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
380 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
381 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
382 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
383 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
384 btwrite(geo->crop, BT848_E_CROP+off);
385 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
386 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
389 /* ---------------------------------------------------------- */
390 /* risc group / risc main loop / dma management */
393 bttv_set_dma(struct bttv *btv, int override)
399 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
400 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
401 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
404 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
405 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
409 "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
410 btv->c.nr,capctl,btv->loop_irq,
411 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
412 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
413 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
414 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
416 cmd = BT848_RISC_JUMP;
418 cmd |= BT848_RISC_IRQ;
419 cmd |= (btv->loop_irq & 0x0f) << 16;
420 cmd |= (~btv->loop_irq & 0x0f) << 20;
422 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
423 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
425 del_timer(&btv->timeout);
427 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
429 btaor(capctl, ~0x0f, BT848_CAP_CTL);
433 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
434 btor(3, BT848_GPIO_DMA_CTL);
439 btand(~3, BT848_GPIO_DMA_CTL);
446 bttv_risc_init_main(struct bttv *btv)
450 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
452 dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
453 btv->c.nr,(unsigned long long)btv->main.dma);
455 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
456 BT848_FIFO_STATUS_VRE);
457 btv->main.cpu[1] = cpu_to_le32(0);
458 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
459 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
462 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
463 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
464 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
465 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
467 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
468 BT848_FIFO_STATUS_VRO);
469 btv->main.cpu[9] = cpu_to_le32(0);
472 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
473 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
474 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
475 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
477 /* jump back to top field */
478 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
479 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
485 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
489 unsigned long next = btv->main.dma + ((slot+2) << 2);
492 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
493 btv->c.nr,risc,slot);
494 btv->main.cpu[slot+1] = cpu_to_le32(next);
496 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
497 btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
498 cmd = BT848_RISC_JUMP;
500 cmd |= BT848_RISC_IRQ;
501 cmd |= (irqflags & 0x0f) << 16;
502 cmd |= (~irqflags & 0x0f) << 20;
504 risc->jmp[0] = cpu_to_le32(cmd);
505 risc->jmp[1] = cpu_to_le32(next);
506 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
512 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
514 BUG_ON(in_interrupt());
515 videobuf_waiton(&buf->vb,0,0);
516 videobuf_dma_unmap(q, &buf->vb.dma);
517 videobuf_dma_free(&buf->vb.dma);
518 btcx_riscmem_free(btv->c.pci,&buf->bottom);
519 btcx_riscmem_free(btv->c.pci,&buf->top);
520 buf->vb.state = STATE_NEEDS_INIT;
524 bttv_buffer_activate_vbi(struct bttv *btv,
525 struct bttv_buffer *vbi)
529 vbi->vb.state = STATE_ACTIVE;
530 list_del(&vbi->vb.queue);
531 bttv_risc_hook(btv, RISC_SLOT_O_VBI, &vbi->top, 0);
532 bttv_risc_hook(btv, RISC_SLOT_E_VBI, &vbi->bottom, 4);
534 bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
535 bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
541 bttv_buffer_activate_video(struct bttv *btv,
542 struct bttv_buffer_set *set)
545 if (NULL != set->top && NULL != set->bottom) {
546 if (set->top == set->bottom) {
547 set->top->vb.state = STATE_ACTIVE;
548 if (set->top->vb.queue.next)
549 list_del(&set->top->vb.queue);
551 set->top->vb.state = STATE_ACTIVE;
552 set->bottom->vb.state = STATE_ACTIVE;
553 if (set->top->vb.queue.next)
554 list_del(&set->top->vb.queue);
555 if (set->bottom->vb.queue.next)
556 list_del(&set->bottom->vb.queue);
558 bttv_apply_geo(btv, &set->top->geo, 1);
559 bttv_apply_geo(btv, &set->bottom->geo,0);
560 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
562 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
564 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
565 ~0xff, BT848_COLOR_FMT);
566 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
567 ~0x0f, BT848_COLOR_CTL);
568 } else if (NULL != set->top) {
569 set->top->vb.state = STATE_ACTIVE;
570 if (set->top->vb.queue.next)
571 list_del(&set->top->vb.queue);
572 bttv_apply_geo(btv, &set->top->geo,1);
573 bttv_apply_geo(btv, &set->top->geo,0);
574 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
576 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
577 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
578 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
579 } else if (NULL != set->bottom) {
580 set->bottom->vb.state = STATE_ACTIVE;
581 if (set->bottom->vb.queue.next)
582 list_del(&set->bottom->vb.queue);
583 bttv_apply_geo(btv, &set->bottom->geo,1);
584 bttv_apply_geo(btv, &set->bottom->geo,0);
585 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
586 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
588 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
589 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
591 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
592 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
597 /* ---------------------------------------------------------- */
599 /* calculate geometry, build risc code */
601 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
603 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
606 "bttv%d: buffer field: %s format: %s size: %dx%d\n",
607 btv->c.nr, v4l2_field_names[buf->vb.field],
608 buf->fmt->name, buf->vb.width, buf->vb.height);
610 /* packed pixel modes */
611 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
612 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
613 int bpf = bpl * (buf->vb.height >> 1);
615 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
616 V4L2_FIELD_HAS_BOTH(buf->vb.field),buf->tvnorm);
618 switch (buf->vb.field) {
620 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
621 0,bpl,0,buf->vb.height);
623 case V4L2_FIELD_BOTTOM:
624 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
625 0,bpl,0,buf->vb.height);
627 case V4L2_FIELD_INTERLACED:
628 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
629 0,bpl,bpl,buf->vb.height >> 1);
630 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
631 bpl,bpl,bpl,buf->vb.height >> 1);
633 case V4L2_FIELD_SEQ_TB:
634 bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
635 0,bpl,0,buf->vb.height >> 1);
636 bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
637 bpf,bpl,0,buf->vb.height >> 1);
645 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
646 int uoffset, voffset;
647 int ypadding, cpadding, lines;
649 /* calculate chroma offsets */
650 uoffset = buf->vb.width * buf->vb.height;
651 voffset = buf->vb.width * buf->vb.height;
652 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
653 /* Y-Cr-Cb plane order */
654 uoffset >>= buf->fmt->hshift;
655 uoffset >>= buf->fmt->vshift;
658 /* Y-Cb-Cr plane order */
659 voffset >>= buf->fmt->hshift;
660 voffset >>= buf->fmt->vshift;
664 switch (buf->vb.field) {
666 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
667 buf->vb.height,0,buf->tvnorm);
668 bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist,
669 0,buf->vb.width,0,buf->vb.height,
670 uoffset,voffset,buf->fmt->hshift,
673 case V4L2_FIELD_BOTTOM:
674 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
675 buf->vb.height,0,buf->tvnorm);
676 bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist,
677 0,buf->vb.width,0,buf->vb.height,
678 uoffset,voffset,buf->fmt->hshift,
681 case V4L2_FIELD_INTERLACED:
682 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
683 buf->vb.height,1,buf->tvnorm);
684 lines = buf->vb.height >> 1;
685 ypadding = buf->vb.width;
686 cpadding = buf->vb.width >> buf->fmt->hshift;
687 bttv_risc_planar(btv,&buf->top,
689 0,buf->vb.width,ypadding,lines,
694 bttv_risc_planar(btv,&buf->bottom,
696 ypadding,buf->vb.width,ypadding,lines,
703 case V4L2_FIELD_SEQ_TB:
704 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
705 buf->vb.height,1,buf->tvnorm);
706 lines = buf->vb.height >> 1;
707 ypadding = buf->vb.width;
708 cpadding = buf->vb.width >> buf->fmt->hshift;
709 bttv_risc_planar(btv,&buf->top,
711 0,buf->vb.width,0,lines,
717 bttv_risc_planar(btv,&buf->bottom,
719 lines * ypadding,buf->vb.width,0,lines,
720 lines * ypadding + (uoffset >> 1),
721 lines * ypadding + (voffset >> 1),
732 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
733 /* build risc code */
734 buf->vb.field = V4L2_FIELD_SEQ_TB;
735 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
737 bttv_risc_packed(btv, &buf->top, buf->vb.dma.sglist,
738 0, RAW_BPL, 0, RAW_LINES);
739 bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
740 buf->vb.size/2 , RAW_BPL, 0, RAW_LINES);
743 /* copy format info */
744 buf->btformat = buf->fmt->btformat;
745 buf->btswap = buf->fmt->btswap;
749 /* ---------------------------------------------------------- */
751 /* calculate geometry, build risc code */
753 bttv_overlay_risc(struct bttv *btv,
754 struct bttv_overlay *ov,
755 const struct bttv_format *fmt,
756 struct bttv_buffer *buf)
758 /* check interleave, bottom+top fields */
760 "bttv%d: overlay fields: %s format: %s size: %dx%d\n",
761 btv->c.nr, v4l2_field_names[buf->vb.field],
762 fmt->name,ov->w.width,ov->w.height);
764 /* calculate geometry */
765 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
766 V4L2_FIELD_HAS_BOTH(ov->field), ov->tvnorm);
768 /* build risc code */
771 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
773 case V4L2_FIELD_BOTTOM:
774 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
776 case V4L2_FIELD_INTERLACED:
777 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
778 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
784 /* copy format info */
785 buf->btformat = fmt->btformat;
786 buf->btswap = fmt->btswap;
787 buf->vb.field = ov->field;