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/slab.h>
30 #include <linux/pci.h>
31 #include <linux/vmalloc.h>
32 #include <linux/interrupt.h>
34 #include <asm/pgtable.h>
35 #include <media/v4l2-ioctl.h>
39 #define VCR_HACK_LINES 4
41 /* ---------------------------------------------------------- */
42 /* risc code generators */
45 bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
46 struct scatterlist *sglist,
47 unsigned int offset, unsigned int bpl,
48 unsigned int padding, unsigned int skip_lines,
49 unsigned int store_lines)
51 u32 instructions,line,todo;
52 struct scatterlist *sg;
56 /* estimate risc mem: worst case is one write per page border +
57 one write per scan line + sync + jump (all 2 dwords). padding
58 can cause next bpl to start close to a page border. First DMA
59 region may be smaller than PAGE_SIZE */
60 instructions = skip_lines * 4;
61 instructions += (1 + ((bpl + padding) * store_lines)
62 / PAGE_SIZE + store_lines) * 8;
63 instructions += 2 * 8;
64 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions)) < 0)
67 /* sync instruction */
69 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
70 *(rp++) = cpu_to_le32(0);
72 while (skip_lines-- > 0) {
73 *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
74 BT848_RISC_EOL | bpl);
79 for (line = 0; line < store_lines; line++) {
80 if ((btv->opt_vcr_hack) &&
81 (line >= (store_lines - VCR_HACK_LINES)))
83 while (offset && offset >= sg_dma_len(sg)) {
84 offset -= sg_dma_len(sg);
87 if (bpl <= sg_dma_len(sg)-offset) {
88 /* fits into current chunk */
89 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
91 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
94 /* scanline needs to be splitted */
96 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
97 (sg_dma_len(sg)-offset));
98 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
99 todo -= (sg_dma_len(sg)-offset);
102 while (todo > sg_dma_len(sg)) {
103 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
105 *(rp++)=cpu_to_le32(sg_dma_address(sg));
106 todo -= sg_dma_len(sg);
109 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
111 *(rp++)=cpu_to_le32(sg_dma_address(sg));
117 /* save pointer to jmp instruction address */
119 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
124 bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
125 struct scatterlist *sglist,
126 unsigned int yoffset, unsigned int ybpl,
127 unsigned int ypadding, unsigned int ylines,
128 unsigned int uoffset, unsigned int voffset,
129 unsigned int hshift, unsigned int vshift,
130 unsigned int cpadding)
132 unsigned int instructions,line,todo,ylen,chroma;
135 struct scatterlist *ysg;
136 struct scatterlist *usg;
137 struct scatterlist *vsg;
138 int topfield = (0 == yoffset);
141 /* estimate risc mem: worst case is one write per page border +
142 one write per scan line (5 dwords)
143 plus sync + jump (2 dwords) */
144 instructions = ((3 + (ybpl + ypadding) * ylines * 2)
145 / PAGE_SIZE) + ylines;
147 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
150 /* sync instruction */
152 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
153 *(rp++) = cpu_to_le32(0);
159 for (line = 0; line < ylines; line++) {
160 if ((btv->opt_vcr_hack) &&
161 (line >= (ylines - VCR_HACK_LINES)))
169 chroma = ((line & 1) == 0);
171 chroma = ((line & 1) == 1);
175 chroma = ((line & 3) == 0);
177 chroma = ((line & 3) == 2);
184 for (todo = ybpl; todo > 0; todo -= ylen) {
185 /* go to next sg entry if needed */
186 while (yoffset && yoffset >= sg_dma_len(ysg)) {
187 yoffset -= sg_dma_len(ysg);
190 while (uoffset && uoffset >= sg_dma_len(usg)) {
191 uoffset -= sg_dma_len(usg);
194 while (voffset && voffset >= sg_dma_len(vsg)) {
195 voffset -= sg_dma_len(vsg);
199 /* calculate max number of bytes we can write */
201 if (yoffset + ylen > sg_dma_len(ysg))
202 ylen = sg_dma_len(ysg) - yoffset;
204 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
205 ylen = (sg_dma_len(usg) - uoffset) << hshift;
206 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
207 ylen = (sg_dma_len(vsg) - voffset) << hshift;
208 ri = BT848_RISC_WRITE123;
210 ri = BT848_RISC_WRITE1S23;
213 ri |= BT848_RISC_SOL;
215 ri |= BT848_RISC_EOL;
217 /* write risc instruction */
218 *(rp++)=cpu_to_le32(ri | ylen);
219 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
221 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
224 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
225 uoffset += ylen >> hshift;
226 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
227 voffset += ylen >> hshift;
237 /* save pointer to jmp instruction address */
239 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
244 bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
245 const struct bttv_format *fmt, struct bttv_overlay *ov,
246 int skip_even, int skip_odd)
248 int dwords, rc, line, maxy, start, end;
249 unsigned skip, nskips;
250 struct btcx_skiplist *skips;
255 /* skip list for window clipping */
256 if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
259 /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
260 + sync + jump (all 2 dwords) */
261 dwords = (3 * ov->nclips + 2) *
262 ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
264 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
269 /* sync instruction */
271 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
272 *(rp++) = cpu_to_le32(0);
274 addr = (unsigned long)btv->fbuf.base;
275 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
276 addr += (fmt->depth >> 3) * ov->w.left;
279 for (maxy = -1, line = 0; line < ov->w.height;
280 line++, addr += btv->fbuf.fmt.bytesperline) {
281 if ((btv->opt_vcr_hack) &&
282 (line >= (ov->w.height - VCR_HACK_LINES)))
284 if ((line%2) == 0 && skip_even)
286 if ((line%2) == 1 && skip_odd)
289 /* calculate clipping */
291 btcx_calc_skips(line, ov->w.width, &maxy,
292 skips, &nskips, ov->clips, ov->nclips);
294 /* write out risc code */
295 for (start = 0, skip = 0; start < ov->w.width; start = end) {
296 if (skip >= nskips) {
297 ri = BT848_RISC_WRITE;
299 } else if (start < skips[skip].start) {
300 ri = BT848_RISC_WRITE;
301 end = skips[skip].start;
303 ri = BT848_RISC_SKIP;
304 end = skips[skip].end;
307 if (BT848_RISC_WRITE == ri)
308 ra = addr + (fmt->depth>>3)*start;
313 ri |= BT848_RISC_SOL;
314 if (ov->w.width == end)
315 ri |= BT848_RISC_EOL;
316 ri |= (fmt->depth>>3) * (end-start);
318 *(rp++)=cpu_to_le32(ri);
320 *(rp++)=cpu_to_le32(ra);
324 /* save pointer to jmp instruction address */
326 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
331 /* ---------------------------------------------------------- */
334 bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
335 int width, int height, int interleaved,
336 const struct bttv_tvnorm *tvnorm)
341 int swidth = tvnorm->swidth;
342 int totalwidth = tvnorm->totalwidth;
343 int scaledtwidth = tvnorm->scaledtwidth;
345 if (btv->input == btv->dig) {
351 vdelay = tvnorm->vdelay;
353 xsf = (width*scaledtwidth)/swidth;
354 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
355 geo->hdelay = tvnorm->hdelayx1;
356 geo->hdelay = (geo->hdelay*width)/swidth;
357 geo->hdelay &= 0x3fe;
358 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
359 geo->vscale = (0x10000UL-sr) & 0x1fff;
360 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
361 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
362 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
363 geo->vdelay = vdelay;
365 geo->sheight = tvnorm->sheight;
366 geo->vtotal = tvnorm->vtotal;
368 if (btv->opt_combfilter) {
369 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
370 geo->comb = (width < 769) ? 1 : 0;
378 bttv_calc_geo (struct bttv * btv,
379 struct bttv_geometry * geo,
383 const struct bttv_tvnorm * tvnorm,
384 const struct v4l2_rect * crop)
386 unsigned int c_width;
387 unsigned int c_height;
390 if ((crop->left == tvnorm->cropcap.defrect.left
391 && crop->top == tvnorm->cropcap.defrect.top
392 && crop->width == tvnorm->cropcap.defrect.width
393 && crop->height == tvnorm->cropcap.defrect.height
394 && width <= tvnorm->swidth /* see PAL-Nc et al */)
395 || btv->input == btv->dig) {
396 bttv_calc_geo_old(btv, geo, width, height,
397 both_fields, tvnorm);
401 /* For bug compatibility the image size checks permit scale
402 factors > 16. See bttv_crop_calc_limits(). */
403 c_width = min((unsigned int) crop->width, width * 16);
404 c_height = min((unsigned int) crop->height, height * 16);
407 geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
408 /* Even to store Cb first, odd for Cr. */
409 geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
411 geo->sheight = c_height;
412 geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
413 sr = c_height >> !both_fields;
414 sr = (sr * 512U + (height >> 1)) / height - 512;
415 geo->vscale = (0x10000UL - sr) & 0x1fff;
416 geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
417 geo->vtotal = tvnorm->vtotal;
419 geo->crop = (((geo->width >> 8) & 0x03) |
420 ((geo->hdelay >> 6) & 0x0c) |
421 ((geo->sheight >> 4) & 0x30) |
422 ((geo->vdelay >> 2) & 0xc0));
424 if (btv->opt_combfilter) {
425 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
426 geo->comb = (width < 769) ? 1 : 0;
434 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
436 int off = odd ? 0x80 : 0x00;
439 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
441 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
443 btwrite(geo->vtc, BT848_E_VTC+off);
444 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
445 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
446 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
447 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
448 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
449 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
450 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
451 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
452 btwrite(geo->crop, BT848_E_CROP+off);
453 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
454 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
457 /* ---------------------------------------------------------- */
458 /* risc group / risc main loop / dma management */
461 bttv_set_dma(struct bttv *btv, int override)
467 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
468 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
469 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
472 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
473 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
477 "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
478 btv->c.nr,capctl,btv->loop_irq,
479 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
480 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
481 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
482 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
484 cmd = BT848_RISC_JUMP;
486 cmd |= BT848_RISC_IRQ;
487 cmd |= (btv->loop_irq & 0x0f) << 16;
488 cmd |= (~btv->loop_irq & 0x0f) << 20;
490 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
491 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
493 del_timer(&btv->timeout);
495 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
497 btaor(capctl, ~0x0f, BT848_CAP_CTL);
501 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
502 btor(3, BT848_GPIO_DMA_CTL);
507 btand(~3, BT848_GPIO_DMA_CTL);
514 bttv_risc_init_main(struct bttv *btv)
518 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
520 dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
521 btv->c.nr,(unsigned long long)btv->main.dma);
523 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
524 BT848_FIFO_STATUS_VRE);
525 btv->main.cpu[1] = cpu_to_le32(0);
526 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
527 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
530 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
531 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
532 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
533 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
535 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
536 BT848_FIFO_STATUS_VRO);
537 btv->main.cpu[9] = cpu_to_le32(0);
540 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
541 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
542 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
543 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
545 /* jump back to top field */
546 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
547 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
553 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
557 unsigned long next = btv->main.dma + ((slot+2) << 2);
560 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
561 btv->c.nr,risc,slot);
562 btv->main.cpu[slot+1] = cpu_to_le32(next);
564 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
565 btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
566 cmd = BT848_RISC_JUMP;
568 cmd |= BT848_RISC_IRQ;
569 cmd |= (irqflags & 0x0f) << 16;
570 cmd |= (~irqflags & 0x0f) << 20;
572 risc->jmp[0] = cpu_to_le32(cmd);
573 risc->jmp[1] = cpu_to_le32(next);
574 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
580 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
582 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
584 BUG_ON(in_interrupt());
585 videobuf_waiton(&buf->vb,0,0);
586 videobuf_dma_unmap(q, dma);
587 videobuf_dma_free(dma);
588 btcx_riscmem_free(btv->c.pci,&buf->bottom);
589 btcx_riscmem_free(btv->c.pci,&buf->top);
590 buf->vb.state = VIDEOBUF_NEEDS_INIT;
594 bttv_buffer_activate_vbi(struct bttv *btv,
595 struct bttv_buffer *vbi)
597 struct btcx_riscmem *top;
598 struct btcx_riscmem *bottom;
600 int bottom_irq_flags;
605 bottom_irq_flags = 0;
608 unsigned int crop, vdelay;
610 vbi->vb.state = VIDEOBUF_ACTIVE;
611 list_del(&vbi->vb.queue);
613 /* VDELAY is start of video, end of VBI capturing. */
614 crop = btread(BT848_E_CROP);
615 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
617 if (vbi->geo.vdelay > vdelay) {
618 vdelay = vbi->geo.vdelay & 0xfe;
619 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
621 btwrite(vdelay, BT848_E_VDELAY_LO);
622 btwrite(crop, BT848_E_CROP);
623 btwrite(vdelay, BT848_O_VDELAY_LO);
624 btwrite(crop, BT848_O_CROP);
627 if (vbi->vbi_count[0] > 0) {
632 if (vbi->vbi_count[1] > 0) {
634 bottom = &vbi->bottom;
635 bottom_irq_flags = 4;
639 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
640 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
646 bttv_buffer_activate_video(struct bttv *btv,
647 struct bttv_buffer_set *set)
650 if (NULL != set->top && NULL != set->bottom) {
651 if (set->top == set->bottom) {
652 set->top->vb.state = VIDEOBUF_ACTIVE;
653 if (set->top->vb.queue.next)
654 list_del(&set->top->vb.queue);
656 set->top->vb.state = VIDEOBUF_ACTIVE;
657 set->bottom->vb.state = VIDEOBUF_ACTIVE;
658 if (set->top->vb.queue.next)
659 list_del(&set->top->vb.queue);
660 if (set->bottom->vb.queue.next)
661 list_del(&set->bottom->vb.queue);
663 bttv_apply_geo(btv, &set->top->geo, 1);
664 bttv_apply_geo(btv, &set->bottom->geo,0);
665 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
667 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
669 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
670 ~0xff, BT848_COLOR_FMT);
671 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
672 ~0x0f, BT848_COLOR_CTL);
673 } else if (NULL != set->top) {
674 set->top->vb.state = VIDEOBUF_ACTIVE;
675 if (set->top->vb.queue.next)
676 list_del(&set->top->vb.queue);
677 bttv_apply_geo(btv, &set->top->geo,1);
678 bttv_apply_geo(btv, &set->top->geo,0);
679 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
681 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
682 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
683 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
684 } else if (NULL != set->bottom) {
685 set->bottom->vb.state = VIDEOBUF_ACTIVE;
686 if (set->bottom->vb.queue.next)
687 list_del(&set->bottom->vb.queue);
688 bttv_apply_geo(btv, &set->bottom->geo,1);
689 bttv_apply_geo(btv, &set->bottom->geo,0);
690 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
691 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
693 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
694 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
696 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
697 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
702 /* ---------------------------------------------------------- */
704 /* calculate geometry, build risc code */
706 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
708 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
709 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
712 "bttv%d: buffer field: %s format: %s size: %dx%d\n",
713 btv->c.nr, v4l2_field_names[buf->vb.field],
714 buf->fmt->name, buf->vb.width, buf->vb.height);
716 /* packed pixel modes */
717 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
718 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
719 int bpf = bpl * (buf->vb.height >> 1);
721 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
722 V4L2_FIELD_HAS_BOTH(buf->vb.field),
725 switch (buf->vb.field) {
727 bttv_risc_packed(btv,&buf->top,dma->sglist,
729 /* padding */ 0,/* skip_lines */ 0,
732 case V4L2_FIELD_BOTTOM:
733 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
734 0,bpl,0,0,buf->vb.height);
736 case V4L2_FIELD_INTERLACED:
737 bttv_risc_packed(btv,&buf->top,dma->sglist,
738 0,bpl,bpl,0,buf->vb.height >> 1);
739 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
740 bpl,bpl,bpl,0,buf->vb.height >> 1);
742 case V4L2_FIELD_SEQ_TB:
743 bttv_risc_packed(btv,&buf->top,dma->sglist,
744 0,bpl,0,0,buf->vb.height >> 1);
745 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
746 bpf,bpl,0,0,buf->vb.height >> 1);
754 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
755 int uoffset, voffset;
756 int ypadding, cpadding, lines;
758 /* calculate chroma offsets */
759 uoffset = buf->vb.width * buf->vb.height;
760 voffset = buf->vb.width * buf->vb.height;
761 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
762 /* Y-Cr-Cb plane order */
763 uoffset >>= buf->fmt->hshift;
764 uoffset >>= buf->fmt->vshift;
767 /* Y-Cb-Cr plane order */
768 voffset >>= buf->fmt->hshift;
769 voffset >>= buf->fmt->vshift;
773 switch (buf->vb.field) {
775 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
776 buf->vb.height,/* both_fields */ 0,
778 bttv_risc_planar(btv, &buf->top, dma->sglist,
779 0,buf->vb.width,0,buf->vb.height,
780 uoffset,voffset,buf->fmt->hshift,
783 case V4L2_FIELD_BOTTOM:
784 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
787 bttv_risc_planar(btv, &buf->bottom, dma->sglist,
788 0,buf->vb.width,0,buf->vb.height,
789 uoffset,voffset,buf->fmt->hshift,
792 case V4L2_FIELD_INTERLACED:
793 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
796 lines = buf->vb.height >> 1;
797 ypadding = buf->vb.width;
798 cpadding = buf->vb.width >> buf->fmt->hshift;
799 bttv_risc_planar(btv,&buf->top,
801 0,buf->vb.width,ypadding,lines,
806 bttv_risc_planar(btv,&buf->bottom,
808 ypadding,buf->vb.width,ypadding,lines,
815 case V4L2_FIELD_SEQ_TB:
816 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
819 lines = buf->vb.height >> 1;
820 ypadding = buf->vb.width;
821 cpadding = buf->vb.width >> buf->fmt->hshift;
822 bttv_risc_planar(btv,&buf->top,
824 0,buf->vb.width,0,lines,
830 bttv_risc_planar(btv,&buf->bottom,
832 lines * ypadding,buf->vb.width,0,lines,
833 lines * ypadding + (uoffset >> 1),
834 lines * ypadding + (voffset >> 1),
845 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
846 /* build risc code */
847 buf->vb.field = V4L2_FIELD_SEQ_TB;
848 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
849 1,tvnorm,&buf->crop);
850 bttv_risc_packed(btv, &buf->top, dma->sglist,
851 /* offset */ 0, RAW_BPL, /* padding */ 0,
852 /* skip_lines */ 0, RAW_LINES);
853 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
854 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
857 /* copy format info */
858 buf->btformat = buf->fmt->btformat;
859 buf->btswap = buf->fmt->btswap;
863 /* ---------------------------------------------------------- */
865 /* calculate geometry, build risc code */
867 bttv_overlay_risc(struct bttv *btv,
868 struct bttv_overlay *ov,
869 const struct bttv_format *fmt,
870 struct bttv_buffer *buf)
872 /* check interleave, bottom+top fields */
874 "bttv%d: overlay fields: %s format: %s size: %dx%d\n",
875 btv->c.nr, v4l2_field_names[buf->vb.field],
876 fmt->name,ov->w.width,ov->w.height);
878 /* calculate geometry */
879 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
880 V4L2_FIELD_HAS_BOTH(ov->field),
881 &bttv_tvnorms[ov->tvnorm],&buf->crop);
883 /* build risc code */
886 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
888 case V4L2_FIELD_BOTTOM:
889 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
891 case V4L2_FIELD_INTERLACED:
892 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
893 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
899 /* copy format info */
900 buf->btformat = fmt->btformat;
901 buf->btswap = fmt->btswap;
902 buf->vb.field = ov->field;