2 $Id: bttv-risc.c,v 1.10 2004/11/19 18:07:12 kraxel Exp $
4 bttv-risc.c -- interfaces to other kernel modules
6 bttv risc code handling
10 (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
12 This program is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 2 of the License, or
15 (at your option) any later version.
17 This program is distributed in the hope that it will be useful,
18 but WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 GNU General Public License for more details.
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include <linux/module.h>
29 #include <linux/init.h>
30 #include <linux/pci.h>
31 #include <linux/vmalloc.h>
32 #include <linux/interrupt.h>
34 #include <asm/pgtable.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 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) */
56 instructions
= (bpl
* lines
) / PAGE_SIZE
+ lines
;
58 if ((rc
= btcx_riscmem_alloc(btv
->c
.pci
,risc
,instructions
*8)) < 0)
61 /* sync instruction */
63 *(rp
++) = cpu_to_le32(BT848_RISC_SYNC
|BT848_FIFO_STATUS_FM1
);
64 *(rp
++) = cpu_to_le32(0);
68 for (line
= 0; line
< lines
; line
++) {
69 if ((btv
->opt_vcr_hack
) &&
70 (line
>= (lines
- VCR_HACK_LINES
)))
72 while (offset
&& offset
>= sg_dma_len(sg
)) {
73 offset
-= sg_dma_len(sg
);
76 if (bpl
<= sg_dma_len(sg
)-offset
) {
77 /* fits into current chunk */
78 *(rp
++)=cpu_to_le32(BT848_RISC_WRITE
|BT848_RISC_SOL
|
80 *(rp
++)=cpu_to_le32(sg_dma_address(sg
)+offset
);
83 /* scanline needs to be splitted */
85 *(rp
++)=cpu_to_le32(BT848_RISC_WRITE
|BT848_RISC_SOL
|
86 (sg_dma_len(sg
)-offset
));
87 *(rp
++)=cpu_to_le32(sg_dma_address(sg
)+offset
);
88 todo
-= (sg_dma_len(sg
)-offset
);
91 while (todo
> sg_dma_len(sg
)) {
92 *(rp
++)=cpu_to_le32(BT848_RISC_WRITE
|
94 *(rp
++)=cpu_to_le32(sg_dma_address(sg
));
95 todo
-= sg_dma_len(sg
);
98 *(rp
++)=cpu_to_le32(BT848_RISC_WRITE
|BT848_RISC_EOL
|
100 *(rp
++)=cpu_to_le32(sg_dma_address(sg
));
106 /* save pointer to jmp instruction address */
108 BUG_ON((risc
->jmp
- risc
->cpu
+ 2) / 4 > risc
->size
);
113 bttv_risc_planar(struct bttv
*btv
, struct btcx_riscmem
*risc
,
114 struct scatterlist
*sglist
,
115 unsigned int yoffset
, unsigned int ybpl
,
116 unsigned int ypadding
, unsigned int ylines
,
117 unsigned int uoffset
, unsigned int voffset
,
118 unsigned int hshift
, unsigned int vshift
,
119 unsigned int cpadding
)
121 unsigned int instructions
,line
,todo
,ylen
,chroma
;
123 struct scatterlist
*ysg
;
124 struct scatterlist
*usg
;
125 struct scatterlist
*vsg
;
126 int topfield
= (0 == yoffset
);
129 /* estimate risc mem: worst case is one write per page border +
130 one write per scan line (5 dwords)
131 plus sync + jump (2 dwords) */
132 instructions
= (ybpl
* ylines
* 2) / PAGE_SIZE
+ ylines
;
134 if ((rc
= btcx_riscmem_alloc(btv
->c
.pci
,risc
,instructions
*4*5)) < 0)
137 /* sync instruction */
139 *(rp
++) = cpu_to_le32(BT848_RISC_SYNC
|BT848_FIFO_STATUS_FM3
);
140 *(rp
++) = cpu_to_le32(0);
146 for (line
= 0; line
< ylines
; line
++) {
147 if ((btv
->opt_vcr_hack
) &&
148 (line
>= (ylines
- VCR_HACK_LINES
)))
156 chroma
= ((line
& 1) == 0);
158 chroma
= ((line
& 1) == 1);
162 chroma
= ((line
& 3) == 0);
164 chroma
= ((line
& 3) == 2);
171 for (todo
= ybpl
; todo
> 0; todo
-= ylen
) {
172 /* go to next sg entry if needed */
173 while (yoffset
&& yoffset
>= sg_dma_len(ysg
)) {
174 yoffset
-= sg_dma_len(ysg
);
177 while (uoffset
&& uoffset
>= sg_dma_len(usg
)) {
178 uoffset
-= sg_dma_len(usg
);
181 while (voffset
&& voffset
>= sg_dma_len(vsg
)) {
182 voffset
-= sg_dma_len(vsg
);
186 /* calculate max number of bytes we can write */
188 if (yoffset
+ ylen
> sg_dma_len(ysg
))
189 ylen
= sg_dma_len(ysg
) - yoffset
;
191 if (uoffset
+ (ylen
>>hshift
) > sg_dma_len(usg
))
192 ylen
= (sg_dma_len(usg
) - uoffset
) << hshift
;
193 if (voffset
+ (ylen
>>hshift
) > sg_dma_len(vsg
))
194 ylen
= (sg_dma_len(vsg
) - voffset
) << hshift
;
195 ri
= BT848_RISC_WRITE123
;
197 ri
= BT848_RISC_WRITE1S23
;
200 ri
|= BT848_RISC_SOL
;
202 ri
|= BT848_RISC_EOL
;
204 /* write risc instruction */
205 *(rp
++)=cpu_to_le32(ri
| ylen
);
206 *(rp
++)=cpu_to_le32(((ylen
>> hshift
) << 16) |
208 *(rp
++)=cpu_to_le32(sg_dma_address(ysg
)+yoffset
);
211 *(rp
++)=cpu_to_le32(sg_dma_address(usg
)+uoffset
);
212 uoffset
+= ylen
>> hshift
;
213 *(rp
++)=cpu_to_le32(sg_dma_address(vsg
)+voffset
);
214 voffset
+= ylen
>> hshift
;
224 /* save pointer to jmp instruction address */
226 BUG_ON((risc
->jmp
- risc
->cpu
+ 2) / 4 > risc
->size
);
231 bttv_risc_overlay(struct bttv
*btv
, struct btcx_riscmem
*risc
,
232 const struct bttv_format
*fmt
, struct bttv_overlay
*ov
,
233 int skip_even
, int skip_odd
)
235 int instructions
,rc
,line
,maxy
,start
,end
,skip
,nskips
;
236 struct btcx_skiplist
*skips
;
240 /* skip list for window clipping */
241 if (NULL
== (skips
= kmalloc(sizeof(*skips
) * ov
->nclips
,GFP_KERNEL
)))
244 /* estimate risc mem: worst case is (clip+1) * lines instructions
245 + sync + jump (all 2 dwords) */
246 instructions
= (ov
->nclips
+ 1) *
247 ((skip_even
|| skip_odd
) ? ov
->w
.height
>>1 : ov
->w
.height
);
249 if ((rc
= btcx_riscmem_alloc(btv
->c
.pci
,risc
,instructions
*8)) < 0) {
254 /* sync instruction */
256 *(rp
++) = cpu_to_le32(BT848_RISC_SYNC
|BT848_FIFO_STATUS_FM1
);
257 *(rp
++) = cpu_to_le32(0);
259 addr
= (unsigned long)btv
->fbuf
.base
;
260 addr
+= btv
->fbuf
.fmt
.bytesperline
* ov
->w
.top
;
261 addr
+= (fmt
->depth
>> 3) * ov
->w
.left
;
264 for (maxy
= -1, line
= 0; line
< ov
->w
.height
;
265 line
++, addr
+= btv
->fbuf
.fmt
.bytesperline
) {
266 if ((btv
->opt_vcr_hack
) &&
267 (line
>= (ov
->w
.height
- VCR_HACK_LINES
)))
269 if ((line
%2) == 0 && skip_even
)
271 if ((line
%2) == 1 && skip_odd
)
274 /* calculate clipping */
276 btcx_calc_skips(line
, ov
->w
.width
, &maxy
,
277 skips
, &nskips
, ov
->clips
, ov
->nclips
);
279 /* write out risc code */
280 for (start
= 0, skip
= 0; start
< ov
->w
.width
; start
= end
) {
281 if (skip
>= nskips
) {
282 ri
= BT848_RISC_WRITE
;
284 } else if (start
< skips
[skip
].start
) {
285 ri
= BT848_RISC_WRITE
;
286 end
= skips
[skip
].start
;
288 ri
= BT848_RISC_SKIP
;
289 end
= skips
[skip
].end
;
292 if (BT848_RISC_WRITE
== ri
)
293 ra
= addr
+ (fmt
->depth
>>3)*start
;
298 ri
|= BT848_RISC_SOL
;
299 if (ov
->w
.width
== end
)
300 ri
|= BT848_RISC_EOL
;
301 ri
|= (fmt
->depth
>>3) * (end
-start
);
303 *(rp
++)=cpu_to_le32(ri
);
305 *(rp
++)=cpu_to_le32(ra
);
309 /* save pointer to jmp instruction address */
311 BUG_ON((risc
->jmp
- risc
->cpu
+ 2) / 4 > risc
->size
);
316 /* ---------------------------------------------------------- */
319 bttv_calc_geo(struct bttv
*btv
, struct bttv_geometry
*geo
,
320 int width
, int height
, int interleaved
, int norm
)
322 const struct bttv_tvnorm
*tvnorm
= &bttv_tvnorms
[norm
];
326 int swidth
= tvnorm
->swidth
;
327 int totalwidth
= tvnorm
->totalwidth
;
328 int scaledtwidth
= tvnorm
->scaledtwidth
;
330 if (bttv_tvcards
[btv
->c
.type
].muxsel
[btv
->input
] < 0) {
336 vdelay
= tvnorm
->vdelay
;
338 if (vdelay
< btv
->vbi
.lines
*2)
339 vdelay
= btv
->vbi
.lines
*2;
342 xsf
= (width
*scaledtwidth
)/swidth
;
343 geo
->hscale
= ((totalwidth
*4096UL)/xsf
-4096);
344 geo
->hdelay
= tvnorm
->hdelayx1
;
345 geo
->hdelay
= (geo
->hdelay
*width
)/swidth
;
346 geo
->hdelay
&= 0x3fe;
347 sr
= ((tvnorm
->sheight
>> (interleaved
?0:1))*512)/height
- 512;
348 geo
->vscale
= (0x10000UL
-sr
) & 0x1fff;
349 geo
->crop
= ((width
>>8)&0x03) | ((geo
->hdelay
>>6)&0x0c) |
350 ((tvnorm
->sheight
>>4)&0x30) | ((vdelay
>>2)&0xc0);
351 geo
->vscale
|= interleaved
? (BT848_VSCALE_INT
<<8) : 0;
352 geo
->vdelay
= vdelay
;
354 geo
->sheight
= tvnorm
->sheight
;
355 geo
->vtotal
= tvnorm
->vtotal
;
357 if (btv
->opt_combfilter
) {
358 geo
->vtc
= (width
< 193) ? 2 : ((width
< 385) ? 1 : 0);
359 geo
->comb
= (width
< 769) ? 1 : 0;
367 bttv_apply_geo(struct bttv
*btv
, struct bttv_geometry
*geo
, int odd
)
369 int off
= odd
? 0x80 : 0x00;
372 btor(BT848_VSCALE_COMB
, BT848_E_VSCALE_HI
+off
);
374 btand(~BT848_VSCALE_COMB
, BT848_E_VSCALE_HI
+off
);
376 btwrite(geo
->vtc
, BT848_E_VTC
+off
);
377 btwrite(geo
->hscale
>> 8, BT848_E_HSCALE_HI
+off
);
378 btwrite(geo
->hscale
& 0xff, BT848_E_HSCALE_LO
+off
);
379 btaor((geo
->vscale
>>8), 0xe0, BT848_E_VSCALE_HI
+off
);
380 btwrite(geo
->vscale
& 0xff, BT848_E_VSCALE_LO
+off
);
381 btwrite(geo
->width
& 0xff, BT848_E_HACTIVE_LO
+off
);
382 btwrite(geo
->hdelay
& 0xff, BT848_E_HDELAY_LO
+off
);
383 btwrite(geo
->sheight
& 0xff, BT848_E_VACTIVE_LO
+off
);
384 btwrite(geo
->vdelay
& 0xff, BT848_E_VDELAY_LO
+off
);
385 btwrite(geo
->crop
, BT848_E_CROP
+off
);
386 btwrite(geo
->vtotal
>>8, BT848_VTOTAL_HI
);
387 btwrite(geo
->vtotal
& 0xff, BT848_VTOTAL_LO
);
390 /* ---------------------------------------------------------- */
391 /* risc group / risc main loop / dma management */
394 bttv_set_dma(struct bttv
*btv
, int override
)
400 if (NULL
!= btv
->curr
.top
) btv
->cap_ctl
|= 0x02;
401 if (NULL
!= btv
->curr
.bottom
) btv
->cap_ctl
|= 0x01;
402 if (NULL
!= btv
->cvbi
) btv
->cap_ctl
|= 0x0c;
405 capctl
|= (btv
->cap_ctl
& 0x03) ? 0x03 : 0x00; /* capture */
406 capctl
|= (btv
->cap_ctl
& 0x0c) ? 0x0c : 0x00; /* vbi data */
410 "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
411 btv
->c
.nr
,capctl
,btv
->loop_irq
,
412 btv
->cvbi
? (unsigned long long)btv
->cvbi
->top
.dma
: 0,
413 btv
->curr
.top
? (unsigned long long)btv
->curr
.top
->top
.dma
: 0,
414 btv
->cvbi
? (unsigned long long)btv
->cvbi
->bottom
.dma
: 0,
415 btv
->curr
.bottom
? (unsigned long long)btv
->curr
.bottom
->bottom
.dma
: 0);
417 cmd
= BT848_RISC_JUMP
;
419 cmd
|= BT848_RISC_IRQ
;
420 cmd
|= (btv
->loop_irq
& 0x0f) << 16;
421 cmd
|= (~btv
->loop_irq
& 0x0f) << 20;
423 if (btv
->curr
.frame_irq
|| btv
->loop_irq
|| btv
->cvbi
) {
424 mod_timer(&btv
->timeout
, jiffies
+BTTV_TIMEOUT
);
426 del_timer(&btv
->timeout
);
428 btv
->main
.cpu
[RISC_SLOT_LOOP
] = cpu_to_le32(cmd
);
430 btaor(capctl
, ~0x0f, BT848_CAP_CTL
);
434 btwrite(btv
->main
.dma
, BT848_RISC_STRT_ADD
);
435 btor(3, BT848_GPIO_DMA_CTL
);
440 btand(~3, BT848_GPIO_DMA_CTL
);
447 bttv_risc_init_main(struct bttv
*btv
)
451 if ((rc
= btcx_riscmem_alloc(btv
->c
.pci
,&btv
->main
,PAGE_SIZE
)) < 0)
453 dprintk(KERN_DEBUG
"bttv%d: risc main @ %08Lx\n",
454 btv
->c
.nr
,(unsigned long long)btv
->main
.dma
);
456 btv
->main
.cpu
[0] = cpu_to_le32(BT848_RISC_SYNC
| BT848_RISC_RESYNC
|
457 BT848_FIFO_STATUS_VRE
);
458 btv
->main
.cpu
[1] = cpu_to_le32(0);
459 btv
->main
.cpu
[2] = cpu_to_le32(BT848_RISC_JUMP
);
460 btv
->main
.cpu
[3] = cpu_to_le32(btv
->main
.dma
+ (4<<2));
463 btv
->main
.cpu
[4] = cpu_to_le32(BT848_RISC_JUMP
);
464 btv
->main
.cpu
[5] = cpu_to_le32(btv
->main
.dma
+ (6<<2));
465 btv
->main
.cpu
[6] = cpu_to_le32(BT848_RISC_JUMP
);
466 btv
->main
.cpu
[7] = cpu_to_le32(btv
->main
.dma
+ (8<<2));
468 btv
->main
.cpu
[8] = cpu_to_le32(BT848_RISC_SYNC
| BT848_RISC_RESYNC
|
469 BT848_FIFO_STATUS_VRO
);
470 btv
->main
.cpu
[9] = cpu_to_le32(0);
473 btv
->main
.cpu
[10] = cpu_to_le32(BT848_RISC_JUMP
);
474 btv
->main
.cpu
[11] = cpu_to_le32(btv
->main
.dma
+ (12<<2));
475 btv
->main
.cpu
[12] = cpu_to_le32(BT848_RISC_JUMP
);
476 btv
->main
.cpu
[13] = cpu_to_le32(btv
->main
.dma
+ (14<<2));
478 /* jump back to top field */
479 btv
->main
.cpu
[14] = cpu_to_le32(BT848_RISC_JUMP
);
480 btv
->main
.cpu
[15] = cpu_to_le32(btv
->main
.dma
+ (0<<2));
486 bttv_risc_hook(struct bttv
*btv
, int slot
, struct btcx_riscmem
*risc
,
490 unsigned long next
= btv
->main
.dma
+ ((slot
+2) << 2);
493 d2printk(KERN_DEBUG
"bttv%d: risc=%p slot[%d]=NULL\n",
494 btv
->c
.nr
,risc
,slot
);
495 btv
->main
.cpu
[slot
+1] = cpu_to_le32(next
);
497 d2printk(KERN_DEBUG
"bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
498 btv
->c
.nr
,risc
,slot
,(unsigned long long)risc
->dma
,irqflags
);
499 cmd
= BT848_RISC_JUMP
;
501 cmd
|= BT848_RISC_IRQ
;
502 cmd
|= (irqflags
& 0x0f) << 16;
503 cmd
|= (~irqflags
& 0x0f) << 20;
505 risc
->jmp
[0] = cpu_to_le32(cmd
);
506 risc
->jmp
[1] = cpu_to_le32(next
);
507 btv
->main
.cpu
[slot
+1] = cpu_to_le32(risc
->dma
);
513 bttv_dma_free(struct bttv
*btv
, struct bttv_buffer
*buf
)
517 videobuf_waiton(&buf
->vb
,0,0);
518 videobuf_dma_pci_unmap(btv
->c
.pci
, &buf
->vb
.dma
);
519 videobuf_dma_free(&buf
->vb
.dma
);
520 btcx_riscmem_free(btv
->c
.pci
,&buf
->bottom
);
521 btcx_riscmem_free(btv
->c
.pci
,&buf
->top
);
522 buf
->vb
.state
= STATE_NEEDS_INIT
;
526 bttv_buffer_activate_vbi(struct bttv
*btv
,
527 struct bttv_buffer
*vbi
)
531 vbi
->vb
.state
= STATE_ACTIVE
;
532 list_del(&vbi
->vb
.queue
);
533 bttv_risc_hook(btv
, RISC_SLOT_O_VBI
, &vbi
->top
, 0);
534 bttv_risc_hook(btv
, RISC_SLOT_E_VBI
, &vbi
->bottom
, 4);
536 bttv_risc_hook(btv
, RISC_SLOT_O_VBI
, NULL
, 0);
537 bttv_risc_hook(btv
, RISC_SLOT_E_VBI
, NULL
, 0);
543 bttv_buffer_activate_video(struct bttv
*btv
,
544 struct bttv_buffer_set
*set
)
547 if (NULL
!= set
->top
&& NULL
!= set
->bottom
) {
548 if (set
->top
== set
->bottom
) {
549 set
->top
->vb
.state
= STATE_ACTIVE
;
550 if (set
->top
->vb
.queue
.next
)
551 list_del(&set
->top
->vb
.queue
);
553 set
->top
->vb
.state
= STATE_ACTIVE
;
554 set
->bottom
->vb
.state
= STATE_ACTIVE
;
555 if (set
->top
->vb
.queue
.next
)
556 list_del(&set
->top
->vb
.queue
);
557 if (set
->bottom
->vb
.queue
.next
)
558 list_del(&set
->bottom
->vb
.queue
);
560 bttv_apply_geo(btv
, &set
->top
->geo
, 1);
561 bttv_apply_geo(btv
, &set
->bottom
->geo
,0);
562 bttv_risc_hook(btv
, RISC_SLOT_O_FIELD
, &set
->top
->top
,
564 bttv_risc_hook(btv
, RISC_SLOT_E_FIELD
, &set
->bottom
->bottom
,
566 btaor((set
->top
->btformat
& 0xf0) | (set
->bottom
->btformat
& 0x0f),
567 ~0xff, BT848_COLOR_FMT
);
568 btaor((set
->top
->btswap
& 0x0a) | (set
->bottom
->btswap
& 0x05),
569 ~0x0f, BT848_COLOR_CTL
);
570 } else if (NULL
!= set
->top
) {
571 set
->top
->vb
.state
= STATE_ACTIVE
;
572 if (set
->top
->vb
.queue
.next
)
573 list_del(&set
->top
->vb
.queue
);
574 bttv_apply_geo(btv
, &set
->top
->geo
,1);
575 bttv_apply_geo(btv
, &set
->top
->geo
,0);
576 bttv_risc_hook(btv
, RISC_SLOT_O_FIELD
, &set
->top
->top
,
578 bttv_risc_hook(btv
, RISC_SLOT_E_FIELD
, NULL
, 0);
579 btaor(set
->top
->btformat
& 0xff, ~0xff, BT848_COLOR_FMT
);
580 btaor(set
->top
->btswap
& 0x0f, ~0x0f, BT848_COLOR_CTL
);
581 } else if (NULL
!= set
->bottom
) {
582 set
->bottom
->vb
.state
= STATE_ACTIVE
;
583 if (set
->bottom
->vb
.queue
.next
)
584 list_del(&set
->bottom
->vb
.queue
);
585 bttv_apply_geo(btv
, &set
->bottom
->geo
,1);
586 bttv_apply_geo(btv
, &set
->bottom
->geo
,0);
587 bttv_risc_hook(btv
, RISC_SLOT_O_FIELD
, NULL
, 0);
588 bttv_risc_hook(btv
, RISC_SLOT_E_FIELD
, &set
->bottom
->bottom
,
590 btaor(set
->bottom
->btformat
& 0xff, ~0xff, BT848_COLOR_FMT
);
591 btaor(set
->bottom
->btswap
& 0x0f, ~0x0f, BT848_COLOR_CTL
);
593 bttv_risc_hook(btv
, RISC_SLOT_O_FIELD
, NULL
, 0);
594 bttv_risc_hook(btv
, RISC_SLOT_E_FIELD
, NULL
, 0);
599 /* ---------------------------------------------------------- */
601 /* calculate geometry, build risc code */
603 bttv_buffer_risc(struct bttv
*btv
, struct bttv_buffer
*buf
)
605 const struct bttv_tvnorm
*tvnorm
= bttv_tvnorms
+ buf
->tvnorm
;
608 "bttv%d: buffer field: %s format: %s size: %dx%d\n",
609 btv
->c
.nr
, v4l2_field_names
[buf
->vb
.field
],
610 buf
->fmt
->name
, buf
->vb
.width
, buf
->vb
.height
);
612 /* packed pixel modes */
613 if (buf
->fmt
->flags
& FORMAT_FLAGS_PACKED
) {
614 int bpl
= (buf
->fmt
->depth
>> 3) * buf
->vb
.width
;
615 int bpf
= bpl
* (buf
->vb
.height
>> 1);
617 bttv_calc_geo(btv
,&buf
->geo
,buf
->vb
.width
,buf
->vb
.height
,
618 V4L2_FIELD_HAS_BOTH(buf
->vb
.field
),buf
->tvnorm
);
620 switch (buf
->vb
.field
) {
622 bttv_risc_packed(btv
,&buf
->top
,buf
->vb
.dma
.sglist
,
623 0,bpl
,0,buf
->vb
.height
);
625 case V4L2_FIELD_BOTTOM
:
626 bttv_risc_packed(btv
,&buf
->bottom
,buf
->vb
.dma
.sglist
,
627 0,bpl
,0,buf
->vb
.height
);
629 case V4L2_FIELD_INTERLACED
:
630 bttv_risc_packed(btv
,&buf
->top
,buf
->vb
.dma
.sglist
,
631 0,bpl
,bpl
,buf
->vb
.height
>> 1);
632 bttv_risc_packed(btv
,&buf
->bottom
,buf
->vb
.dma
.sglist
,
633 bpl
,bpl
,bpl
,buf
->vb
.height
>> 1);
635 case V4L2_FIELD_SEQ_TB
:
636 bttv_risc_packed(btv
,&buf
->top
,buf
->vb
.dma
.sglist
,
637 0,bpl
,0,buf
->vb
.height
>> 1);
638 bttv_risc_packed(btv
,&buf
->bottom
,buf
->vb
.dma
.sglist
,
639 bpf
,bpl
,0,buf
->vb
.height
>> 1);
647 if (buf
->fmt
->flags
& FORMAT_FLAGS_PLANAR
) {
648 int uoffset
, voffset
;
649 int ypadding
, cpadding
, lines
;
651 /* calculate chroma offsets */
652 uoffset
= buf
->vb
.width
* buf
->vb
.height
;
653 voffset
= buf
->vb
.width
* buf
->vb
.height
;
654 if (buf
->fmt
->flags
& FORMAT_FLAGS_CrCb
) {
655 /* Y-Cr-Cb plane order */
656 uoffset
>>= buf
->fmt
->hshift
;
657 uoffset
>>= buf
->fmt
->vshift
;
660 /* Y-Cb-Cr plane order */
661 voffset
>>= buf
->fmt
->hshift
;
662 voffset
>>= buf
->fmt
->vshift
;
666 switch (buf
->vb
.field
) {
668 bttv_calc_geo(btv
,&buf
->geo
,buf
->vb
.width
,
669 buf
->vb
.height
,0,buf
->tvnorm
);
670 bttv_risc_planar(btv
, &buf
->top
, buf
->vb
.dma
.sglist
,
671 0,buf
->vb
.width
,0,buf
->vb
.height
,
672 uoffset
,voffset
,buf
->fmt
->hshift
,
675 case V4L2_FIELD_BOTTOM
:
676 bttv_calc_geo(btv
,&buf
->geo
,buf
->vb
.width
,
677 buf
->vb
.height
,0,buf
->tvnorm
);
678 bttv_risc_planar(btv
, &buf
->bottom
, buf
->vb
.dma
.sglist
,
679 0,buf
->vb
.width
,0,buf
->vb
.height
,
680 uoffset
,voffset
,buf
->fmt
->hshift
,
683 case V4L2_FIELD_INTERLACED
:
684 bttv_calc_geo(btv
,&buf
->geo
,buf
->vb
.width
,
685 buf
->vb
.height
,1,buf
->tvnorm
);
686 lines
= buf
->vb
.height
>> 1;
687 ypadding
= buf
->vb
.width
;
688 cpadding
= buf
->vb
.width
>> buf
->fmt
->hshift
;
689 bttv_risc_planar(btv
,&buf
->top
,
691 0,buf
->vb
.width
,ypadding
,lines
,
696 bttv_risc_planar(btv
,&buf
->bottom
,
698 ypadding
,buf
->vb
.width
,ypadding
,lines
,
705 case V4L2_FIELD_SEQ_TB
:
706 bttv_calc_geo(btv
,&buf
->geo
,buf
->vb
.width
,
707 buf
->vb
.height
,1,buf
->tvnorm
);
708 lines
= buf
->vb
.height
>> 1;
709 ypadding
= buf
->vb
.width
;
710 cpadding
= buf
->vb
.width
>> buf
->fmt
->hshift
;
711 bttv_risc_planar(btv
,&buf
->top
,
713 0,buf
->vb
.width
,0,lines
,
719 bttv_risc_planar(btv
,&buf
->bottom
,
721 lines
* ypadding
,buf
->vb
.width
,0,lines
,
722 lines
* ypadding
+ (uoffset
>> 1),
723 lines
* ypadding
+ (voffset
>> 1),
734 if (buf
->fmt
->flags
& FORMAT_FLAGS_RAW
) {
735 /* build risc code */
736 buf
->vb
.field
= V4L2_FIELD_SEQ_TB
;
737 bttv_calc_geo(btv
,&buf
->geo
,tvnorm
->swidth
,tvnorm
->sheight
,
739 bttv_risc_packed(btv
, &buf
->top
, buf
->vb
.dma
.sglist
,
740 0, RAW_BPL
, 0, RAW_LINES
);
741 bttv_risc_packed(btv
, &buf
->bottom
, buf
->vb
.dma
.sglist
,
742 buf
->vb
.size
/2 , RAW_BPL
, 0, RAW_LINES
);
745 /* copy format info */
746 buf
->btformat
= buf
->fmt
->btformat
;
747 buf
->btswap
= buf
->fmt
->btswap
;
751 /* ---------------------------------------------------------- */
753 /* calculate geometry, build risc code */
755 bttv_overlay_risc(struct bttv
*btv
,
756 struct bttv_overlay
*ov
,
757 const struct bttv_format
*fmt
,
758 struct bttv_buffer
*buf
)
760 /* check interleave, bottom+top fields */
762 "bttv%d: overlay fields: %s format: %s size: %dx%d\n",
763 btv
->c
.nr
, v4l2_field_names
[buf
->vb
.field
],
764 fmt
->name
,ov
->w
.width
,ov
->w
.height
);
766 /* calculate geometry */
767 bttv_calc_geo(btv
,&buf
->geo
,ov
->w
.width
,ov
->w
.height
,
768 V4L2_FIELD_HAS_BOTH(ov
->field
), ov
->tvnorm
);
770 /* build risc code */
773 bttv_risc_overlay(btv
, &buf
->top
, fmt
, ov
, 0, 0);
775 case V4L2_FIELD_BOTTOM
:
776 bttv_risc_overlay(btv
, &buf
->bottom
, fmt
, ov
, 0, 0);
778 case V4L2_FIELD_INTERLACED
:
780 bttv_risc_overlay(btv
, &buf
->top
, fmt
, ov
, 1, 0);
781 bttv_risc_overlay(btv
, &buf
->bottom
, fmt
, ov
, 0, 1);
783 bttv_risc_overlay(btv
, &buf
->top
, fmt
, ov
, 0, 1);
784 bttv_risc_overlay(btv
, &buf
->bottom
, fmt
, ov
, 1, 0);
791 /* copy format info */
792 buf
->btformat
= fmt
->btformat
;
793 buf
->btswap
= fmt
->btswap
;
794 buf
->vb
.field
= ov
->field
;