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