V4L/DVB (3420): Nskips maybe used uninitialized in bttv_risc_overlay
[linux-2.6.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                 else
280                         nskips = 0;
281
282                 /* write out risc code */
283                 for (start = 0, skip = 0; start < ov->w.width; start = end) {
284                         if (skip >= nskips) {
285                                 ri  = BT848_RISC_WRITE;
286                                 end = ov->w.width;
287                         } else if (start < skips[skip].start) {
288                                 ri  = BT848_RISC_WRITE;
289                                 end = skips[skip].start;
290                         } else {
291                                 ri  = BT848_RISC_SKIP;
292                                 end = skips[skip].end;
293                                 skip++;
294                         }
295                         if (BT848_RISC_WRITE == ri)
296                                 ra = addr + (fmt->depth>>3)*start;
297                         else
298                                 ra = 0;
299
300                         if (0 == start)
301                                 ri |= BT848_RISC_SOL;
302                         if (ov->w.width == end)
303                                 ri |= BT848_RISC_EOL;
304                         ri |= (fmt->depth>>3) * (end-start);
305
306                         *(rp++)=cpu_to_le32(ri);
307                         if (0 != ra)
308                                 *(rp++)=cpu_to_le32(ra);
309                 }
310         }
311
312         /* save pointer to jmp instruction address */
313         risc->jmp = rp;
314         BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
315         kfree(skips);
316         return 0;
317 }
318
319 /* ---------------------------------------------------------- */
320
321 static void
322 bttv_calc_geo(struct bttv *btv, struct bttv_geometry *geo,
323               int width, int height, int interleaved, int norm)
324 {
325         const struct bttv_tvnorm *tvnorm = &bttv_tvnorms[norm];
326         u32 xsf, sr;
327         int vdelay;
328
329         int swidth       = tvnorm->swidth;
330         int totalwidth   = tvnorm->totalwidth;
331         int scaledtwidth = tvnorm->scaledtwidth;
332
333         if (bttv_tvcards[btv->c.type].muxsel[btv->input] < 0) {
334                 swidth       = 720;
335                 totalwidth   = 858;
336                 scaledtwidth = 858;
337         }
338
339         vdelay = tvnorm->vdelay;
340
341         xsf = (width*scaledtwidth)/swidth;
342         geo->hscale =  ((totalwidth*4096UL)/xsf-4096);
343         geo->hdelay =  tvnorm->hdelayx1;
344         geo->hdelay =  (geo->hdelay*width)/swidth;
345         geo->hdelay &= 0x3fe;
346         sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
347         geo->vscale =  (0x10000UL-sr) & 0x1fff;
348         geo->crop   =  ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
349                 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
350         geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
351         geo->vdelay  =  vdelay;
352         geo->width   =  width;
353         geo->sheight =  tvnorm->sheight;
354         geo->vtotal  =  tvnorm->vtotal;
355
356         if (btv->opt_combfilter) {
357                 geo->vtc  = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
358                 geo->comb = (width < 769) ? 1 : 0;
359         } else {
360                 geo->vtc  = 0;
361                 geo->comb = 0;
362         }
363 }
364
365 static void
366 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
367 {
368         int off = odd ? 0x80 : 0x00;
369
370         if (geo->comb)
371                 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
372         else
373                 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
374
375         btwrite(geo->vtc,             BT848_E_VTC+off);
376         btwrite(geo->hscale >> 8,     BT848_E_HSCALE_HI+off);
377         btwrite(geo->hscale & 0xff,   BT848_E_HSCALE_LO+off);
378         btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
379         btwrite(geo->vscale & 0xff,   BT848_E_VSCALE_LO+off);
380         btwrite(geo->width & 0xff,    BT848_E_HACTIVE_LO+off);
381         btwrite(geo->hdelay & 0xff,   BT848_E_HDELAY_LO+off);
382         btwrite(geo->sheight & 0xff,  BT848_E_VACTIVE_LO+off);
383         btwrite(geo->vdelay & 0xff,   BT848_E_VDELAY_LO+off);
384         btwrite(geo->crop,            BT848_E_CROP+off);
385         btwrite(geo->vtotal>>8,       BT848_VTOTAL_HI);
386         btwrite(geo->vtotal & 0xff,   BT848_VTOTAL_LO);
387 }
388
389 /* ---------------------------------------------------------- */
390 /* risc group / risc main loop / dma management               */
391
392 void
393 bttv_set_dma(struct bttv *btv, int override)
394 {
395         unsigned long cmd;
396         int capctl;
397
398         btv->cap_ctl = 0;
399         if (NULL != btv->curr.top)      btv->cap_ctl |= 0x02;
400         if (NULL != btv->curr.bottom)   btv->cap_ctl |= 0x01;
401         if (NULL != btv->cvbi)          btv->cap_ctl |= 0x0c;
402
403         capctl  = 0;
404         capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00;  /* capture  */
405         capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00;  /* vbi data */
406         capctl |= override;
407
408         d2printk(KERN_DEBUG
409                  "bttv%d: capctl=%x lirq=%d top=%08Lx/%08Lx even=%08Lx/%08Lx\n",
410                  btv->c.nr,capctl,btv->loop_irq,
411                  btv->cvbi         ? (unsigned long long)btv->cvbi->top.dma            : 0,
412                  btv->curr.top     ? (unsigned long long)btv->curr.top->top.dma        : 0,
413                  btv->cvbi         ? (unsigned long long)btv->cvbi->bottom.dma         : 0,
414                  btv->curr.bottom  ? (unsigned long long)btv->curr.bottom->bottom.dma  : 0);
415
416         cmd = BT848_RISC_JUMP;
417         if (btv->loop_irq) {
418                 cmd |= BT848_RISC_IRQ;
419                 cmd |= (btv->loop_irq  & 0x0f) << 16;
420                 cmd |= (~btv->loop_irq & 0x0f) << 20;
421         }
422         if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
423                 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
424         } else {
425                 del_timer(&btv->timeout);
426         }
427         btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
428
429         btaor(capctl, ~0x0f, BT848_CAP_CTL);
430         if (capctl) {
431                 if (btv->dma_on)
432                         return;
433                 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
434                 btor(3, BT848_GPIO_DMA_CTL);
435                 btv->dma_on = 1;
436         } else {
437                 if (!btv->dma_on)
438                         return;
439                 btand(~3, BT848_GPIO_DMA_CTL);
440                 btv->dma_on = 0;
441         }
442         return;
443 }
444
445 int
446 bttv_risc_init_main(struct bttv *btv)
447 {
448         int rc;
449
450         if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
451                 return rc;
452         dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
453                 btv->c.nr,(unsigned long long)btv->main.dma);
454
455         btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
456                                        BT848_FIFO_STATUS_VRE);
457         btv->main.cpu[1] = cpu_to_le32(0);
458         btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
459         btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
460
461         /* top field */
462         btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
463         btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
464         btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
465         btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
466
467         btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
468                                        BT848_FIFO_STATUS_VRO);
469         btv->main.cpu[9] = cpu_to_le32(0);
470
471         /* bottom field */
472         btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
473         btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
474         btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
475         btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
476
477         /* jump back to top field */
478         btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
479         btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
480
481         return 0;
482 }
483
484 int
485 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
486                int irqflags)
487 {
488         unsigned long cmd;
489         unsigned long next = btv->main.dma + ((slot+2) << 2);
490
491         if (NULL == risc) {
492                 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
493                          btv->c.nr,risc,slot);
494                 btv->main.cpu[slot+1] = cpu_to_le32(next);
495         } else {
496                 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
497                          btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
498                 cmd = BT848_RISC_JUMP;
499                 if (irqflags) {
500                         cmd |= BT848_RISC_IRQ;
501                         cmd |= (irqflags  & 0x0f) << 16;
502                         cmd |= (~irqflags & 0x0f) << 20;
503                 }
504                 risc->jmp[0] = cpu_to_le32(cmd);
505                 risc->jmp[1] = cpu_to_le32(next);
506                 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
507         }
508         return 0;
509 }
510
511 void
512 bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf)
513 {
514         if (in_interrupt())
515                 BUG();
516         videobuf_waiton(&buf->vb,0,0);
517         videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma);
518         videobuf_dma_free(&buf->vb.dma);
519         btcx_riscmem_free(btv->c.pci,&buf->bottom);
520         btcx_riscmem_free(btv->c.pci,&buf->top);
521         buf->vb.state = STATE_NEEDS_INIT;
522 }
523
524 int
525 bttv_buffer_activate_vbi(struct bttv *btv,
526                          struct bttv_buffer *vbi)
527 {
528         /* vbi capture */
529         if (vbi) {
530                 vbi->vb.state = STATE_ACTIVE;
531                 list_del(&vbi->vb.queue);
532                 bttv_risc_hook(btv, RISC_SLOT_O_VBI, &vbi->top,    0);
533                 bttv_risc_hook(btv, RISC_SLOT_E_VBI, &vbi->bottom, 4);
534         } else {
535                 bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
536                 bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
537         }
538         return 0;
539 }
540
541 int
542 bttv_buffer_activate_video(struct bttv *btv,
543                            struct bttv_buffer_set *set)
544 {
545         /* video capture */
546         if (NULL != set->top  &&  NULL != set->bottom) {
547                 if (set->top == set->bottom) {
548                         set->top->vb.state    = STATE_ACTIVE;
549                         if (set->top->vb.queue.next)
550                                 list_del(&set->top->vb.queue);
551                 } else {
552                         set->top->vb.state    = STATE_ACTIVE;
553                         set->bottom->vb.state = STATE_ACTIVE;
554                         if (set->top->vb.queue.next)
555                                 list_del(&set->top->vb.queue);
556                         if (set->bottom->vb.queue.next)
557                                 list_del(&set->bottom->vb.queue);
558                 }
559                 bttv_apply_geo(btv, &set->top->geo, 1);
560                 bttv_apply_geo(btv, &set->bottom->geo,0);
561                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
562                                set->top_irq);
563                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
564                                set->frame_irq);
565                 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
566                       ~0xff, BT848_COLOR_FMT);
567                 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
568                       ~0x0f, BT848_COLOR_CTL);
569         } else if (NULL != set->top) {
570                 set->top->vb.state  = STATE_ACTIVE;
571                 if (set->top->vb.queue.next)
572                         list_del(&set->top->vb.queue);
573                 bttv_apply_geo(btv, &set->top->geo,1);
574                 bttv_apply_geo(btv, &set->top->geo,0);
575                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
576                                set->frame_irq);
577                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL,           0);
578                 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
579                 btaor(set->top->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
580         } else if (NULL != set->bottom) {
581                 set->bottom->vb.state = STATE_ACTIVE;
582                 if (set->bottom->vb.queue.next)
583                         list_del(&set->bottom->vb.queue);
584                 bttv_apply_geo(btv, &set->bottom->geo,1);
585                 bttv_apply_geo(btv, &set->bottom->geo,0);
586                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
587                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
588                                set->frame_irq);
589                 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
590                 btaor(set->bottom->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
591         } else {
592                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
593                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
594         }
595         return 0;
596 }
597
598 /* ---------------------------------------------------------- */
599
600 /* calculate geometry, build risc code */
601 int
602 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
603 {
604         const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
605
606         dprintk(KERN_DEBUG
607                 "bttv%d: buffer field: %s  format: %s  size: %dx%d\n",
608                 btv->c.nr, v4l2_field_names[buf->vb.field],
609                 buf->fmt->name, buf->vb.width, buf->vb.height);
610
611         /* packed pixel modes */
612         if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
613                 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
614                 int bpf = bpl * (buf->vb.height >> 1);
615
616                 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
617                               V4L2_FIELD_HAS_BOTH(buf->vb.field),buf->tvnorm);
618
619                 switch (buf->vb.field) {
620                 case V4L2_FIELD_TOP:
621                         bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
622                                          0,bpl,0,buf->vb.height);
623                         break;
624                 case V4L2_FIELD_BOTTOM:
625                         bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
626                                          0,bpl,0,buf->vb.height);
627                         break;
628                 case V4L2_FIELD_INTERLACED:
629                         bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
630                                          0,bpl,bpl,buf->vb.height >> 1);
631                         bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
632                                          bpl,bpl,bpl,buf->vb.height >> 1);
633                         break;
634                 case V4L2_FIELD_SEQ_TB:
635                         bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
636                                          0,bpl,0,buf->vb.height >> 1);
637                         bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
638                                          bpf,bpl,0,buf->vb.height >> 1);
639                         break;
640                 default:
641                         BUG();
642                 }
643         }
644
645         /* planar modes */
646         if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
647                 int uoffset, voffset;
648                 int ypadding, cpadding, lines;
649
650                 /* calculate chroma offsets */
651                 uoffset = buf->vb.width * buf->vb.height;
652                 voffset = buf->vb.width * buf->vb.height;
653                 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
654                         /* Y-Cr-Cb plane order */
655                         uoffset >>= buf->fmt->hshift;
656                         uoffset >>= buf->fmt->vshift;
657                         uoffset  += voffset;
658                 } else {
659                         /* Y-Cb-Cr plane order */
660                         voffset >>= buf->fmt->hshift;
661                         voffset >>= buf->fmt->vshift;
662                         voffset  += uoffset;
663                 }
664
665                 switch (buf->vb.field) {
666                 case V4L2_FIELD_TOP:
667                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
668                                       buf->vb.height,0,buf->tvnorm);
669                         bttv_risc_planar(btv, &buf->top, buf->vb.dma.sglist,
670                                          0,buf->vb.width,0,buf->vb.height,
671                                          uoffset,voffset,buf->fmt->hshift,
672                                          buf->fmt->vshift,0);
673                         break;
674                 case V4L2_FIELD_BOTTOM:
675                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
676                                       buf->vb.height,0,buf->tvnorm);
677                         bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist,
678                                          0,buf->vb.width,0,buf->vb.height,
679                                          uoffset,voffset,buf->fmt->hshift,
680                                          buf->fmt->vshift,0);
681                         break;
682                 case V4L2_FIELD_INTERLACED:
683                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
684                                       buf->vb.height,1,buf->tvnorm);
685                         lines    = buf->vb.height >> 1;
686                         ypadding = buf->vb.width;
687                         cpadding = buf->vb.width >> buf->fmt->hshift;
688                         bttv_risc_planar(btv,&buf->top,
689                                          buf->vb.dma.sglist,
690                                          0,buf->vb.width,ypadding,lines,
691                                          uoffset,voffset,
692                                          buf->fmt->hshift,
693                                          buf->fmt->vshift,
694                                          cpadding);
695                         bttv_risc_planar(btv,&buf->bottom,
696                                          buf->vb.dma.sglist,
697                                          ypadding,buf->vb.width,ypadding,lines,
698                                          uoffset+cpadding,
699                                          voffset+cpadding,
700                                          buf->fmt->hshift,
701                                          buf->fmt->vshift,
702                                          cpadding);
703                         break;
704                 case V4L2_FIELD_SEQ_TB:
705                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
706                                       buf->vb.height,1,buf->tvnorm);
707                         lines    = buf->vb.height >> 1;
708                         ypadding = buf->vb.width;
709                         cpadding = buf->vb.width >> buf->fmt->hshift;
710                         bttv_risc_planar(btv,&buf->top,
711                                          buf->vb.dma.sglist,
712                                          0,buf->vb.width,0,lines,
713                                          uoffset >> 1,
714                                          voffset >> 1,
715                                          buf->fmt->hshift,
716                                          buf->fmt->vshift,
717                                          0);
718                         bttv_risc_planar(btv,&buf->bottom,
719                                          buf->vb.dma.sglist,
720                                          lines * ypadding,buf->vb.width,0,lines,
721                                          lines * ypadding + (uoffset >> 1),
722                                          lines * ypadding + (voffset >> 1),
723                                          buf->fmt->hshift,
724                                          buf->fmt->vshift,
725                                          0);
726                         break;
727                 default:
728                         BUG();
729                 }
730         }
731
732         /* raw data */
733         if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
734                 /* build risc code */
735                 buf->vb.field = V4L2_FIELD_SEQ_TB;
736                 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
737                               1,buf->tvnorm);
738                 bttv_risc_packed(btv, &buf->top,  buf->vb.dma.sglist,
739                                  0, RAW_BPL, 0, RAW_LINES);
740                 bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
741                                  buf->vb.size/2 , RAW_BPL, 0, RAW_LINES);
742         }
743
744         /* copy format info */
745         buf->btformat = buf->fmt->btformat;
746         buf->btswap   = buf->fmt->btswap;
747         return 0;
748 }
749
750 /* ---------------------------------------------------------- */
751
752 /* calculate geometry, build risc code */
753 int
754 bttv_overlay_risc(struct bttv *btv,
755                   struct bttv_overlay *ov,
756                   const struct bttv_format *fmt,
757                   struct bttv_buffer *buf)
758 {
759         /* check interleave, bottom+top fields */
760         dprintk(KERN_DEBUG
761                 "bttv%d: overlay fields: %s format: %s  size: %dx%d\n",
762                 btv->c.nr, v4l2_field_names[buf->vb.field],
763                 fmt->name,ov->w.width,ov->w.height);
764
765         /* calculate geometry */
766         bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
767                       V4L2_FIELD_HAS_BOTH(ov->field), ov->tvnorm);
768
769         /* build risc code */
770         switch (ov->field) {
771         case V4L2_FIELD_TOP:
772                 bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 0);
773                 break;
774         case V4L2_FIELD_BOTTOM:
775                 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
776                 break;
777         case V4L2_FIELD_INTERLACED:
778                 bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 1);
779                 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
780                 break;
781         default:
782                 BUG();
783         }
784
785         /* copy format info */
786         buf->btformat = fmt->btformat;
787         buf->btswap   = fmt->btswap;
788         buf->vb.field = ov->field;
789         return 0;
790 }
791
792 /*
793  * Local variables:
794  * c-basic-offset: 8
795  * End:
796  */