treewide: kmalloc() -> kmalloc_array()
[linux-block.git] / drivers / media / pci / bt8xx / bttv-risc.c
CommitLineData
1da177e4 1/*
1da177e4
LT
2
3 bttv-risc.c -- interfaces to other kernel modules
4
5 bttv risc code handling
6 - memory management
7 - generation
8
9 (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
10
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.
15
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.
20
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.
24
25*/
26
8af443e5
JP
27#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28
1da177e4
LT
29#include <linux/module.h>
30#include <linux/init.h>
5a0e3ad6 31#include <linux/slab.h>
1da177e4
LT
32#include <linux/pci.h>
33#include <linux/vmalloc.h>
34#include <linux/interrupt.h>
35#include <asm/page.h>
36#include <asm/pgtable.h>
35ea11ff 37#include <media/v4l2-ioctl.h>
1da177e4
LT
38
39#include "bttvp.h"
40
41#define VCR_HACK_LINES 4
42
43/* ---------------------------------------------------------- */
44/* risc code generators */
45
46int
47bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
48 struct scatterlist *sglist,
49 unsigned int offset, unsigned int bpl,
e5bd0260
MS
50 unsigned int padding, unsigned int skip_lines,
51 unsigned int store_lines)
1da177e4
LT
52{
53 u32 instructions,line,todo;
54 struct scatterlist *sg;
d8eaa58b 55 __le32 *rp;
1da177e4
LT
56 int rc;
57
58 /* estimate risc mem: worst case is one write per page border +
4a287cfe
DS
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 */
e5bd0260
MS
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)
1da177e4
LT
67 return rc;
68
69 /* sync instruction */
70 rp = risc->cpu;
71 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
72 *(rp++) = cpu_to_le32(0);
73
e5bd0260
MS
74 while (skip_lines-- > 0) {
75 *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
76 BT848_RISC_EOL | bpl);
77 }
78
1da177e4
LT
79 /* scan lines */
80 sg = sglist;
e5bd0260 81 for (line = 0; line < store_lines; line++) {
1da177e4 82 if ((btv->opt_vcr_hack) &&
e5bd0260 83 (line >= (store_lines - VCR_HACK_LINES)))
1da177e4
LT
84 continue;
85 while (offset && offset >= sg_dma_len(sg)) {
86 offset -= sg_dma_len(sg);
872dfcfe 87 sg = sg_next(sg);
1da177e4
LT
88 }
89 if (bpl <= sg_dma_len(sg)-offset) {
90 /* fits into current chunk */
4ac97914 91 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
1da177e4 92 BT848_RISC_EOL|bpl);
4ac97914
MCC
93 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
94 offset+=bpl;
1da177e4
LT
95 } else {
96 /* scanline needs to be splitted */
4ac97914
MCC
97 todo = bpl;
98 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
1da177e4 99 (sg_dma_len(sg)-offset));
4ac97914
MCC
100 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
101 todo -= (sg_dma_len(sg)-offset);
102 offset = 0;
872dfcfe 103 sg = sg_next(sg);
4ac97914 104 while (todo > sg_dma_len(sg)) {
f2421ca3 105 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
1da177e4 106 sg_dma_len(sg));
f2421ca3 107 *(rp++)=cpu_to_le32(sg_dma_address(sg));
1da177e4 108 todo -= sg_dma_len(sg);
872dfcfe 109 sg = sg_next(sg);
1da177e4 110 }
4ac97914 111 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
1da177e4
LT
112 todo);
113 *(rp++)=cpu_to_le32(sg_dma_address(sg));
114 offset += todo;
115 }
116 offset += padding;
117 }
118
119 /* save pointer to jmp instruction address */
120 risc->jmp = rp;
4a287cfe 121 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1da177e4
LT
122 return 0;
123}
124
125static int
126bttv_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)
133{
134 unsigned int instructions,line,todo,ylen,chroma;
d8eaa58b
AV
135 __le32 *rp;
136 u32 ri;
1da177e4
LT
137 struct scatterlist *ysg;
138 struct scatterlist *usg;
139 struct scatterlist *vsg;
140 int topfield = (0 == yoffset);
141 int rc;
142
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) */
e5bd0260
MS
146 instructions = ((3 + (ybpl + ypadding) * ylines * 2)
147 / PAGE_SIZE) + ylines;
1da177e4
LT
148 instructions += 2;
149 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
150 return rc;
151
152 /* sync instruction */
153 rp = risc->cpu;
154 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
155 *(rp++) = cpu_to_le32(0);
156
157 /* scan lines */
158 ysg = sglist;
159 usg = sglist;
160 vsg = sglist;
161 for (line = 0; line < ylines; line++) {
162 if ((btv->opt_vcr_hack) &&
163 (line >= (ylines - VCR_HACK_LINES)))
164 continue;
165 switch (vshift) {
166 case 0:
167 chroma = 1;
168 break;
169 case 1:
170 if (topfield)
171 chroma = ((line & 1) == 0);
172 else
173 chroma = ((line & 1) == 1);
174 break;
175 case 2:
176 if (topfield)
177 chroma = ((line & 3) == 0);
178 else
179 chroma = ((line & 3) == 2);
180 break;
181 default:
182 chroma = 0;
183 break;
184 }
185
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);
872dfcfe 190 ysg = sg_next(ysg);
1da177e4 191 }
1da177e4
LT
192
193 /* calculate max number of bytes we can write */
194 ylen = todo;
195 if (yoffset + ylen > sg_dma_len(ysg))
196 ylen = sg_dma_len(ysg) - yoffset;
197 if (chroma) {
6f7e780b
SW
198 while (uoffset && uoffset >= sg_dma_len(usg)) {
199 uoffset -= sg_dma_len(usg);
200 usg = sg_next(usg);
201 }
202 while (voffset && voffset >= sg_dma_len(vsg)) {
203 voffset -= sg_dma_len(vsg);
204 vsg = sg_next(vsg);
205 }
206
1da177e4
LT
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;
212 } else {
213 ri = BT848_RISC_WRITE1S23;
214 }
215 if (ybpl == todo)
216 ri |= BT848_RISC_SOL;
217 if (ylen == todo)
218 ri |= BT848_RISC_EOL;
219
220 /* write risc instruction */
4ac97914
MCC
221 *(rp++)=cpu_to_le32(ri | ylen);
222 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
1da177e4
LT
223 (ylen >> hshift));
224 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
225 yoffset += ylen;
226 if (chroma) {
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;
231 }
232 }
233 yoffset += ypadding;
234 if (chroma) {
235 uoffset += cpadding;
236 voffset += cpadding;
237 }
238 }
239
240 /* save pointer to jmp instruction address */
241 risc->jmp = rp;
4a287cfe 242 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1da177e4
LT
243 return 0;
244}
245
246static int
247bttv_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)
250{
c6eb8eaf
HV
251 int dwords, rc, line, maxy, start, end;
252 unsigned skip, nskips;
1da177e4 253 struct btcx_skiplist *skips;
d8eaa58b
AV
254 __le32 *rp;
255 u32 ri,ra;
1da177e4
LT
256 u32 addr;
257
258 /* skip list for window clipping */
6da2ec56
KC
259 skips = kmalloc_array(ov->nclips, sizeof(*skips),GFP_KERNEL);
260 if (NULL == skips)
1da177e4
LT
261 return -ENOMEM;
262
3203f94a 263 /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
1da177e4 264 + sync + jump (all 2 dwords) */
3203f94a
DS
265 dwords = (3 * ov->nclips + 2) *
266 ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
267 dwords += 4;
268 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
1da177e4
LT
269 kfree(skips);
270 return rc;
271 }
272
273 /* sync instruction */
274 rp = risc->cpu;
275 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
276 *(rp++) = cpu_to_le32(0);
277
278 addr = (unsigned long)btv->fbuf.base;
279 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
280 addr += (fmt->depth >> 3) * ov->w.left;
281
282 /* scan lines */
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)))
287 continue;
288 if ((line%2) == 0 && skip_even)
289 continue;
290 if ((line%2) == 1 && skip_odd)
291 continue;
292
293 /* calculate clipping */
294 if (line > maxy)
295 btcx_calc_skips(line, ov->w.width, &maxy,
296 skips, &nskips, ov->clips, ov->nclips);
297
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;
302 end = ov->w.width;
303 } else if (start < skips[skip].start) {
304 ri = BT848_RISC_WRITE;
305 end = skips[skip].start;
306 } else {
307 ri = BT848_RISC_SKIP;
308 end = skips[skip].end;
309 skip++;
310 }
311 if (BT848_RISC_WRITE == ri)
312 ra = addr + (fmt->depth>>3)*start;
313 else
314 ra = 0;
315
316 if (0 == start)
317 ri |= BT848_RISC_SOL;
318 if (ov->w.width == end)
319 ri |= BT848_RISC_EOL;
320 ri |= (fmt->depth>>3) * (end-start);
321
322 *(rp++)=cpu_to_le32(ri);
323 if (0 != ra)
324 *(rp++)=cpu_to_le32(ra);
325 }
326 }
327
328 /* save pointer to jmp instruction address */
329 risc->jmp = rp;
4a287cfe 330 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1da177e4
LT
331 kfree(skips);
332 return 0;
333}
334
335/* ---------------------------------------------------------- */
336
337static void
e5bd0260
MS
338bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
339 int width, int height, int interleaved,
340 const struct bttv_tvnorm *tvnorm)
1da177e4 341{
4ac97914 342 u32 xsf, sr;
1da177e4
LT
343 int vdelay;
344
345 int swidth = tvnorm->swidth;
346 int totalwidth = tvnorm->totalwidth;
347 int scaledtwidth = tvnorm->scaledtwidth;
348
5221e21e 349 if (btv->input == btv->dig) {
1da177e4
LT
350 swidth = 720;
351 totalwidth = 858;
352 scaledtwidth = 858;
353 }
354
355 vdelay = tvnorm->vdelay;
1da177e4 356
4ac97914
MCC
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;
368 geo->width = width;
369 geo->sheight = tvnorm->sheight;
1da177e4
LT
370 geo->vtotal = tvnorm->vtotal;
371
4ac97914
MCC
372 if (btv->opt_combfilter) {
373 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
374 geo->comb = (width < 769) ? 1 : 0;
375 } else {
376 geo->vtc = 0;
377 geo->comb = 0;
378 }
1da177e4
LT
379}
380
e5bd0260
MS
381static void
382bttv_calc_geo (struct bttv * btv,
383 struct bttv_geometry * geo,
384 unsigned int width,
385 unsigned int height,
386 int both_fields,
387 const struct bttv_tvnorm * tvnorm,
388 const struct v4l2_rect * crop)
389{
390 unsigned int c_width;
391 unsigned int c_height;
392 u32 sr;
393
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 */)
5221e21e 399 || btv->input == btv->dig) {
e5bd0260
MS
400 bttv_calc_geo_old(btv, geo, width, height,
401 both_fields, tvnorm);
402 return;
403 }
404
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);
409
410 geo->width = width;
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;
414
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;
422
423 geo->crop = (((geo->width >> 8) & 0x03) |
424 ((geo->hdelay >> 6) & 0x0c) |
425 ((geo->sheight >> 4) & 0x30) |
426 ((geo->vdelay >> 2) & 0xc0));
427
428 if (btv->opt_combfilter) {
429 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
430 geo->comb = (width < 769) ? 1 : 0;
431 } else {
432 geo->vtc = 0;
433 geo->comb = 0;
434 }
435}
436
1da177e4
LT
437static void
438bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
439{
4ac97914 440 int off = odd ? 0x80 : 0x00;
1da177e4
LT
441
442 if (geo->comb)
443 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
444 else
445 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
446
4ac97914
MCC
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);
1da177e4 457 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
4ac97914 458 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
1da177e4
LT
459}
460
461/* ---------------------------------------------------------- */
462/* risc group / risc main loop / dma management */
463
464void
465bttv_set_dma(struct bttv *btv, int override)
466{
467 unsigned long cmd;
468 int capctl;
469
470 btv->cap_ctl = 0;
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;
474
475 capctl = 0;
476 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
477 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
478 capctl |= override;
479
8af443e5 480 d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n",
1da177e4
LT
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);
486
487 cmd = BT848_RISC_JUMP;
488 if (btv->loop_irq) {
489 cmd |= BT848_RISC_IRQ;
490 cmd |= (btv->loop_irq & 0x0f) << 16;
491 cmd |= (~btv->loop_irq & 0x0f) << 20;
492 }
493 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
494 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
495 } else {
496 del_timer(&btv->timeout);
497 }
4ac97914 498 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
1da177e4
LT
499
500 btaor(capctl, ~0x0f, BT848_CAP_CTL);
501 if (capctl) {
502 if (btv->dma_on)
503 return;
504 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
505 btor(3, BT848_GPIO_DMA_CTL);
506 btv->dma_on = 1;
507 } else {
508 if (!btv->dma_on)
509 return;
4ac97914 510 btand(~3, BT848_GPIO_DMA_CTL);
1da177e4
LT
511 btv->dma_on = 0;
512 }
513 return;
514}
515
516int
517bttv_risc_init_main(struct bttv *btv)
518{
519 int rc;
520
521 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
522 return rc;
8af443e5
JP
523 dprintk("%d: risc main @ %08llx\n",
524 btv->c.nr, (unsigned long long)btv->main.dma);
1da177e4
LT
525
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));
531
532 /* top field */
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));
537
4ac97914 538 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
1da177e4 539 BT848_FIFO_STATUS_VRO);
4ac97914 540 btv->main.cpu[9] = cpu_to_le32(0);
1da177e4
LT
541
542 /* bottom field */
4ac97914 543 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
1da177e4 544 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
4ac97914 545 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
1da177e4
LT
546 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
547
548 /* jump back to top field */
549 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
4ac97914 550 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
1da177e4
LT
551
552 return 0;
553}
554
555int
556bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
557 int irqflags)
558{
559 unsigned long cmd;
560 unsigned long next = btv->main.dma + ((slot+2) << 2);
561
562 if (NULL == risc) {
8af443e5 563 d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot);
1da177e4
LT
564 btv->main.cpu[slot+1] = cpu_to_le32(next);
565 } else {
8af443e5
JP
566 d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n",
567 btv->c.nr, risc, slot,
568 (unsigned long long)risc->dma, irqflags);
1da177e4
LT
569 cmd = BT848_RISC_JUMP;
570 if (irqflags) {
571 cmd |= BT848_RISC_IRQ;
572 cmd |= (irqflags & 0x0f) << 16;
573 cmd |= (~irqflags & 0x0f) << 20;
574 }
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);
578 }
579 return 0;
580}
581
582void
c7b0ac05 583bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
1da177e4 584{
c1accaa2
MCC
585 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
586
ae24601b 587 BUG_ON(in_interrupt());
0e0809a5 588 videobuf_waiton(q, &buf->vb, 0, 0);
95268403 589 videobuf_dma_unmap(q->dev, dma);
c1accaa2 590 videobuf_dma_free(dma);
1da177e4
LT
591 btcx_riscmem_free(btv->c.pci,&buf->bottom);
592 btcx_riscmem_free(btv->c.pci,&buf->top);
0fc0686e 593 buf->vb.state = VIDEOBUF_NEEDS_INIT;
1da177e4
LT
594}
595
596int
597bttv_buffer_activate_vbi(struct bttv *btv,
598 struct bttv_buffer *vbi)
599{
e5bd0260
MS
600 struct btcx_riscmem *top;
601 struct btcx_riscmem *bottom;
602 int top_irq_flags;
603 int bottom_irq_flags;
604
605 top = NULL;
606 bottom = NULL;
607 top_irq_flags = 0;
608 bottom_irq_flags = 0;
609
1da177e4 610 if (vbi) {
e5bd0260
MS
611 unsigned int crop, vdelay;
612
0fc0686e 613 vbi->vb.state = VIDEOBUF_ACTIVE;
1da177e4 614 list_del(&vbi->vb.queue);
e5bd0260
MS
615
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);
619
620 if (vbi->geo.vdelay > vdelay) {
621 vdelay = vbi->geo.vdelay & 0xfe;
622 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
623
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);
628 }
629
630 if (vbi->vbi_count[0] > 0) {
631 top = &vbi->top;
632 top_irq_flags = 4;
633 }
634
635 if (vbi->vbi_count[1] > 0) {
636 top_irq_flags = 0;
637 bottom = &vbi->bottom;
638 bottom_irq_flags = 4;
639 }
1da177e4 640 }
e5bd0260
MS
641
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);
644
1da177e4
LT
645 return 0;
646}
647
648int
649bttv_buffer_activate_video(struct bttv *btv,
650 struct bttv_buffer_set *set)
651{
652 /* video capture */
653 if (NULL != set->top && NULL != set->bottom) {
654 if (set->top == set->bottom) {
0fc0686e 655 set->top->vb.state = VIDEOBUF_ACTIVE;
1da177e4
LT
656 if (set->top->vb.queue.next)
657 list_del(&set->top->vb.queue);
658 } else {
0fc0686e
BP
659 set->top->vb.state = VIDEOBUF_ACTIVE;
660 set->bottom->vb.state = VIDEOBUF_ACTIVE;
1da177e4
LT
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);
665 }
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,
669 set->top_irq);
670 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
671 set->frame_irq);
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) {
0fc0686e 677 set->top->vb.state = VIDEOBUF_ACTIVE;
1da177e4
LT
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,
683 set->frame_irq);
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) {
0fc0686e 688 set->bottom->vb.state = VIDEOBUF_ACTIVE;
1da177e4
LT
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,
695 set->frame_irq);
696 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
697 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
698 } else {
699 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
700 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
701 }
702 return 0;
703}
704
705/* ---------------------------------------------------------- */
706
707/* calculate geometry, build risc code */
708int
709bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
710{
711 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
c1accaa2 712 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
1da177e4 713
8af443e5 714 dprintk("%d: buffer field: %s format: %s size: %dx%d\n",
1da177e4
LT
715 btv->c.nr, v4l2_field_names[buf->vb.field],
716 buf->fmt->name, buf->vb.width, buf->vb.height);
717
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);
722
723 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
e5bd0260
MS
724 V4L2_FIELD_HAS_BOTH(buf->vb.field),
725 tvnorm,&buf->crop);
1da177e4
LT
726
727 switch (buf->vb.field) {
728 case V4L2_FIELD_TOP:
c1accaa2 729 bttv_risc_packed(btv,&buf->top,dma->sglist,
e5bd0260
MS
730 /* offset */ 0,bpl,
731 /* padding */ 0,/* skip_lines */ 0,
732 buf->vb.height);
1da177e4
LT
733 break;
734 case V4L2_FIELD_BOTTOM:
c1accaa2 735 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
e5bd0260 736 0,bpl,0,0,buf->vb.height);
1da177e4
LT
737 break;
738 case V4L2_FIELD_INTERLACED:
c1accaa2 739 bttv_risc_packed(btv,&buf->top,dma->sglist,
e5bd0260 740 0,bpl,bpl,0,buf->vb.height >> 1);
c1accaa2 741 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
e5bd0260 742 bpl,bpl,bpl,0,buf->vb.height >> 1);
1da177e4
LT
743 break;
744 case V4L2_FIELD_SEQ_TB:
c1accaa2 745 bttv_risc_packed(btv,&buf->top,dma->sglist,
e5bd0260 746 0,bpl,0,0,buf->vb.height >> 1);
c1accaa2 747 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
e5bd0260 748 bpf,bpl,0,0,buf->vb.height >> 1);
1da177e4
LT
749 break;
750 default:
751 BUG();
752 }
753 }
754
755 /* planar modes */
756 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
757 int uoffset, voffset;
758 int ypadding, cpadding, lines;
759
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;
767 uoffset += voffset;
768 } else {
769 /* Y-Cb-Cr plane order */
770 voffset >>= buf->fmt->hshift;
771 voffset >>= buf->fmt->vshift;
772 voffset += uoffset;
773 }
774
775 switch (buf->vb.field) {
776 case V4L2_FIELD_TOP:
777 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
e5bd0260
MS
778 buf->vb.height,/* both_fields */ 0,
779 tvnorm,&buf->crop);
c1accaa2 780 bttv_risc_planar(btv, &buf->top, dma->sglist,
1da177e4
LT
781 0,buf->vb.width,0,buf->vb.height,
782 uoffset,voffset,buf->fmt->hshift,
783 buf->fmt->vshift,0);
784 break;
785 case V4L2_FIELD_BOTTOM:
786 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
e5bd0260
MS
787 buf->vb.height,0,
788 tvnorm,&buf->crop);
c1accaa2 789 bttv_risc_planar(btv, &buf->bottom, dma->sglist,
1da177e4
LT
790 0,buf->vb.width,0,buf->vb.height,
791 uoffset,voffset,buf->fmt->hshift,
792 buf->fmt->vshift,0);
793 break;
794 case V4L2_FIELD_INTERLACED:
795 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
e5bd0260
MS
796 buf->vb.height,1,
797 tvnorm,&buf->crop);
1da177e4
LT
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,
c1accaa2 802 dma->sglist,
1da177e4
LT
803 0,buf->vb.width,ypadding,lines,
804 uoffset,voffset,
805 buf->fmt->hshift,
806 buf->fmt->vshift,
807 cpadding);
808 bttv_risc_planar(btv,&buf->bottom,
c1accaa2 809 dma->sglist,
1da177e4
LT
810 ypadding,buf->vb.width,ypadding,lines,
811 uoffset+cpadding,
812 voffset+cpadding,
813 buf->fmt->hshift,
814 buf->fmt->vshift,
815 cpadding);
816 break;
817 case V4L2_FIELD_SEQ_TB:
818 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
e5bd0260
MS
819 buf->vb.height,1,
820 tvnorm,&buf->crop);
1da177e4
LT
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,
c1accaa2 825 dma->sglist,
1da177e4
LT
826 0,buf->vb.width,0,lines,
827 uoffset >> 1,
828 voffset >> 1,
829 buf->fmt->hshift,
830 buf->fmt->vshift,
831 0);
832 bttv_risc_planar(btv,&buf->bottom,
c1accaa2 833 dma->sglist,
1da177e4
LT
834 lines * ypadding,buf->vb.width,0,lines,
835 lines * ypadding + (uoffset >> 1),
836 lines * ypadding + (voffset >> 1),
837 buf->fmt->hshift,
838 buf->fmt->vshift,
839 0);
840 break;
841 default:
842 BUG();
843 }
844 }
845
846 /* raw data */
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,
e5bd0260 851 1,tvnorm,&buf->crop);
c1accaa2 852 bttv_risc_packed(btv, &buf->top, dma->sglist,
e5bd0260
MS
853 /* offset */ 0, RAW_BPL, /* padding */ 0,
854 /* skip_lines */ 0, RAW_LINES);
c1accaa2 855 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
e5bd0260 856 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
1da177e4
LT
857 }
858
859 /* copy format info */
860 buf->btformat = buf->fmt->btformat;
861 buf->btswap = buf->fmt->btswap;
862 return 0;
863}
864
865/* ---------------------------------------------------------- */
866
867/* calculate geometry, build risc code */
868int
869bttv_overlay_risc(struct bttv *btv,
870 struct bttv_overlay *ov,
871 const struct bttv_format *fmt,
872 struct bttv_buffer *buf)
873{
874 /* check interleave, bottom+top fields */
8af443e5 875 dprintk("%d: overlay fields: %s format: %s size: %dx%d\n",
1da177e4 876 btv->c.nr, v4l2_field_names[buf->vb.field],
8af443e5 877 fmt->name, ov->w.width, ov->w.height);
1da177e4
LT
878
879 /* calculate geometry */
880 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
e5bd0260
MS
881 V4L2_FIELD_HAS_BOTH(ov->field),
882 &bttv_tvnorms[ov->tvnorm],&buf->crop);
1da177e4
LT
883
884 /* build risc code */
885 switch (ov->field) {
886 case V4L2_FIELD_TOP:
887 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
888 break;
889 case V4L2_FIELD_BOTTOM:
890 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
891 break;
892 case V4L2_FIELD_INTERLACED:
1da177e4
LT
893 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
894 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
1da177e4
LT
895 break;
896 default:
897 BUG();
898 }
899
900 /* copy format info */
901 buf->btformat = fmt->btformat;
902 buf->btswap = fmt->btswap;
903 buf->vb.field = ov->field;
904 return 0;
905}