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