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>
37 #define VCR_HACK_LINES 4
39 /* ---------------------------------------------------------- */
40 /* risc code generators */
43 bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
44 struct scatterlist *sglist,
45 unsigned int offset, unsigned int bpl,
46 unsigned int padding, unsigned int skip_lines,
47 unsigned int store_lines)
49 u32 instructions,line,todo;
50 struct scatterlist *sg;
54 /* estimate risc mem: worst case is one write per page border +
55 one write per scan line + sync + jump (all 2 dwords). padding
56 can cause next bpl to start close to a page border. First DMA
57 region may be smaller than PAGE_SIZE */
58 instructions = skip_lines * 4;
59 instructions += (1 + ((bpl + padding) * store_lines)
60 / PAGE_SIZE + store_lines) * 8;
61 instructions += 2 * 8;
62 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions)) < 0)
65 /* sync instruction */
67 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
68 *(rp++) = cpu_to_le32(0);
70 while (skip_lines-- > 0) {
71 *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
72 BT848_RISC_EOL | bpl);
77 for (line = 0; line < store_lines; line++) {
78 if ((btv->opt_vcr_hack) &&
79 (line >= (store_lines - VCR_HACK_LINES)))
81 while (offset && offset >= sg_dma_len(sg)) {
82 offset -= sg_dma_len(sg);
85 if (bpl <= sg_dma_len(sg)-offset) {
86 /* fits into current chunk */
87 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
89 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
92 /* scanline needs to be splitted */
94 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
95 (sg_dma_len(sg)-offset));
96 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
97 todo -= (sg_dma_len(sg)-offset);
100 while (todo > sg_dma_len(sg)) {
101 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
103 *(rp++)=cpu_to_le32(sg_dma_address(sg));
104 todo -= sg_dma_len(sg);
107 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
109 *(rp++)=cpu_to_le32(sg_dma_address(sg));
115 /* save pointer to jmp instruction address */
117 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
122 bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
123 struct scatterlist *sglist,
124 unsigned int yoffset, unsigned int ybpl,
125 unsigned int ypadding, unsigned int ylines,
126 unsigned int uoffset, unsigned int voffset,
127 unsigned int hshift, unsigned int vshift,
128 unsigned int cpadding)
130 unsigned int instructions,line,todo,ylen,chroma;
133 struct scatterlist *ysg;
134 struct scatterlist *usg;
135 struct scatterlist *vsg;
136 int topfield = (0 == yoffset);
139 /* estimate risc mem: worst case is one write per page border +
140 one write per scan line (5 dwords)
141 plus sync + jump (2 dwords) */
142 instructions = ((3 + (ybpl + ypadding) * ylines * 2)
143 / PAGE_SIZE) + ylines;
145 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
148 /* sync instruction */
150 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
151 *(rp++) = cpu_to_le32(0);
157 for (line = 0; line < ylines; line++) {
158 if ((btv->opt_vcr_hack) &&
159 (line >= (ylines - VCR_HACK_LINES)))
167 chroma = ((line & 1) == 0);
169 chroma = ((line & 1) == 1);
173 chroma = ((line & 3) == 0);
175 chroma = ((line & 3) == 2);
182 for (todo = ybpl; todo > 0; todo -= ylen) {
183 /* go to next sg entry if needed */
184 while (yoffset && yoffset >= sg_dma_len(ysg)) {
185 yoffset -= sg_dma_len(ysg);
188 while (uoffset && uoffset >= sg_dma_len(usg)) {
189 uoffset -= sg_dma_len(usg);
192 while (voffset && voffset >= sg_dma_len(vsg)) {
193 voffset -= sg_dma_len(vsg);
197 /* calculate max number of bytes we can write */
199 if (yoffset + ylen > sg_dma_len(ysg))
200 ylen = sg_dma_len(ysg) - yoffset;
202 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
203 ylen = (sg_dma_len(usg) - uoffset) << hshift;
204 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
205 ylen = (sg_dma_len(vsg) - voffset) << hshift;
206 ri = BT848_RISC_WRITE123;
208 ri = BT848_RISC_WRITE1S23;
211 ri |= BT848_RISC_SOL;
213 ri |= BT848_RISC_EOL;
215 /* write risc instruction */
216 *(rp++)=cpu_to_le32(ri | ylen);
217 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
219 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
222 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
223 uoffset += ylen >> hshift;
224 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
225 voffset += ylen >> hshift;
235 /* save pointer to jmp instruction address */
237 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
242 bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
243 const struct bttv_format *fmt, struct bttv_overlay *ov,
244 int skip_even, int skip_odd)
246 int dwords,rc,line,maxy,start,end,skip,nskips;
247 struct btcx_skiplist *skips;
252 /* skip list for window clipping */
253 if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
256 /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
257 + sync + jump (all 2 dwords) */
258 dwords = (3 * ov->nclips + 2) *
259 ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
261 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
266 /* sync instruction */
268 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
269 *(rp++) = cpu_to_le32(0);
271 addr = (unsigned long)btv->fbuf.base;
272 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
273 addr += (fmt->depth >> 3) * ov->w.left;
276 for (maxy = -1, line = 0; line < ov->w.height;
277 line++, addr += btv->fbuf.fmt.bytesperline) {
278 if ((btv->opt_vcr_hack) &&
279 (line >= (ov->w.height - VCR_HACK_LINES)))
281 if ((line%2) == 0 && skip_even)
283 if ((line%2) == 1 && skip_odd)
286 /* calculate clipping */
288 btcx_calc_skips(line, ov->w.width, &maxy,
289 skips, &nskips, ov->clips, ov->nclips);
291 /* write out risc code */
292 for (start = 0, skip = 0; start < ov->w.width; start = end) {
293 if (skip >= nskips) {
294 ri = BT848_RISC_WRITE;
296 } else if (start < skips[skip].start) {
297 ri = BT848_RISC_WRITE;
298 end = skips[skip].start;
300 ri = BT848_RISC_SKIP;
301 end = skips[skip].end;
304 if (BT848_RISC_WRITE == ri)
305 ra = addr + (fmt->depth>>3)*start;
310 ri |= BT848_RISC_SOL;
311 if (ov->w.width == end)
312 ri |= BT848_RISC_EOL;
313 ri |= (fmt->depth>>3) * (end-start);
315 *(rp++)=cpu_to_le32(ri);
317 *(rp++)=cpu_to_le32(ra);
321 /* save pointer to jmp instruction address */
323 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
328 /* ---------------------------------------------------------- */
331 bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
332 int width, int height, int interleaved,
333 const struct bttv_tvnorm *tvnorm)
338 int swidth = tvnorm->swidth;
339 int totalwidth = tvnorm->totalwidth;
340 int scaledtwidth = tvnorm->scaledtwidth;
342 if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
348 vdelay = tvnorm->vdelay;
350 xsf = (width*scaledtwidth)/swidth;
351 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
352 geo->hdelay = tvnorm->hdelayx1;
353 geo->hdelay = (geo->hdelay*width)/swidth;
354 geo->hdelay &= 0x3fe;
355 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
356 geo->vscale = (0x10000UL-sr) & 0x1fff;
357 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
358 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
359 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
360 geo->vdelay = vdelay;
362 geo->sheight = tvnorm->sheight;
363 geo->vtotal = tvnorm->vtotal;
365 if (btv->opt_combfilter) {
366 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
367 geo->comb = (width < 769) ? 1 : 0;
375 bttv_calc_geo (struct bttv * btv,
376 struct bttv_geometry * geo,
380 const struct bttv_tvnorm * tvnorm,
381 const struct v4l2_rect * crop)
383 unsigned int c_width;
384 unsigned int c_height;
387 if ((crop->left == tvnorm->cropcap.defrect.left
388 && crop->top == tvnorm->cropcap.defrect.top
389 && crop->width == tvnorm->cropcap.defrect.width
390 && crop->height == tvnorm->cropcap.defrect.height
391 && width <= tvnorm->swidth /* see PAL-Nc et al */)
392 || bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
393 bttv_calc_geo_old(btv, geo, width, height,
394 both_fields, tvnorm);
398 /* For bug compatibility the image size checks permit scale
399 factors > 16. See bttv_crop_calc_limits(). */
400 c_width = min((unsigned int) crop->width, width * 16);
401 c_height = min((unsigned int) crop->height, height * 16);
404 geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
405 /* Even to store Cb first, odd for Cr. */
406 geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
408 geo->sheight = c_height;
409 geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
410 sr = c_height >> !both_fields;
411 sr = (sr * 512U + (height >> 1)) / height - 512;
412 geo->vscale = (0x10000UL - sr) & 0x1fff;
413 geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
414 geo->vtotal = tvnorm->vtotal;
416 geo->crop = (((geo->width >> 8) & 0x03) |
417 ((geo->hdelay >> 6) & 0x0c) |
418 ((geo->sheight >> 4) & 0x30) |
419 ((geo->vdelay >> 2) & 0xc0));
421 if (btv->opt_combfilter) {
422 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
423 geo->comb = (width < 769) ? 1 : 0;
431 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
433 int off = odd ? 0x80 : 0x00;
436 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
438 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
440 btwrite(geo->vtc, BT848_E_VTC+off);
441 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
442 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
443 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
444 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
445 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
446 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
447 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
448 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
449 btwrite(geo->crop, BT848_E_CROP+off);
450 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
451 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
454 /* ---------------------------------------------------------- */
455 /* risc group / risc main loop / dma management */
458 bttv_set_dma(struct bttv *btv, int override)
464 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
465 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
466 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
469 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
470 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
474 "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
475 btv->c.nr,capctl,btv->loop_irq,
476 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
477 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
478 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
479 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
481 cmd = BT848_RISC_JUMP;
483 cmd |= BT848_RISC_IRQ;
484 cmd |= (btv->loop_irq & 0x0f) << 16;
485 cmd |= (~btv->loop_irq & 0x0f) << 20;
487 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
488 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
490 del_timer(&btv->timeout);
492 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
494 btaor(capctl, ~0x0f, BT848_CAP_CTL);
498 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
499 btor(3, BT848_GPIO_DMA_CTL);
504 btand(~3, BT848_GPIO_DMA_CTL);
511 bttv_risc_init_main(struct bttv *btv)
515 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
517 dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
518 btv->c.nr,(unsigned long long)btv->main.dma);
520 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
521 BT848_FIFO_STATUS_VRE);
522 btv->main.cpu[1] = cpu_to_le32(0);
523 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
524 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
527 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
528 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
529 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
530 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
532 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
533 BT848_FIFO_STATUS_VRO);
534 btv->main.cpu[9] = cpu_to_le32(0);
537 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
538 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
539 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
540 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
542 /* jump back to top field */
543 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
544 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
550 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
554 unsigned long next = btv->main.dma + ((slot+2) << 2);
557 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
558 btv->c.nr,risc,slot);
559 btv->main.cpu[slot+1] = cpu_to_le32(next);
561 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
562 btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
563 cmd = BT848_RISC_JUMP;
565 cmd |= BT848_RISC_IRQ;
566 cmd |= (irqflags & 0x0f) << 16;
567 cmd |= (~irqflags & 0x0f) << 20;
569 risc->jmp[0] = cpu_to_le32(cmd);
570 risc->jmp[1] = cpu_to_le32(next);
571 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
577 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
579 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
581 BUG_ON(in_interrupt());
582 videobuf_waiton(&buf->vb,0,0);
583 videobuf_dma_unmap(q, dma);
584 videobuf_dma_free(dma);
585 btcx_riscmem_free(btv->c.pci,&buf->bottom);
586 btcx_riscmem_free(btv->c.pci,&buf->top);
587 buf->vb.state = VIDEOBUF_NEEDS_INIT;
591 bttv_buffer_activate_vbi(struct bttv *btv,
592 struct bttv_buffer *vbi)
594 struct btcx_riscmem *top;
595 struct btcx_riscmem *bottom;
597 int bottom_irq_flags;
602 bottom_irq_flags = 0;
605 unsigned int crop, vdelay;
607 vbi->vb.state = VIDEOBUF_ACTIVE;
608 list_del(&vbi->vb.queue);
610 /* VDELAY is start of video, end of VBI capturing. */
611 crop = btread(BT848_E_CROP);
612 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
614 if (vbi->geo.vdelay > vdelay) {
615 vdelay = vbi->geo.vdelay & 0xfe;
616 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
618 btwrite(vdelay, BT848_E_VDELAY_LO);
619 btwrite(crop, BT848_E_CROP);
620 btwrite(vdelay, BT848_O_VDELAY_LO);
621 btwrite(crop, BT848_O_CROP);
624 if (vbi->vbi_count[0] > 0) {
629 if (vbi->vbi_count[1] > 0) {
631 bottom = &vbi->bottom;
632 bottom_irq_flags = 4;
636 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
637 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
643 bttv_buffer_activate_video(struct bttv *btv,
644 struct bttv_buffer_set *set)
647 if (NULL != set->top && NULL != set->bottom) {
648 if (set->top == set->bottom) {
649 set->top->vb.state = VIDEOBUF_ACTIVE;
650 if (set->top->vb.queue.next)
651 list_del(&set->top->vb.queue);
653 set->top->vb.state = VIDEOBUF_ACTIVE;
654 set->bottom->vb.state = VIDEOBUF_ACTIVE;
655 if (set->top->vb.queue.next)
656 list_del(&set->top->vb.queue);
657 if (set->bottom->vb.queue.next)
658 list_del(&set->bottom->vb.queue);
660 bttv_apply_geo(btv, &set->top->geo, 1);
661 bttv_apply_geo(btv, &set->bottom->geo,0);
662 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
664 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
666 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
667 ~0xff, BT848_COLOR_FMT);
668 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
669 ~0x0f, BT848_COLOR_CTL);
670 } else if (NULL != set->top) {
671 set->top->vb.state = VIDEOBUF_ACTIVE;
672 if (set->top->vb.queue.next)
673 list_del(&set->top->vb.queue);
674 bttv_apply_geo(btv, &set->top->geo,1);
675 bttv_apply_geo(btv, &set->top->geo,0);
676 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
678 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
679 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
680 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
681 } else if (NULL != set->bottom) {
682 set->bottom->vb.state = VIDEOBUF_ACTIVE;
683 if (set->bottom->vb.queue.next)
684 list_del(&set->bottom->vb.queue);
685 bttv_apply_geo(btv, &set->bottom->geo,1);
686 bttv_apply_geo(btv, &set->bottom->geo,0);
687 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
688 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
690 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
691 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
693 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
694 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
699 /* ---------------------------------------------------------- */
701 /* calculate geometry, build risc code */
703 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
705 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
706 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
709 "bttv%d: buffer field: %s format: %s size: %dx%d\n",
710 btv->c.nr, v4l2_field_names[buf->vb.field],
711 buf->fmt->name, buf->vb.width, buf->vb.height);
713 /* packed pixel modes */
714 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
715 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
716 int bpf = bpl * (buf->vb.height >> 1);
718 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
719 V4L2_FIELD_HAS_BOTH(buf->vb.field),
722 switch (buf->vb.field) {
724 bttv_risc_packed(btv,&buf->top,dma->sglist,
726 /* padding */ 0,/* skip_lines */ 0,
729 case V4L2_FIELD_BOTTOM:
730 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
731 0,bpl,0,0,buf->vb.height);
733 case V4L2_FIELD_INTERLACED:
734 bttv_risc_packed(btv,&buf->top,dma->sglist,
735 0,bpl,bpl,0,buf->vb.height >> 1);
736 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
737 bpl,bpl,bpl,0,buf->vb.height >> 1);
739 case V4L2_FIELD_SEQ_TB:
740 bttv_risc_packed(btv,&buf->top,dma->sglist,
741 0,bpl,0,0,buf->vb.height >> 1);
742 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
743 bpf,bpl,0,0,buf->vb.height >> 1);
751 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
752 int uoffset, voffset;
753 int ypadding, cpadding, lines;
755 /* calculate chroma offsets */
756 uoffset = buf->vb.width * buf->vb.height;
757 voffset = buf->vb.width * buf->vb.height;
758 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
759 /* Y-Cr-Cb plane order */
760 uoffset >>= buf->fmt->hshift;
761 uoffset >>= buf->fmt->vshift;
764 /* Y-Cb-Cr plane order */
765 voffset >>= buf->fmt->hshift;
766 voffset >>= buf->fmt->vshift;
770 switch (buf->vb.field) {
772 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
773 buf->vb.height,/* both_fields */ 0,
775 bttv_risc_planar(btv, &buf->top, dma->sglist,
776 0,buf->vb.width,0,buf->vb.height,
777 uoffset,voffset,buf->fmt->hshift,
780 case V4L2_FIELD_BOTTOM:
781 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
784 bttv_risc_planar(btv, &buf->bottom, dma->sglist,
785 0,buf->vb.width,0,buf->vb.height,
786 uoffset,voffset,buf->fmt->hshift,
789 case V4L2_FIELD_INTERLACED:
790 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
793 lines = buf->vb.height >> 1;
794 ypadding = buf->vb.width;
795 cpadding = buf->vb.width >> buf->fmt->hshift;
796 bttv_risc_planar(btv,&buf->top,
798 0,buf->vb.width,ypadding,lines,
803 bttv_risc_planar(btv,&buf->bottom,
805 ypadding,buf->vb.width,ypadding,lines,
812 case V4L2_FIELD_SEQ_TB:
813 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
816 lines = buf->vb.height >> 1;
817 ypadding = buf->vb.width;
818 cpadding = buf->vb.width >> buf->fmt->hshift;
819 bttv_risc_planar(btv,&buf->top,
821 0,buf->vb.width,0,lines,
827 bttv_risc_planar(btv,&buf->bottom,
829 lines * ypadding,buf->vb.width,0,lines,
830 lines * ypadding + (uoffset >> 1),
831 lines * ypadding + (voffset >> 1),
842 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
843 /* build risc code */
844 buf->vb.field = V4L2_FIELD_SEQ_TB;
845 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
846 1,tvnorm,&buf->crop);
847 bttv_risc_packed(btv, &buf->top, dma->sglist,
848 /* offset */ 0, RAW_BPL, /* padding */ 0,
849 /* skip_lines */ 0, RAW_LINES);
850 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
851 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
854 /* copy format info */
855 buf->btformat = buf->fmt->btformat;
856 buf->btswap = buf->fmt->btswap;
860 /* ---------------------------------------------------------- */
862 /* calculate geometry, build risc code */
864 bttv_overlay_risc(struct bttv *btv,
865 struct bttv_overlay *ov,
866 const struct bttv_format *fmt,
867 struct bttv_buffer *buf)
869 /* check interleave, bottom+top fields */
871 "bttv%d: overlay fields: %s format: %s size: %dx%d\n",
872 btv->c.nr, v4l2_field_names[buf->vb.field],
873 fmt->name,ov->w.width,ov->w.height);
875 /* calculate geometry */
876 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
877 V4L2_FIELD_HAS_BOTH(ov->field),
878 &bttv_tvnorms[ov->tvnorm],&buf->crop);
880 /* build risc code */
883 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
885 case V4L2_FIELD_BOTTOM:
886 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
888 case V4L2_FIELD_INTERLACED:
889 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
890 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
896 /* copy format info */
897 buf->btformat = fmt->btformat;
898 buf->btswap = fmt->btswap;
899 buf->vb.field = ov->field;