1 // SPDX-License-Identifier: GPL-2.0-or-later
4 bttv-risc.c -- interfaces to other kernel modules
6 bttv risc code handling
10 (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/slab.h>
20 #include <linux/pci.h>
21 #include <linux/vmalloc.h>
22 #include <linux/interrupt.h>
23 #include <linux/pgtable.h>
25 #include <media/v4l2-ioctl.h>
29 #define VCR_HACK_LINES 4
31 /* ---------------------------------------------------------- */
32 /* risc code generators */
35 bttv_risc_packed(struct bttv
*btv
, struct btcx_riscmem
*risc
,
36 struct scatterlist
*sglist
,
37 unsigned int offset
, unsigned int bpl
,
38 unsigned int padding
, unsigned int skip_lines
,
39 unsigned int store_lines
)
41 u32 instructions
,line
,todo
;
42 struct scatterlist
*sg
;
46 /* estimate risc mem: worst case is one write per page border +
47 one write per scan line + sync + jump (all 2 dwords). padding
48 can cause next bpl to start close to a page border. First DMA
49 region may be smaller than PAGE_SIZE */
50 instructions
= skip_lines
* 4;
51 instructions
+= (1 + ((bpl
+ padding
) * store_lines
)
52 / PAGE_SIZE
+ store_lines
) * 8;
53 instructions
+= 2 * 8;
54 if ((rc
= btcx_riscmem_alloc(btv
->c
.pci
,risc
,instructions
)) < 0)
57 /* sync instruction */
59 *(rp
++) = cpu_to_le32(BT848_RISC_SYNC
|BT848_FIFO_STATUS_FM1
);
60 *(rp
++) = cpu_to_le32(0);
62 while (skip_lines
-- > 0) {
63 *(rp
++) = cpu_to_le32(BT848_RISC_SKIP
| BT848_RISC_SOL
|
64 BT848_RISC_EOL
| bpl
);
69 for (line
= 0; line
< store_lines
; line
++) {
70 if ((line
>= (store_lines
- VCR_HACK_LINES
)) &&
73 while (offset
&& offset
>= sg_dma_len(sg
)) {
74 offset
-= sg_dma_len(sg
);
77 if (bpl
<= sg_dma_len(sg
)-offset
) {
78 /* fits into current chunk */
79 *(rp
++)=cpu_to_le32(BT848_RISC_WRITE
|BT848_RISC_SOL
|
81 *(rp
++)=cpu_to_le32(sg_dma_address(sg
)+offset
);
84 /* scanline needs to be split */
86 *(rp
++)=cpu_to_le32(BT848_RISC_WRITE
|BT848_RISC_SOL
|
87 (sg_dma_len(sg
)-offset
));
88 *(rp
++)=cpu_to_le32(sg_dma_address(sg
)+offset
);
89 todo
-= (sg_dma_len(sg
)-offset
);
92 while (todo
> sg_dma_len(sg
)) {
93 *(rp
++)=cpu_to_le32(BT848_RISC_WRITE
|
95 *(rp
++)=cpu_to_le32(sg_dma_address(sg
));
96 todo
-= sg_dma_len(sg
);
99 *(rp
++)=cpu_to_le32(BT848_RISC_WRITE
|BT848_RISC_EOL
|
101 *(rp
++)=cpu_to_le32(sg_dma_address(sg
));
107 /* save pointer to jmp instruction address */
109 WARN_ON((risc
->jmp
- risc
->cpu
+ 2) * sizeof(*risc
->cpu
) > risc
->size
);
114 bttv_risc_planar(struct bttv
*btv
, struct btcx_riscmem
*risc
,
115 struct scatterlist
*sglist
,
116 unsigned int yoffset
, unsigned int ybpl
,
117 unsigned int ypadding
, unsigned int ylines
,
118 unsigned int uoffset
, unsigned int voffset
,
119 unsigned int hshift
, unsigned int vshift
,
120 unsigned int cpadding
)
122 unsigned int instructions
,line
,todo
,ylen
,chroma
;
125 struct scatterlist
*ysg
;
126 struct scatterlist
*usg
;
127 struct scatterlist
*vsg
;
128 int topfield
= (0 == yoffset
);
131 /* estimate risc mem: worst case is one write per page border +
132 one write per scan line (5 dwords)
133 plus sync + jump (2 dwords) */
134 instructions
= ((3 + (ybpl
+ ypadding
) * ylines
* 2)
135 / PAGE_SIZE
) + ylines
;
137 if ((rc
= btcx_riscmem_alloc(btv
->c
.pci
,risc
,instructions
*4*5)) < 0)
140 /* sync instruction */
142 *(rp
++) = cpu_to_le32(BT848_RISC_SYNC
|BT848_FIFO_STATUS_FM3
);
143 *(rp
++) = cpu_to_le32(0);
149 for (line
= 0; line
< ylines
; line
++) {
150 if ((btv
->opt_vcr_hack
) &&
151 (line
>= (ylines
- VCR_HACK_LINES
)))
159 chroma
= ((line
& 1) == 0);
161 chroma
= ((line
& 1) == 1);
165 chroma
= ((line
& 3) == 0);
167 chroma
= ((line
& 3) == 2);
174 for (todo
= ybpl
; todo
> 0; todo
-= ylen
) {
175 /* go to next sg entry if needed */
176 while (yoffset
&& yoffset
>= sg_dma_len(ysg
)) {
177 yoffset
-= sg_dma_len(ysg
);
181 /* calculate max number of bytes we can write */
183 if (yoffset
+ ylen
> sg_dma_len(ysg
))
184 ylen
= sg_dma_len(ysg
) - yoffset
;
186 while (uoffset
&& uoffset
>= sg_dma_len(usg
)) {
187 uoffset
-= sg_dma_len(usg
);
190 while (voffset
&& voffset
>= sg_dma_len(vsg
)) {
191 voffset
-= sg_dma_len(vsg
);
195 if (uoffset
+ (ylen
>>hshift
) > sg_dma_len(usg
))
196 ylen
= (sg_dma_len(usg
) - uoffset
) << hshift
;
197 if (voffset
+ (ylen
>>hshift
) > sg_dma_len(vsg
))
198 ylen
= (sg_dma_len(vsg
) - voffset
) << hshift
;
199 ri
= BT848_RISC_WRITE123
;
201 ri
= BT848_RISC_WRITE1S23
;
204 ri
|= BT848_RISC_SOL
;
206 ri
|= BT848_RISC_EOL
;
208 /* write risc instruction */
209 *(rp
++)=cpu_to_le32(ri
| ylen
);
210 *(rp
++)=cpu_to_le32(((ylen
>> hshift
) << 16) |
212 *(rp
++)=cpu_to_le32(sg_dma_address(ysg
)+yoffset
);
215 *(rp
++)=cpu_to_le32(sg_dma_address(usg
)+uoffset
);
216 uoffset
+= ylen
>> hshift
;
217 *(rp
++)=cpu_to_le32(sg_dma_address(vsg
)+voffset
);
218 voffset
+= ylen
>> hshift
;
228 /* save pointer to jmp instruction address */
230 WARN_ON((risc
->jmp
- risc
->cpu
+ 2) * sizeof(*risc
->cpu
) > risc
->size
);
234 /* ---------------------------------------------------------- */
237 bttv_calc_geo_old(struct bttv
*btv
, struct bttv_geometry
*geo
,
238 int width
, int height
, int interleaved
,
239 const struct bttv_tvnorm
*tvnorm
)
244 int swidth
= tvnorm
->swidth
;
245 int totalwidth
= tvnorm
->totalwidth
;
246 int scaledtwidth
= tvnorm
->scaledtwidth
;
248 if (btv
->input
== btv
->dig
) {
254 vdelay
= tvnorm
->vdelay
;
256 xsf
= (width
*scaledtwidth
)/swidth
;
257 geo
->hscale
= ((totalwidth
*4096UL)/xsf
-4096);
258 geo
->hdelay
= tvnorm
->hdelayx1
;
259 geo
->hdelay
= (geo
->hdelay
*width
)/swidth
;
260 geo
->hdelay
&= 0x3fe;
261 sr
= ((tvnorm
->sheight
>> (interleaved
?0:1))*512)/height
- 512;
262 geo
->vscale
= (0x10000UL
-sr
) & 0x1fff;
263 geo
->crop
= ((width
>>8)&0x03) | ((geo
->hdelay
>>6)&0x0c) |
264 ((tvnorm
->sheight
>>4)&0x30) | ((vdelay
>>2)&0xc0);
265 geo
->vscale
|= interleaved
? (BT848_VSCALE_INT
<<8) : 0;
266 geo
->vdelay
= vdelay
;
268 geo
->sheight
= tvnorm
->sheight
;
269 geo
->vtotal
= tvnorm
->vtotal
;
271 if (btv
->opt_combfilter
) {
272 geo
->vtc
= (width
< 193) ? 2 : ((width
< 385) ? 1 : 0);
273 geo
->comb
= (width
< 769) ? 1 : 0;
281 bttv_calc_geo (struct bttv
* btv
,
282 struct bttv_geometry
* geo
,
286 const struct bttv_tvnorm
* tvnorm
,
287 const struct v4l2_rect
* crop
)
289 unsigned int c_width
;
290 unsigned int c_height
;
293 if ((crop
->left
== tvnorm
->cropcap
.defrect
.left
294 && crop
->top
== tvnorm
->cropcap
.defrect
.top
295 && crop
->width
== tvnorm
->cropcap
.defrect
.width
296 && crop
->height
== tvnorm
->cropcap
.defrect
.height
297 && width
<= tvnorm
->swidth
/* see PAL-Nc et al */)
298 || btv
->input
== btv
->dig
) {
299 bttv_calc_geo_old(btv
, geo
, width
, height
,
300 both_fields
, tvnorm
);
304 /* For bug compatibility the image size checks permit scale
305 factors > 16. See bttv_crop_calc_limits(). */
306 c_width
= min((unsigned int) crop
->width
, width
* 16);
307 c_height
= min((unsigned int) crop
->height
, height
* 16);
310 geo
->hscale
= (c_width
* 4096U + (width
>> 1)) / width
- 4096;
311 /* Even to store Cb first, odd for Cr. */
312 geo
->hdelay
= ((crop
->left
* width
+ c_width
) / c_width
) & ~1;
314 geo
->sheight
= c_height
;
315 geo
->vdelay
= crop
->top
- tvnorm
->cropcap
.bounds
.top
+ MIN_VDELAY
;
316 sr
= c_height
>> !both_fields
;
317 sr
= (sr
* 512U + (height
>> 1)) / height
- 512;
318 geo
->vscale
= (0x10000UL
- sr
) & 0x1fff;
319 geo
->vscale
|= both_fields
? (BT848_VSCALE_INT
<< 8) : 0;
320 geo
->vtotal
= tvnorm
->vtotal
;
322 geo
->crop
= (((geo
->width
>> 8) & 0x03) |
323 ((geo
->hdelay
>> 6) & 0x0c) |
324 ((geo
->sheight
>> 4) & 0x30) |
325 ((geo
->vdelay
>> 2) & 0xc0));
327 if (btv
->opt_combfilter
) {
328 geo
->vtc
= (width
< 193) ? 2 : ((width
< 385) ? 1 : 0);
329 geo
->comb
= (width
< 769) ? 1 : 0;
337 bttv_apply_geo(struct bttv
*btv
, struct bttv_geometry
*geo
, int odd
)
339 int off
= odd
? 0x80 : 0x00;
342 btor(BT848_VSCALE_COMB
, BT848_E_VSCALE_HI
+off
);
344 btand(~BT848_VSCALE_COMB
, BT848_E_VSCALE_HI
+off
);
346 btwrite(geo
->vtc
, BT848_E_VTC
+off
);
347 btwrite(geo
->hscale
>> 8, BT848_E_HSCALE_HI
+off
);
348 btwrite(geo
->hscale
& 0xff, BT848_E_HSCALE_LO
+off
);
349 btaor((geo
->vscale
>>8), 0xe0, BT848_E_VSCALE_HI
+off
);
350 btwrite(geo
->vscale
& 0xff, BT848_E_VSCALE_LO
+off
);
351 btwrite(geo
->width
& 0xff, BT848_E_HACTIVE_LO
+off
);
352 btwrite(geo
->hdelay
& 0xff, BT848_E_HDELAY_LO
+off
);
353 btwrite(geo
->sheight
& 0xff, BT848_E_VACTIVE_LO
+off
);
354 btwrite(geo
->vdelay
& 0xff, BT848_E_VDELAY_LO
+off
);
355 btwrite(geo
->crop
, BT848_E_CROP
+off
);
356 btwrite(geo
->vtotal
>>8, BT848_VTOTAL_HI
);
357 btwrite(geo
->vtotal
& 0xff, BT848_VTOTAL_LO
);
360 /* ---------------------------------------------------------- */
361 /* risc group / risc main loop / dma management */
363 static void bttv_set_risc_status(struct bttv
*btv
)
365 unsigned long cmd
= BT848_RISC_JUMP
;
367 cmd
|= BT848_RISC_IRQ
;
368 cmd
|= (btv
->loop_irq
& 0x0f) << 16;
369 cmd
|= (~btv
->loop_irq
& 0x0f) << 20;
371 btv
->main
.cpu
[RISC_SLOT_LOOP
] = cpu_to_le32(cmd
);
374 static void bttv_set_irq_timer(struct bttv
*btv
)
376 if (btv
->curr
.frame_irq
|| btv
->loop_irq
|| btv
->cvbi
)
377 mod_timer(&btv
->timeout
, jiffies
+ BTTV_TIMEOUT
);
379 del_timer(&btv
->timeout
);
382 static int bttv_set_capture_control(struct bttv
*btv
, int start_capture
)
386 if (btv
->curr
.top
|| btv
->curr
.bottom
)
387 capctl
= BT848_CAP_CTL_CAPTURE_ODD
|
388 BT848_CAP_CTL_CAPTURE_EVEN
;
391 capctl
|= BT848_CAP_CTL_CAPTURE_VBI_ODD
|
392 BT848_CAP_CTL_CAPTURE_VBI_EVEN
;
394 capctl
|= start_capture
;
396 btaor(capctl
, ~0x0f, BT848_CAP_CTL
);
401 static void bttv_start_dma(struct bttv
*btv
)
405 btwrite(btv
->main
.dma
, BT848_RISC_STRT_ADD
);
406 btor(BT848_GPIO_DMA_CTL_RISC_ENABLE
| BT848_GPIO_DMA_CTL_FIFO_ENABLE
,
411 static void bttv_stop_dma(struct bttv
*btv
)
415 btand(~(BT848_GPIO_DMA_CTL_RISC_ENABLE
|
416 BT848_GPIO_DMA_CTL_FIFO_ENABLE
), BT848_GPIO_DMA_CTL
);
420 void bttv_set_dma(struct bttv
*btv
, int start_capture
)
424 bttv_set_risc_status(btv
);
425 bttv_set_irq_timer(btv
);
426 capctl
= bttv_set_capture_control(btv
, start_capture
);
433 d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n",
434 btv
->c
.nr
,capctl
,btv
->loop_irq
,
435 btv
->cvbi
? (unsigned long long)btv
->cvbi
->top
.dma
: 0,
436 btv
->curr
.top
? (unsigned long long)btv
->curr
.top
->top
.dma
: 0,
437 btv
->cvbi
? (unsigned long long)btv
->cvbi
->bottom
.dma
: 0,
438 btv
->curr
.bottom
? (unsigned long long)btv
->curr
.bottom
->bottom
.dma
: 0);
442 bttv_risc_init_main(struct bttv
*btv
)
446 if ((rc
= btcx_riscmem_alloc(btv
->c
.pci
,&btv
->main
,PAGE_SIZE
)) < 0)
448 dprintk("%d: risc main @ %08llx\n",
449 btv
->c
.nr
, (unsigned long long)btv
->main
.dma
);
451 btv
->main
.cpu
[0] = cpu_to_le32(BT848_RISC_SYNC
| BT848_RISC_RESYNC
|
452 BT848_FIFO_STATUS_VRE
);
453 btv
->main
.cpu
[1] = cpu_to_le32(0);
454 btv
->main
.cpu
[2] = cpu_to_le32(BT848_RISC_JUMP
);
455 btv
->main
.cpu
[3] = cpu_to_le32(btv
->main
.dma
+ (4<<2));
458 btv
->main
.cpu
[4] = cpu_to_le32(BT848_RISC_JUMP
);
459 btv
->main
.cpu
[5] = cpu_to_le32(btv
->main
.dma
+ (6<<2));
460 btv
->main
.cpu
[6] = cpu_to_le32(BT848_RISC_JUMP
);
461 btv
->main
.cpu
[7] = cpu_to_le32(btv
->main
.dma
+ (8<<2));
463 btv
->main
.cpu
[8] = cpu_to_le32(BT848_RISC_SYNC
| BT848_RISC_RESYNC
|
464 BT848_FIFO_STATUS_VRO
);
465 btv
->main
.cpu
[9] = cpu_to_le32(0);
468 btv
->main
.cpu
[10] = cpu_to_le32(BT848_RISC_JUMP
);
469 btv
->main
.cpu
[11] = cpu_to_le32(btv
->main
.dma
+ (12<<2));
470 btv
->main
.cpu
[12] = cpu_to_le32(BT848_RISC_JUMP
);
471 btv
->main
.cpu
[13] = cpu_to_le32(btv
->main
.dma
+ (14<<2));
473 /* jump back to top field */
474 btv
->main
.cpu
[14] = cpu_to_le32(BT848_RISC_JUMP
);
475 btv
->main
.cpu
[15] = cpu_to_le32(btv
->main
.dma
+ (0<<2));
481 bttv_risc_hook(struct bttv
*btv
, int slot
, struct btcx_riscmem
*risc
,
485 unsigned long next
= btv
->main
.dma
+ ((slot
+2) << 2);
488 d2printk("%d: risc=%p slot[%d]=NULL\n", btv
->c
.nr
, risc
, slot
);
489 btv
->main
.cpu
[slot
+1] = cpu_to_le32(next
);
491 d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n",
492 btv
->c
.nr
, risc
, slot
,
493 (unsigned long long)risc
->dma
, irqflags
);
494 cmd
= BT848_RISC_JUMP
;
496 cmd
|= BT848_RISC_IRQ
;
497 cmd
|= (irqflags
& 0x0f) << 16;
498 cmd
|= (~irqflags
& 0x0f) << 20;
500 risc
->jmp
[0] = cpu_to_le32(cmd
);
501 risc
->jmp
[1] = cpu_to_le32(next
);
502 btv
->main
.cpu
[slot
+1] = cpu_to_le32(risc
->dma
);
507 int bttv_buffer_risc_vbi(struct bttv
*btv
, struct bttv_buffer
*buf
)
511 unsigned int bpl
= 2044; /* max. vbipack */
512 unsigned int padding
= VBI_BPL
- bpl
;
513 unsigned int skip_lines0
= 0;
514 unsigned int skip_lines1
= 0;
515 unsigned int min_vdelay
= MIN_VDELAY
;
517 const struct bttv_tvnorm
*tvnorm
= btv
->vbi_fmt
.tvnorm
;
518 struct sg_table
*sgt
= vb2_dma_sg_plane_desc(&buf
->vbuf
.vb2_buf
, 0);
519 struct scatterlist
*list
= sgt
->sgl
;
521 if (btv
->vbi_fmt
.fmt
.count
[0] > 0)
522 skip_lines0
= max(0, (btv
->vbi_fmt
.fmt
.start
[0] -
523 tvnorm
->vbistart
[0]));
524 if (btv
->vbi_fmt
.fmt
.count
[1] > 0)
525 skip_lines1
= max(0, (btv
->vbi_fmt
.fmt
.start
[1] -
526 tvnorm
->vbistart
[1]));
528 if (btv
->vbi_fmt
.fmt
.count
[0] > 0) {
529 r
= bttv_risc_packed(btv
, &buf
->top
, list
, 0, bpl
, padding
,
530 skip_lines0
, btv
->vbi_fmt
.fmt
.count
[0]);
535 if (btv
->vbi_fmt
.fmt
.count
[1] > 0) {
536 offset
= btv
->vbi_fmt
.fmt
.count
[0] * VBI_BPL
;
537 r
= bttv_risc_packed(btv
, &buf
->bottom
, list
, offset
, bpl
,
538 padding
, skip_lines1
,
539 btv
->vbi_fmt
.fmt
.count
[1]);
544 if (btv
->vbi_fmt
.end
>= tvnorm
->cropcap
.bounds
.top
)
545 min_vdelay
+= btv
->vbi_fmt
.end
- tvnorm
->cropcap
.bounds
.top
;
547 /* For bttv_buffer_activate_vbi(). */
548 buf
->geo
.vdelay
= min_vdelay
;
554 bttv_buffer_activate_vbi(struct bttv
*btv
,
555 struct bttv_buffer
*vbi
)
557 struct btcx_riscmem
*top
;
558 struct btcx_riscmem
*bottom
;
560 int bottom_irq_flags
;
565 bottom_irq_flags
= 0;
568 unsigned int crop
, vdelay
;
570 list_del(&vbi
->list
);
572 /* VDELAY is start of video, end of VBI capturing. */
573 crop
= btread(BT848_E_CROP
);
574 vdelay
= btread(BT848_E_VDELAY_LO
) + ((crop
& 0xc0) << 2);
576 if (vbi
->geo
.vdelay
> vdelay
) {
577 vdelay
= vbi
->geo
.vdelay
& 0xfe;
578 crop
= (crop
& 0x3f) | ((vbi
->geo
.vdelay
>> 2) & 0xc0);
580 btwrite(vdelay
, BT848_E_VDELAY_LO
);
581 btwrite(crop
, BT848_E_CROP
);
582 btwrite(vdelay
, BT848_O_VDELAY_LO
);
583 btwrite(crop
, BT848_O_CROP
);
586 if (btv
->vbi_count
[0] > 0) {
591 if (btv
->vbi_count
[1] > 0) {
593 bottom
= &vbi
->bottom
;
594 bottom_irq_flags
= 4;
598 bttv_risc_hook(btv
, RISC_SLOT_O_VBI
, top
, top_irq_flags
);
599 bttv_risc_hook(btv
, RISC_SLOT_E_VBI
, bottom
, bottom_irq_flags
);
605 bttv_buffer_activate_video(struct bttv
*btv
,
606 struct bttv_buffer_set
*set
)
609 if (NULL
!= set
->top
&& NULL
!= set
->bottom
) {
610 if (set
->top
== set
->bottom
) {
611 if (set
->top
->list
.next
)
612 list_del(&set
->top
->list
);
614 if (set
->top
->list
.next
)
615 list_del(&set
->top
->list
);
616 if (set
->bottom
->list
.next
)
617 list_del(&set
->bottom
->list
);
619 bttv_apply_geo(btv
, &set
->top
->geo
, 1);
620 bttv_apply_geo(btv
, &set
->bottom
->geo
,0);
621 bttv_risc_hook(btv
, RISC_SLOT_O_FIELD
, &set
->top
->top
,
623 bttv_risc_hook(btv
, RISC_SLOT_E_FIELD
, &set
->bottom
->bottom
,
625 btaor((set
->top
->btformat
& 0xf0) | (set
->bottom
->btformat
& 0x0f),
626 ~0xff, BT848_COLOR_FMT
);
627 btaor((set
->top
->btswap
& 0x0a) | (set
->bottom
->btswap
& 0x05),
628 ~0x0f, BT848_COLOR_CTL
);
629 } else if (NULL
!= set
->top
) {
630 if (set
->top
->list
.next
)
631 list_del(&set
->top
->list
);
632 bttv_apply_geo(btv
, &set
->top
->geo
,1);
633 bttv_apply_geo(btv
, &set
->top
->geo
,0);
634 bttv_risc_hook(btv
, RISC_SLOT_O_FIELD
, &set
->top
->top
,
636 bttv_risc_hook(btv
, RISC_SLOT_E_FIELD
, NULL
, 0);
637 btaor(set
->top
->btformat
& 0xff, ~0xff, BT848_COLOR_FMT
);
638 btaor(set
->top
->btswap
& 0x0f, ~0x0f, BT848_COLOR_CTL
);
639 } else if (NULL
!= set
->bottom
) {
640 if (set
->bottom
->list
.next
)
641 list_del(&set
->bottom
->list
);
642 bttv_apply_geo(btv
, &set
->bottom
->geo
,1);
643 bttv_apply_geo(btv
, &set
->bottom
->geo
,0);
644 bttv_risc_hook(btv
, RISC_SLOT_O_FIELD
, NULL
, 0);
645 bttv_risc_hook(btv
, RISC_SLOT_E_FIELD
, &set
->bottom
->bottom
,
647 btaor(set
->bottom
->btformat
& 0xff, ~0xff, BT848_COLOR_FMT
);
648 btaor(set
->bottom
->btswap
& 0x0f, ~0x0f, BT848_COLOR_CTL
);
650 bttv_risc_hook(btv
, RISC_SLOT_O_FIELD
, NULL
, 0);
651 bttv_risc_hook(btv
, RISC_SLOT_E_FIELD
, NULL
, 0);
656 /* ---------------------------------------------------------- */
658 /* calculate geometry, build risc code */
660 bttv_buffer_risc(struct bttv
*btv
, struct bttv_buffer
*buf
)
663 const struct bttv_tvnorm
*tvnorm
= bttv_tvnorms
+ btv
->tvnorm
;
664 struct sg_table
*sgt
= vb2_dma_sg_plane_desc(&buf
->vbuf
.vb2_buf
, 0);
665 struct scatterlist
*list
= sgt
->sgl
;
666 unsigned long size
= (btv
->fmt
->depth
* btv
->width
* btv
->height
) >> 3;
668 /* packed pixel modes */
669 if (btv
->fmt
->flags
& FORMAT_FLAGS_PACKED
) {
670 int bpl
= (btv
->fmt
->depth
>> 3) * btv
->width
;
671 int bpf
= bpl
* (btv
->height
>> 1);
673 bttv_calc_geo(btv
, &buf
->geo
, btv
->width
, btv
->height
,
674 V4L2_FIELD_HAS_BOTH(buf
->vbuf
.field
), tvnorm
,
675 &btv
->crop
[!!btv
->do_crop
].rect
);
676 switch (buf
->vbuf
.field
) {
678 r
= bttv_risc_packed(btv
, &buf
->top
, list
, 0, bpl
, 0,
681 case V4L2_FIELD_BOTTOM
:
682 r
= bttv_risc_packed(btv
, &buf
->bottom
, list
, 0, bpl
,
685 case V4L2_FIELD_INTERLACED
:
686 r
= bttv_risc_packed(btv
, &buf
->top
, list
, 0, bpl
,
687 bpl
, 0, btv
->height
>> 1);
688 r
= bttv_risc_packed(btv
, &buf
->bottom
, list
, bpl
,
689 bpl
, bpl
, 0, btv
->height
>> 1);
691 case V4L2_FIELD_SEQ_TB
:
692 r
= bttv_risc_packed(btv
, &buf
->top
, list
, 0, bpl
, 0,
693 0, btv
->height
>> 1);
694 r
= bttv_risc_packed(btv
, &buf
->bottom
, list
, bpf
,
695 bpl
, 0, 0, btv
->height
>> 1);
703 if (btv
->fmt
->flags
& FORMAT_FLAGS_PLANAR
) {
704 int uoffset
, voffset
;
705 int ypadding
, cpadding
, lines
;
707 /* calculate chroma offsets */
708 uoffset
= btv
->width
* btv
->height
;
709 voffset
= btv
->width
* btv
->height
;
710 if (btv
->fmt
->flags
& FORMAT_FLAGS_CrCb
) {
711 /* Y-Cr-Cb plane order */
712 uoffset
>>= btv
->fmt
->hshift
;
713 uoffset
>>= btv
->fmt
->vshift
;
716 /* Y-Cb-Cr plane order */
717 voffset
>>= btv
->fmt
->hshift
;
718 voffset
>>= btv
->fmt
->vshift
;
721 switch (buf
->vbuf
.field
) {
723 bttv_calc_geo(btv
, &buf
->geo
, btv
->width
, btv
->height
,
725 &btv
->crop
[!!btv
->do_crop
].rect
);
726 r
= bttv_risc_planar(btv
, &buf
->top
, list
, 0,
727 btv
->width
, 0, btv
->height
,
730 btv
->fmt
->vshift
, 0);
732 case V4L2_FIELD_BOTTOM
:
733 bttv_calc_geo(btv
, &buf
->geo
, btv
->width
, btv
->height
,
735 &btv
->crop
[!!btv
->do_crop
].rect
);
736 r
= bttv_risc_planar(btv
, &buf
->bottom
, list
, 0,
737 btv
->width
, 0, btv
->height
,
740 btv
->fmt
->vshift
, 0);
742 case V4L2_FIELD_INTERLACED
:
743 bttv_calc_geo(btv
, &buf
->geo
, btv
->width
, btv
->height
,
745 &btv
->crop
[!!btv
->do_crop
].rect
);
746 lines
= btv
->height
>> 1;
747 ypadding
= btv
->width
;
748 cpadding
= btv
->width
>> btv
->fmt
->hshift
;
749 r
= bttv_risc_planar(btv
, &buf
->top
, list
, 0,
750 btv
->width
, ypadding
, lines
,
753 btv
->fmt
->vshift
, cpadding
);
755 r
= bttv_risc_planar(btv
, &buf
->bottom
, list
,
756 ypadding
, btv
->width
, ypadding
,
757 lines
, uoffset
+ cpadding
,
760 btv
->fmt
->vshift
, cpadding
);
762 case V4L2_FIELD_SEQ_TB
:
763 bttv_calc_geo(btv
, &buf
->geo
, btv
->width
, btv
->height
,
765 &btv
->crop
[!!btv
->do_crop
].rect
);
766 lines
= btv
->height
>> 1;
767 ypadding
= btv
->width
;
768 cpadding
= btv
->width
>> btv
->fmt
->hshift
;
769 r
= bttv_risc_planar(btv
, &buf
->top
, list
, 0,
770 btv
->width
, 0, lines
,
771 uoffset
>> 1, voffset
>> 1,
773 btv
->fmt
->vshift
, 0);
774 r
= bttv_risc_planar(btv
, &buf
->bottom
, list
,
776 btv
->width
, 0, lines
,
777 lines
* ypadding
+ (uoffset
>> 1),
778 lines
* ypadding
+ (voffset
>> 1),
780 btv
->fmt
->vshift
, 0);
788 if (btv
->fmt
->flags
& FORMAT_FLAGS_RAW
) {
789 /* build risc code */
790 buf
->vbuf
.field
= V4L2_FIELD_SEQ_TB
;
791 bttv_calc_geo(btv
, &buf
->geo
, tvnorm
->swidth
, tvnorm
->sheight
,
792 1, tvnorm
, &btv
->crop
[!!btv
->do_crop
].rect
);
793 r
= bttv_risc_packed(btv
, &buf
->top
, list
, 0, RAW_BPL
, 0, 0,
795 r
= bttv_risc_packed(btv
, &buf
->bottom
, list
, size
/ 2,
796 RAW_BPL
, 0, 0, RAW_LINES
);
799 /* copy format info */
800 buf
->btformat
= btv
->fmt
->btformat
;
801 buf
->btswap
= btv
->fmt
->btswap
;