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