VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[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->cvbi)          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->cvbi         ? (unsigned long long)btv->cvbi->top.dma            : 0,
393                  btv->curr.top     ? (unsigned long long)btv->curr.top->top.dma        : 0,
394                  btv->cvbi         ? (unsigned long long)btv->cvbi->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         }
403         if (irqflags || btv->cvbi) {
404                 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
405         } else {
406                 del_timer(&btv->timeout);
407         }
408         btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
409         
410         btaor(capctl, ~0x0f, BT848_CAP_CTL);
411         if (capctl) {
412                 if (btv->dma_on)
413                         return;
414                 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
415                 btor(3, BT848_GPIO_DMA_CTL);
416                 btv->dma_on = 1;
417         } else {
418                 if (!btv->dma_on)
419                         return;
420                 btand(~3, BT848_GPIO_DMA_CTL);
421                 btv->dma_on = 0;
422         }
423         return;
424 }
425
426 int
427 bttv_risc_init_main(struct bttv *btv)
428 {
429         int rc;
430         
431         if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
432                 return rc;
433         dprintk(KERN_DEBUG "bttv%d: risc main @ %08Lx\n",
434                 btv->c.nr,(unsigned long long)btv->main.dma);
435
436         btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
437                                        BT848_FIFO_STATUS_VRE);
438         btv->main.cpu[1] = cpu_to_le32(0);
439         btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
440         btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
441
442         /* top field */
443         btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
444         btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
445         btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
446         btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
447
448         btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
449                                        BT848_FIFO_STATUS_VRO);
450         btv->main.cpu[9] = cpu_to_le32(0);
451
452         /* bottom field */
453         btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
454         btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
455         btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
456         btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
457
458         /* jump back to top field */
459         btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
460         btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
461
462         return 0;
463 }
464
465 int
466 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
467                int irqflags)
468 {
469         unsigned long cmd;
470         unsigned long next = btv->main.dma + ((slot+2) << 2);
471
472         if (NULL == risc) {
473                 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=NULL\n",
474                          btv->c.nr,risc,slot);
475                 btv->main.cpu[slot+1] = cpu_to_le32(next);
476         } else {
477                 d2printk(KERN_DEBUG "bttv%d: risc=%p slot[%d]=%08Lx irq=%d\n",
478                          btv->c.nr,risc,slot,(unsigned long long)risc->dma,irqflags);
479                 cmd = BT848_RISC_JUMP;
480                 if (irqflags) {
481                         cmd |= BT848_RISC_IRQ;
482                         cmd |= (irqflags  & 0x0f) << 16;
483                         cmd |= (~irqflags & 0x0f) << 20;
484                 }
485                 risc->jmp[0] = cpu_to_le32(cmd);
486                 risc->jmp[1] = cpu_to_le32(next);
487                 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
488         }
489         return 0;
490 }
491
492 void
493 bttv_dma_free(struct bttv *btv, struct bttv_buffer *buf)
494 {
495         if (in_interrupt())
496                 BUG();
497         videobuf_waiton(&buf->vb,0,0);
498         videobuf_dma_pci_unmap(btv->c.pci, &buf->vb.dma);
499         videobuf_dma_free(&buf->vb.dma);
500         btcx_riscmem_free(btv->c.pci,&buf->bottom);
501         btcx_riscmem_free(btv->c.pci,&buf->top);
502         buf->vb.state = STATE_NEEDS_INIT;
503 }
504
505 int
506 bttv_buffer_activate_vbi(struct bttv *btv,
507                          struct bttv_buffer *vbi)
508 {
509         /* vbi capture */
510         if (vbi) {
511                 vbi->vb.state = STATE_ACTIVE;
512                 list_del(&vbi->vb.queue);
513                 bttv_risc_hook(btv, RISC_SLOT_O_VBI, &vbi->top,    0);
514                 bttv_risc_hook(btv, RISC_SLOT_E_VBI, &vbi->bottom, 4);
515         } else {
516                 bttv_risc_hook(btv, RISC_SLOT_O_VBI, NULL, 0);
517                 bttv_risc_hook(btv, RISC_SLOT_E_VBI, NULL, 0);
518         }
519         return 0;
520 }
521
522 int
523 bttv_buffer_activate_video(struct bttv *btv,
524                            struct bttv_buffer_set *set)
525 {
526         /* video capture */
527         if (NULL != set->top  &&  NULL != set->bottom) {
528                 if (set->top == set->bottom) {
529                         set->top->vb.state    = STATE_ACTIVE;
530                         if (set->top->vb.queue.next)
531                                 list_del(&set->top->vb.queue);
532                 } else {
533                         set->top->vb.state    = STATE_ACTIVE;
534                         set->bottom->vb.state = STATE_ACTIVE;
535                         if (set->top->vb.queue.next)
536                                 list_del(&set->top->vb.queue);
537                         if (set->bottom->vb.queue.next)
538                                 list_del(&set->bottom->vb.queue);
539                 }
540                 bttv_apply_geo(btv, &set->top->geo, 1);
541                 bttv_apply_geo(btv, &set->bottom->geo,0);
542                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, set->topirq);
543                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 0);
544                 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
545                       ~0xff, BT848_COLOR_FMT);
546                 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
547                       ~0x0f, BT848_COLOR_CTL);
548         } else if (NULL != set->top) {
549                 set->top->vb.state  = STATE_ACTIVE;
550                 if (set->top->vb.queue.next)
551                         list_del(&set->top->vb.queue);
552                 bttv_apply_geo(btv, &set->top->geo,1);
553                 bttv_apply_geo(btv, &set->top->geo,0);
554                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top, 0);
555                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL,           0);
556                 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
557                 btaor(set->top->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
558         } else if (NULL != set->bottom) {
559                 set->bottom->vb.state = STATE_ACTIVE;
560                 if (set->bottom->vb.queue.next)
561                         list_del(&set->bottom->vb.queue);
562                 bttv_apply_geo(btv, &set->bottom->geo,1);
563                 bttv_apply_geo(btv, &set->bottom->geo,0);
564                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL,                 0);
565                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom, 0);
566                 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
567                 btaor(set->bottom->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
568         } else {
569                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
570                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
571         }
572         return 0;
573 }
574
575 /* ---------------------------------------------------------- */
576
577 /* calculate geometry, build risc code */
578 int
579 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
580 {
581         const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
582
583         dprintk(KERN_DEBUG
584                 "bttv%d: buffer field: %s  format: %s  size: %dx%d\n",
585                 btv->c.nr, v4l2_field_names[buf->vb.field],
586                 buf->fmt->name, buf->vb.width, buf->vb.height);
587
588         /* packed pixel modes */
589         if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
590                 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
591                 int bpf = bpl * (buf->vb.height >> 1);
592
593                 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
594                               V4L2_FIELD_HAS_BOTH(buf->vb.field),buf->tvnorm);
595                 
596                 switch (buf->vb.field) {
597                 case V4L2_FIELD_TOP:
598                         bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
599                                          0,bpl,0,buf->vb.height);
600                         break;
601                 case V4L2_FIELD_BOTTOM:
602                         bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
603                                          0,bpl,0,buf->vb.height);
604                         break;
605                 case V4L2_FIELD_INTERLACED:
606                         bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
607                                          0,bpl,bpl,buf->vb.height >> 1);
608                         bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
609                                          bpl,bpl,bpl,buf->vb.height >> 1);
610                         break;
611                 case V4L2_FIELD_SEQ_TB:
612                         bttv_risc_packed(btv,&buf->top,buf->vb.dma.sglist,
613                                          0,bpl,0,buf->vb.height >> 1);
614                         bttv_risc_packed(btv,&buf->bottom,buf->vb.dma.sglist,
615                                          bpf,bpl,0,buf->vb.height >> 1);
616                         break;
617                 default:
618                         BUG();
619                 }
620         }
621
622         /* planar modes */
623         if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
624                 int uoffset, voffset;
625                 int ypadding, cpadding, lines;
626
627                 /* calculate chroma offsets */
628                 uoffset = buf->vb.width * buf->vb.height;
629                 voffset = buf->vb.width * buf->vb.height;
630                 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
631                         /* Y-Cr-Cb plane order */
632                         uoffset >>= buf->fmt->hshift;
633                         uoffset >>= buf->fmt->vshift;
634                         uoffset  += voffset;
635                 } else {
636                         /* Y-Cb-Cr plane order */
637                         voffset >>= buf->fmt->hshift;
638                         voffset >>= buf->fmt->vshift;
639                         voffset  += uoffset;
640                 }
641
642                 switch (buf->vb.field) {
643                 case V4L2_FIELD_TOP:
644                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
645                                       buf->vb.height,0,buf->tvnorm);
646                         bttv_risc_planar(btv, &buf->top, 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_BOTTOM:
652                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
653                                       buf->vb.height,0,buf->tvnorm);
654                         bttv_risc_planar(btv, &buf->bottom, buf->vb.dma.sglist,
655                                          0,buf->vb.width,0,buf->vb.height,
656                                          uoffset,voffset,buf->fmt->hshift,
657                                          buf->fmt->vshift,0);
658                         break;
659                 case V4L2_FIELD_INTERLACED:
660                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
661                                       buf->vb.height,1,buf->tvnorm);
662                         lines    = buf->vb.height >> 1;
663                         ypadding = buf->vb.width;
664                         cpadding = buf->vb.width >> buf->fmt->hshift;
665                         bttv_risc_planar(btv,&buf->top,
666                                          buf->vb.dma.sglist,
667                                          0,buf->vb.width,ypadding,lines,
668                                          uoffset,voffset,
669                                          buf->fmt->hshift,
670                                          buf->fmt->vshift,
671                                          cpadding);
672                         bttv_risc_planar(btv,&buf->bottom,
673                                          buf->vb.dma.sglist,
674                                          ypadding,buf->vb.width,ypadding,lines,
675                                          uoffset+cpadding,
676                                          voffset+cpadding,
677                                          buf->fmt->hshift,
678                                          buf->fmt->vshift,
679                                          cpadding);
680                         break;
681                 case V4L2_FIELD_SEQ_TB:
682                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
683                                       buf->vb.height,1,buf->tvnorm);
684                         lines    = buf->vb.height >> 1;
685                         ypadding = buf->vb.width;
686                         cpadding = buf->vb.width >> buf->fmt->hshift;
687                         bttv_risc_planar(btv,&buf->top,
688                                          buf->vb.dma.sglist,
689                                          0,buf->vb.width,0,lines,
690                                          uoffset >> 1,
691                                          voffset >> 1,
692                                          buf->fmt->hshift,
693                                          buf->fmt->vshift,
694                                          0);
695                         bttv_risc_planar(btv,&buf->bottom,
696                                          buf->vb.dma.sglist,
697                                          lines * ypadding,buf->vb.width,0,lines,
698                                          lines * ypadding + (uoffset >> 1),
699                                          lines * ypadding + (voffset >> 1),
700                                          buf->fmt->hshift,
701                                          buf->fmt->vshift,
702                                          0);
703                         break;
704                 default:
705                         BUG();
706                 }
707         }
708
709         /* raw data */
710         if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
711                 /* build risc code */
712                 buf->vb.field = V4L2_FIELD_SEQ_TB;
713                 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
714                               1,buf->tvnorm);
715                 bttv_risc_packed(btv, &buf->top,  buf->vb.dma.sglist,
716                                  0, RAW_BPL, 0, RAW_LINES);
717                 bttv_risc_packed(btv, &buf->bottom, buf->vb.dma.sglist,
718                                  buf->vb.size/2 , RAW_BPL, 0, RAW_LINES);
719         }
720
721         /* copy format info */
722         buf->btformat = buf->fmt->btformat;
723         buf->btswap   = buf->fmt->btswap;
724         return 0;
725 }
726
727 /* ---------------------------------------------------------- */
728
729 /* calculate geometry, build risc code */
730 int
731 bttv_overlay_risc(struct bttv *btv,
732                   struct bttv_overlay *ov,
733                   const struct bttv_format *fmt,
734                   struct bttv_buffer *buf)
735 {
736         /* check interleave, bottom+top fields */
737         dprintk(KERN_DEBUG
738                 "bttv%d: overlay fields: %s format: %s  size: %dx%d\n",
739                 btv->c.nr, v4l2_field_names[buf->vb.field],
740                 fmt->name,ov->w.width,ov->w.height);
741
742         /* calculate geometry */
743         bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
744                       V4L2_FIELD_HAS_BOTH(ov->field), ov->tvnorm);
745
746         /* build risc code */
747         switch (ov->field) {
748         case V4L2_FIELD_TOP:
749                 bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 0);
750                 break;
751         case V4L2_FIELD_BOTTOM:
752                 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
753                 break;
754         case V4L2_FIELD_INTERLACED:
755 #if 0
756                 bttv_risc_overlay(btv, &buf->top,    fmt, ov, 1, 0);
757                 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 1);
758 #else
759                 bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 1);
760                 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
761 #endif
762                 break;
763         default:
764                 BUG();
765         }
766
767         /* copy format info */
768         buf->btformat = fmt->btformat;
769         buf->btswap   = fmt->btswap;
770         buf->vb.field = ov->field;
771         return 0;
772 }
773
774 /*
775  * Local variables:
776  * c-basic-offset: 8
777  * End:
778  */