1 /*
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
27 #include <linux/module.h>
28 #include <linux/init.h>
29 #include <linux/slab.h>
30 #include <linux/pci.h>
31 #include <linux/vmalloc.h>
32 #include <linux/interrupt.h>
33 #include <asm/page.h>
34 #include <asm/pgtable.h>
35 #include <media/v4l2-ioctl.h>
36
37 #include "bttvp.h"
38
39 #define VCR_HACK_LINES 4
40
41 /* ---------------------------------------------------------- */
42 /* risc code generators */
43
44 int
bttv_risc_packed(struct bttv * btv,struct btcx_riscmem * risc,struct scatterlist * sglist,unsigned int offset,unsigned int bpl,unsigned int padding,unsigned int skip_lines,unsigned int store_lines)45 bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
46 struct scatterlist *sglist,
47 unsigned int offset, unsigned int bpl,
48 unsigned int padding, unsigned int skip_lines,
49 unsigned int store_lines)
50 {
51 u32 instructions,line,todo;
52 struct scatterlist *sg;
53 __le32 *rp;
54 int rc;
55
56 /* estimate risc mem: worst case is one write per page border +
57 one write per scan line + sync + jump (all 2 dwords). padding
58 can cause next bpl to start close to a page border. First DMA
59 region may be smaller than PAGE_SIZE */
60 instructions = skip_lines * 4;
61 instructions += (1 + ((bpl + padding) * store_lines)
62 / PAGE_SIZE + store_lines) * 8;
63 instructions += 2 * 8;
64 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions)) < 0)
65 return rc;
66
67 /* sync instruction */
68 rp = risc->cpu;
69 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
70 *(rp++) = cpu_to_le32(0);
71
72 while (skip_lines-- > 0) {
73 *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
74 BT848_RISC_EOL | bpl);
75 }
76
77 /* scan lines */
78 sg = sglist;
79 for (line = 0; line < store_lines; line++) {
80 if ((btv->opt_vcr_hack) &&
81 (line >= (store_lines - VCR_HACK_LINES)))
82 continue;
83 while (offset && offset >= sg_dma_len(sg)) {
84 offset -= sg_dma_len(sg);
85 sg++;
86 }
87 if (bpl <= sg_dma_len(sg)-offset) {
88 /* fits into current chunk */
89 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
90 BT848_RISC_EOL|bpl);
91 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
92 offset+=bpl;
93 } else {
94 /* scanline needs to be splitted */
95 todo = bpl;
96 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
97 (sg_dma_len(sg)-offset));
98 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
99 todo -= (sg_dma_len(sg)-offset);
100 offset = 0;
101 sg++;
102 while (todo > sg_dma_len(sg)) {
103 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
104 sg_dma_len(sg));
105 *(rp++)=cpu_to_le32(sg_dma_address(sg));
106 todo -= sg_dma_len(sg);
107 sg++;
108 }
109 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
110 todo);
111 *(rp++)=cpu_to_le32(sg_dma_address(sg));
112 offset += todo;
113 }
114 offset += padding;
115 }
116
117 /* save pointer to jmp instruction address */
118 risc->jmp = rp;
119 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
120 return 0;
121 }
122
123 static int
bttv_risc_planar(struct bttv * btv,struct btcx_riscmem * risc,struct scatterlist * sglist,unsigned int yoffset,unsigned int ybpl,unsigned int ypadding,unsigned int ylines,unsigned int uoffset,unsigned int voffset,unsigned int hshift,unsigned int vshift,unsigned int cpadding)124 bttv_risc_planar(struct bttv *btv, struct btcx_riscmem *risc,
125 struct scatterlist *sglist,
126 unsigned int yoffset, unsigned int ybpl,
127 unsigned int ypadding, unsigned int ylines,
128 unsigned int uoffset, unsigned int voffset,
129 unsigned int hshift, unsigned int vshift,
130 unsigned int cpadding)
131 {
132 unsigned int instructions,line,todo,ylen,chroma;
133 __le32 *rp;
134 u32 ri;
135 struct scatterlist *ysg;
136 struct scatterlist *usg;
137 struct scatterlist *vsg;
138 int topfield = (0 == yoffset);
139 int rc;
140
141 /* estimate risc mem: worst case is one write per page border +
142 one write per scan line (5 dwords)
143 plus sync + jump (2 dwords) */
144 instructions = ((3 + (ybpl + ypadding) * ylines * 2)
145 / PAGE_SIZE) + ylines;
146 instructions += 2;
147 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
148 return rc;
149
150 /* sync instruction */
151 rp = risc->cpu;
152 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
153 *(rp++) = cpu_to_le32(0);
154
155 /* scan lines */
156 ysg = sglist;
157 usg = sglist;
158 vsg = sglist;
159 for (line = 0; line < ylines; line++) {
160 if ((btv->opt_vcr_hack) &&
161 (line >= (ylines - VCR_HACK_LINES)))
162 continue;
163 switch (vshift) {
164 case 0:
165 chroma = 1;
166 break;
167 case 1:
168 if (topfield)
169 chroma = ((line & 1) == 0);
170 else
171 chroma = ((line & 1) == 1);
172 break;
173 case 2:
174 if (topfield)
175 chroma = ((line & 3) == 0);
176 else
177 chroma = ((line & 3) == 2);
178 break;
179 default:
180 chroma = 0;
181 break;
182 }
183
184 for (todo = ybpl; todo > 0; todo -= ylen) {
185 /* go to next sg entry if needed */
186 while (yoffset && yoffset >= sg_dma_len(ysg)) {
187 yoffset -= sg_dma_len(ysg);
188 ysg++;
189 }
190 while (uoffset && uoffset >= sg_dma_len(usg)) {
191 uoffset -= sg_dma_len(usg);
192 usg++;
193 }
194 while (voffset && voffset >= sg_dma_len(vsg)) {
195 voffset -= sg_dma_len(vsg);
196 vsg++;
197 }
198
199 /* calculate max number of bytes we can write */
200 ylen = todo;
201 if (yoffset + ylen > sg_dma_len(ysg))
202 ylen = sg_dma_len(ysg) - yoffset;
203 if (chroma) {
204 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
205 ylen = (sg_dma_len(usg) - uoffset) << hshift;
206 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
207 ylen = (sg_dma_len(vsg) - voffset) << hshift;
208 ri = BT848_RISC_WRITE123;
209 } else {
210 ri = BT848_RISC_WRITE1S23;
211 }
212 if (ybpl == todo)
213 ri |= BT848_RISC_SOL;
214 if (ylen == todo)
215 ri |= BT848_RISC_EOL;
216
217 /* write risc instruction */
218 *(rp++)=cpu_to_le32(ri | ylen);
219 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
220 (ylen >> hshift));
221 *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
222 yoffset += ylen;
223 if (chroma) {
224 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
225 uoffset += ylen >> hshift;
226 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
227 voffset += ylen >> hshift;
228 }
229 }
230 yoffset += ypadding;
231 if (chroma) {
232 uoffset += cpadding;
233 voffset += cpadding;
234 }
235 }
236
237 /* save pointer to jmp instruction address */
238 risc->jmp = rp;
239 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
240 return 0;
241 }
242
243 static int
bttv_risc_overlay(struct bttv * btv,struct btcx_riscmem * risc,const struct bttv_format * fmt,struct bttv_overlay * ov,int skip_even,int skip_odd)244 bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
245 const struct bttv_format *fmt, struct bttv_overlay *ov,
246 int skip_even, int skip_odd)
247 {
248 int dwords, rc, line, maxy, start, end;
249 unsigned skip, nskips;
250 struct btcx_skiplist *skips;
251 __le32 *rp;
252 u32 ri,ra;
253 u32 addr;
254
255 /* skip list for window clipping */
256 if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
257 return -ENOMEM;
258
259 /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
260 + sync + jump (all 2 dwords) */
261 dwords = (3 * ov->nclips + 2) *
262 ((skip_even || skip_odd) ? (ov->w.height+1)>>1 : ov->w.height);
263 dwords += 4;
264 if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
265 kfree(skips);
266 return rc;
267 }
268
269 /* sync instruction */
270 rp = risc->cpu;
271 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
272 *(rp++) = cpu_to_le32(0);
273
274 addr = (unsigned long)btv->fbuf.base;
275 addr += btv->fbuf.fmt.bytesperline * ov->w.top;
276 addr += (fmt->depth >> 3) * ov->w.left;
277
278 /* scan lines */
279 for (maxy = -1, line = 0; line < ov->w.height;
280 line++, addr += btv->fbuf.fmt.bytesperline) {
281 if ((btv->opt_vcr_hack) &&
282 (line >= (ov->w.height - VCR_HACK_LINES)))
283 continue;
284 if ((line%2) == 0 && skip_even)
285 continue;
286 if ((line%2) == 1 && skip_odd)
287 continue;
288
289 /* calculate clipping */
290 if (line > maxy)
291 btcx_calc_skips(line, ov->w.width, &maxy,
292 skips, &nskips, ov->clips, ov->nclips);
293
294 /* write out risc code */
295 for (start = 0, skip = 0; start < ov->w.width; start = end) {
296 if (skip >= nskips) {
297 ri = BT848_RISC_WRITE;
298 end = ov->w.width;
299 } else if (start < skips[skip].start) {
300 ri = BT848_RISC_WRITE;
301 end = skips[skip].start;
302 } else {
303 ri = BT848_RISC_SKIP;
304 end = skips[skip].end;
305 skip++;
306 }
307 if (BT848_RISC_WRITE == ri)
308 ra = addr + (fmt->depth>>3)*start;
309 else
310 ra = 0;
311
312 if (0 == start)
313 ri |= BT848_RISC_SOL;
314 if (ov->w.width == end)
315 ri |= BT848_RISC_EOL;
316 ri |= (fmt->depth>>3) * (end-start);
317
318 *(rp++)=cpu_to_le32(ri);
319 if (0 != ra)
320 *(rp++)=cpu_to_le32(ra);
321 }
322 }
323
324 /* save pointer to jmp instruction address */
325 risc->jmp = rp;
326 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
327 kfree(skips);
328 return 0;
329 }
330
331 /* ---------------------------------------------------------- */
332
333 static void
bttv_calc_geo_old(struct bttv * btv,struct bttv_geometry * geo,int width,int height,int interleaved,const struct bttv_tvnorm * tvnorm)334 bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
335 int width, int height, int interleaved,
336 const struct bttv_tvnorm *tvnorm)
337 {
338 u32 xsf, sr;
339 int vdelay;
340
341 int swidth = tvnorm->swidth;
342 int totalwidth = tvnorm->totalwidth;
343 int scaledtwidth = tvnorm->scaledtwidth;
344
345 if (btv->input == btv->dig) {
346 swidth = 720;
347 totalwidth = 858;
348 scaledtwidth = 858;
349 }
350
351 vdelay = tvnorm->vdelay;
352
353 xsf = (width*scaledtwidth)/swidth;
354 geo->hscale = ((totalwidth*4096UL)/xsf-4096);
355 geo->hdelay = tvnorm->hdelayx1;
356 geo->hdelay = (geo->hdelay*width)/swidth;
357 geo->hdelay &= 0x3fe;
358 sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
359 geo->vscale = (0x10000UL-sr) & 0x1fff;
360 geo->crop = ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
361 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
362 geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
363 geo->vdelay = vdelay;
364 geo->width = width;
365 geo->sheight = tvnorm->sheight;
366 geo->vtotal = tvnorm->vtotal;
367
368 if (btv->opt_combfilter) {
369 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
370 geo->comb = (width < 769) ? 1 : 0;
371 } else {
372 geo->vtc = 0;
373 geo->comb = 0;
374 }
375 }
376
377 static void
bttv_calc_geo(struct bttv * btv,struct bttv_geometry * geo,unsigned int width,unsigned int height,int both_fields,const struct bttv_tvnorm * tvnorm,const struct v4l2_rect * crop)378 bttv_calc_geo (struct bttv * btv,
379 struct bttv_geometry * geo,
380 unsigned int width,
381 unsigned int height,
382 int both_fields,
383 const struct bttv_tvnorm * tvnorm,
384 const struct v4l2_rect * crop)
385 {
386 unsigned int c_width;
387 unsigned int c_height;
388 u32 sr;
389
390 if ((crop->left == tvnorm->cropcap.defrect.left
391 && crop->top == tvnorm->cropcap.defrect.top
392 && crop->width == tvnorm->cropcap.defrect.width
393 && crop->height == tvnorm->cropcap.defrect.height
394 && width <= tvnorm->swidth /* see PAL-Nc et al */)
395 || btv->input == btv->dig) {
396 bttv_calc_geo_old(btv, geo, width, height,
397 both_fields, tvnorm);
398 return;
399 }
400
401 /* For bug compatibility the image size checks permit scale
402 factors > 16. See bttv_crop_calc_limits(). */
403 c_width = min((unsigned int) crop->width, width * 16);
404 c_height = min((unsigned int) crop->height, height * 16);
405
406 geo->width = width;
407 geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
408 /* Even to store Cb first, odd for Cr. */
409 geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
410
411 geo->sheight = c_height;
412 geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
413 sr = c_height >> !both_fields;
414 sr = (sr * 512U + (height >> 1)) / height - 512;
415 geo->vscale = (0x10000UL - sr) & 0x1fff;
416 geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
417 geo->vtotal = tvnorm->vtotal;
418
419 geo->crop = (((geo->width >> 8) & 0x03) |
420 ((geo->hdelay >> 6) & 0x0c) |
421 ((geo->sheight >> 4) & 0x30) |
422 ((geo->vdelay >> 2) & 0xc0));
423
424 if (btv->opt_combfilter) {
425 geo->vtc = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
426 geo->comb = (width < 769) ? 1 : 0;
427 } else {
428 geo->vtc = 0;
429 geo->comb = 0;
430 }
431 }
432
433 static void
bttv_apply_geo(struct bttv * btv,struct bttv_geometry * geo,int odd)434 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
435 {
436 int off = odd ? 0x80 : 0x00;
437
438 if (geo->comb)
439 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
440 else
441 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
442
443 btwrite(geo->vtc, BT848_E_VTC+off);
444 btwrite(geo->hscale >> 8, BT848_E_HSCALE_HI+off);
445 btwrite(geo->hscale & 0xff, BT848_E_HSCALE_LO+off);
446 btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
447 btwrite(geo->vscale & 0xff, BT848_E_VSCALE_LO+off);
448 btwrite(geo->width & 0xff, BT848_E_HACTIVE_LO+off);
449 btwrite(geo->hdelay & 0xff, BT848_E_HDELAY_LO+off);
450 btwrite(geo->sheight & 0xff, BT848_E_VACTIVE_LO+off);
451 btwrite(geo->vdelay & 0xff, BT848_E_VDELAY_LO+off);
452 btwrite(geo->crop, BT848_E_CROP+off);
453 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
454 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
455 }
456
457 /* ---------------------------------------------------------- */
458 /* risc group / risc main loop / dma management */
459
460 void
bttv_set_dma(struct bttv * btv,int override)461 bttv_set_dma(struct bttv *btv, int override)
462 {
463 unsigned long cmd;
464 int capctl;
465
466 btv->cap_ctl = 0;
467 if (NULL != btv->curr.top) btv->cap_ctl |= 0x02;
468 if (NULL != btv->curr.bottom) btv->cap_ctl |= 0x01;
469 if (NULL != btv->cvbi) btv->cap_ctl |= 0x0c;
470
471 capctl = 0;
472 capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00; /* capture */
473 capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00; /* vbi data */
474 capctl |= override;
475
476 d2printk(KERN_DEBUG
477 "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
478 btv->c.nr,capctl,btv->loop_irq,
479 btv->cvbi ? (unsigned long long)btv->cvbi->top.dma : 0,
480 btv->curr.top ? (unsigned long long)btv->curr.top->top.dma : 0,
481 btv->cvbi ? (unsigned long long)btv->cvbi->bottom.dma : 0,
482 btv->curr.bottom ? (unsigned long long)btv->curr.bottom->bottom.dma : 0);
483
484 cmd = BT848_RISC_JUMP;
485 if (btv->loop_irq) {
486 cmd |= BT848_RISC_IRQ;
487 cmd |= (btv->loop_irq & 0x0f) << 16;
488 cmd |= (~btv->loop_irq & 0x0f) << 20;
489 }
490 if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
491 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
492 } else {
493 del_timer(&btv->timeout);
494 }
495 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
496
497 btaor(capctl, ~0x0f, BT848_CAP_CTL);
498 if (capctl) {
499 if (btv->dma_on)
500 return;
501 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
502 btor(3, BT848_GPIO_DMA_CTL);
503 btv->dma_on = 1;
504 } else {
505 if (!btv->dma_on)
506 return;
507 btand(~3, BT848_GPIO_DMA_CTL);
508 btv->dma_on = 0;
509 }
510 return;
511 }
512
513 int
bttv_risc_init_main(struct bttv * btv)514 bttv_risc_init_main(struct bttv *btv)
515 {
516 int rc;
517
518 if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
519 return rc;
520 dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
521 btv->c.nr,(unsigned long long)btv->main.dma);
522
523 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
524 BT848_FIFO_STATUS_VRE);
525 btv->main.cpu[1] = cpu_to_le32(0);
526 btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
527 btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
528
529 /* top field */
530 btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
531 btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
532 btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
533 btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
534
535 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
536 BT848_FIFO_STATUS_VRO);
537 btv->main.cpu[9] = cpu_to_le32(0);
538
539 /* bottom field */
540 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
541 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
542 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
543 btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
544
545 /* jump back to top field */
546 btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
547 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
548
549 return 0;
550 }
551
552 int
bttv_risc_hook(struct bttv * btv,int slot,struct btcx_riscmem * risc,int irqflags)553 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
554 int irqflags)
555 {
556 unsigned long cmd;
557 unsigned long next = btv->main.dma + ((slot+2) << 2);
558
559 if (NULL == risc) {
560 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
561 btv->c.nr,risc,slot);
562 btv->main.cpu[slot+1] = cpu_to_le32(next);
563 } else {
564 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
565 btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
566 cmd = BT848_RISC_JUMP;
567 if (irqflags) {
568 cmd |= BT848_RISC_IRQ;
569 cmd |= (irqflags & 0x0f) << 16;
570 cmd |= (~irqflags & 0x0f) << 20;
571 }
572 risc->jmp[0] = cpu_to_le32(cmd);
573 risc->jmp[1] = cpu_to_le32(next);
574 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
575 }
576 return 0;
577 }
578
579 void
bttv_dma_free(struct videobuf_queue * q,struct bttv * btv,struct bttv_buffer * buf)580 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
581 {
582 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
583
584 BUG_ON(in_interrupt());
585 videobuf_waiton(q, &buf->vb, 0, 0);
586 videobuf_dma_unmap(q->dev, dma);
587 videobuf_dma_free(dma);
588 btcx_riscmem_free(btv->c.pci,&buf->bottom);
589 btcx_riscmem_free(btv->c.pci,&buf->top);
590 buf->vb.state = VIDEOBUF_NEEDS_INIT;
591 }
592
593 int
bttv_buffer_activate_vbi(struct bttv * btv,struct bttv_buffer * vbi)594 bttv_buffer_activate_vbi(struct bttv *btv,
595 struct bttv_buffer *vbi)
596 {
597 struct btcx_riscmem *top;
598 struct btcx_riscmem *bottom;
599 int top_irq_flags;
600 int bottom_irq_flags;
601
602 top = NULL;
603 bottom = NULL;
604 top_irq_flags = 0;
605 bottom_irq_flags = 0;
606
607 if (vbi) {
608 unsigned int crop, vdelay;
609
610 vbi->vb.state = VIDEOBUF_ACTIVE;
611 list_del(&vbi->vb.queue);
612
613 /* VDELAY is start of video, end of VBI capturing. */
614 crop = btread(BT848_E_CROP);
615 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
616
617 if (vbi->geo.vdelay > vdelay) {
618 vdelay = vbi->geo.vdelay & 0xfe;
619 crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
620
621 btwrite(vdelay, BT848_E_VDELAY_LO);
622 btwrite(crop, BT848_E_CROP);
623 btwrite(vdelay, BT848_O_VDELAY_LO);
624 btwrite(crop, BT848_O_CROP);
625 }
626
627 if (vbi->vbi_count[0] > 0) {
628 top = &vbi->top;
629 top_irq_flags = 4;
630 }
631
632 if (vbi->vbi_count[1] > 0) {
633 top_irq_flags = 0;
634 bottom = &vbi->bottom;
635 bottom_irq_flags = 4;
636 }
637 }
638
639 bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
640 bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
641
642 return 0;
643 }
644
645 int
bttv_buffer_activate_video(struct bttv * btv,struct bttv_buffer_set * set)646 bttv_buffer_activate_video(struct bttv *btv,
647 struct bttv_buffer_set *set)
648 {
649 /* video capture */
650 if (NULL != set->top && NULL != set->bottom) {
651 if (set->top == set->bottom) {
652 set->top->vb.state = VIDEOBUF_ACTIVE;
653 if (set->top->vb.queue.next)
654 list_del(&set->top->vb.queue);
655 } else {
656 set->top->vb.state = VIDEOBUF_ACTIVE;
657 set->bottom->vb.state = VIDEOBUF_ACTIVE;
658 if (set->top->vb.queue.next)
659 list_del(&set->top->vb.queue);
660 if (set->bottom->vb.queue.next)
661 list_del(&set->bottom->vb.queue);
662 }
663 bttv_apply_geo(btv, &set->top->geo, 1);
664 bttv_apply_geo(btv, &set->bottom->geo,0);
665 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
666 set->top_irq);
667 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
668 set->frame_irq);
669 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
670 ~0xff, BT848_COLOR_FMT);
671 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
672 ~0x0f, BT848_COLOR_CTL);
673 } else if (NULL != set->top) {
674 set->top->vb.state = VIDEOBUF_ACTIVE;
675 if (set->top->vb.queue.next)
676 list_del(&set->top->vb.queue);
677 bttv_apply_geo(btv, &set->top->geo,1);
678 bttv_apply_geo(btv, &set->top->geo,0);
679 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
680 set->frame_irq);
681 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
682 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
683 btaor(set->top->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
684 } else if (NULL != set->bottom) {
685 set->bottom->vb.state = VIDEOBUF_ACTIVE;
686 if (set->bottom->vb.queue.next)
687 list_del(&set->bottom->vb.queue);
688 bttv_apply_geo(btv, &set->bottom->geo,1);
689 bttv_apply_geo(btv, &set->bottom->geo,0);
690 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
691 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
692 set->frame_irq);
693 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
694 btaor(set->bottom->btswap & 0x0f, ~0x0f, BT848_COLOR_CTL);
695 } else {
696 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
697 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
698 }
699 return 0;
700 }
701
702 /* ---------------------------------------------------------- */
703
704 /* calculate geometry, build risc code */
705 int
bttv_buffer_risc(struct bttv * btv,struct bttv_buffer * buf)706 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
707 {
708 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
709 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
710
711 dprintk(KERN_DEBUG
712 "bttv%d: buffer field: %s format: %s size: %dx%d\n",
713 btv->c.nr, v4l2_field_names[buf->vb.field],
714 buf->fmt->name, buf->vb.width, buf->vb.height);
715
716 /* packed pixel modes */
717 if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
718 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
719 int bpf = bpl * (buf->vb.height >> 1);
720
721 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
722 V4L2_FIELD_HAS_BOTH(buf->vb.field),
723 tvnorm,&buf->crop);
724
725 switch (buf->vb.field) {
726 case V4L2_FIELD_TOP:
727 bttv_risc_packed(btv,&buf->top,dma->sglist,
728 /* offset */ 0,bpl,
729 /* padding */ 0,/* skip_lines */ 0,
730 buf->vb.height);
731 break;
732 case V4L2_FIELD_BOTTOM:
733 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
734 0,bpl,0,0,buf->vb.height);
735 break;
736 case V4L2_FIELD_INTERLACED:
737 bttv_risc_packed(btv,&buf->top,dma->sglist,
738 0,bpl,bpl,0,buf->vb.height >> 1);
739 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
740 bpl,bpl,bpl,0,buf->vb.height >> 1);
741 break;
742 case V4L2_FIELD_SEQ_TB:
743 bttv_risc_packed(btv,&buf->top,dma->sglist,
744 0,bpl,0,0,buf->vb.height >> 1);
745 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
746 bpf,bpl,0,0,buf->vb.height >> 1);
747 break;
748 default:
749 BUG();
750 }
751 }
752
753 /* planar modes */
754 if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
755 int uoffset, voffset;
756 int ypadding, cpadding, lines;
757
758 /* calculate chroma offsets */
759 uoffset = buf->vb.width * buf->vb.height;
760 voffset = buf->vb.width * buf->vb.height;
761 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
762 /* Y-Cr-Cb plane order */
763 uoffset >>= buf->fmt->hshift;
764 uoffset >>= buf->fmt->vshift;
765 uoffset += voffset;
766 } else {
767 /* Y-Cb-Cr plane order */
768 voffset >>= buf->fmt->hshift;
769 voffset >>= buf->fmt->vshift;
770 voffset += uoffset;
771 }
772
773 switch (buf->vb.field) {
774 case V4L2_FIELD_TOP:
775 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
776 buf->vb.height,/* both_fields */ 0,
777 tvnorm,&buf->crop);
778 bttv_risc_planar(btv, &buf->top, dma->sglist,
779 0,buf->vb.width,0,buf->vb.height,
780 uoffset,voffset,buf->fmt->hshift,
781 buf->fmt->vshift,0);
782 break;
783 case V4L2_FIELD_BOTTOM:
784 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
785 buf->vb.height,0,
786 tvnorm,&buf->crop);
787 bttv_risc_planar(btv, &buf->bottom, dma->sglist,
788 0,buf->vb.width,0,buf->vb.height,
789 uoffset,voffset,buf->fmt->hshift,
790 buf->fmt->vshift,0);
791 break;
792 case V4L2_FIELD_INTERLACED:
793 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
794 buf->vb.height,1,
795 tvnorm,&buf->crop);
796 lines = buf->vb.height >> 1;
797 ypadding = buf->vb.width;
798 cpadding = buf->vb.width >> buf->fmt->hshift;
799 bttv_risc_planar(btv,&buf->top,
800 dma->sglist,
801 0,buf->vb.width,ypadding,lines,
802 uoffset,voffset,
803 buf->fmt->hshift,
804 buf->fmt->vshift,
805 cpadding);
806 bttv_risc_planar(btv,&buf->bottom,
807 dma->sglist,
808 ypadding,buf->vb.width,ypadding,lines,
809 uoffset+cpadding,
810 voffset+cpadding,
811 buf->fmt->hshift,
812 buf->fmt->vshift,
813 cpadding);
814 break;
815 case V4L2_FIELD_SEQ_TB:
816 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
817 buf->vb.height,1,
818 tvnorm,&buf->crop);
819 lines = buf->vb.height >> 1;
820 ypadding = buf->vb.width;
821 cpadding = buf->vb.width >> buf->fmt->hshift;
822 bttv_risc_planar(btv,&buf->top,
823 dma->sglist,
824 0,buf->vb.width,0,lines,
825 uoffset >> 1,
826 voffset >> 1,
827 buf->fmt->hshift,
828 buf->fmt->vshift,
829 0);
830 bttv_risc_planar(btv,&buf->bottom,
831 dma->sglist,
832 lines * ypadding,buf->vb.width,0,lines,
833 lines * ypadding + (uoffset >> 1),
834 lines * ypadding + (voffset >> 1),
835 buf->fmt->hshift,
836 buf->fmt->vshift,
837 0);
838 break;
839 default:
840 BUG();
841 }
842 }
843
844 /* raw data */
845 if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
846 /* build risc code */
847 buf->vb.field = V4L2_FIELD_SEQ_TB;
848 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
849 1,tvnorm,&buf->crop);
850 bttv_risc_packed(btv, &buf->top, dma->sglist,
851 /* offset */ 0, RAW_BPL, /* padding */ 0,
852 /* skip_lines */ 0, RAW_LINES);
853 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
854 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
855 }
856
857 /* copy format info */
858 buf->btformat = buf->fmt->btformat;
859 buf->btswap = buf->fmt->btswap;
860 return 0;
861 }
862
863 /* ---------------------------------------------------------- */
864
865 /* calculate geometry, build risc code */
866 int
bttv_overlay_risc(struct bttv * btv,struct bttv_overlay * ov,const struct bttv_format * fmt,struct bttv_buffer * buf)867 bttv_overlay_risc(struct bttv *btv,
868 struct bttv_overlay *ov,
869 const struct bttv_format *fmt,
870 struct bttv_buffer *buf)
871 {
872 /* check interleave, bottom+top fields */
873 dprintk(KERN_DEBUG
874 "bttv%d: overlay fields: %s format: %s size: %dx%d\n",
875 btv->c.nr, v4l2_field_names[buf->vb.field],
876 fmt->name,ov->w.width,ov->w.height);
877
878 /* calculate geometry */
879 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
880 V4L2_FIELD_HAS_BOTH(ov->field),
881 &bttv_tvnorms[ov->tvnorm],&buf->crop);
882
883 /* build risc code */
884 switch (ov->field) {
885 case V4L2_FIELD_TOP:
886 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 0);
887 break;
888 case V4L2_FIELD_BOTTOM:
889 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
890 break;
891 case V4L2_FIELD_INTERLACED:
892 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
893 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
894 break;
895 default:
896 BUG();
897 }
898
899 /* copy format info */
900 buf->btformat = fmt->btformat;
901 buf->btswap = fmt->btswap;
902 buf->vb.field = ov->field;
903 return 0;
904 }
905
906 /*
907 * Local variables:
908 * c-basic-offset: 8
909 * End:
910 */
911