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