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