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 split */
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);
193 /* calculate max number of bytes we can write */
195 if (yoffset + ylen > sg_dma_len(ysg))
196 ylen = sg_dma_len(ysg) - yoffset;
198 while (uoffset && uoffset >= sg_dma_len(usg)) {
199 uoffset -= sg_dma_len(usg);
202 while (voffset && voffset >= sg_dma_len(vsg)) {
203 voffset -= sg_dma_len(vsg);
207 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
208 ylen = (sg_dma_len(usg) - uoffset) << hshift;
209 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
210 ylen = (sg_dma_len(vsg) - voffset) << hshift;
211 ri = BT848_RISC_WRITE123;
213 ri = BT848_RISC_WRITE1S23;
216 ri |= BT848_RISC_SOL;
218 ri |= BT848_RISC_EOL;
220 /* write risc instruction */
221 *(rp++)=cpu_to_le32(ri | ylen);
222 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
224 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
227 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
228 uoffset += ylen >> hshift;
229 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
230 voffset += ylen >> hshift;
240 /* save pointer to jmp instruction address */
242 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
247 bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
248 const struct bttv_format *fmt, struct bttv_overlay *ov,
249 int skip_even, int skip_odd)
251 int dwords, rc, line, maxy, start, end;
252 unsigned skip, nskips;
253 struct btcx_skiplist *skips;
258 /* skip list for window clipping */
259 skips = kmalloc_array(ov->nclips, sizeof(*skips),GFP_KERNEL);
263 /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
264 + sync + jump (all 2 dwords) */
265 dwords = (3 * ov->nclips + 2) *
266 ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
268 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
273 /* sync instruction */
275 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
276 *(rp++) = cpu_to_le32(0);
278 addr = (unsigned long)btv->fbuf.base;
279 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
280 addr += (fmt->depth >> 3) * ov->w.left;
283 for (maxy = -1, line = 0; line < ov->w.height;
284 line++, addr += btv->fbuf.fmt.bytesperline) {
285 if ((btv->opt_vcr_hack) &&
286 (line >= (ov->w.height - VCR_HACK_LINES)))
288 if ((line%2) == 0 && skip_even)
290 if ((line%2) == 1 && skip_odd)
293 /* calculate clipping */
295 btcx_calc_skips(line, ov->w.width, &maxy,
296 skips, &nskips, ov->clips, ov->nclips);
298 /* write out risc code */
299 for (start = 0, skip = 0; start < ov->w.width; start = end) {
300 if (skip >= nskips) {
301 ri = BT848_RISC_WRITE;
303 } else if (start < skips[skip].start) {
304 ri = BT848_RISC_WRITE;
305 end = skips[skip].start;
307 ri = BT848_RISC_SKIP;
308 end = skips[skip].end;
311 if (BT848_RISC_WRITE == ri)
312 ra = addr + (fmt->depth>>3)*start;
317 ri |= BT848_RISC_SOL;
318 if (ov->w.width == end)
319 ri |= BT848_RISC_EOL;
320 ri |= (fmt->depth>>3) * (end-start);
322 *(rp++)=cpu_to_le32(ri);
324 *(rp++)=cpu_to_le32(ra);
328 /* save pointer to jmp instruction address */
330 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
335 /* ---------------------------------------------------------- */
338 bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
339 int width, int height, int interleaved,
340 const struct bttv_tvnorm *tvnorm)
345 int swidth = tvnorm->swidth;
346 int totalwidth = tvnorm->totalwidth;
347 int scaledtwidth = tvnorm->scaledtwidth;
349 if (btv->input == btv->dig) {
355 vdelay = tvnorm->vdelay;
357 xsf = (width*scaledtwidth)/swidth;
358 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
359 geo->hdelay = tvnorm->hdelayx1;
360 geo->hdelay = (geo->hdelay*width)/swidth;
361 geo->hdelay &= 0x3fe;
362 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
363 geo->vscale = (0x10000UL-sr) & 0x1fff;
364 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
365 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
366 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
367 geo->vdelay = vdelay;
369 geo->sheight = tvnorm->sheight;
370 geo->vtotal = tvnorm->vtotal;
372 if (btv->opt_combfilter) {
373 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
374 geo->comb = (width < 769) ? 1 : 0;
382 bttv_calc_geo (struct bttv * btv,
383 struct bttv_geometry * geo,
387 const struct bttv_tvnorm * tvnorm,
388 const struct v4l2_rect * crop)
390 unsigned int c_width;
391 unsigned int c_height;
394 if ((crop->left == tvnorm->cropcap.defrect.left
395 && crop->top == tvnorm->cropcap.defrect.top
396 && crop->width == tvnorm->cropcap.defrect.width
397 && crop->height == tvnorm->cropcap.defrect.height
398 && width <= tvnorm->swidth /* see PAL-Nc et al */)
399 || btv->input == btv->dig) {
400 bttv_calc_geo_old(btv, geo, width, height,
401 both_fields, tvnorm);
405 /* For bug compatibility the image size checks permit scale
406 factors > 16. See bttv_crop_calc_limits(). */
407 c_width = min((unsigned int) crop->width, width * 16);
408 c_height = min((unsigned int) crop->height, height * 16);
411 geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
412 /* Even to store Cb first, odd for Cr. */
413 geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
415 geo->sheight = c_height;
416 geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
417 sr = c_height >> !both_fields;
418 sr = (sr * 512U + (height >> 1)) / height - 512;
419 geo->vscale = (0x10000UL - sr) & 0x1fff;
420 geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
421 geo->vtotal = tvnorm->vtotal;
423 geo->crop = (((geo->width >> 8) & 0x03) |
424 ((geo->hdelay >> 6) & 0x0c) |
425 ((geo->sheight >> 4) & 0x30) |
426 ((geo->vdelay >> 2) & 0xc0));
428 if (btv->opt_combfilter) {
429 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
430 geo->comb = (width < 769) ? 1 : 0;
438 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
440 int off = odd ? 0x80 : 0x00;
443 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
445 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
447 btwrite(geo->vtc, BT848_E_VTC+off);
448 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
449 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
450 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
451 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
452 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
453 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
454 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
455 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
456 btwrite(geo->crop, BT848_E_CROP+off);
457 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
458 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
461 /* ---------------------------------------------------------- */
462 /* risc group / risc main loop / dma management */
465 bttv_set_dma(struct bttv *btv, int override)
471 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
472 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
473 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
476 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
477 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
480 d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n",
481 btv->c.nr,capctl,btv->loop_irq,
482 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
483 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
484 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
485 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
487 cmd = BT848_RISC_JUMP;
489 cmd |= BT848_RISC_IRQ;
490 cmd |= (btv->loop_irq & 0x0f) << 16;
491 cmd |= (~btv->loop_irq & 0x0f) << 20;
493 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
494 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
496 del_timer(&btv->timeout);
498 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
500 btaor(capctl, ~0x0f, BT848_CAP_CTL);
504 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
505 btor(3, BT848_GPIO_DMA_CTL);
510 btand(~3, BT848_GPIO_DMA_CTL);
517 bttv_risc_init_main(struct bttv *btv)
521 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
523 dprintk("%d: risc main @ %08llx\n",
524 btv->c.nr, (unsigned long long)btv->main.dma);
526 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
527 BT848_FIFO_STATUS_VRE);
528 btv->main.cpu[1] = cpu_to_le32(0);
529 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
530 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
533 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
534 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
535 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
536 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
538 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
539 BT848_FIFO_STATUS_VRO);
540 btv->main.cpu[9] = cpu_to_le32(0);
543 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
544 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
545 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
546 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
548 /* jump back to top field */
549 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
550 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
556 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
560 unsigned long next = btv->main.dma + ((slot+2) << 2);
563 d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot);
564 btv->main.cpu[slot+1] = cpu_to_le32(next);
566 d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n",
567 btv->c.nr, risc, slot,
568 (unsigned long long)risc->dma, irqflags);
569 cmd = BT848_RISC_JUMP;
571 cmd |= BT848_RISC_IRQ;
572 cmd |= (irqflags & 0x0f) << 16;
573 cmd |= (~irqflags & 0x0f) << 20;
575 risc->jmp[0] = cpu_to_le32(cmd);
576 risc->jmp[1] = cpu_to_le32(next);
577 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
583 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
585 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
587 BUG_ON(in_interrupt());
588 videobuf_waiton(q, &buf->vb, 0, 0);
589 videobuf_dma_unmap(q->dev, dma);
590 videobuf_dma_free(dma);
591 btcx_riscmem_free(btv->c.pci,&buf->bottom);
592 btcx_riscmem_free(btv->c.pci,&buf->top);
593 buf->vb.state = VIDEOBUF_NEEDS_INIT;
597 bttv_buffer_activate_vbi(struct bttv *btv,
598 struct bttv_buffer *vbi)
600 struct btcx_riscmem *top;
601 struct btcx_riscmem *bottom;
603 int bottom_irq_flags;
608 bottom_irq_flags = 0;
611 unsigned int crop, vdelay;
613 vbi->vb.state = VIDEOBUF_ACTIVE;
614 list_del(&vbi->vb.queue);
616 /* VDELAY is start of video, end of VBI capturing. */
617 crop = btread(BT848_E_CROP);
618 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
620 if (vbi->geo.vdelay > vdelay) {
621 vdelay = vbi->geo.vdelay & 0xfe;
622 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
624 btwrite(vdelay, BT848_E_VDELAY_LO);
625 btwrite(crop, BT848_E_CROP);
626 btwrite(vdelay, BT848_O_VDELAY_LO);
627 btwrite(crop, BT848_O_CROP);
630 if (vbi->vbi_count[0] > 0) {
635 if (vbi->vbi_count[1] > 0) {
637 bottom = &vbi->bottom;
638 bottom_irq_flags = 4;
642 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
643 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
649 bttv_buffer_activate_video(struct bttv *btv,
650 struct bttv_buffer_set *set)
653 if (NULL != set->top && NULL != set->bottom) {
654 if (set->top == set->bottom) {
655 set->top->vb.state = VIDEOBUF_ACTIVE;
656 if (set->top->vb.queue.next)
657 list_del(&set->top->vb.queue);
659 set->top->vb.state = VIDEOBUF_ACTIVE;
660 set->bottom->vb.state = VIDEOBUF_ACTIVE;
661 if (set->top->vb.queue.next)
662 list_del(&set->top->vb.queue);
663 if (set->bottom->vb.queue.next)
664 list_del(&set->bottom->vb.queue);
666 bttv_apply_geo(btv, &set->top->geo, 1);
667 bttv_apply_geo(btv, &set->bottom->geo,0);
668 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
670 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
672 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
673 ~0xff, BT848_COLOR_FMT);
674 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
675 ~0x0f, BT848_COLOR_CTL);
676 } else if (NULL != set->top) {
677 set->top->vb.state = VIDEOBUF_ACTIVE;
678 if (set->top->vb.queue.next)
679 list_del(&set->top->vb.queue);
680 bttv_apply_geo(btv, &set->top->geo,1);
681 bttv_apply_geo(btv, &set->top->geo,0);
682 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
684 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
685 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
686 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
687 } else if (NULL != set->bottom) {
688 set->bottom->vb.state = VIDEOBUF_ACTIVE;
689 if (set->bottom->vb.queue.next)
690 list_del(&set->bottom->vb.queue);
691 bttv_apply_geo(btv, &set->bottom->geo,1);
692 bttv_apply_geo(btv, &set->bottom->geo,0);
693 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
694 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
696 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
697 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
699 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
700 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
705 /* ---------------------------------------------------------- */
707 /* calculate geometry, build risc code */
709 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
711 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
712 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
714 dprintk("%d: buffer field: %s format: %s size: %dx%d\n",
715 btv->c.nr, v4l2_field_names[buf->vb.field],
716 buf->fmt->name, buf->vb.width, buf->vb.height);
718 /* packed pixel modes */
719 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
720 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
721 int bpf = bpl * (buf->vb.height >> 1);
723 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
724 V4L2_FIELD_HAS_BOTH(buf->vb.field),
727 switch (buf->vb.field) {
729 bttv_risc_packed(btv,&buf->top,dma->sglist,
731 /* padding */ 0,/* skip_lines */ 0,
734 case V4L2_FIELD_BOTTOM:
735 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
736 0,bpl,0,0,buf->vb.height);
738 case V4L2_FIELD_INTERLACED:
739 bttv_risc_packed(btv,&buf->top,dma->sglist,
740 0,bpl,bpl,0,buf->vb.height >> 1);
741 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
742 bpl,bpl,bpl,0,buf->vb.height >> 1);
744 case V4L2_FIELD_SEQ_TB:
745 bttv_risc_packed(btv,&buf->top,dma->sglist,
746 0,bpl,0,0,buf->vb.height >> 1);
747 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
748 bpf,bpl,0,0,buf->vb.height >> 1);
756 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
757 int uoffset, voffset;
758 int ypadding, cpadding, lines;
760 /* calculate chroma offsets */
761 uoffset = buf->vb.width * buf->vb.height;
762 voffset = buf->vb.width * buf->vb.height;
763 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
764 /* Y-Cr-Cb plane order */
765 uoffset >>= buf->fmt->hshift;
766 uoffset >>= buf->fmt->vshift;
769 /* Y-Cb-Cr plane order */
770 voffset >>= buf->fmt->hshift;
771 voffset >>= buf->fmt->vshift;
775 switch (buf->vb.field) {
777 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
778 buf->vb.height,/* both_fields */ 0,
780 bttv_risc_planar(btv, &buf->top, dma->sglist,
781 0,buf->vb.width,0,buf->vb.height,
782 uoffset,voffset,buf->fmt->hshift,
785 case V4L2_FIELD_BOTTOM:
786 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
789 bttv_risc_planar(btv, &buf->bottom, dma->sglist,
790 0,buf->vb.width,0,buf->vb.height,
791 uoffset,voffset,buf->fmt->hshift,
794 case V4L2_FIELD_INTERLACED:
795 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
798 lines = buf->vb.height >> 1;
799 ypadding = buf->vb.width;
800 cpadding = buf->vb.width >> buf->fmt->hshift;
801 bttv_risc_planar(btv,&buf->top,
803 0,buf->vb.width,ypadding,lines,
808 bttv_risc_planar(btv,&buf->bottom,
810 ypadding,buf->vb.width,ypadding,lines,
817 case V4L2_FIELD_SEQ_TB:
818 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
821 lines = buf->vb.height >> 1;
822 ypadding = buf->vb.width;
823 cpadding = buf->vb.width >> buf->fmt->hshift;
824 bttv_risc_planar(btv,&buf->top,
826 0,buf->vb.width,0,lines,
832 bttv_risc_planar(btv,&buf->bottom,
834 lines * ypadding,buf->vb.width,0,lines,
835 lines * ypadding + (uoffset >> 1),
836 lines * ypadding + (voffset >> 1),
847 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
848 /* build risc code */
849 buf->vb.field = V4L2_FIELD_SEQ_TB;
850 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
851 1,tvnorm,&buf->crop);
852 bttv_risc_packed(btv, &buf->top, dma->sglist,
853 /* offset */ 0, RAW_BPL, /* padding */ 0,
854 /* skip_lines */ 0, RAW_LINES);
855 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
856 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
859 /* copy format info */
860 buf->btformat = buf->fmt->btformat;
861 buf->btswap = buf->fmt->btswap;
865 /* ---------------------------------------------------------- */
867 /* calculate geometry, build risc code */
869 bttv_overlay_risc(struct bttv *btv,
870 struct bttv_overlay *ov,
871 const struct bttv_format *fmt,
872 struct bttv_buffer *buf)
874 /* check interleave, bottom+top fields */
875 dprintk("%d: overlay fields: %s format: %s size: %dx%d\n",
876 btv->c.nr, v4l2_field_names[buf->vb.field],
877 fmt->name, ov->w.width, ov->w.height);
879 /* calculate geometry */
880 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
881 V4L2_FIELD_HAS_BOTH(ov->field),
882 &bttv_tvnorms[ov->tvnorm],&buf->crop);
884 /* build risc code */
887 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
889 case V4L2_FIELD_BOTTOM:
890 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
892 case V4L2_FIELD_INTERLACED:
893 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
894 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
900 /* copy format info */
901 buf->btformat = fmt->btformat;
902 buf->btswap = fmt->btswap;
903 buf->vb.field = ov->field;