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