Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/hskinnemoen...
[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         struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
578
579         BUG_ON(in_interrupt());
580         videobuf_waiton(&buf->vb,0,0);
581         videobuf_dma_unmap(q, dma);
582         videobuf_dma_free(dma);
583         btcx_riscmem_free(btv->c.pci,&buf->bottom);
584         btcx_riscmem_free(btv->c.pci,&buf->top);
585         buf->vb.state = VIDEOBUF_NEEDS_INIT;
586 }
587
588 int
589 bttv_buffer_activate_vbi(struct bttv *btv,
590                          struct bttv_buffer *vbi)
591 {
592         struct btcx_riscmem *top;
593         struct btcx_riscmem *bottom;
594         int top_irq_flags;
595         int bottom_irq_flags;
596
597         top = NULL;
598         bottom = NULL;
599         top_irq_flags = 0;
600         bottom_irq_flags = 0;
601
602         if (vbi) {
603                 unsigned int crop, vdelay;
604
605                 vbi->vb.state = VIDEOBUF_ACTIVE;
606                 list_del(&vbi->vb.queue);
607
608                 /* VDELAY is start of video, end of VBI capturing. */
609                 crop = btread(BT848_E_CROP);
610                 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
611
612                 if (vbi->geo.vdelay > vdelay) {
613                         vdelay = vbi->geo.vdelay & 0xfe;
614                         crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
615
616                         btwrite(vdelay, BT848_E_VDELAY_LO);
617                         btwrite(crop,   BT848_E_CROP);
618                         btwrite(vdelay, BT848_O_VDELAY_LO);
619                         btwrite(crop,   BT848_O_CROP);
620                 }
621
622                 if (vbi->vbi_count[0] > 0) {
623                         top = &vbi->top;
624                         top_irq_flags = 4;
625                 }
626
627                 if (vbi->vbi_count[1] > 0) {
628                         top_irq_flags = 0;
629                         bottom = &vbi->bottom;
630                         bottom_irq_flags = 4;
631                 }
632         }
633
634         bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
635         bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
636
637         return 0;
638 }
639
640 int
641 bttv_buffer_activate_video(struct bttv *btv,
642                            struct bttv_buffer_set *set)
643 {
644         /* video capture */
645         if (NULL != set->top  &&  NULL != set->bottom) {
646                 if (set->top == set->bottom) {
647                         set->top->vb.state    = VIDEOBUF_ACTIVE;
648                         if (set->top->vb.queue.next)
649                                 list_del(&set->top->vb.queue);
650                 } else {
651                         set->top->vb.state    = VIDEOBUF_ACTIVE;
652                         set->bottom->vb.state = VIDEOBUF_ACTIVE;
653                         if (set->top->vb.queue.next)
654                                 list_del(&set->top->vb.queue);
655                         if (set->bottom->vb.queue.next)
656                                 list_del(&set->bottom->vb.queue);
657                 }
658                 bttv_apply_geo(btv, &set->top->geo, 1);
659                 bttv_apply_geo(btv, &set->bottom->geo,0);
660                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
661                                set->top_irq);
662                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
663                                set->frame_irq);
664                 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
665                       ~0xff, BT848_COLOR_FMT);
666                 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
667                       ~0x0f, BT848_COLOR_CTL);
668         } else if (NULL != set->top) {
669                 set->top->vb.state  = VIDEOBUF_ACTIVE;
670                 if (set->top->vb.queue.next)
671                         list_del(&set->top->vb.queue);
672                 bttv_apply_geo(btv, &set->top->geo,1);
673                 bttv_apply_geo(btv, &set->top->geo,0);
674                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
675                                set->frame_irq);
676                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL,           0);
677                 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
678                 btaor(set->top->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
679         } else if (NULL != set->bottom) {
680                 set->bottom->vb.state = VIDEOBUF_ACTIVE;
681                 if (set->bottom->vb.queue.next)
682                         list_del(&set->bottom->vb.queue);
683                 bttv_apply_geo(btv, &set->bottom->geo,1);
684                 bttv_apply_geo(btv, &set->bottom->geo,0);
685                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
686                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
687                                set->frame_irq);
688                 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
689                 btaor(set->bottom->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
690         } else {
691                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
692                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
693         }
694         return 0;
695 }
696
697 /* ---------------------------------------------------------- */
698
699 /* calculate geometry, build risc code */
700 int
701 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
702 {
703         const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
704         struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
705
706         dprintk(KERN_DEBUG
707                 "bttv%d: buffer field: %s  format: %s  size: %dx%d\n",
708                 btv->c.nr, v4l2_field_names[buf->vb.field],
709                 buf->fmt->name, buf->vb.width, buf->vb.height);
710
711         /* packed pixel modes */
712         if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
713                 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
714                 int bpf = bpl * (buf->vb.height >> 1);
715
716                 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
717                               V4L2_FIELD_HAS_BOTH(buf->vb.field),
718                               tvnorm,&buf->crop);
719
720                 switch (buf->vb.field) {
721                 case V4L2_FIELD_TOP:
722                         bttv_risc_packed(btv,&buf->top,dma->sglist,
723                                          /* offset */ 0,bpl,
724                                          /* padding */ 0,/* skip_lines */ 0,
725                                          buf->vb.height);
726                         break;
727                 case V4L2_FIELD_BOTTOM:
728                         bttv_risc_packed(btv,&buf->bottom,dma->sglist,
729                                          0,bpl,0,0,buf->vb.height);
730                         break;
731                 case V4L2_FIELD_INTERLACED:
732                         bttv_risc_packed(btv,&buf->top,dma->sglist,
733                                          0,bpl,bpl,0,buf->vb.height >> 1);
734                         bttv_risc_packed(btv,&buf->bottom,dma->sglist,
735                                          bpl,bpl,bpl,0,buf->vb.height >> 1);
736                         break;
737                 case V4L2_FIELD_SEQ_TB:
738                         bttv_risc_packed(btv,&buf->top,dma->sglist,
739                                          0,bpl,0,0,buf->vb.height >> 1);
740                         bttv_risc_packed(btv,&buf->bottom,dma->sglist,
741                                          bpf,bpl,0,0,buf->vb.height >> 1);
742                         break;
743                 default:
744                         BUG();
745                 }
746         }
747
748         /* planar modes */
749         if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
750                 int uoffset, voffset;
751                 int ypadding, cpadding, lines;
752
753                 /* calculate chroma offsets */
754                 uoffset = buf->vb.width * buf->vb.height;
755                 voffset = buf->vb.width * buf->vb.height;
756                 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
757                         /* Y-Cr-Cb plane order */
758                         uoffset >>= buf->fmt->hshift;
759                         uoffset >>= buf->fmt->vshift;
760                         uoffset  += voffset;
761                 } else {
762                         /* Y-Cb-Cr plane order */
763                         voffset >>= buf->fmt->hshift;
764                         voffset >>= buf->fmt->vshift;
765                         voffset  += uoffset;
766                 }
767
768                 switch (buf->vb.field) {
769                 case V4L2_FIELD_TOP:
770                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
771                                       buf->vb.height,/* both_fields */ 0,
772                                       tvnorm,&buf->crop);
773                         bttv_risc_planar(btv, &buf->top, dma->sglist,
774                                          0,buf->vb.width,0,buf->vb.height,
775                                          uoffset,voffset,buf->fmt->hshift,
776                                          buf->fmt->vshift,0);
777                         break;
778                 case V4L2_FIELD_BOTTOM:
779                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
780                                       buf->vb.height,0,
781                                       tvnorm,&buf->crop);
782                         bttv_risc_planar(btv, &buf->bottom, dma->sglist,
783                                          0,buf->vb.width,0,buf->vb.height,
784                                          uoffset,voffset,buf->fmt->hshift,
785                                          buf->fmt->vshift,0);
786                         break;
787                 case V4L2_FIELD_INTERLACED:
788                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
789                                       buf->vb.height,1,
790                                       tvnorm,&buf->crop);
791                         lines    = buf->vb.height >> 1;
792                         ypadding = buf->vb.width;
793                         cpadding = buf->vb.width >> buf->fmt->hshift;
794                         bttv_risc_planar(btv,&buf->top,
795                                          dma->sglist,
796                                          0,buf->vb.width,ypadding,lines,
797                                          uoffset,voffset,
798                                          buf->fmt->hshift,
799                                          buf->fmt->vshift,
800                                          cpadding);
801                         bttv_risc_planar(btv,&buf->bottom,
802                                          dma->sglist,
803                                          ypadding,buf->vb.width,ypadding,lines,
804                                          uoffset+cpadding,
805                                          voffset+cpadding,
806                                          buf->fmt->hshift,
807                                          buf->fmt->vshift,
808                                          cpadding);
809                         break;
810                 case V4L2_FIELD_SEQ_TB:
811                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
812                                       buf->vb.height,1,
813                                       tvnorm,&buf->crop);
814                         lines    = buf->vb.height >> 1;
815                         ypadding = buf->vb.width;
816                         cpadding = buf->vb.width >> buf->fmt->hshift;
817                         bttv_risc_planar(btv,&buf->top,
818                                          dma->sglist,
819                                          0,buf->vb.width,0,lines,
820                                          uoffset >> 1,
821                                          voffset >> 1,
822                                          buf->fmt->hshift,
823                                          buf->fmt->vshift,
824                                          0);
825                         bttv_risc_planar(btv,&buf->bottom,
826                                          dma->sglist,
827                                          lines * ypadding,buf->vb.width,0,lines,
828                                          lines * ypadding + (uoffset >> 1),
829                                          lines * ypadding + (voffset >> 1),
830                                          buf->fmt->hshift,
831                                          buf->fmt->vshift,
832                                          0);
833                         break;
834                 default:
835                         BUG();
836                 }
837         }
838
839         /* raw data */
840         if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
841                 /* build risc code */
842                 buf->vb.field = V4L2_FIELD_SEQ_TB;
843                 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
844                               1,tvnorm,&buf->crop);
845                 bttv_risc_packed(btv, &buf->top,  dma->sglist,
846                                  /* offset */ 0, RAW_BPL, /* padding */ 0,
847                                  /* skip_lines */ 0, RAW_LINES);
848                 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
849                                  buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
850         }
851
852         /* copy format info */
853         buf->btformat = buf->fmt->btformat;
854         buf->btswap   = buf->fmt->btswap;
855         return 0;
856 }
857
858 /* ---------------------------------------------------------- */
859
860 /* calculate geometry, build risc code */
861 int
862 bttv_overlay_risc(struct bttv *btv,
863                   struct bttv_overlay *ov,
864                   const struct bttv_format *fmt,
865                   struct bttv_buffer *buf)
866 {
867         /* check interleave, bottom+top fields */
868         dprintk(KERN_DEBUG
869                 "bttv%d: overlay fields: %s format: %s  size: %dx%d\n",
870                 btv->c.nr, v4l2_field_names[buf->vb.field],
871                 fmt->name,ov->w.width,ov->w.height);
872
873         /* calculate geometry */
874         bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
875                       V4L2_FIELD_HAS_BOTH(ov->field),
876                       &bttv_tvnorms[ov->tvnorm],&buf->crop);
877
878         /* build risc code */
879         switch (ov->field) {
880         case V4L2_FIELD_TOP:
881                 bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 0);
882                 break;
883         case V4L2_FIELD_BOTTOM:
884                 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
885                 break;
886         case V4L2_FIELD_INTERLACED:
887                 bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 1);
888                 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
889                 break;
890         default:
891                 BUG();
892         }
893
894         /* copy format info */
895         buf->btformat = fmt->btformat;
896         buf->btswap   = fmt->btswap;
897         buf->vb.field = ov->field;
898         return 0;
899 }
900
901 /*
902  * Local variables:
903  * c-basic-offset: 8
904  * End:
905  */