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