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