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 skip_lines,
47 unsigned int store_lines)
49 u32 instructions,line,todo;
50 struct scatterlist *sg;
54 /* estimate risc mem: worst case is one write per page border +
55 one write per scan line + sync + jump (all 2 dwords). padding
56 can cause next bpl to start close to a page border. First DMA
57 region may be smaller than PAGE_SIZE */
58 instructions = skip_lines * 4;
59 instructions += (1 + ((bpl + padding) * store_lines)
60 / PAGE_SIZE + store_lines) * 8;
61 instructions += 2 * 8;
62 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions)) < 0)
65 /* sync instruction */
67 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
68 *(rp++) = cpu_to_le32(0);
70 while (skip_lines-- > 0) {
71 *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
72 BT848_RISC_EOL | bpl);
77 for (line = 0; line < store_lines; line++) {
78 if ((btv->opt_vcr_hack) &&
79 (line >= (store_lines - VCR_HACK_LINES)))
81 while (offset && offset >= sg_dma_len(sg)) {
82 offset -= sg_dma_len(sg);
85 if (bpl <= sg_dma_len(sg)-offset) {
86 /* fits into current chunk */
87 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
89 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
92 /* scanline needs to be splitted */
94 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
95 (sg_dma_len(sg)-offset));
96 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
97 todo -= (sg_dma_len(sg)-offset);
100 while (todo > sg_dma_len(sg)) {
101 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
103 *(rp++)=cpu_to_le32(sg_dma_address(sg));
104 todo -= sg_dma_len(sg);
107 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
109 *(rp++)=cpu_to_le32(sg_dma_address(sg));
115 /* save pointer to jmp instruction address */
117 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
122 bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
123 struct scatterlist *sglist,
124 unsigned int yoffset, unsigned int ybpl,
125 unsigned int ypadding, unsigned int ylines,
126 unsigned int uoffset, unsigned int voffset,
127 unsigned int hshift, unsigned int vshift,
128 unsigned int cpadding)
130 unsigned int instructions,line,todo,ylen,chroma;
132 struct scatterlist *ysg;
133 struct scatterlist *usg;
134 struct scatterlist *vsg;
135 int topfield = (0 == yoffset);
138 /* estimate risc mem: worst case is one write per page border +
139 one write per scan line (5 dwords)
140 plus sync + jump (2 dwords) */
141 instructions = ((3 + (ybpl + ypadding) * ylines * 2)
142 / PAGE_SIZE) + ylines;
144 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
147 /* sync instruction */
149 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
150 *(rp++) = cpu_to_le32(0);
156 for (line = 0; line < ylines; line++) {
157 if ((btv->opt_vcr_hack) &&
158 (line >= (ylines - VCR_HACK_LINES)))
166 chroma = ((line & 1) == 0);
168 chroma = ((line & 1) == 1);
172 chroma = ((line & 3) == 0);
174 chroma = ((line & 3) == 2);
181 for (todo = ybpl; todo > 0; todo -= ylen) {
182 /* go to next sg entry if needed */
183 while (yoffset && yoffset >= sg_dma_len(ysg)) {
184 yoffset -= sg_dma_len(ysg);
187 while (uoffset && uoffset >= sg_dma_len(usg)) {
188 uoffset -= sg_dma_len(usg);
191 while (voffset && voffset >= sg_dma_len(vsg)) {
192 voffset -= sg_dma_len(vsg);
196 /* calculate max number of bytes we can write */
198 if (yoffset + ylen > sg_dma_len(ysg))
199 ylen = sg_dma_len(ysg) - yoffset;
201 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
202 ylen = (sg_dma_len(usg) - uoffset) << hshift;
203 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
204 ylen = (sg_dma_len(vsg) - voffset) << hshift;
205 ri = BT848_RISC_WRITE123;
207 ri = BT848_RISC_WRITE1S23;
210 ri |= BT848_RISC_SOL;
212 ri |= BT848_RISC_EOL;
214 /* write risc instruction */
215 *(rp++)=cpu_to_le32(ri | ylen);
216 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
218 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
221 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
222 uoffset += ylen >> hshift;
223 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
224 voffset += ylen >> hshift;
234 /* save pointer to jmp instruction address */
236 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
241 bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
242 const struct bttv_format *fmt, struct bttv_overlay *ov,
243 int skip_even, int skip_odd)
245 int dwords,rc,line,maxy,start,end,skip,nskips;
246 struct btcx_skiplist *skips;
250 /* skip list for window clipping */
251 if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
254 /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
255 + sync + jump (all 2 dwords) */
256 dwords = (3 * ov->nclips + 2) *
257 ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
259 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
264 /* sync instruction */
266 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
267 *(rp++) = cpu_to_le32(0);
269 addr = (unsigned long)btv->fbuf.base;
270 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
271 addr += (fmt->depth >> 3) * ov->w.left;
274 for (maxy = -1, line = 0; line < ov->w.height;
275 line++, addr += btv->fbuf.fmt.bytesperline) {
276 if ((btv->opt_vcr_hack) &&
277 (line >= (ov->w.height - VCR_HACK_LINES)))
279 if ((line%2) == 0 && skip_even)
281 if ((line%2) == 1 && skip_odd)
284 /* calculate clipping */
286 btcx_calc_skips(line, ov->w.width, &maxy,
287 skips, &nskips, ov->clips, ov->nclips);
289 /* write out risc code */
290 for (start = 0, skip = 0; start < ov->w.width; start = end) {
291 if (skip >= nskips) {
292 ri = BT848_RISC_WRITE;
294 } else if (start < skips[skip].start) {
295 ri = BT848_RISC_WRITE;
296 end = skips[skip].start;
298 ri = BT848_RISC_SKIP;
299 end = skips[skip].end;
302 if (BT848_RISC_WRITE == ri)
303 ra = addr + (fmt->depth>>3)*start;
308 ri |= BT848_RISC_SOL;
309 if (ov->w.width == end)
310 ri |= BT848_RISC_EOL;
311 ri |= (fmt->depth>>3) * (end-start);
313 *(rp++)=cpu_to_le32(ri);
315 *(rp++)=cpu_to_le32(ra);
319 /* save pointer to jmp instruction address */
321 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
326 /* ---------------------------------------------------------- */
329 bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
330 int width, int height, int interleaved,
331 const struct bttv_tvnorm *tvnorm)
336 int swidth = tvnorm->swidth;
337 int totalwidth = tvnorm->totalwidth;
338 int scaledtwidth = tvnorm->scaledtwidth;
340 if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
346 vdelay = tvnorm->vdelay;
348 xsf = (width*scaledtwidth)/swidth;
349 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
350 geo->hdelay = tvnorm->hdelayx1;
351 geo->hdelay = (geo->hdelay*width)/swidth;
352 geo->hdelay &= 0x3fe;
353 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
354 geo->vscale = (0x10000UL-sr) & 0x1fff;
355 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
356 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
357 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
358 geo->vdelay = vdelay;
360 geo->sheight = tvnorm->sheight;
361 geo->vtotal = tvnorm->vtotal;
363 if (btv->opt_combfilter) {
364 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
365 geo->comb = (width < 769) ? 1 : 0;
373 bttv_calc_geo (struct bttv * btv,
374 struct bttv_geometry * geo,
378 const struct bttv_tvnorm * tvnorm,
379 const struct v4l2_rect * crop)
381 unsigned int c_width;
382 unsigned int c_height;
385 if ((crop->left == tvnorm->cropcap.defrect.left
386 && crop->top == tvnorm->cropcap.defrect.top
387 && crop->width == tvnorm->cropcap.defrect.width
388 && crop->height == tvnorm->cropcap.defrect.height
389 && width <= tvnorm->swidth /* see PAL-Nc et al */)
390 || bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
391 bttv_calc_geo_old(btv, geo, width, height,
392 both_fields, tvnorm);
396 /* For bug compatibility the image size checks permit scale
397 factors > 16. See bttv_crop_calc_limits(). */
398 c_width = min((unsigned int) crop->width, width * 16);
399 c_height = min((unsigned int) crop->height, height * 16);
402 geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
403 /* Even to store Cb first, odd for Cr. */
404 geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
406 geo->sheight = c_height;
407 geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
408 sr = c_height >> !both_fields;
409 sr = (sr * 512U + (height >> 1)) / height - 512;
410 geo->vscale = (0x10000UL - sr) & 0x1fff;
411 geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
412 geo->vtotal = tvnorm->vtotal;
414 geo->crop = (((geo->width >> 8) & 0x03) |
415 ((geo->hdelay >> 6) & 0x0c) |
416 ((geo->sheight >> 4) & 0x30) |
417 ((geo->vdelay >> 2) & 0xc0));
419 if (btv->opt_combfilter) {
420 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
421 geo->comb = (width < 769) ? 1 : 0;
429 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
431 int off = odd ? 0x80 : 0x00;
434 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
436 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
438 btwrite(geo->vtc, BT848_E_VTC+off);
439 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
440 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
441 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
442 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
443 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
444 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
445 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
446 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
447 btwrite(geo->crop, BT848_E_CROP+off);
448 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
449 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
452 /* ---------------------------------------------------------- */
453 /* risc group / risc main loop / dma management */
456 bttv_set_dma(struct bttv *btv, int override)
462 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
463 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
464 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
467 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
468 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
472 "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
473 btv->c.nr,capctl,btv->loop_irq,
474 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
475 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
476 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
477 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
479 cmd = BT848_RISC_JUMP;
481 cmd |= BT848_RISC_IRQ;
482 cmd |= (btv->loop_irq & 0x0f) << 16;
483 cmd |= (~btv->loop_irq & 0x0f) << 20;
485 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
486 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
488 del_timer(&btv->timeout);
490 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
492 btaor(capctl, ~0x0f, BT848_CAP_CTL);
496 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
497 btor(3, BT848_GPIO_DMA_CTL);
502 btand(~3, BT848_GPIO_DMA_CTL);
509 bttv_risc_init_main(struct bttv *btv)
513 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
515 dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
516 btv->c.nr,(unsigned long long)btv->main.dma);
518 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
519 BT848_FIFO_STATUS_VRE);
520 btv->main.cpu[1] = cpu_to_le32(0);
521 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
522 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
525 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
526 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
527 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
528 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
530 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
531 BT848_FIFO_STATUS_VRO);
532 btv->main.cpu[9] = cpu_to_le32(0);
535 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
536 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
537 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
538 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
540 /* jump back to top field */
541 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
542 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
548 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
552 unsigned long next = btv->main.dma + ((slot+2) << 2);
555 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
556 btv->c.nr,risc,slot);
557 btv->main.cpu[slot+1] = cpu_to_le32(next);
559 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
560 btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
561 cmd = BT848_RISC_JUMP;
563 cmd |= BT848_RISC_IRQ;
564 cmd |= (irqflags & 0x0f) << 16;
565 cmd |= (~irqflags & 0x0f) << 20;
567 risc->jmp[0] = cpu_to_le32(cmd);
568 risc->jmp[1] = cpu_to_le32(next);
569 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
575 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
577 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
579 BUG_ON(in_interrupt());
580 videobuf_waiton(&buf->vb,0,0);
581 videobuf_dma_unmap(q, dma);
582 videobuf_dma_free(dma);
583 btcx_riscmem_free(btv->c.pci,&buf->bottom);
584 btcx_riscmem_free(btv->c.pci,&buf->top);
585 buf->vb.state = VIDEOBUF_NEEDS_INIT;
589 bttv_buffer_activate_vbi(struct bttv *btv,
590 struct bttv_buffer *vbi)
592 struct btcx_riscmem *top;
593 struct btcx_riscmem *bottom;
595 int bottom_irq_flags;
600 bottom_irq_flags = 0;
603 unsigned int crop, vdelay;
605 vbi->vb.state = VIDEOBUF_ACTIVE;
606 list_del(&vbi->vb.queue);
608 /* VDELAY is start of video, end of VBI capturing. */
609 crop = btread(BT848_E_CROP);
610 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
612 if (vbi->geo.vdelay > vdelay) {
613 vdelay = vbi->geo.vdelay & 0xfe;
614 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
616 btwrite(vdelay, BT848_E_VDELAY_LO);
617 btwrite(crop, BT848_E_CROP);
618 btwrite(vdelay, BT848_O_VDELAY_LO);
619 btwrite(crop, BT848_O_CROP);
622 if (vbi->vbi_count[0] > 0) {
627 if (vbi->vbi_count[1] > 0) {
629 bottom = &vbi->bottom;
630 bottom_irq_flags = 4;
634 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
635 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
641 bttv_buffer_activate_video(struct bttv *btv,
642 struct bttv_buffer_set *set)
645 if (NULL != set->top && NULL != set->bottom) {
646 if (set->top == set->bottom) {
647 set->top->vb.state = VIDEOBUF_ACTIVE;
648 if (set->top->vb.queue.next)
649 list_del(&set->top->vb.queue);
651 set->top->vb.state = VIDEOBUF_ACTIVE;
652 set->bottom->vb.state = VIDEOBUF_ACTIVE;
653 if (set->top->vb.queue.next)
654 list_del(&set->top->vb.queue);
655 if (set->bottom->vb.queue.next)
656 list_del(&set->bottom->vb.queue);
658 bttv_apply_geo(btv, &set->top->geo, 1);
659 bttv_apply_geo(btv, &set->bottom->geo,0);
660 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
662 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
664 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
665 ~0xff, BT848_COLOR_FMT);
666 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
667 ~0x0f, BT848_COLOR_CTL);
668 } else if (NULL != set->top) {
669 set->top->vb.state = VIDEOBUF_ACTIVE;
670 if (set->top->vb.queue.next)
671 list_del(&set->top->vb.queue);
672 bttv_apply_geo(btv, &set->top->geo,1);
673 bttv_apply_geo(btv, &set->top->geo,0);
674 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
676 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
677 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
678 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
679 } else if (NULL != set->bottom) {
680 set->bottom->vb.state = VIDEOBUF_ACTIVE;
681 if (set->bottom->vb.queue.next)
682 list_del(&set->bottom->vb.queue);
683 bttv_apply_geo(btv, &set->bottom->geo,1);
684 bttv_apply_geo(btv, &set->bottom->geo,0);
685 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
686 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
688 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
689 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
691 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
692 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
697 /* ---------------------------------------------------------- */
699 /* calculate geometry, build risc code */
701 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
703 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
704 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
707 "bttv%d: buffer field: %s format: %s size: %dx%d\n",
708 btv->c.nr, v4l2_field_names[buf->vb.field],
709 buf->fmt->name, buf->vb.width, buf->vb.height);
711 /* packed pixel modes */
712 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
713 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
714 int bpf = bpl * (buf->vb.height >> 1);
716 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
717 V4L2_FIELD_HAS_BOTH(buf->vb.field),
720 switch (buf->vb.field) {
722 bttv_risc_packed(btv,&buf->top,dma->sglist,
724 /* padding */ 0,/* skip_lines */ 0,
727 case V4L2_FIELD_BOTTOM:
728 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
729 0,bpl,0,0,buf->vb.height);
731 case V4L2_FIELD_INTERLACED:
732 bttv_risc_packed(btv,&buf->top,dma->sglist,
733 0,bpl,bpl,0,buf->vb.height >> 1);
734 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
735 bpl,bpl,bpl,0,buf->vb.height >> 1);
737 case V4L2_FIELD_SEQ_TB:
738 bttv_risc_packed(btv,&buf->top,dma->sglist,
739 0,bpl,0,0,buf->vb.height >> 1);
740 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
741 bpf,bpl,0,0,buf->vb.height >> 1);
749 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
750 int uoffset, voffset;
751 int ypadding, cpadding, lines;
753 /* calculate chroma offsets */
754 uoffset = buf->vb.width * buf->vb.height;
755 voffset = buf->vb.width * buf->vb.height;
756 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
757 /* Y-Cr-Cb plane order */
758 uoffset >>= buf->fmt->hshift;
759 uoffset >>= buf->fmt->vshift;
762 /* Y-Cb-Cr plane order */
763 voffset >>= buf->fmt->hshift;
764 voffset >>= buf->fmt->vshift;
768 switch (buf->vb.field) {
770 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
771 buf->vb.height,/* both_fields */ 0,
773 bttv_risc_planar(btv, &buf->top, dma->sglist,
774 0,buf->vb.width,0,buf->vb.height,
775 uoffset,voffset,buf->fmt->hshift,
778 case V4L2_FIELD_BOTTOM:
779 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
782 bttv_risc_planar(btv, &buf->bottom, dma->sglist,
783 0,buf->vb.width,0,buf->vb.height,
784 uoffset,voffset,buf->fmt->hshift,
787 case V4L2_FIELD_INTERLACED:
788 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
791 lines = buf->vb.height >> 1;
792 ypadding = buf->vb.width;
793 cpadding = buf->vb.width >> buf->fmt->hshift;
794 bttv_risc_planar(btv,&buf->top,
796 0,buf->vb.width,ypadding,lines,
801 bttv_risc_planar(btv,&buf->bottom,
803 ypadding,buf->vb.width,ypadding,lines,
810 case V4L2_FIELD_SEQ_TB:
811 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
814 lines = buf->vb.height >> 1;
815 ypadding = buf->vb.width;
816 cpadding = buf->vb.width >> buf->fmt->hshift;
817 bttv_risc_planar(btv,&buf->top,
819 0,buf->vb.width,0,lines,
825 bttv_risc_planar(btv,&buf->bottom,
827 lines * ypadding,buf->vb.width,0,lines,
828 lines * ypadding + (uoffset >> 1),
829 lines * ypadding + (voffset >> 1),
840 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
841 /* build risc code */
842 buf->vb.field = V4L2_FIELD_SEQ_TB;
843 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
844 1,tvnorm,&buf->crop);
845 bttv_risc_packed(btv, &buf->top, dma->sglist,
846 /* offset */ 0, RAW_BPL, /* padding */ 0,
847 /* skip_lines */ 0, RAW_LINES);
848 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
849 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
852 /* copy format info */
853 buf->btformat = buf->fmt->btformat;
854 buf->btswap = buf->fmt->btswap;
858 /* ---------------------------------------------------------- */
860 /* calculate geometry, build risc code */
862 bttv_overlay_risc(struct bttv *btv,
863 struct bttv_overlay *ov,
864 const struct bttv_format *fmt,
865 struct bttv_buffer *buf)
867 /* check interleave, bottom+top fields */
869 "bttv%d: overlay fields: %s format: %s size: %dx%d\n",
870 btv->c.nr, v4l2_field_names[buf->vb.field],
871 fmt->name,ov->w.width,ov->w.height);
873 /* calculate geometry */
874 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
875 V4L2_FIELD_HAS_BOTH(ov->field),
876 &bttv_tvnorms[ov->tvnorm],&buf->crop);
878 /* build risc code */
881 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
883 case V4L2_FIELD_BOTTOM:
884 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
886 case V4L2_FIELD_INTERLACED:
887 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
888 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
894 /* copy format info */
895 buf->btformat = fmt->btformat;
896 buf->btswap = fmt->btswap;
897 buf->vb.field = ov->field;