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