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,skip,nskips;
248 struct btcx_skiplist *skips;
253 /* skip list for window clipping */
254 if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
257 /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
258 + sync + jump (all 2 dwords) */
259 dwords = (3 * ov->nclips + 2) *
260 ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
262 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
267 /* sync instruction */
269 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
270 *(rp++) = cpu_to_le32(0);
272 addr = (unsigned long)btv->fbuf.base;
273 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
274 addr += (fmt->depth >> 3) * ov->w.left;
277 for (maxy = -1, line = 0; line < ov->w.height;
278 line++, addr += btv->fbuf.fmt.bytesperline) {
279 if ((btv->opt_vcr_hack) &&
280 (line >= (ov->w.height - VCR_HACK_LINES)))
282 if ((line%2) == 0 && skip_even)
284 if ((line%2) == 1 && skip_odd)
287 /* calculate clipping */
289 btcx_calc_skips(line, ov->w.width, &maxy,
290 skips, &nskips, ov->clips, ov->nclips);
292 /* write out risc code */
293 for (start = 0, skip = 0; start < ov->w.width; start = end) {
294 if (skip >= nskips) {
295 ri = BT848_RISC_WRITE;
297 } else if (start < skips[skip].start) {
298 ri = BT848_RISC_WRITE;
299 end = skips[skip].start;
301 ri = BT848_RISC_SKIP;
302 end = skips[skip].end;
305 if (BT848_RISC_WRITE == ri)
306 ra = addr + (fmt->depth>>3)*start;
311 ri |= BT848_RISC_SOL;
312 if (ov->w.width == end)
313 ri |= BT848_RISC_EOL;
314 ri |= (fmt->depth>>3) * (end-start);
316 *(rp++)=cpu_to_le32(ri);
318 *(rp++)=cpu_to_le32(ra);
322 /* save pointer to jmp instruction address */
324 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
329 /* ---------------------------------------------------------- */
332 bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
333 int width, int height, int interleaved,
334 const struct bttv_tvnorm *tvnorm)
339 int swidth = tvnorm->swidth;
340 int totalwidth = tvnorm->totalwidth;
341 int scaledtwidth = tvnorm->scaledtwidth;
343 if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
349 vdelay = tvnorm->vdelay;
351 xsf = (width*scaledtwidth)/swidth;
352 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
353 geo->hdelay = tvnorm->hdelayx1;
354 geo->hdelay = (geo->hdelay*width)/swidth;
355 geo->hdelay &= 0x3fe;
356 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
357 geo->vscale = (0x10000UL-sr) & 0x1fff;
358 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
359 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
360 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
361 geo->vdelay = vdelay;
363 geo->sheight = tvnorm->sheight;
364 geo->vtotal = tvnorm->vtotal;
366 if (btv->opt_combfilter) {
367 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
368 geo->comb = (width < 769) ? 1 : 0;
376 bttv_calc_geo (struct bttv * btv,
377 struct bttv_geometry * geo,
381 const struct bttv_tvnorm * tvnorm,
382 const struct v4l2_rect * crop)
384 unsigned int c_width;
385 unsigned int c_height;
388 if ((crop->left == tvnorm->cropcap.defrect.left
389 && crop->top == tvnorm->cropcap.defrect.top
390 && crop->width == tvnorm->cropcap.defrect.width
391 && crop->height == tvnorm->cropcap.defrect.height
392 && width <= tvnorm->swidth /* see PAL-Nc et al */)
393 || bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
394 bttv_calc_geo_old(btv, geo, width, height,
395 both_fields, tvnorm);
399 /* For bug compatibility the image size checks permit scale
400 factors > 16. See bttv_crop_calc_limits(). */
401 c_width = min((unsigned int) crop->width, width * 16);
402 c_height = min((unsigned int) crop->height, height * 16);
405 geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
406 /* Even to store Cb first, odd for Cr. */
407 geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
409 geo->sheight = c_height;
410 geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
411 sr = c_height >> !both_fields;
412 sr = (sr * 512U + (height >> 1)) / height - 512;
413 geo->vscale = (0x10000UL - sr) & 0x1fff;
414 geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
415 geo->vtotal = tvnorm->vtotal;
417 geo->crop = (((geo->width >> 8) & 0x03) |
418 ((geo->hdelay >> 6) & 0x0c) |
419 ((geo->sheight >> 4) & 0x30) |
420 ((geo->vdelay >> 2) & 0xc0));
422 if (btv->opt_combfilter) {
423 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
424 geo->comb = (width < 769) ? 1 : 0;
432 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
434 int off = odd ? 0x80 : 0x00;
437 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
439 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
441 btwrite(geo->vtc, BT848_E_VTC+off);
442 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
443 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
444 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
445 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
446 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
447 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
448 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
449 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
450 btwrite(geo->crop, BT848_E_CROP+off);
451 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
452 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
455 /* ---------------------------------------------------------- */
456 /* risc group / risc main loop / dma management */
459 bttv_set_dma(struct bttv *btv, int override)
465 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
466 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
467 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
470 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
471 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
475 "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
476 btv->c.nr,capctl,btv->loop_irq,
477 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
478 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
479 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
480 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
482 cmd = BT848_RISC_JUMP;
484 cmd |= BT848_RISC_IRQ;
485 cmd |= (btv->loop_irq & 0x0f) << 16;
486 cmd |= (~btv->loop_irq & 0x0f) << 20;
488 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
489 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
491 del_timer(&btv->timeout);
493 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
495 btaor(capctl, ~0x0f, BT848_CAP_CTL);
499 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
500 btor(3, BT848_GPIO_DMA_CTL);
505 btand(~3, BT848_GPIO_DMA_CTL);
512 bttv_risc_init_main(struct bttv *btv)
516 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
518 dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
519 btv->c.nr,(unsigned long long)btv->main.dma);
521 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
522 BT848_FIFO_STATUS_VRE);
523 btv->main.cpu[1] = cpu_to_le32(0);
524 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
525 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
528 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
529 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
530 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
531 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
533 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
534 BT848_FIFO_STATUS_VRO);
535 btv->main.cpu[9] = cpu_to_le32(0);
538 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
539 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
540 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
541 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
543 /* jump back to top field */
544 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
545 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
551 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
555 unsigned long next = btv->main.dma + ((slot+2) << 2);
558 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
559 btv->c.nr,risc,slot);
560 btv->main.cpu[slot+1] = cpu_to_le32(next);
562 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
563 btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
564 cmd = BT848_RISC_JUMP;
566 cmd |= BT848_RISC_IRQ;
567 cmd |= (irqflags & 0x0f) << 16;
568 cmd |= (~irqflags & 0x0f) << 20;
570 risc->jmp[0] = cpu_to_le32(cmd);
571 risc->jmp[1] = cpu_to_le32(next);
572 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
578 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
580 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
582 BUG_ON(in_interrupt());
583 videobuf_waiton(&buf->vb,0,0);
584 videobuf_dma_unmap(q, dma);
585 videobuf_dma_free(dma);
586 btcx_riscmem_free(btv->c.pci,&buf->bottom);
587 btcx_riscmem_free(btv->c.pci,&buf->top);
588 buf->vb.state = VIDEOBUF_NEEDS_INIT;
592 bttv_buffer_activate_vbi(struct bttv *btv,
593 struct bttv_buffer *vbi)
595 struct btcx_riscmem *top;
596 struct btcx_riscmem *bottom;
598 int bottom_irq_flags;
603 bottom_irq_flags = 0;
606 unsigned int crop, vdelay;
608 vbi->vb.state = VIDEOBUF_ACTIVE;
609 list_del(&vbi->vb.queue);
611 /* VDELAY is start of video, end of VBI capturing. */
612 crop = btread(BT848_E_CROP);
613 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
615 if (vbi->geo.vdelay > vdelay) {
616 vdelay = vbi->geo.vdelay & 0xfe;
617 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
619 btwrite(vdelay, BT848_E_VDELAY_LO);
620 btwrite(crop, BT848_E_CROP);
621 btwrite(vdelay, BT848_O_VDELAY_LO);
622 btwrite(crop, BT848_O_CROP);
625 if (vbi->vbi_count[0] > 0) {
630 if (vbi->vbi_count[1] > 0) {
632 bottom = &vbi->bottom;
633 bottom_irq_flags = 4;
637 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
638 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
644 bttv_buffer_activate_video(struct bttv *btv,
645 struct bttv_buffer_set *set)
648 if (NULL != set->top && NULL != set->bottom) {
649 if (set->top == set->bottom) {
650 set->top->vb.state = VIDEOBUF_ACTIVE;
651 if (set->top->vb.queue.next)
652 list_del(&set->top->vb.queue);
654 set->top->vb.state = VIDEOBUF_ACTIVE;
655 set->bottom->vb.state = VIDEOBUF_ACTIVE;
656 if (set->top->vb.queue.next)
657 list_del(&set->top->vb.queue);
658 if (set->bottom->vb.queue.next)
659 list_del(&set->bottom->vb.queue);
661 bttv_apply_geo(btv, &set->top->geo, 1);
662 bttv_apply_geo(btv, &set->bottom->geo,0);
663 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
665 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
667 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
668 ~0xff, BT848_COLOR_FMT);
669 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
670 ~0x0f, BT848_COLOR_CTL);
671 } else if (NULL != set->top) {
672 set->top->vb.state = VIDEOBUF_ACTIVE;
673 if (set->top->vb.queue.next)
674 list_del(&set->top->vb.queue);
675 bttv_apply_geo(btv, &set->top->geo,1);
676 bttv_apply_geo(btv, &set->top->geo,0);
677 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
679 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
680 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
681 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
682 } else if (NULL != set->bottom) {
683 set->bottom->vb.state = VIDEOBUF_ACTIVE;
684 if (set->bottom->vb.queue.next)
685 list_del(&set->bottom->vb.queue);
686 bttv_apply_geo(btv, &set->bottom->geo,1);
687 bttv_apply_geo(btv, &set->bottom->geo,0);
688 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
689 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
691 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
692 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
694 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
695 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
700 /* ---------------------------------------------------------- */
702 /* calculate geometry, build risc code */
704 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
706 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
707 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
710 "bttv%d: buffer field: %s format: %s size: %dx%d\n",
711 btv->c.nr, v4l2_field_names[buf->vb.field],
712 buf->fmt->name, buf->vb.width, buf->vb.height);
714 /* packed pixel modes */
715 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
716 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
717 int bpf = bpl * (buf->vb.height >> 1);
719 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
720 V4L2_FIELD_HAS_BOTH(buf->vb.field),
723 switch (buf->vb.field) {
725 bttv_risc_packed(btv,&buf->top,dma->sglist,
727 /* padding */ 0,/* skip_lines */ 0,
730 case V4L2_FIELD_BOTTOM:
731 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
732 0,bpl,0,0,buf->vb.height);
734 case V4L2_FIELD_INTERLACED:
735 bttv_risc_packed(btv,&buf->top,dma->sglist,
736 0,bpl,bpl,0,buf->vb.height >> 1);
737 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
738 bpl,bpl,bpl,0,buf->vb.height >> 1);
740 case V4L2_FIELD_SEQ_TB:
741 bttv_risc_packed(btv,&buf->top,dma->sglist,
742 0,bpl,0,0,buf->vb.height >> 1);
743 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
744 bpf,bpl,0,0,buf->vb.height >> 1);
752 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
753 int uoffset, voffset;
754 int ypadding, cpadding, lines;
756 /* calculate chroma offsets */
757 uoffset = buf->vb.width * buf->vb.height;
758 voffset = buf->vb.width * buf->vb.height;
759 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
760 /* Y-Cr-Cb plane order */
761 uoffset >>= buf->fmt->hshift;
762 uoffset >>= buf->fmt->vshift;
765 /* Y-Cb-Cr plane order */
766 voffset >>= buf->fmt->hshift;
767 voffset >>= buf->fmt->vshift;
771 switch (buf->vb.field) {
773 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
774 buf->vb.height,/* both_fields */ 0,
776 bttv_risc_planar(btv, &buf->top, dma->sglist,
777 0,buf->vb.width,0,buf->vb.height,
778 uoffset,voffset,buf->fmt->hshift,
781 case V4L2_FIELD_BOTTOM:
782 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
785 bttv_risc_planar(btv, &buf->bottom, dma->sglist,
786 0,buf->vb.width,0,buf->vb.height,
787 uoffset,voffset,buf->fmt->hshift,
790 case V4L2_FIELD_INTERLACED:
791 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
794 lines = buf->vb.height >> 1;
795 ypadding = buf->vb.width;
796 cpadding = buf->vb.width >> buf->fmt->hshift;
797 bttv_risc_planar(btv,&buf->top,
799 0,buf->vb.width,ypadding,lines,
804 bttv_risc_planar(btv,&buf->bottom,
806 ypadding,buf->vb.width,ypadding,lines,
813 case V4L2_FIELD_SEQ_TB:
814 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
817 lines = buf->vb.height >> 1;
818 ypadding = buf->vb.width;
819 cpadding = buf->vb.width >> buf->fmt->hshift;
820 bttv_risc_planar(btv,&buf->top,
822 0,buf->vb.width,0,lines,
828 bttv_risc_planar(btv,&buf->bottom,
830 lines * ypadding,buf->vb.width,0,lines,
831 lines * ypadding + (uoffset >> 1),
832 lines * ypadding + (voffset >> 1),
843 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
844 /* build risc code */
845 buf->vb.field = V4L2_FIELD_SEQ_TB;
846 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
847 1,tvnorm,&buf->crop);
848 bttv_risc_packed(btv, &buf->top, dma->sglist,
849 /* offset */ 0, RAW_BPL, /* padding */ 0,
850 /* skip_lines */ 0, RAW_LINES);
851 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
852 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
855 /* copy format info */
856 buf->btformat = buf->fmt->btformat;
857 buf->btswap = buf->fmt->btswap;
861 /* ---------------------------------------------------------- */
863 /* calculate geometry, build risc code */
865 bttv_overlay_risc(struct bttv *btv,
866 struct bttv_overlay *ov,
867 const struct bttv_format *fmt,
868 struct bttv_buffer *buf)
870 /* check interleave, bottom+top fields */
872 "bttv%d: overlay fields: %s format: %s size: %dx%d\n",
873 btv->c.nr, v4l2_field_names[buf->vb.field],
874 fmt->name,ov->w.width,ov->w.height);
876 /* calculate geometry */
877 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
878 V4L2_FIELD_HAS_BOTH(ov->field),
879 &bttv_tvnorms[ov->tvnorm],&buf->crop);
881 /* build risc code */
884 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
886 case V4L2_FIELD_BOTTOM:
887 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
889 case V4L2_FIELD_INTERLACED:
890 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
891 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
897 /* copy format info */
898 buf->btformat = fmt->btformat;
899 buf->btswap = fmt->btswap;
900 buf->vb.field = ov->field;