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>
34 #include <media/v4l2-ioctl.h>
38 #define VCR_HACK_LINES 4
40 /* ---------------------------------------------------------- */
41 /* risc code generators */
44 bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
45 struct scatterlist *sglist,
46 unsigned int offset, unsigned int bpl,
47 unsigned int padding, unsigned int skip_lines,
48 unsigned int store_lines)
50 u32 instructions,line,todo;
51 struct scatterlist *sg;
55 /* estimate risc mem: worst case is one write per page border +
56 one write per scan line + sync + jump (all 2 dwords). padding
57 can cause next bpl to start close to a page border. First DMA
58 region may be smaller than PAGE_SIZE */
59 instructions = skip_lines * 4;
60 instructions += (1 + ((bpl + padding) * store_lines)
61 / PAGE_SIZE + store_lines) * 8;
62 instructions += 2 * 8;
63 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions)) < 0)
66 /* sync instruction */
68 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
69 *(rp++) = cpu_to_le32(0);
71 while (skip_lines-- > 0) {
72 *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
73 BT848_RISC_EOL | bpl);
78 for (line = 0; line < store_lines; line++) {
79 if ((btv->opt_vcr_hack) &&
80 (line >= (store_lines - VCR_HACK_LINES)))
82 while (offset && offset >= sg_dma_len(sg)) {
83 offset -= sg_dma_len(sg);
86 if (bpl <= sg_dma_len(sg)-offset) {
87 /* fits into current chunk */
88 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
90 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
93 /* scanline needs to be splitted */
95 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
96 (sg_dma_len(sg)-offset));
97 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
98 todo -= (sg_dma_len(sg)-offset);
101 while (todo > sg_dma_len(sg)) {
102 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
104 *(rp++)=cpu_to_le32(sg_dma_address(sg));
105 todo -= sg_dma_len(sg);
108 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
110 *(rp++)=cpu_to_le32(sg_dma_address(sg));
116 /* save pointer to jmp instruction address */
118 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
123 bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
124 struct scatterlist *sglist,
125 unsigned int yoffset, unsigned int ybpl,
126 unsigned int ypadding, unsigned int ylines,
127 unsigned int uoffset, unsigned int voffset,
128 unsigned int hshift, unsigned int vshift,
129 unsigned int cpadding)
131 unsigned int instructions,line,todo,ylen,chroma;
134 struct scatterlist *ysg;
135 struct scatterlist *usg;
136 struct scatterlist *vsg;
137 int topfield = (0 == yoffset);
140 /* estimate risc mem: worst case is one write per page border +
141 one write per scan line (5 dwords)
142 plus sync + jump (2 dwords) */
143 instructions = ((3 + (ybpl + ypadding) * ylines * 2)
144 / PAGE_SIZE) + ylines;
146 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
149 /* sync instruction */
151 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
152 *(rp++) = cpu_to_le32(0);
158 for (line = 0; line < ylines; line++) {
159 if ((btv->opt_vcr_hack) &&
160 (line >= (ylines - VCR_HACK_LINES)))
168 chroma = ((line & 1) == 0);
170 chroma = ((line & 1) == 1);
174 chroma = ((line & 3) == 0);
176 chroma = ((line & 3) == 2);
183 for (todo = ybpl; todo > 0; todo -= ylen) {
184 /* go to next sg entry if needed */
185 while (yoffset && yoffset >= sg_dma_len(ysg)) {
186 yoffset -= sg_dma_len(ysg);
189 while (uoffset && uoffset >= sg_dma_len(usg)) {
190 uoffset -= sg_dma_len(usg);
193 while (voffset && voffset >= sg_dma_len(vsg)) {
194 voffset -= sg_dma_len(vsg);
198 /* calculate max number of bytes we can write */
200 if (yoffset + ylen > sg_dma_len(ysg))
201 ylen = sg_dma_len(ysg) - yoffset;
203 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
204 ylen = (sg_dma_len(usg) - uoffset) << hshift;
205 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
206 ylen = (sg_dma_len(vsg) - voffset) << hshift;
207 ri = BT848_RISC_WRITE123;
209 ri = BT848_RISC_WRITE1S23;
212 ri |= BT848_RISC_SOL;
214 ri |= BT848_RISC_EOL;
216 /* write risc instruction */
217 *(rp++)=cpu_to_le32(ri | ylen);
218 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
220 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
223 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
224 uoffset += ylen >> hshift;
225 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
226 voffset += ylen >> hshift;
236 /* save pointer to jmp instruction address */
238 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
243 bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
244 const struct bttv_format *fmt, struct bttv_overlay *ov,
245 int skip_even, int skip_odd)
247 int dwords, rc, line, maxy, start, end;
248 unsigned skip, nskips;
249 struct btcx_skiplist *skips;
254 /* skip list for window clipping */
255 if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
258 /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
259 + sync + jump (all 2 dwords) */
260 dwords = (3 * ov->nclips + 2) *
261 ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
263 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
268 /* sync instruction */
270 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
271 *(rp++) = cpu_to_le32(0);
273 addr = (unsigned long)btv->fbuf.base;
274 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
275 addr += (fmt->depth >> 3) * ov->w.left;
278 for (maxy = -1, line = 0; line < ov->w.height;
279 line++, addr += btv->fbuf.fmt.bytesperline) {
280 if ((btv->opt_vcr_hack) &&
281 (line >= (ov->w.height - VCR_HACK_LINES)))
283 if ((line%2) == 0 && skip_even)
285 if ((line%2) == 1 && skip_odd)
288 /* calculate clipping */
290 btcx_calc_skips(line, ov->w.width, &maxy,
291 skips, &nskips, ov->clips, ov->nclips);
293 /* write out risc code */
294 for (start = 0, skip = 0; start < ov->w.width; start = end) {
295 if (skip >= nskips) {
296 ri = BT848_RISC_WRITE;
298 } else if (start < skips[skip].start) {
299 ri = BT848_RISC_WRITE;
300 end = skips[skip].start;
302 ri = BT848_RISC_SKIP;
303 end = skips[skip].end;
306 if (BT848_RISC_WRITE == ri)
307 ra = addr + (fmt->depth>>3)*start;
312 ri |= BT848_RISC_SOL;
313 if (ov->w.width == end)
314 ri |= BT848_RISC_EOL;
315 ri |= (fmt->depth>>3) * (end-start);
317 *(rp++)=cpu_to_le32(ri);
319 *(rp++)=cpu_to_le32(ra);
323 /* save pointer to jmp instruction address */
325 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
330 /* ---------------------------------------------------------- */
333 bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
334 int width, int height, int interleaved,
335 const struct bttv_tvnorm *tvnorm)
340 int swidth = tvnorm->swidth;
341 int totalwidth = tvnorm->totalwidth;
342 int scaledtwidth = tvnorm->scaledtwidth;
344 if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
350 vdelay = tvnorm->vdelay;
352 xsf = (width*scaledtwidth)/swidth;
353 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
354 geo->hdelay = tvnorm->hdelayx1;
355 geo->hdelay = (geo->hdelay*width)/swidth;
356 geo->hdelay &= 0x3fe;
357 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
358 geo->vscale = (0x10000UL-sr) & 0x1fff;
359 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
360 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
361 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
362 geo->vdelay = vdelay;
364 geo->sheight = tvnorm->sheight;
365 geo->vtotal = tvnorm->vtotal;
367 if (btv->opt_combfilter) {
368 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
369 geo->comb = (width < 769) ? 1 : 0;
377 bttv_calc_geo (struct bttv * btv,
378 struct bttv_geometry * geo,
382 const struct bttv_tvnorm * tvnorm,
383 const struct v4l2_rect * crop)
385 unsigned int c_width;
386 unsigned int c_height;
389 if ((crop->left == tvnorm->cropcap.defrect.left
390 && crop->top == tvnorm->cropcap.defrect.top
391 && crop->width == tvnorm->cropcap.defrect.width
392 && crop->height == tvnorm->cropcap.defrect.height
393 && width <= tvnorm->swidth /* see PAL-Nc et al */)
394 || bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
395 bttv_calc_geo_old(btv, geo, width, height,
396 both_fields, tvnorm);
400 /* For bug compatibility the image size checks permit scale
401 factors > 16. See bttv_crop_calc_limits(). */
402 c_width = min((unsigned int) crop->width, width * 16);
403 c_height = min((unsigned int) crop->height, height * 16);
406 geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
407 /* Even to store Cb first, odd for Cr. */
408 geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
410 geo->sheight = c_height;
411 geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
412 sr = c_height >> !both_fields;
413 sr = (sr * 512U + (height >> 1)) / height - 512;
414 geo->vscale = (0x10000UL - sr) & 0x1fff;
415 geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
416 geo->vtotal = tvnorm->vtotal;
418 geo->crop = (((geo->width >> 8) & 0x03) |
419 ((geo->hdelay >> 6) & 0x0c) |
420 ((geo->sheight >> 4) & 0x30) |
421 ((geo->vdelay >> 2) & 0xc0));
423 if (btv->opt_combfilter) {
424 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
425 geo->comb = (width < 769) ? 1 : 0;
433 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
435 int off = odd ? 0x80 : 0x00;
438 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
440 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
442 btwrite(geo->vtc, BT848_E_VTC+off);
443 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
444 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
445 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
446 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
447 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
448 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
449 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
450 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
451 btwrite(geo->crop, BT848_E_CROP+off);
452 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
453 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
456 /* ---------------------------------------------------------- */
457 /* risc group / risc main loop / dma management */
460 bttv_set_dma(struct bttv *btv, int override)
466 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
467 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
468 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
471 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
472 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
476 "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
477 btv->c.nr,capctl,btv->loop_irq,
478 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
479 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
480 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
481 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
483 cmd = BT848_RISC_JUMP;
485 cmd |= BT848_RISC_IRQ;
486 cmd |= (btv->loop_irq & 0x0f) << 16;
487 cmd |= (~btv->loop_irq & 0x0f) << 20;
489 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
490 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
492 del_timer(&btv->timeout);
494 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
496 btaor(capctl, ~0x0f, BT848_CAP_CTL);
500 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
501 btor(3, BT848_GPIO_DMA_CTL);
506 btand(~3, BT848_GPIO_DMA_CTL);
513 bttv_risc_init_main(struct bttv *btv)
517 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
519 dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
520 btv->c.nr,(unsigned long long)btv->main.dma);
522 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
523 BT848_FIFO_STATUS_VRE);
524 btv->main.cpu[1] = cpu_to_le32(0);
525 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
526 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
529 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
530 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
531 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
532 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
534 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
535 BT848_FIFO_STATUS_VRO);
536 btv->main.cpu[9] = cpu_to_le32(0);
539 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
540 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
541 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
542 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
544 /* jump back to top field */
545 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
546 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
552 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
556 unsigned long next = btv->main.dma + ((slot+2) << 2);
559 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
560 btv->c.nr,risc,slot);
561 btv->main.cpu[slot+1] = cpu_to_le32(next);
563 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
564 btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
565 cmd = BT848_RISC_JUMP;
567 cmd |= BT848_RISC_IRQ;
568 cmd |= (irqflags & 0x0f) << 16;
569 cmd |= (~irqflags & 0x0f) << 20;
571 risc->jmp[0] = cpu_to_le32(cmd);
572 risc->jmp[1] = cpu_to_le32(next);
573 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
579 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
581 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
583 BUG_ON(in_interrupt());
584 videobuf_waiton(&buf->vb,0,0);
585 videobuf_dma_unmap(q, dma);
586 videobuf_dma_free(dma);
587 btcx_riscmem_free(btv->c.pci,&buf->bottom);
588 btcx_riscmem_free(btv->c.pci,&buf->top);
589 buf->vb.state = VIDEOBUF_NEEDS_INIT;
593 bttv_buffer_activate_vbi(struct bttv *btv,
594 struct bttv_buffer *vbi)
596 struct btcx_riscmem *top;
597 struct btcx_riscmem *bottom;
599 int bottom_irq_flags;
604 bottom_irq_flags = 0;
607 unsigned int crop, vdelay;
609 vbi->vb.state = VIDEOBUF_ACTIVE;
610 list_del(&vbi->vb.queue);
612 /* VDELAY is start of video, end of VBI capturing. */
613 crop = btread(BT848_E_CROP);
614 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
616 if (vbi->geo.vdelay > vdelay) {
617 vdelay = vbi->geo.vdelay & 0xfe;
618 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
620 btwrite(vdelay, BT848_E_VDELAY_LO);
621 btwrite(crop, BT848_E_CROP);
622 btwrite(vdelay, BT848_O_VDELAY_LO);
623 btwrite(crop, BT848_O_CROP);
626 if (vbi->vbi_count[0] > 0) {
631 if (vbi->vbi_count[1] > 0) {
633 bottom = &vbi->bottom;
634 bottom_irq_flags = 4;
638 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
639 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
645 bttv_buffer_activate_video(struct bttv *btv,
646 struct bttv_buffer_set *set)
649 if (NULL != set->top && NULL != set->bottom) {
650 if (set->top == set->bottom) {
651 set->top->vb.state = VIDEOBUF_ACTIVE;
652 if (set->top->vb.queue.next)
653 list_del(&set->top->vb.queue);
655 set->top->vb.state = VIDEOBUF_ACTIVE;
656 set->bottom->vb.state = VIDEOBUF_ACTIVE;
657 if (set->top->vb.queue.next)
658 list_del(&set->top->vb.queue);
659 if (set->bottom->vb.queue.next)
660 list_del(&set->bottom->vb.queue);
662 bttv_apply_geo(btv, &set->top->geo, 1);
663 bttv_apply_geo(btv, &set->bottom->geo,0);
664 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
666 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
668 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
669 ~0xff, BT848_COLOR_FMT);
670 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
671 ~0x0f, BT848_COLOR_CTL);
672 } else if (NULL != set->top) {
673 set->top->vb.state = VIDEOBUF_ACTIVE;
674 if (set->top->vb.queue.next)
675 list_del(&set->top->vb.queue);
676 bttv_apply_geo(btv, &set->top->geo,1);
677 bttv_apply_geo(btv, &set->top->geo,0);
678 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
680 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
681 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
682 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
683 } else if (NULL != set->bottom) {
684 set->bottom->vb.state = VIDEOBUF_ACTIVE;
685 if (set->bottom->vb.queue.next)
686 list_del(&set->bottom->vb.queue);
687 bttv_apply_geo(btv, &set->bottom->geo,1);
688 bttv_apply_geo(btv, &set->bottom->geo,0);
689 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
690 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
692 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
693 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
695 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
696 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
701 /* ---------------------------------------------------------- */
703 /* calculate geometry, build risc code */
705 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
707 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
708 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
711 "bttv%d: buffer field: %s format: %s size: %dx%d\n",
712 btv->c.nr, v4l2_field_names[buf->vb.field],
713 buf->fmt->name, buf->vb.width, buf->vb.height);
715 /* packed pixel modes */
716 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
717 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
718 int bpf = bpl * (buf->vb.height >> 1);
720 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
721 V4L2_FIELD_HAS_BOTH(buf->vb.field),
724 switch (buf->vb.field) {
726 bttv_risc_packed(btv,&buf->top,dma->sglist,
728 /* padding */ 0,/* skip_lines */ 0,
731 case V4L2_FIELD_BOTTOM:
732 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
733 0,bpl,0,0,buf->vb.height);
735 case V4L2_FIELD_INTERLACED:
736 bttv_risc_packed(btv,&buf->top,dma->sglist,
737 0,bpl,bpl,0,buf->vb.height >> 1);
738 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
739 bpl,bpl,bpl,0,buf->vb.height >> 1);
741 case V4L2_FIELD_SEQ_TB:
742 bttv_risc_packed(btv,&buf->top,dma->sglist,
743 0,bpl,0,0,buf->vb.height >> 1);
744 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
745 bpf,bpl,0,0,buf->vb.height >> 1);
753 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
754 int uoffset, voffset;
755 int ypadding, cpadding, lines;
757 /* calculate chroma offsets */
758 uoffset = buf->vb.width * buf->vb.height;
759 voffset = buf->vb.width * buf->vb.height;
760 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
761 /* Y-Cr-Cb plane order */
762 uoffset >>= buf->fmt->hshift;
763 uoffset >>= buf->fmt->vshift;
766 /* Y-Cb-Cr plane order */
767 voffset >>= buf->fmt->hshift;
768 voffset >>= buf->fmt->vshift;
772 switch (buf->vb.field) {
774 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
775 buf->vb.height,/* both_fields */ 0,
777 bttv_risc_planar(btv, &buf->top, dma->sglist,
778 0,buf->vb.width,0,buf->vb.height,
779 uoffset,voffset,buf->fmt->hshift,
782 case V4L2_FIELD_BOTTOM:
783 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
786 bttv_risc_planar(btv, &buf->bottom, dma->sglist,
787 0,buf->vb.width,0,buf->vb.height,
788 uoffset,voffset,buf->fmt->hshift,
791 case V4L2_FIELD_INTERLACED:
792 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
795 lines = buf->vb.height >> 1;
796 ypadding = buf->vb.width;
797 cpadding = buf->vb.width >> buf->fmt->hshift;
798 bttv_risc_planar(btv,&buf->top,
800 0,buf->vb.width,ypadding,lines,
805 bttv_risc_planar(btv,&buf->bottom,
807 ypadding,buf->vb.width,ypadding,lines,
814 case V4L2_FIELD_SEQ_TB:
815 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
818 lines = buf->vb.height >> 1;
819 ypadding = buf->vb.width;
820 cpadding = buf->vb.width >> buf->fmt->hshift;
821 bttv_risc_planar(btv,&buf->top,
823 0,buf->vb.width,0,lines,
829 bttv_risc_planar(btv,&buf->bottom,
831 lines * ypadding,buf->vb.width,0,lines,
832 lines * ypadding + (uoffset >> 1),
833 lines * ypadding + (voffset >> 1),
844 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
845 /* build risc code */
846 buf->vb.field = V4L2_FIELD_SEQ_TB;
847 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
848 1,tvnorm,&buf->crop);
849 bttv_risc_packed(btv, &buf->top, dma->sglist,
850 /* offset */ 0, RAW_BPL, /* padding */ 0,
851 /* skip_lines */ 0, RAW_LINES);
852 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
853 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
856 /* copy format info */
857 buf->btformat = buf->fmt->btformat;
858 buf->btswap = buf->fmt->btswap;
862 /* ---------------------------------------------------------- */
864 /* calculate geometry, build risc code */
866 bttv_overlay_risc(struct bttv *btv,
867 struct bttv_overlay *ov,
868 const struct bttv_format *fmt,
869 struct bttv_buffer *buf)
871 /* check interleave, bottom+top fields */
873 "bttv%d: overlay fields: %s format: %s size: %dx%d\n",
874 btv->c.nr, v4l2_field_names[buf->vb.field],
875 fmt->name,ov->w.width,ov->w.height);
877 /* calculate geometry */
878 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
879 V4L2_FIELD_HAS_BOTH(ov->field),
880 &bttv_tvnorms[ov->tvnorm],&buf->crop);
882 /* build risc code */
885 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
887 case V4L2_FIELD_BOTTOM:
888 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
890 case V4L2_FIELD_INTERLACED:
891 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
892 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
898 /* copy format info */
899 buf->btformat = fmt->btformat;
900 buf->btswap = fmt->btswap;
901 buf->vb.field = ov->field;