]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/media/video/bt8xx/bttv-risc.c
include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit...
[net-next-2.6.git] / drivers / media / video / 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
27#include <linux/module.h>
28#include <linux/init.h>
5a0e3ad6 29#include <linux/slab.h>
1da177e4
LT
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>
35ea11ff 35#include <media/v4l2-ioctl.h>
1da177e4
LT
36
37#include "bttvp.h"
38
39#define VCR_HACK_LINES 4
40
41/* ---------------------------------------------------------- */
42/* risc code generators */
43
44int
45bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
46 struct scatterlist *sglist,
47 unsigned int offset, unsigned int bpl,
e5bd0260
MS
48 unsigned int padding, unsigned int skip_lines,
49 unsigned int store_lines)
1da177e4
LT
50{
51 u32 instructions,line,todo;
52 struct scatterlist *sg;
d8eaa58b 53 __le32 *rp;
1da177e4
LT
54 int rc;
55
56 /* estimate risc mem: worst case is one write per page border +
4a287cfe
DS
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 */
e5bd0260
MS
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)
1da177e4
LT
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
e5bd0260
MS
72 while (skip_lines-- > 0) {
73 *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
74 BT848_RISC_EOL | bpl);
75 }
76
1da177e4
LT
77 /* scan lines */
78 sg = sglist;
e5bd0260 79 for (line = 0; line < store_lines; line++) {
1da177e4 80 if ((btv->opt_vcr_hack) &&
e5bd0260 81 (line >= (store_lines - VCR_HACK_LINES)))
1da177e4
LT
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 */
4ac97914 89 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
1da177e4 90 BT848_RISC_EOL|bpl);
4ac97914
MCC
91 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
92 offset+=bpl;
1da177e4
LT
93 } else {
94 /* scanline needs to be splitted */
4ac97914
MCC
95 todo = bpl;
96 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
1da177e4 97 (sg_dma_len(sg)-offset));
4ac97914
MCC
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)) {
f2421ca3 103 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
1da177e4 104 sg_dma_len(sg));
f2421ca3 105 *(rp++)=cpu_to_le32(sg_dma_address(sg));
1da177e4
LT
106 todo -= sg_dma_len(sg);
107 sg++;
108 }
4ac97914 109 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
1da177e4
LT
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;
4a287cfe 119 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1da177e4
LT
120 return 0;
121}
122
123static int
124bttv_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;
d8eaa58b
AV
133 __le32 *rp;
134 u32 ri;
1da177e4
LT
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) */
e5bd0260
MS
144 instructions = ((3 + (ybpl + ypadding) * ylines * 2)
145 / PAGE_SIZE) + ylines;
1da177e4
LT
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 */
4ac97914
MCC
218 *(rp++)=cpu_to_le32(ri | ylen);
219 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
1da177e4
LT
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;
4a287cfe 239 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1da177e4
LT
240 return 0;
241}
242
243static int
244bttv_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{
c6eb8eaf
HV
248 int dwords, rc, line, maxy, start, end;
249 unsigned skip, nskips;
1da177e4 250 struct btcx_skiplist *skips;
d8eaa58b
AV
251 __le32 *rp;
252 u32 ri,ra;
1da177e4
LT
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
3203f94a 259 /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
1da177e4 260 + sync + jump (all 2 dwords) */
3203f94a
DS
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) {
1da177e4
LT
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;
4a287cfe 326 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
1da177e4
LT
327 kfree(skips);
328 return 0;
329}
330
331/* ---------------------------------------------------------- */
332
333static void
e5bd0260
MS
334bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
335 int width, int height, int interleaved,
336 const struct bttv_tvnorm *tvnorm)
1da177e4 337{
4ac97914 338 u32 xsf, sr;
1da177e4
LT
339 int vdelay;
340
341 int swidth = tvnorm->swidth;
342 int totalwidth = tvnorm->totalwidth;
343 int scaledtwidth = tvnorm->scaledtwidth;
344
5221e21e 345 if (btv->input == btv->dig) {
1da177e4
LT
346 swidth = 720;
347 totalwidth = 858;
348 scaledtwidth = 858;
349 }
350
351 vdelay = tvnorm->vdelay;
1da177e4 352
4ac97914
MCC
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;
1da177e4
LT
366 geo->vtotal = tvnorm->vtotal;
367
4ac97914
MCC
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 }
1da177e4
LT
375}
376
e5bd0260
MS
377static void
378bttv_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 */)
5221e21e 395 || btv->input == btv->dig) {
e5bd0260
MS
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
1da177e4
LT
433static void
434bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
435{
4ac97914 436 int off = odd ? 0x80 : 0x00;
1da177e4
LT
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
4ac97914
MCC
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);
1da177e4 453 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
4ac97914 454 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
1da177e4
LT
455}
456
457/* ---------------------------------------------------------- */
458/* risc group / risc main loop / dma management */
459
460void
461bttv_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 }
4ac97914 495 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
1da177e4
LT
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;
4ac97914 507 btand(~3, BT848_GPIO_DMA_CTL);
1da177e4
LT
508 btv->dma_on = 0;
509 }
510 return;
511}
512
513int
514bttv_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
4ac97914 535 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
1da177e4 536 BT848_FIFO_STATUS_VRO);
4ac97914 537 btv->main.cpu[9] = cpu_to_le32(0);
1da177e4
LT
538
539 /* bottom field */
4ac97914 540 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
1da177e4 541 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
4ac97914 542 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
1da177e4
LT
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);
4ac97914 547 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
1da177e4
LT
548
549 return 0;
550}
551
552int
553bttv_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
579void
c7b0ac05 580bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
1da177e4 581{
c1accaa2
MCC
582 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
583
ae24601b 584 BUG_ON(in_interrupt());
1da177e4 585 videobuf_waiton(&buf->vb,0,0);
c1accaa2
MCC
586 videobuf_dma_unmap(q, dma);
587 videobuf_dma_free(dma);
1da177e4
LT
588 btcx_riscmem_free(btv->c.pci,&buf->bottom);
589 btcx_riscmem_free(btv->c.pci,&buf->top);
0fc0686e 590 buf->vb.state = VIDEOBUF_NEEDS_INIT;
1da177e4
LT
591}
592
593int
594bttv_buffer_activate_vbi(struct bttv *btv,
595 struct bttv_buffer *vbi)
596{
e5bd0260
MS
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
1da177e4 607 if (vbi) {
e5bd0260
MS
608 unsigned int crop, vdelay;
609
0fc0686e 610 vbi->vb.state = VIDEOBUF_ACTIVE;
1da177e4 611 list_del(&vbi->vb.queue);
e5bd0260
MS
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 }
1da177e4 637 }
e5bd0260
MS
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
1da177e4
LT
642 return 0;
643}
644
645int
646bttv_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) {
0fc0686e 652 set->top->vb.state = VIDEOBUF_ACTIVE;
1da177e4
LT
653 if (set->top->vb.queue.next)
654 list_del(&set->top->vb.queue);
655 } else {
0fc0686e
BP
656 set->top->vb.state = VIDEOBUF_ACTIVE;
657 set->bottom->vb.state = VIDEOBUF_ACTIVE;
1da177e4
LT
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) {
0fc0686e 674 set->top->vb.state = VIDEOBUF_ACTIVE;
1da177e4
LT
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) {
0fc0686e 685 set->bottom->vb.state = VIDEOBUF_ACTIVE;
1da177e4
LT
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 */
705int
706bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
707{
708 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
c1accaa2 709 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
1da177e4
LT
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,
e5bd0260
MS
722 V4L2_FIELD_HAS_BOTH(buf->vb.field),
723 tvnorm,&buf->crop);
1da177e4
LT
724
725 switch (buf->vb.field) {
726 case V4L2_FIELD_TOP:
c1accaa2 727 bttv_risc_packed(btv,&buf->top,dma->sglist,
e5bd0260
MS
728 /* offset */ 0,bpl,
729 /* padding */ 0,/* skip_lines */ 0,
730 buf->vb.height);
1da177e4
LT
731 break;
732 case V4L2_FIELD_BOTTOM:
c1accaa2 733 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
e5bd0260 734 0,bpl,0,0,buf->vb.height);
1da177e4
LT
735 break;
736 case V4L2_FIELD_INTERLACED:
c1accaa2 737 bttv_risc_packed(btv,&buf->top,dma->sglist,
e5bd0260 738 0,bpl,bpl,0,buf->vb.height >> 1);
c1accaa2 739 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
e5bd0260 740 bpl,bpl,bpl,0,buf->vb.height >> 1);
1da177e4
LT
741 break;
742 case V4L2_FIELD_SEQ_TB:
c1accaa2 743 bttv_risc_packed(btv,&buf->top,dma->sglist,
e5bd0260 744 0,bpl,0,0,buf->vb.height >> 1);
c1accaa2 745 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
e5bd0260 746 bpf,bpl,0,0,buf->vb.height >> 1);
1da177e4
LT
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,
e5bd0260
MS
776 buf->vb.height,/* both_fields */ 0,
777 tvnorm,&buf->crop);
c1accaa2 778 bttv_risc_planar(btv, &buf->top, dma->sglist,
1da177e4
LT
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,
e5bd0260
MS
785 buf->vb.height,0,
786 tvnorm,&buf->crop);
c1accaa2 787 bttv_risc_planar(btv, &buf->bottom, dma->sglist,
1da177e4
LT
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,
e5bd0260
MS
794 buf->vb.height,1,
795 tvnorm,&buf->crop);
1da177e4
LT
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,
c1accaa2 800 dma->sglist,
1da177e4
LT
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,
c1accaa2 807 dma->sglist,
1da177e4
LT
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,
e5bd0260
MS
817 buf->vb.height,1,
818 tvnorm,&buf->crop);
1da177e4
LT
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,
c1accaa2 823 dma->sglist,
1da177e4
LT
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,
c1accaa2 831 dma->sglist,
1da177e4
LT
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,
e5bd0260 849 1,tvnorm,&buf->crop);
c1accaa2 850 bttv_risc_packed(btv, &buf->top, dma->sglist,
e5bd0260
MS
851 /* offset */ 0, RAW_BPL, /* padding */ 0,
852 /* skip_lines */ 0, RAW_LINES);
c1accaa2 853 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
e5bd0260 854 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
1da177e4
LT
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 */
866int
867bttv_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,
e5bd0260
MS
880 V4L2_FIELD_HAS_BOTH(ov->field),
881 &bttv_tvnorms[ov->tvnorm],&buf->crop);
1da177e4
LT
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:
1da177e4
LT
892 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
893 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
1da177e4
LT
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 */