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