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