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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
29 #include <linux/module.h>
30 #include <linux/init.h>
31 #include <linux/slab.h>
32 #include <linux/pci.h>
33 #include <linux/vmalloc.h>
34 #include <linux/interrupt.h>
36 #include <asm/pgtable.h>
37 #include <media/v4l2-ioctl.h>
41 #define VCR_HACK_LINES 4
43 /* ---------------------------------------------------------- */
44 /* risc code generators */
47 bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
48 struct scatterlist *sglist,
49 unsigned int offset, unsigned int bpl,
50 unsigned int padding, unsigned int skip_lines,
51 unsigned int store_lines)
53 u32 instructions,line,todo;
54 struct scatterlist *sg;
58 /* estimate risc mem: worst case is one write per page border +
59 one write per scan line + sync + jump (all 2 dwords). padding
60 can cause next bpl to start close to a page border. First DMA
61 region may be smaller than PAGE_SIZE */
62 instructions = skip_lines * 4;
63 instructions += (1 + ((bpl + padding) * store_lines)
64 / PAGE_SIZE + store_lines) * 8;
65 instructions += 2 * 8;
66 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions)) < 0)
69 /* sync instruction */
71 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
72 *(rp++) = cpu_to_le32(0);
74 while (skip_lines-- > 0) {
75 *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
76 BT848_RISC_EOL | bpl);
81 for (line = 0; line < store_lines; line++) {
82 if ((btv->opt_vcr_hack) &&
83 (line >= (store_lines - VCR_HACK_LINES)))
85 while (offset && offset >= sg_dma_len(sg)) {
86 offset -= sg_dma_len(sg);
89 if (bpl <= sg_dma_len(sg)-offset) {
90 /* fits into current chunk */
91 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
93 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
96 /* scanline needs to be splitted */
98 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
99 (sg_dma_len(sg)-offset));
100 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
101 todo -= (sg_dma_len(sg)-offset);
104 while (todo > sg_dma_len(sg)) {
105 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
107 *(rp++)=cpu_to_le32(sg_dma_address(sg));
108 todo -= sg_dma_len(sg);
111 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
113 *(rp++)=cpu_to_le32(sg_dma_address(sg));
119 /* save pointer to jmp instruction address */
121 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
126 bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
127 struct scatterlist *sglist,
128 unsigned int yoffset, unsigned int ybpl,
129 unsigned int ypadding, unsigned int ylines,
130 unsigned int uoffset, unsigned int voffset,
131 unsigned int hshift, unsigned int vshift,
132 unsigned int cpadding)
134 unsigned int instructions,line,todo,ylen,chroma;
137 struct scatterlist *ysg;
138 struct scatterlist *usg;
139 struct scatterlist *vsg;
140 int topfield = (0 == yoffset);
143 /* estimate risc mem: worst case is one write per page border +
144 one write per scan line (5 dwords)
145 plus sync + jump (2 dwords) */
146 instructions = ((3 + (ybpl + ypadding) * ylines * 2)
147 / PAGE_SIZE) + ylines;
149 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
152 /* sync instruction */
154 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
155 *(rp++) = cpu_to_le32(0);
161 for (line = 0; line < ylines; line++) {
162 if ((btv->opt_vcr_hack) &&
163 (line >= (ylines - VCR_HACK_LINES)))
171 chroma = ((line & 1) == 0);
173 chroma = ((line & 1) == 1);
177 chroma = ((line & 3) == 0);
179 chroma = ((line & 3) == 2);
186 for (todo = ybpl; todo > 0; todo -= ylen) {
187 /* go to next sg entry if needed */
188 while (yoffset && yoffset >= sg_dma_len(ysg)) {
189 yoffset -= sg_dma_len(ysg);
192 while (uoffset && uoffset >= sg_dma_len(usg)) {
193 uoffset -= sg_dma_len(usg);
196 while (voffset && voffset >= sg_dma_len(vsg)) {
197 voffset -= sg_dma_len(vsg);
201 /* calculate max number of bytes we can write */
203 if (yoffset + ylen > sg_dma_len(ysg))
204 ylen = sg_dma_len(ysg) - yoffset;
206 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
207 ylen = (sg_dma_len(usg) - uoffset) << hshift;
208 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
209 ylen = (sg_dma_len(vsg) - voffset) << hshift;
210 ri = BT848_RISC_WRITE123;
212 ri = BT848_RISC_WRITE1S23;
215 ri |= BT848_RISC_SOL;
217 ri |= BT848_RISC_EOL;
219 /* write risc instruction */
220 *(rp++)=cpu_to_le32(ri | ylen);
221 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
223 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
226 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
227 uoffset += ylen >> hshift;
228 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
229 voffset += ylen >> hshift;
239 /* save pointer to jmp instruction address */
241 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
246 bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
247 const struct bttv_format *fmt, struct bttv_overlay *ov,
248 int skip_even, int skip_odd)
250 int dwords, rc, line, maxy, start, end;
251 unsigned skip, nskips;
252 struct btcx_skiplist *skips;
257 /* skip list for window clipping */
258 if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
261 /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
262 + sync + jump (all 2 dwords) */
263 dwords = (3 * ov->nclips + 2) *
264 ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
266 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
271 /* sync instruction */
273 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
274 *(rp++) = cpu_to_le32(0);
276 addr = (unsigned long)btv->fbuf.base;
277 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
278 addr += (fmt->depth >> 3) * ov->w.left;
281 for (maxy = -1, line = 0; line < ov->w.height;
282 line++, addr += btv->fbuf.fmt.bytesperline) {
283 if ((btv->opt_vcr_hack) &&
284 (line >= (ov->w.height - VCR_HACK_LINES)))
286 if ((line%2) == 0 && skip_even)
288 if ((line%2) == 1 && skip_odd)
291 /* calculate clipping */
293 btcx_calc_skips(line, ov->w.width, &maxy,
294 skips, &nskips, ov->clips, ov->nclips);
296 /* write out risc code */
297 for (start = 0, skip = 0; start < ov->w.width; start = end) {
298 if (skip >= nskips) {
299 ri = BT848_RISC_WRITE;
301 } else if (start < skips[skip].start) {
302 ri = BT848_RISC_WRITE;
303 end = skips[skip].start;
305 ri = BT848_RISC_SKIP;
306 end = skips[skip].end;
309 if (BT848_RISC_WRITE == ri)
310 ra = addr + (fmt->depth>>3)*start;
315 ri |= BT848_RISC_SOL;
316 if (ov->w.width == end)
317 ri |= BT848_RISC_EOL;
318 ri |= (fmt->depth>>3) * (end-start);
320 *(rp++)=cpu_to_le32(ri);
322 *(rp++)=cpu_to_le32(ra);
326 /* save pointer to jmp instruction address */
328 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
333 /* ---------------------------------------------------------- */
336 bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
337 int width, int height, int interleaved,
338 const struct bttv_tvnorm *tvnorm)
343 int swidth = tvnorm->swidth;
344 int totalwidth = tvnorm->totalwidth;
345 int scaledtwidth = tvnorm->scaledtwidth;
347 if (btv->input == btv->dig) {
353 vdelay = tvnorm->vdelay;
355 xsf = (width*scaledtwidth)/swidth;
356 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
357 geo->hdelay = tvnorm->hdelayx1;
358 geo->hdelay = (geo->hdelay*width)/swidth;
359 geo->hdelay &= 0x3fe;
360 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
361 geo->vscale = (0x10000UL-sr) & 0x1fff;
362 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
363 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
364 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
365 geo->vdelay = vdelay;
367 geo->sheight = tvnorm->sheight;
368 geo->vtotal = tvnorm->vtotal;
370 if (btv->opt_combfilter) {
371 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
372 geo->comb = (width < 769) ? 1 : 0;
380 bttv_calc_geo (struct bttv * btv,
381 struct bttv_geometry * geo,
385 const struct bttv_tvnorm * tvnorm,
386 const struct v4l2_rect * crop)
388 unsigned int c_width;
389 unsigned int c_height;
392 if ((crop->left == tvnorm->cropcap.defrect.left
393 && crop->top == tvnorm->cropcap.defrect.top
394 && crop->width == tvnorm->cropcap.defrect.width
395 && crop->height == tvnorm->cropcap.defrect.height
396 && width <= tvnorm->swidth /* see PAL-Nc et al */)
397 || btv->input == btv->dig) {
398 bttv_calc_geo_old(btv, geo, width, height,
399 both_fields, tvnorm);
403 /* For bug compatibility the image size checks permit scale
404 factors > 16. See bttv_crop_calc_limits(). */
405 c_width = min((unsigned int) crop->width, width * 16);
406 c_height = min((unsigned int) crop->height, height * 16);
409 geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
410 /* Even to store Cb first, odd for Cr. */
411 geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
413 geo->sheight = c_height;
414 geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
415 sr = c_height >> !both_fields;
416 sr = (sr * 512U + (height >> 1)) / height - 512;
417 geo->vscale = (0x10000UL - sr) & 0x1fff;
418 geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
419 geo->vtotal = tvnorm->vtotal;
421 geo->crop = (((geo->width >> 8) & 0x03) |
422 ((geo->hdelay >> 6) & 0x0c) |
423 ((geo->sheight >> 4) & 0x30) |
424 ((geo->vdelay >> 2) & 0xc0));
426 if (btv->opt_combfilter) {
427 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
428 geo->comb = (width < 769) ? 1 : 0;
436 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
438 int off = odd ? 0x80 : 0x00;
441 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
443 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
445 btwrite(geo->vtc, BT848_E_VTC+off);
446 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
447 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
448 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
449 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
450 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
451 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
452 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
453 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
454 btwrite(geo->crop, BT848_E_CROP+off);
455 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
456 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
459 /* ---------------------------------------------------------- */
460 /* risc group / risc main loop / dma management */
463 bttv_set_dma(struct bttv *btv, int override)
469 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
470 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
471 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
474 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
475 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
478 d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n",
479 btv->c.nr,capctl,btv->loop_irq,
480 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
481 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
482 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
483 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
485 cmd = BT848_RISC_JUMP;
487 cmd |= BT848_RISC_IRQ;
488 cmd |= (btv->loop_irq & 0x0f) << 16;
489 cmd |= (~btv->loop_irq & 0x0f) << 20;
491 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
492 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
494 del_timer(&btv->timeout);
496 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
498 btaor(capctl, ~0x0f, BT848_CAP_CTL);
502 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
503 btor(3, BT848_GPIO_DMA_CTL);
508 btand(~3, BT848_GPIO_DMA_CTL);
515 bttv_risc_init_main(struct bttv *btv)
519 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
521 dprintk("%d: risc main @ %08llx\n",
522 btv->c.nr, (unsigned long long)btv->main.dma);
524 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
525 BT848_FIFO_STATUS_VRE);
526 btv->main.cpu[1] = cpu_to_le32(0);
527 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
528 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
531 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
532 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
533 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
534 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
536 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
537 BT848_FIFO_STATUS_VRO);
538 btv->main.cpu[9] = cpu_to_le32(0);
541 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
542 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
543 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
544 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
546 /* jump back to top field */
547 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
548 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
554 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
558 unsigned long next = btv->main.dma + ((slot+2) << 2);
561 d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot);
562 btv->main.cpu[slot+1] = cpu_to_le32(next);
564 d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n",
565 btv->c.nr, risc, slot,
566 (unsigned long long)risc->dma, irqflags);
567 cmd = BT848_RISC_JUMP;
569 cmd |= BT848_RISC_IRQ;
570 cmd |= (irqflags & 0x0f) << 16;
571 cmd |= (~irqflags & 0x0f) << 20;
573 risc->jmp[0] = cpu_to_le32(cmd);
574 risc->jmp[1] = cpu_to_le32(next);
575 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
581 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
583 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
585 BUG_ON(in_interrupt());
586 videobuf_waiton(q, &buf->vb, 0, 0);
587 videobuf_dma_unmap(q->dev, dma);
588 videobuf_dma_free(dma);
589 btcx_riscmem_free(btv->c.pci,&buf->bottom);
590 btcx_riscmem_free(btv->c.pci,&buf->top);
591 buf->vb.state = VIDEOBUF_NEEDS_INIT;
595 bttv_buffer_activate_vbi(struct bttv *btv,
596 struct bttv_buffer *vbi)
598 struct btcx_riscmem *top;
599 struct btcx_riscmem *bottom;
601 int bottom_irq_flags;
606 bottom_irq_flags = 0;
609 unsigned int crop, vdelay;
611 vbi->vb.state = VIDEOBUF_ACTIVE;
612 list_del(&vbi->vb.queue);
614 /* VDELAY is start of video, end of VBI capturing. */
615 crop = btread(BT848_E_CROP);
616 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
618 if (vbi->geo.vdelay > vdelay) {
619 vdelay = vbi->geo.vdelay & 0xfe;
620 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
622 btwrite(vdelay, BT848_E_VDELAY_LO);
623 btwrite(crop, BT848_E_CROP);
624 btwrite(vdelay, BT848_O_VDELAY_LO);
625 btwrite(crop, BT848_O_CROP);
628 if (vbi->vbi_count[0] > 0) {
633 if (vbi->vbi_count[1] > 0) {
635 bottom = &vbi->bottom;
636 bottom_irq_flags = 4;
640 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
641 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
647 bttv_buffer_activate_video(struct bttv *btv,
648 struct bttv_buffer_set *set)
651 if (NULL != set->top && NULL != set->bottom) {
652 if (set->top == set->bottom) {
653 set->top->vb.state = VIDEOBUF_ACTIVE;
654 if (set->top->vb.queue.next)
655 list_del(&set->top->vb.queue);
657 set->top->vb.state = VIDEOBUF_ACTIVE;
658 set->bottom->vb.state = VIDEOBUF_ACTIVE;
659 if (set->top->vb.queue.next)
660 list_del(&set->top->vb.queue);
661 if (set->bottom->vb.queue.next)
662 list_del(&set->bottom->vb.queue);
664 bttv_apply_geo(btv, &set->top->geo, 1);
665 bttv_apply_geo(btv, &set->bottom->geo,0);
666 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
668 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
670 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
671 ~0xff, BT848_COLOR_FMT);
672 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
673 ~0x0f, BT848_COLOR_CTL);
674 } else if (NULL != set->top) {
675 set->top->vb.state = VIDEOBUF_ACTIVE;
676 if (set->top->vb.queue.next)
677 list_del(&set->top->vb.queue);
678 bttv_apply_geo(btv, &set->top->geo,1);
679 bttv_apply_geo(btv, &set->top->geo,0);
680 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
682 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
683 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
684 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
685 } else if (NULL != set->bottom) {
686 set->bottom->vb.state = VIDEOBUF_ACTIVE;
687 if (set->bottom->vb.queue.next)
688 list_del(&set->bottom->vb.queue);
689 bttv_apply_geo(btv, &set->bottom->geo,1);
690 bttv_apply_geo(btv, &set->bottom->geo,0);
691 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
692 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
694 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
695 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
697 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
698 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
703 /* ---------------------------------------------------------- */
705 /* calculate geometry, build risc code */
707 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
709 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
710 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
712 dprintk("%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 */
873 dprintk("%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;