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