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