Linux-libre 5.4.49-gnu
[librecmc/linux-libre.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 <asm/page.h>
24 #include <asm/pgtable.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         BUG_ON(in_interrupt());
576         videobuf_waiton(q, &buf->vb, 0, 0);
577         videobuf_dma_unmap(q->dev, dma);
578         videobuf_dma_free(dma);
579         btcx_riscmem_free(btv->c.pci,&buf->bottom);
580         btcx_riscmem_free(btv->c.pci,&buf->top);
581         buf->vb.state = VIDEOBUF_NEEDS_INIT;
582 }
583
584 int
585 bttv_buffer_activate_vbi(struct bttv *btv,
586                          struct bttv_buffer *vbi)
587 {
588         struct btcx_riscmem *top;
589         struct btcx_riscmem *bottom;
590         int top_irq_flags;
591         int bottom_irq_flags;
592
593         top = NULL;
594         bottom = NULL;
595         top_irq_flags = 0;
596         bottom_irq_flags = 0;
597
598         if (vbi) {
599                 unsigned int crop, vdelay;
600
601                 vbi->vb.state = VIDEOBUF_ACTIVE;
602                 list_del(&vbi->vb.queue);
603
604                 /* VDELAY is start of video, end of VBI capturing. */
605                 crop = btread(BT848_E_CROP);
606                 vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
607
608                 if (vbi->geo.vdelay > vdelay) {
609                         vdelay = vbi->geo.vdelay & 0xfe;
610                         crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
611
612                         btwrite(vdelay, BT848_E_VDELAY_LO);
613                         btwrite(crop,   BT848_E_CROP);
614                         btwrite(vdelay, BT848_O_VDELAY_LO);
615                         btwrite(crop,   BT848_O_CROP);
616                 }
617
618                 if (vbi->vbi_count[0] > 0) {
619                         top = &vbi->top;
620                         top_irq_flags = 4;
621                 }
622
623                 if (vbi->vbi_count[1] > 0) {
624                         top_irq_flags = 0;
625                         bottom = &vbi->bottom;
626                         bottom_irq_flags = 4;
627                 }
628         }
629
630         bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
631         bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
632
633         return 0;
634 }
635
636 int
637 bttv_buffer_activate_video(struct bttv *btv,
638                            struct bttv_buffer_set *set)
639 {
640         /* video capture */
641         if (NULL != set->top  &&  NULL != set->bottom) {
642                 if (set->top == set->bottom) {
643                         set->top->vb.state    = VIDEOBUF_ACTIVE;
644                         if (set->top->vb.queue.next)
645                                 list_del(&set->top->vb.queue);
646                 } else {
647                         set->top->vb.state    = VIDEOBUF_ACTIVE;
648                         set->bottom->vb.state = VIDEOBUF_ACTIVE;
649                         if (set->top->vb.queue.next)
650                                 list_del(&set->top->vb.queue);
651                         if (set->bottom->vb.queue.next)
652                                 list_del(&set->bottom->vb.queue);
653                 }
654                 bttv_apply_geo(btv, &set->top->geo, 1);
655                 bttv_apply_geo(btv, &set->bottom->geo,0);
656                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
657                                set->top_irq);
658                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
659                                set->frame_irq);
660                 btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
661                       ~0xff, BT848_COLOR_FMT);
662                 btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
663                       ~0x0f, BT848_COLOR_CTL);
664         } else if (NULL != set->top) {
665                 set->top->vb.state  = VIDEOBUF_ACTIVE;
666                 if (set->top->vb.queue.next)
667                         list_del(&set->top->vb.queue);
668                 bttv_apply_geo(btv, &set->top->geo,1);
669                 bttv_apply_geo(btv, &set->top->geo,0);
670                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
671                                set->frame_irq);
672                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL,           0);
673                 btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
674                 btaor(set->top->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
675         } else if (NULL != set->bottom) {
676                 set->bottom->vb.state = VIDEOBUF_ACTIVE;
677                 if (set->bottom->vb.queue.next)
678                         list_del(&set->bottom->vb.queue);
679                 bttv_apply_geo(btv, &set->bottom->geo,1);
680                 bttv_apply_geo(btv, &set->bottom->geo,0);
681                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
682                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
683                                set->frame_irq);
684                 btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
685                 btaor(set->bottom->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
686         } else {
687                 bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
688                 bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
689         }
690         return 0;
691 }
692
693 /* ---------------------------------------------------------- */
694
695 /* calculate geometry, build risc code */
696 int
697 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
698 {
699         const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
700         struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
701
702         dprintk("%d: buffer field: %s  format: 0x%08x  size: %dx%d\n",
703                 btv->c.nr, v4l2_field_names[buf->vb.field],
704                 buf->fmt->fourcc, buf->vb.width, buf->vb.height);
705
706         /* packed pixel modes */
707         if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
708                 int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
709                 int bpf = bpl * (buf->vb.height >> 1);
710
711                 bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
712                               V4L2_FIELD_HAS_BOTH(buf->vb.field),
713                               tvnorm,&buf->crop);
714
715                 switch (buf->vb.field) {
716                 case V4L2_FIELD_TOP:
717                         bttv_risc_packed(btv,&buf->top,dma->sglist,
718                                          /* offset */ 0,bpl,
719                                          /* padding */ 0,/* skip_lines */ 0,
720                                          buf->vb.height);
721                         break;
722                 case V4L2_FIELD_BOTTOM:
723                         bttv_risc_packed(btv,&buf->bottom,dma->sglist,
724                                          0,bpl,0,0,buf->vb.height);
725                         break;
726                 case V4L2_FIELD_INTERLACED:
727                         bttv_risc_packed(btv,&buf->top,dma->sglist,
728                                          0,bpl,bpl,0,buf->vb.height >> 1);
729                         bttv_risc_packed(btv,&buf->bottom,dma->sglist,
730                                          bpl,bpl,bpl,0,buf->vb.height >> 1);
731                         break;
732                 case V4L2_FIELD_SEQ_TB:
733                         bttv_risc_packed(btv,&buf->top,dma->sglist,
734                                          0,bpl,0,0,buf->vb.height >> 1);
735                         bttv_risc_packed(btv,&buf->bottom,dma->sglist,
736                                          bpf,bpl,0,0,buf->vb.height >> 1);
737                         break;
738                 default:
739                         BUG();
740                 }
741         }
742
743         /* planar modes */
744         if (buf->fmt->flags & FORMAT_FLAGS_PLANAR) {
745                 int uoffset, voffset;
746                 int ypadding, cpadding, lines;
747
748                 /* calculate chroma offsets */
749                 uoffset = buf->vb.width * buf->vb.height;
750                 voffset = buf->vb.width * buf->vb.height;
751                 if (buf->fmt->flags & FORMAT_FLAGS_CrCb) {
752                         /* Y-Cr-Cb plane order */
753                         uoffset >>= buf->fmt->hshift;
754                         uoffset >>= buf->fmt->vshift;
755                         uoffset  += voffset;
756                 } else {
757                         /* Y-Cb-Cr plane order */
758                         voffset >>= buf->fmt->hshift;
759                         voffset >>= buf->fmt->vshift;
760                         voffset  += uoffset;
761                 }
762
763                 switch (buf->vb.field) {
764                 case V4L2_FIELD_TOP:
765                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
766                                       buf->vb.height,/* both_fields */ 0,
767                                       tvnorm,&buf->crop);
768                         bttv_risc_planar(btv, &buf->top, dma->sglist,
769                                          0,buf->vb.width,0,buf->vb.height,
770                                          uoffset,voffset,buf->fmt->hshift,
771                                          buf->fmt->vshift,0);
772                         break;
773                 case V4L2_FIELD_BOTTOM:
774                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
775                                       buf->vb.height,0,
776                                       tvnorm,&buf->crop);
777                         bttv_risc_planar(btv, &buf->bottom, dma->sglist,
778                                          0,buf->vb.width,0,buf->vb.height,
779                                          uoffset,voffset,buf->fmt->hshift,
780                                          buf->fmt->vshift,0);
781                         break;
782                 case V4L2_FIELD_INTERLACED:
783                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
784                                       buf->vb.height,1,
785                                       tvnorm,&buf->crop);
786                         lines    = buf->vb.height >> 1;
787                         ypadding = buf->vb.width;
788                         cpadding = buf->vb.width >> buf->fmt->hshift;
789                         bttv_risc_planar(btv,&buf->top,
790                                          dma->sglist,
791                                          0,buf->vb.width,ypadding,lines,
792                                          uoffset,voffset,
793                                          buf->fmt->hshift,
794                                          buf->fmt->vshift,
795                                          cpadding);
796                         bttv_risc_planar(btv,&buf->bottom,
797                                          dma->sglist,
798                                          ypadding,buf->vb.width,ypadding,lines,
799                                          uoffset+cpadding,
800                                          voffset+cpadding,
801                                          buf->fmt->hshift,
802                                          buf->fmt->vshift,
803                                          cpadding);
804                         break;
805                 case V4L2_FIELD_SEQ_TB:
806                         bttv_calc_geo(btv,&buf->geo,buf->vb.width,
807                                       buf->vb.height,1,
808                                       tvnorm,&buf->crop);
809                         lines    = buf->vb.height >> 1;
810                         ypadding = buf->vb.width;
811                         cpadding = buf->vb.width >> buf->fmt->hshift;
812                         bttv_risc_planar(btv,&buf->top,
813                                          dma->sglist,
814                                          0,buf->vb.width,0,lines,
815                                          uoffset >> 1,
816                                          voffset >> 1,
817                                          buf->fmt->hshift,
818                                          buf->fmt->vshift,
819                                          0);
820                         bttv_risc_planar(btv,&buf->bottom,
821                                          dma->sglist,
822                                          lines * ypadding,buf->vb.width,0,lines,
823                                          lines * ypadding + (uoffset >> 1),
824                                          lines * ypadding + (voffset >> 1),
825                                          buf->fmt->hshift,
826                                          buf->fmt->vshift,
827                                          0);
828                         break;
829                 default:
830                         BUG();
831                 }
832         }
833
834         /* raw data */
835         if (buf->fmt->flags & FORMAT_FLAGS_RAW) {
836                 /* build risc code */
837                 buf->vb.field = V4L2_FIELD_SEQ_TB;
838                 bttv_calc_geo(btv,&buf->geo,tvnorm->swidth,tvnorm->sheight,
839                               1,tvnorm,&buf->crop);
840                 bttv_risc_packed(btv, &buf->top,  dma->sglist,
841                                  /* offset */ 0, RAW_BPL, /* padding */ 0,
842                                  /* skip_lines */ 0, RAW_LINES);
843                 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
844                                  buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
845         }
846
847         /* copy format info */
848         buf->btformat = buf->fmt->btformat;
849         buf->btswap   = buf->fmt->btswap;
850         return 0;
851 }
852
853 /* ---------------------------------------------------------- */
854
855 /* calculate geometry, build risc code */
856 int
857 bttv_overlay_risc(struct bttv *btv,
858                   struct bttv_overlay *ov,
859                   const struct bttv_format *fmt,
860                   struct bttv_buffer *buf)
861 {
862         /* check interleave, bottom+top fields */
863         dprintk("%d: overlay fields: %s format: 0x%08x  size: %dx%d\n",
864                 btv->c.nr, v4l2_field_names[buf->vb.field],
865                 fmt->fourcc, ov->w.width, ov->w.height);
866
867         /* calculate geometry */
868         bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
869                       V4L2_FIELD_HAS_BOTH(ov->field),
870                       &bttv_tvnorms[ov->tvnorm],&buf->crop);
871
872         /* build risc code */
873         switch (ov->field) {
874         case V4L2_FIELD_TOP:
875                 bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 0);
876                 break;
877         case V4L2_FIELD_BOTTOM:
878                 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
879                 break;
880         case V4L2_FIELD_INTERLACED:
881                 bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 1);
882                 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
883                 break;
884         default:
885                 BUG();
886         }
887
888         /* copy format info */
889         buf->btformat = fmt->btformat;
890         buf->btswap   = fmt->btswap;
891         buf->vb.field = ov->field;
892         return 0;
893 }