Merge tag 'microblaze-v5.14' of git://git.monstr.eu/linux-2.6-microblaze
[linux-2.6-microblaze.git] / drivers / media / pci / bt8xx / bttv-risc.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3
4     bttv-risc.c  --  interfaces to other kernel modules
5
6     bttv risc code handling
7         - memory management
8         - generation
9
10     (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
11
12
13 */
14
15 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
16
17 #include <linux/module.h>
18 #include <linux/init.h>
19 #include <linux/slab.h>
20 #include <linux/pci.h>
21 #include <linux/vmalloc.h>
22 #include <linux/interrupt.h>
23 #include <linux/pgtable.h>
24 #include <asm/page.h>
25 #include <media/v4l2-ioctl.h>
26
27 #include "bttvp.h"
28
29 #define VCR_HACK_LINES 4
30
31 /* ---------------------------------------------------------- */
32 /* risc code generators                                       */
33
34 int
35 bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
36                  struct scatterlist *sglist,
37                  unsigned int offset, unsigned int bpl,
38                  unsigned int padding, unsigned int skip_lines,
39                  unsigned int store_lines)
40 {
41         u32 instructions,line,todo;
42         struct scatterlist *sg;
43         __le32 *rp;
44         int rc;
45
46         /* estimate risc mem: worst case is one write per page border +
47            one write per scan line + sync + jump (all 2 dwords).  padding
48            can cause next bpl to start close to a page border.  First DMA
49            region may be smaller than PAGE_SIZE */
50         instructions  = skip_lines * 4;
51         instructions += (1 + ((bpl + padding) * store_lines)
52                          / PAGE_SIZE + store_lines) * 8;
53         instructions += 2 * 8;
54         if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions)) < 0)
55                 return rc;
56
57         /* sync instruction */
58         rp = risc->cpu;
59         *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
60         *(rp++) = cpu_to_le32(0);
61
62         while (skip_lines-- > 0) {
63                 *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
64                                       BT848_RISC_EOL | bpl);
65         }
66
67         /* scan lines */
68         sg = sglist;
69         for (line = 0; line < store_lines; line++) {
70                 if ((btv->opt_vcr_hack) &&
71                     (line >= (store_lines - VCR_HACK_LINES)))
72                         continue;
73                 while (offset && offset >= sg_dma_len(sg)) {
74                         offset -= sg_dma_len(sg);
75                         sg = sg_next(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 split */
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 = sg_next(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 = sg_next(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         __le32 *rp;
124         u32 ri;
125         struct scatterlist *ysg;
126         struct scatterlist *usg;
127         struct scatterlist *vsg;
128         int topfield = (0 == yoffset);
129         int rc;
130
131         /* estimate risc mem: worst case is one write per page border +
132            one write per scan line (5 dwords)
133            plus sync + jump (2 dwords) */
134         instructions  = ((3 + (ybpl + ypadding) * ylines * 2)
135                          / PAGE_SIZE) + ylines;
136         instructions += 2;
137         if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,instructions*4*5)) < 0)
138                 return rc;
139
140         /* sync instruction */
141         rp = risc->cpu;
142         *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
143         *(rp++) = cpu_to_le32(0);
144
145         /* scan lines */
146         ysg = sglist;
147         usg = sglist;
148         vsg = sglist;
149         for (line = 0; line < ylines; line++) {
150                 if ((btv->opt_vcr_hack) &&
151                     (line >= (ylines - VCR_HACK_LINES)))
152                         continue;
153                 switch (vshift) {
154                 case 0:
155                         chroma = 1;
156                         break;
157                 case 1:
158                         if (topfield)
159                                 chroma = ((line & 1) == 0);
160                         else
161                                 chroma = ((line & 1) == 1);
162                         break;
163                 case 2:
164                         if (topfield)
165                                 chroma = ((line & 3) == 0);
166                         else
167                                 chroma = ((line & 3) == 2);
168                         break;
169                 default:
170                         chroma = 0;
171                         break;
172                 }
173
174                 for (todo = ybpl; todo > 0; todo -= ylen) {
175                         /* go to next sg entry if needed */
176                         while (yoffset && yoffset >= sg_dma_len(ysg)) {
177                                 yoffset -= sg_dma_len(ysg);
178                                 ysg = sg_next(ysg);
179                         }
180
181                         /* calculate max number of bytes we can write */
182                         ylen = todo;
183                         if (yoffset + ylen > sg_dma_len(ysg))
184                                 ylen = sg_dma_len(ysg) - yoffset;
185                         if (chroma) {
186                                 while (uoffset && uoffset >= sg_dma_len(usg)) {
187                                         uoffset -= sg_dma_len(usg);
188                                         usg = sg_next(usg);
189                                 }
190                                 while (voffset && voffset >= sg_dma_len(vsg)) {
191                                         voffset -= sg_dma_len(vsg);
192                                         vsg = sg_next(vsg);
193                                 }
194
195                                 if (uoffset + (ylen>>hshift) > sg_dma_len(usg))
196                                         ylen = (sg_dma_len(usg) - uoffset) << hshift;
197                                 if (voffset + (ylen>>hshift) > sg_dma_len(vsg))
198                                         ylen = (sg_dma_len(vsg) - voffset) << hshift;
199                                 ri = BT848_RISC_WRITE123;
200                         } else {
201                                 ri = BT848_RISC_WRITE1S23;
202                         }
203                         if (ybpl == todo)
204                                 ri |= BT848_RISC_SOL;
205                         if (ylen == todo)
206                                 ri |= BT848_RISC_EOL;
207
208                         /* write risc instruction */
209                         *(rp++)=cpu_to_le32(ri | ylen);
210                         *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
211                                             (ylen >> hshift));
212                         *(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
213                         yoffset += ylen;
214                         if (chroma) {
215                                 *(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
216                                 uoffset += ylen >> hshift;
217                                 *(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
218                                 voffset += ylen >> hshift;
219                         }
220                 }
221                 yoffset += ypadding;
222                 if (chroma) {
223                         uoffset += cpadding;
224                         voffset += cpadding;
225                 }
226         }
227
228         /* save pointer to jmp instruction address */
229         risc->jmp = rp;
230         BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
231         return 0;
232 }
233
234 static int
235 bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
236                   const struct bttv_format *fmt, struct bttv_overlay *ov,
237                   int skip_even, int skip_odd)
238 {
239         int dwords, rc, line, maxy, start, end;
240         unsigned skip, nskips;
241         struct btcx_skiplist *skips;
242         __le32 *rp;
243         u32 ri,ra;
244         u32 addr;
245
246         /* skip list for window clipping */
247         skips = kmalloc_array(ov->nclips, sizeof(*skips),GFP_KERNEL);
248         if (NULL == skips)
249                 return -ENOMEM;
250
251         /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
252            + sync + jump (all 2 dwords) */
253         dwords  = (3 * ov->nclips + 2) *
254                 ((skip_even || skip_odd) ? (ov->w.height+1)>>1 :  ov->w.height);
255         dwords += 4;
256         if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
257                 kfree(skips);
258                 return rc;
259         }
260
261         /* sync instruction */
262         rp = risc->cpu;
263         *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
264         *(rp++) = cpu_to_le32(0);
265
266         addr  = (unsigned long)btv->fbuf.base;
267         addr += btv->fbuf.fmt.bytesperline * ov->w.top;
268         addr += (fmt->depth >> 3)          * ov->w.left;
269
270         /* scan lines */
271         for (maxy = -1, line = 0; line < ov->w.height;
272              line++, addr += btv->fbuf.fmt.bytesperline) {
273                 if ((btv->opt_vcr_hack) &&
274                      (line >= (ov->w.height - VCR_HACK_LINES)))
275                         continue;
276                 if ((line%2) == 0  &&  skip_even)
277                         continue;
278                 if ((line%2) == 1  &&  skip_odd)
279                         continue;
280
281                 /* calculate clipping */
282                 if (line > maxy)
283                         btcx_calc_skips(line, ov->w.width, &maxy,
284                                         skips, &nskips, ov->clips, ov->nclips);
285
286                 /* write out risc code */
287                 for (start = 0, skip = 0; start < ov->w.width; start = end) {
288                         if (skip >= nskips) {
289                                 ri  = BT848_RISC_WRITE;
290                                 end = ov->w.width;
291                         } else if (start < skips[skip].start) {
292                                 ri  = BT848_RISC_WRITE;
293                                 end = skips[skip].start;
294                         } else {
295                                 ri  = BT848_RISC_SKIP;
296                                 end = skips[skip].end;
297                                 skip++;
298                         }
299                         if (BT848_RISC_WRITE == ri)
300                                 ra = addr + (fmt->depth>>3)*start;
301                         else
302                                 ra = 0;
303
304                         if (0 == start)
305                                 ri |= BT848_RISC_SOL;
306                         if (ov->w.width == end)
307                                 ri |= BT848_RISC_EOL;
308                         ri |= (fmt->depth>>3) * (end-start);
309
310                         *(rp++)=cpu_to_le32(ri);
311                         if (0 != ra)
312                                 *(rp++)=cpu_to_le32(ra);
313                 }
314         }
315
316         /* save pointer to jmp instruction address */
317         risc->jmp = rp;
318         BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
319         kfree(skips);
320         return 0;
321 }
322
323 /* ---------------------------------------------------------- */
324
325 static void
326 bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
327                   int width, int height, int interleaved,
328                   const struct bttv_tvnorm *tvnorm)
329 {
330         u32 xsf, sr;
331         int vdelay;
332
333         int swidth       = tvnorm->swidth;
334         int totalwidth   = tvnorm->totalwidth;
335         int scaledtwidth = tvnorm->scaledtwidth;
336
337         if (btv->input == btv->dig) {
338                 swidth       = 720;
339                 totalwidth   = 858;
340                 scaledtwidth = 858;
341         }
342
343         vdelay = tvnorm->vdelay;
344
345         xsf = (width*scaledtwidth)/swidth;
346         geo->hscale =  ((totalwidth*4096UL)/xsf-4096);
347         geo->hdelay =  tvnorm->hdelayx1;
348         geo->hdelay =  (geo->hdelay*width)/swidth;
349         geo->hdelay &= 0x3fe;
350         sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
351         geo->vscale =  (0x10000UL-sr) & 0x1fff;
352         geo->crop   =  ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
353                 ((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
354         geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
355         geo->vdelay  =  vdelay;
356         geo->width   =  width;
357         geo->sheight =  tvnorm->sheight;
358         geo->vtotal  =  tvnorm->vtotal;
359
360         if (btv->opt_combfilter) {
361                 geo->vtc  = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
362                 geo->comb = (width < 769) ? 1 : 0;
363         } else {
364                 geo->vtc  = 0;
365                 geo->comb = 0;
366         }
367 }
368
369 static void
370 bttv_calc_geo           (struct bttv *                  btv,
371                          struct bttv_geometry *         geo,
372                          unsigned int                   width,
373                          unsigned int                   height,
374                          int                            both_fields,
375                          const struct bttv_tvnorm *     tvnorm,
376                          const struct v4l2_rect *       crop)
377 {
378         unsigned int c_width;
379         unsigned int c_height;
380         u32 sr;
381
382         if ((crop->left == tvnorm->cropcap.defrect.left
383              && crop->top == tvnorm->cropcap.defrect.top
384              && crop->width == tvnorm->cropcap.defrect.width
385              && crop->height == tvnorm->cropcap.defrect.height
386              && width <= tvnorm->swidth /* see PAL-Nc et al */)
387             || btv->input == btv->dig) {
388                 bttv_calc_geo_old(btv, geo, width, height,
389                                   both_fields, tvnorm);
390                 return;
391         }
392
393         /* For bug compatibility the image size checks permit scale
394            factors > 16. See bttv_crop_calc_limits(). */
395         c_width = min((unsigned int) crop->width, width * 16);
396         c_height = min((unsigned int) crop->height, height * 16);
397
398         geo->width = width;
399         geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
400         /* Even to store Cb first, odd for Cr. */
401         geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
402
403         geo->sheight = c_height;
404         geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
405         sr = c_height >> !both_fields;
406         sr = (sr * 512U + (height >> 1)) / height - 512;
407         geo->vscale = (0x10000UL - sr) & 0x1fff;
408         geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
409         geo->vtotal = tvnorm->vtotal;
410
411         geo->crop = (((geo->width   >> 8) & 0x03) |
412                      ((geo->hdelay  >> 6) & 0x0c) |
413                      ((geo->sheight >> 4) & 0x30) |
414                      ((geo->vdelay  >> 2) & 0xc0));
415
416         if (btv->opt_combfilter) {
417                 geo->vtc  = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
418                 geo->comb = (width < 769) ? 1 : 0;
419         } else {
420                 geo->vtc  = 0;
421                 geo->comb = 0;
422         }
423 }
424
425 static void
426 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
427 {
428         int off = odd ? 0x80 : 0x00;
429
430         if (geo->comb)
431                 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
432         else
433                 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
434
435         btwrite(geo->vtc,             BT848_E_VTC+off);
436         btwrite(geo->hscale >> 8,     BT848_E_HSCALE_HI+off);
437         btwrite(geo->hscale & 0xff,   BT848_E_HSCALE_LO+off);
438         btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
439         btwrite(geo->vscale & 0xff,   BT848_E_VSCALE_LO+off);
440         btwrite(geo->width & 0xff,    BT848_E_HACTIVE_LO+off);
441         btwrite(geo->hdelay & 0xff,   BT848_E_HDELAY_LO+off);
442         btwrite(geo->sheight & 0xff,  BT848_E_VACTIVE_LO+off);
443         btwrite(geo->vdelay & 0xff,   BT848_E_VDELAY_LO+off);
444         btwrite(geo->crop,            BT848_E_CROP+off);
445         btwrite(geo->vtotal>>8,       BT848_VTOTAL_HI);
446         btwrite(geo->vtotal & 0xff,   BT848_VTOTAL_LO);
447 }
448
449 /* ---------------------------------------------------------- */
450 /* risc group / risc main loop / dma management               */
451
452 void
453 bttv_set_dma(struct bttv *btv, int override)
454 {
455         unsigned long cmd;
456         int capctl;
457
458         btv->cap_ctl = 0;
459         if (NULL != btv->curr.top)      btv->cap_ctl |= 0x02;
460         if (NULL != btv->curr.bottom)   btv->cap_ctl |= 0x01;
461         if (NULL != btv->cvbi)          btv->cap_ctl |= 0x0c;
462
463         capctl  = 0;
464         capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00;  /* capture  */
465         capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00;  /* vbi data */
466         capctl |= override;
467
468         d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n",
469                  btv->c.nr,capctl,btv->loop_irq,
470                  btv->cvbi         ? (unsigned long long)btv->cvbi->top.dma            : 0,
471                  btv->curr.top     ? (unsigned long long)btv->curr.top->top.dma        : 0,
472                  btv->cvbi         ? (unsigned long long)btv->cvbi->bottom.dma         : 0,
473                  btv->curr.bottom  ? (unsigned long long)btv->curr.bottom->bottom.dma  : 0);
474
475         cmd = BT848_RISC_JUMP;
476         if (btv->loop_irq) {
477                 cmd |= BT848_RISC_IRQ;
478                 cmd |= (btv->loop_irq  & 0x0f) << 16;
479                 cmd |= (~btv->loop_irq & 0x0f) << 20;
480         }
481         if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
482                 mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
483         } else {
484                 del_timer(&btv->timeout);
485         }
486         btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
487
488         btaor(capctl, ~0x0f, BT848_CAP_CTL);
489         if (capctl) {
490                 if (btv->dma_on)
491                         return;
492                 btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
493                 btor(3, BT848_GPIO_DMA_CTL);
494                 btv->dma_on = 1;
495         } else {
496                 if (!btv->dma_on)
497                         return;
498                 btand(~3, BT848_GPIO_DMA_CTL);
499                 btv->dma_on = 0;
500         }
501         return;
502 }
503
504 int
505 bttv_risc_init_main(struct bttv *btv)
506 {
507         int rc;
508
509         if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
510                 return rc;
511         dprintk("%d: risc main @ %08llx\n",
512                 btv->c.nr, (unsigned long long)btv->main.dma);
513
514         btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
515                                        BT848_FIFO_STATUS_VRE);
516         btv->main.cpu[1] = cpu_to_le32(0);
517         btv->main.cpu[2] = cpu_to_le32(BT848_RISC_JUMP);
518         btv->main.cpu[3] = cpu_to_le32(btv->main.dma + (4<<2));
519
520         /* top field */
521         btv->main.cpu[4] = cpu_to_le32(BT848_RISC_JUMP);
522         btv->main.cpu[5] = cpu_to_le32(btv->main.dma + (6<<2));
523         btv->main.cpu[6] = cpu_to_le32(BT848_RISC_JUMP);
524         btv->main.cpu[7] = cpu_to_le32(btv->main.dma + (8<<2));
525
526         btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
527                                        BT848_FIFO_STATUS_VRO);
528         btv->main.cpu[9] = cpu_to_le32(0);
529
530         /* bottom field */
531         btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
532         btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
533         btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
534         btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
535
536         /* jump back to top field */
537         btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
538         btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
539
540         return 0;
541 }
542
543 int
544 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
545                int irqflags)
546 {
547         unsigned long cmd;
548         unsigned long next = btv->main.dma + ((slot+2) << 2);
549
550         if (NULL == risc) {
551                 d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot);
552                 btv->main.cpu[slot+1] = cpu_to_le32(next);
553         } else {
554                 d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n",
555                          btv->c.nr, risc, slot,
556                          (unsigned long long)risc->dma, irqflags);
557                 cmd = BT848_RISC_JUMP;
558                 if (irqflags) {
559                         cmd |= BT848_RISC_IRQ;
560                         cmd |= (irqflags  & 0x0f) << 16;
561                         cmd |= (~irqflags & 0x0f) << 20;
562                 }
563                 risc->jmp[0] = cpu_to_le32(cmd);
564                 risc->jmp[1] = cpu_to_le32(next);
565                 btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
566         }
567         return 0;
568 }
569
570 void
571 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
572 {
573         struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
574
575         videobuf_waiton(q, &buf->vb, 0, 0);
576         videobuf_dma_unmap(q->dev, dma);
577         videobuf_dma_free(dma);
578         btcx_riscmem_free(btv->c.pci,&buf->bottom);
579         btcx_riscmem_free(btv->c.pci,&buf->top);
580         buf->vb.state = VIDEOBUF_NEEDS_INIT;
581 }
582
583 int
584 bttv_buffer_activate_vbi(struct bttv *btv,
585                          struct bttv_buffer *vbi)
586 {
587         struct btcx_riscmem *top;
588         struct btcx_riscmem *bottom;
589         int top_irq_flags;
590         int bottom_irq_flags;
591
592         top = NULL;
593         bottom = NULL;
594         top_irq_flags = 0;
595         bottom_irq_flags = 0;
596
597         if (vbi) {
598                 unsigned int crop, vdelay;
599
600                 vbi->vb.state = VIDEOBUF_ACTIVE;
601                 list_del(&vbi->vb.queue);
602
603                 /* VDELAY is start of video, end of VBI capturing. */
604                 crop = btread(BT848_E_CROP);
605                 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
606
607                 if (vbi->geo.vdelay > vdelay) {
608                         vdelay = vbi->geo.vdelay & 0xfe;
609                         crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
610
611                         btwrite(vdelay, BT848_E_VDELAY_LO);
612                         btwrite(crop,   BT848_E_CROP);
613                         btwrite(vdelay, BT848_O_VDELAY_LO);
614                         btwrite(crop,   BT848_O_CROP);
615                 }
616
617                 if (vbi->vbi_count[0] > 0) {
618                         top = &vbi->top;
619                         top_irq_flags = 4;
620                 }
621
622                 if (vbi->vbi_count[1] > 0) {
623                         top_irq_flags = 0;
624                         bottom = &vbi->bottom;
625                         bottom_irq_flags = 4;
626                 }
627         }
628
629         bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
630         bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
631
632         return 0;
633 }
634
635 int
636 bttv_buffer_activate_video(struct bttv *btv,
637                            struct bttv_buffer_set *set)
638 {
639         /* video capture */
640         if (NULL != set->top  &&  NULL != set->bottom) {
641                 if (set->top == set->bottom) {
642                         set->top->vb.state    = VIDEOBUF_ACTIVE;
643                         if (set->top->vb.queue.next)
644                                 list_del(&set->top->vb.queue);
645                 } else {
646                         set->top->vb.state    = VIDEOBUF_ACTIVE;
647                         set->bottom->vb.state = VIDEOBUF_ACTIVE;
648                         if (set->top->vb.queue.next)
649                                 list_del(&set->top->vb.queue);
650                         if (set->bottom->vb.queue.next)
651                                 list_del(&set->bottom->vb.queue);
652                 }
653                 bttv_apply_geo(btv, &set->top->geo, 1);
654                 bttv_apply_geo(btv, &set->bottom->geo,0);
655                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
656                                set->top_irq);
657                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
658                                set->frame_irq);
659                 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
660                       ~0xff, BT848_COLOR_FMT);
661                 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
662                       ~0x0f, BT848_COLOR_CTL);
663         } else if (NULL != set->top) {
664                 set->top->vb.state  = VIDEOBUF_ACTIVE;
665                 if (set->top->vb.queue.next)
666                         list_del(&set->top->vb.queue);
667                 bttv_apply_geo(btv, &set->top->geo,1);
668                 bttv_apply_geo(btv, &set->top->geo,0);
669                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
670                                set->frame_irq);
671                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL,           0);
672                 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
673                 btaor(set->top->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
674         } else if (NULL != set->bottom) {
675                 set->bottom->vb.state = VIDEOBUF_ACTIVE;
676                 if (set->bottom->vb.queue.next)
677                         list_del(&set->bottom->vb.queue);
678                 bttv_apply_geo(btv, &set->bottom->geo,1);
679                 bttv_apply_geo(btv, &set->bottom->geo,0);
680                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
681                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
682                                set->frame_irq);
683                 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
684                 btaor(set->bottom->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
685         } else {
686                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
687                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
688         }
689         return 0;
690 }
691
692 /* ---------------------------------------------------------- */
693
694 /* calculate geometry, build risc code */
695 int
696 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
697 {
698         const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
699         struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
700
701         dprintk("%d: buffer field: %s  format: 0x%08x  size: %dx%d\n",
702                 btv->c.nr, v4l2_field_names[buf->vb.field],
703                 buf->fmt->fourcc, buf->vb.width, buf->vb.height);
704
705         /* packed pixel modes */
706         if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
707                 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
708                 int bpf = bpl * (buf->vb.height >> 1);
709
710                 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
711                               V4L2_FIELD_HAS_BOTH(buf->vb.field),
712                               tvnorm,&buf->crop);
713
714                 switch (buf->vb.field) {
715                 case V4L2_FIELD_TOP:
716                         bttv_risc_packed(btv,&buf->top,dma->sglist,
717                                          /* offset */ 0,bpl,
718                                          /* padding */ 0,/* skip_lines */ 0,
719                                          buf->vb.height);
720                         break;
721                 case V4L2_FIELD_BOTTOM:
722                         bttv_risc_packed(btv,&buf->bottom,dma->sglist,
723                                          0,bpl,0,0,buf->vb.height);
724                         break;
725                 case V4L2_FIELD_INTERLACED:
726                         bttv_risc_packed(btv,&buf->top,dma->sglist,
727                                          0,bpl,bpl,0,buf->vb.height >> 1);
728                         bttv_risc_packed(btv,&buf->bottom,dma->sglist,
729                                          bpl,bpl,bpl,0,buf->vb.height >> 1);
730                         break;
731                 case V4L2_FIELD_SEQ_TB:
732                         bttv_risc_packed(btv,&buf->top,dma->sglist,
733                                          0,bpl,0,0,buf->vb.height >> 1);
734                         bttv_risc_packed(btv,&buf->bottom,dma->sglist,
735                                          bpf,bpl,0,0,buf->vb.height >> 1);
736                         break;
737                 default:
738                         BUG();
739                 }
740         }
741
742         /* planar modes */
743         if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
744                 int uoffset, voffset;
745                 int ypadding, cpadding, lines;
746
747                 /* calculate chroma offsets */
748                 uoffset = buf->vb.width * buf->vb.height;
749                 voffset = buf->vb.width * buf->vb.height;
750                 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
751                         /* Y-Cr-Cb plane order */
752                         uoffset >>= buf->fmt->hshift;
753                         uoffset >>= buf->fmt->vshift;
754                         uoffset  += voffset;
755                 } else {
756                         /* Y-Cb-Cr plane order */
757                         voffset >>= buf->fmt->hshift;
758                         voffset >>= buf->fmt->vshift;
759                         voffset  += uoffset;
760                 }
761
762                 switch (buf->vb.field) {
763                 case V4L2_FIELD_TOP:
764                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
765                                       buf->vb.height,/* both_fields */ 0,
766                                       tvnorm,&buf->crop);
767                         bttv_risc_planar(btv, &buf->top, dma->sglist,
768                                          0,buf->vb.width,0,buf->vb.height,
769                                          uoffset,voffset,buf->fmt->hshift,
770                                          buf->fmt->vshift,0);
771                         break;
772                 case V4L2_FIELD_BOTTOM:
773                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
774                                       buf->vb.height,0,
775                                       tvnorm,&buf->crop);
776                         bttv_risc_planar(btv, &buf->bottom, dma->sglist,
777                                          0,buf->vb.width,0,buf->vb.height,
778                                          uoffset,voffset,buf->fmt->hshift,
779                                          buf->fmt->vshift,0);
780                         break;
781                 case V4L2_FIELD_INTERLACED:
782                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
783                                       buf->vb.height,1,
784                                       tvnorm,&buf->crop);
785                         lines    = buf->vb.height >> 1;
786                         ypadding = buf->vb.width;
787                         cpadding = buf->vb.width >> buf->fmt->hshift;
788                         bttv_risc_planar(btv,&buf->top,
789                                          dma->sglist,
790                                          0,buf->vb.width,ypadding,lines,
791                                          uoffset,voffset,
792                                          buf->fmt->hshift,
793                                          buf->fmt->vshift,
794                                          cpadding);
795                         bttv_risc_planar(btv,&buf->bottom,
796                                          dma->sglist,
797                                          ypadding,buf->vb.width,ypadding,lines,
798                                          uoffset+cpadding,
799                                          voffset+cpadding,
800                                          buf->fmt->hshift,
801                                          buf->fmt->vshift,
802                                          cpadding);
803                         break;
804                 case V4L2_FIELD_SEQ_TB:
805                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
806                                       buf->vb.height,1,
807                                       tvnorm,&buf->crop);
808                         lines    = buf->vb.height >> 1;
809                         ypadding = buf->vb.width;
810                         cpadding = buf->vb.width >> buf->fmt->hshift;
811                         bttv_risc_planar(btv,&buf->top,
812                                          dma->sglist,
813                                          0,buf->vb.width,0,lines,
814                                          uoffset >> 1,
815                                          voffset >> 1,
816                                          buf->fmt->hshift,
817                                          buf->fmt->vshift,
818                                          0);
819                         bttv_risc_planar(btv,&buf->bottom,
820                                          dma->sglist,
821                                          lines * ypadding,buf->vb.width,0,lines,
822                                          lines * ypadding + (uoffset >> 1),
823                                          lines * ypadding + (voffset >> 1),
824                                          buf->fmt->hshift,
825                                          buf->fmt->vshift,
826                                          0);
827                         break;
828                 default:
829                         BUG();
830                 }
831         }
832
833         /* raw data */
834         if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
835                 /* build risc code */
836                 buf->vb.field = V4L2_FIELD_SEQ_TB;
837                 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
838                               1,tvnorm,&buf->crop);
839                 bttv_risc_packed(btv, &buf->top,  dma->sglist,
840                                  /* offset */ 0, RAW_BPL, /* padding */ 0,
841                                  /* skip_lines */ 0, RAW_LINES);
842                 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
843                                  buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
844         }
845
846         /* copy format info */
847         buf->btformat = buf->fmt->btformat;
848         buf->btswap   = buf->fmt->btswap;
849         return 0;
850 }
851
852 /* ---------------------------------------------------------- */
853
854 /* calculate geometry, build risc code */
855 int
856 bttv_overlay_risc(struct bttv *btv,
857                   struct bttv_overlay *ov,
858                   const struct bttv_format *fmt,
859                   struct bttv_buffer *buf)
860 {
861         /* check interleave, bottom+top fields */
862         dprintk("%d: overlay fields: %s format: 0x%08x  size: %dx%d\n",
863                 btv->c.nr, v4l2_field_names[buf->vb.field],
864                 fmt->fourcc, ov->w.width, ov->w.height);
865
866         /* calculate geometry */
867         bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
868                       V4L2_FIELD_HAS_BOTH(ov->field),
869                       &bttv_tvnorms[ov->tvnorm],&buf->crop);
870
871         /* build risc code */
872         switch (ov->field) {
873         case V4L2_FIELD_TOP:
874                 bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 0);
875                 break;
876         case V4L2_FIELD_BOTTOM:
877                 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
878                 break;
879         case V4L2_FIELD_INTERLACED:
880                 bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 1);
881                 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
882                 break;
883         default:
884                 BUG();
885         }
886
887         /* copy format info */
888         buf->btformat = fmt->btformat;
889         buf->btswap   = fmt->btswap;
890         buf->vb.field = ov->field;
891         return 0;
892 }