blob: 82cc47d2e3fa0e840f00d1741c17da7e7c019638 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002
3 bttv-risc.c -- interfaces to other kernel modules
4
5 bttv risc code handling
6 - memory management
7 - generation
8
9 (c) 2000-2003 Gerd Knorr <kraxel@bytesex.org>
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
25*/
26
Joe Perches8af443e2011-08-21 19:56:48 -030027#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
28
Linus Torvalds1da177e2005-04-16 15:20:36 -070029#include <linux/module.h>
30#include <linux/init.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090031#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/pci.h>
33#include <linux/vmalloc.h>
34#include <linux/interrupt.h>
35#include <asm/page.h>
36#include <asm/pgtable.h>
Hans Verkuil35ea11f2008-07-20 08:12:02 -030037#include <media/v4l2-ioctl.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070038
39#include "bttvp.h"
40
41#define VCR_HACK_LINES 4
42
43/* ---------------------------------------------------------- */
44/* risc code generators */
45
46int
47bttv_risc_packed(struct bttv *btv, struct btcx_riscmem *risc,
48 struct scatterlist *sglist,
49 unsigned int offset, unsigned int bpl,
Michael Schimeke5bd0262007-01-18 16:17:39 -030050 unsigned int padding, unsigned int skip_lines,
51 unsigned int store_lines)
Linus Torvalds1da177e2005-04-16 15:20:36 -070052{
53 u32 instructions,line,todo;
54 struct scatterlist *sg;
Al Virod8eaa582008-05-21 00:31:51 -030055 __le32 *rp;
Linus Torvalds1da177e2005-04-16 15:20:36 -070056 int rc;
57
58 /* estimate risc mem: worst case is one write per page border +
Duncan Sands4a287cf2006-02-27 00:09:48 -030059 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 */
Michael Schimeke5bd0262007-01-18 16:17:39 -030062 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)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067 return rc;
68
69 /* sync instruction */
70 rp = risc->cpu;
71 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
72 *(rp++) = cpu_to_le32(0);
73
Michael Schimeke5bd0262007-01-18 16:17:39 -030074 while (skip_lines-- > 0) {
75 *(rp++) = cpu_to_le32(BT848_RISC_SKIP | BT848_RISC_SOL |
76 BT848_RISC_EOL | bpl);
77 }
78
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 /* scan lines */
80 sg = sglist;
Michael Schimeke5bd0262007-01-18 16:17:39 -030081 for (line = 0; line < store_lines; line++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 if ((btv->opt_vcr_hack) &&
Michael Schimeke5bd0262007-01-18 16:17:39 -030083 (line >= (store_lines - VCR_HACK_LINES)))
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 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 */
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -080091 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 BT848_RISC_EOL|bpl);
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -080093 *(rp++)=cpu_to_le32(sg_dma_address(sg)+offset);
94 offset+=bpl;
Linus Torvalds1da177e2005-04-16 15:20:36 -070095 } else {
96 /* scanline needs to be splitted */
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -080097 todo = bpl;
98 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_SOL|
Linus Torvalds1da177e2005-04-16 15:20:36 -070099 (sg_dma_len(sg)-offset));
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800100 *(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)) {
Mauro Carvalho Chehabf2421ca2005-11-08 21:37:45 -0800105 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106 sg_dma_len(sg));
Mauro Carvalho Chehabf2421ca2005-11-08 21:37:45 -0800107 *(rp++)=cpu_to_le32(sg_dma_address(sg));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 todo -= sg_dma_len(sg);
109 sg++;
110 }
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800111 *(rp++)=cpu_to_le32(BT848_RISC_WRITE|BT848_RISC_EOL|
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 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;
Duncan Sands4a287cf2006-02-27 00:09:48 -0300121 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700122 return 0;
123}
124
125static int
126bttv_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;
Al Virod8eaa582008-05-21 00:31:51 -0300135 __le32 *rp;
136 u32 ri;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700137 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) */
Michael Schimeke5bd0262007-01-18 16:17:39 -0300146 instructions = ((3 + (ybpl + ypadding) * ylines * 2)
147 / PAGE_SIZE) + ylines;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700148 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;
154 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM3);
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 {
212 ri = BT848_RISC_WRITE1S23;
213 }
214 if (ybpl == todo)
215 ri |= BT848_RISC_SOL;
216 if (ylen == todo)
217 ri |= BT848_RISC_EOL;
218
219 /* write risc instruction */
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800220 *(rp++)=cpu_to_le32(ri | ylen);
221 *(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
Linus Torvalds1da177e2005-04-16 15:20:36 -0700222 (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;
Duncan Sands4a287cf2006-02-27 00:09:48 -0300241 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242 return 0;
243}
244
245static int
246bttv_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{
Hans Verkuilc6eb8ea2008-09-03 17:11:54 -0300250 int dwords, rc, line, maxy, start, end;
251 unsigned skip, nskips;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 struct btcx_skiplist *skips;
Al Virod8eaa582008-05-21 00:31:51 -0300253 __le32 *rp;
254 u32 ri,ra;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 u32 addr;
256
257 /* skip list for window clipping */
258 if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
259 return -ENOMEM;
260
Duncan Sands3203f942006-04-02 04:14:57 -0300261 /* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
Linus Torvalds1da177e2005-04-16 15:20:36 -0700262 + sync + jump (all 2 dwords) */
Duncan Sands3203f942006-04-02 04:14:57 -0300263 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) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267 kfree(skips);
268 return rc;
269 }
270
271 /* sync instruction */
272 rp = risc->cpu;
273 *(rp++) = cpu_to_le32(BT848_RISC_SYNC|BT848_FIFO_STATUS_FM1);
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;
Duncan Sands4a287cf2006-02-27 00:09:48 -0300328 BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329 kfree(skips);
330 return 0;
331}
332
333/* ---------------------------------------------------------- */
334
335static void
Michael Schimeke5bd0262007-01-18 16:17:39 -0300336bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
337 int width, int height, int interleaved,
338 const struct bttv_tvnorm *tvnorm)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700339{
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800340 u32 xsf, sr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 int vdelay;
342
343 int swidth = tvnorm->swidth;
344 int totalwidth = tvnorm->totalwidth;
345 int scaledtwidth = tvnorm->scaledtwidth;
346
Trent Piepho5221e212009-01-28 21:32:59 -0300347 if (btv->input == btv->dig) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700348 swidth = 720;
349 totalwidth = 858;
350 scaledtwidth = 858;
351 }
352
353 vdelay = tvnorm->vdelay;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700354
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800355 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;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368 geo->vtotal = tvnorm->vtotal;
369
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800370 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 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377}
378
379static void
Michael Schimeke5bd0262007-01-18 16:17:39 -0300380bttv_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 */)
Trent Piepho5221e212009-01-28 21:32:59 -0300397 || btv->input == btv->dig) {
Michael Schimeke5bd0262007-01-18 16:17:39 -0300398 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
435static void
Linus Torvalds1da177e2005-04-16 15:20:36 -0700436bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
437{
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800438 int off = odd ? 0x80 : 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439
440 if (geo->comb)
441 btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
442 else
443 btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
444
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800445 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);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 btwrite(geo->vtotal>>8, BT848_VTOTAL_HI);
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800456 btwrite(geo->vtotal & 0xff, BT848_VTOTAL_LO);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457}
458
459/* ---------------------------------------------------------- */
460/* risc group / risc main loop / dma management */
461
462void
463bttv_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
Joe Perches8af443e2011-08-21 19:56:48 -0300478 d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700479 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 }
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800496 btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700497
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);
503 btor(3, BT848_GPIO_DMA_CTL);
504 btv->dma_on = 1;
505 } else {
506 if (!btv->dma_on)
507 return;
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800508 btand(~3, BT848_GPIO_DMA_CTL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700509 btv->dma_on = 0;
510 }
511 return;
512}
513
514int
515bttv_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;
Joe Perches8af443e2011-08-21 19:56:48 -0300521 dprintk("%d: risc main @ %08llx\n",
522 btv->c.nr, (unsigned long long)btv->main.dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523
524 btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
525 BT848_FIFO_STATUS_VRE);
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
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800536 btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 BT848_FIFO_STATUS_VRO);
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800538 btv->main.cpu[9] = cpu_to_le32(0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539
540 /* bottom field */
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800541 btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800543 btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700544 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);
Mauro Carvalho Chehab4ac97912005-11-08 21:37:43 -0800548 btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700549
550 return 0;
551}
552
553int
554bttv_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) {
Joe Perches8af443e2011-08-21 19:56:48 -0300561 d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 btv->main.cpu[slot+1] = cpu_to_le32(next);
563 } else {
Joe Perches8af443e2011-08-21 19:56:48 -0300564 d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n",
565 btv->c.nr, risc, slot,
566 (unsigned long long)risc->dma, irqflags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 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
580void
Mauro Carvalho Chehabc7b0ac02006-03-10 12:29:15 -0300581bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700582{
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300583 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
584
Eric Sesterhennae246012006-03-13 13:17:11 -0300585 BUG_ON(in_interrupt());
Hans Verkuil0e0809a2010-09-26 09:01:26 -0300586 videobuf_waiton(q, &buf->vb, 0, 0);
Laurent Pinchart95268402010-05-11 10:36:30 -0300587 videobuf_dma_unmap(q->dev, dma);
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300588 videobuf_dma_free(dma);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 btcx_riscmem_free(btv->c.pci,&buf->bottom);
590 btcx_riscmem_free(btv->c.pci,&buf->top);
Brandon Philips0fc06862007-11-06 20:02:36 -0300591 buf->vb.state = VIDEOBUF_NEEDS_INIT;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700592}
593
594int
595bttv_buffer_activate_vbi(struct bttv *btv,
596 struct bttv_buffer *vbi)
597{
Michael Schimeke5bd0262007-01-18 16:17:39 -0300598 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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 if (vbi) {
Michael Schimeke5bd0262007-01-18 16:17:39 -0300609 unsigned int crop, vdelay;
610
Brandon Philips0fc06862007-11-06 20:02:36 -0300611 vbi->vb.state = VIDEOBUF_ACTIVE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612 list_del(&vbi->vb.queue);
Michael Schimeke5bd0262007-01-18 16:17:39 -0300613
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 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700638 }
Michael Schimeke5bd0262007-01-18 16:17:39 -0300639
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
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643 return 0;
644}
645
646int
647bttv_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) {
Brandon Philips0fc06862007-11-06 20:02:36 -0300653 set->top->vb.state = VIDEOBUF_ACTIVE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 if (set->top->vb.queue.next)
655 list_del(&set->top->vb.queue);
656 } else {
Brandon Philips0fc06862007-11-06 20:02:36 -0300657 set->top->vb.state = VIDEOBUF_ACTIVE;
658 set->bottom->vb.state = VIDEOBUF_ACTIVE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700659 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) {
Brandon Philips0fc06862007-11-06 20:02:36 -0300675 set->top->vb.state = VIDEOBUF_ACTIVE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676 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) {
Brandon Philips0fc06862007-11-06 20:02:36 -0300686 set->bottom->vb.state = VIDEOBUF_ACTIVE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700687 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 */
706int
707bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
708{
709 const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300710 struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711
Joe Perches8af443e2011-08-21 19:56:48 -0300712 dprintk("%d: buffer field: %s format: %s size: %dx%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713 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,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300722 V4L2_FIELD_HAS_BOTH(buf->vb.field),
723 tvnorm,&buf->crop);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724
725 switch (buf->vb.field) {
726 case V4L2_FIELD_TOP:
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300727 bttv_risc_packed(btv,&buf->top,dma->sglist,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300728 /* offset */ 0,bpl,
729 /* padding */ 0,/* skip_lines */ 0,
730 buf->vb.height);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700731 break;
732 case V4L2_FIELD_BOTTOM:
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300733 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300734 0,bpl,0,0,buf->vb.height);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735 break;
736 case V4L2_FIELD_INTERLACED:
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300737 bttv_risc_packed(btv,&buf->top,dma->sglist,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300738 0,bpl,bpl,0,buf->vb.height >> 1);
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300739 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300740 bpl,bpl,bpl,0,buf->vb.height >> 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700741 break;
742 case V4L2_FIELD_SEQ_TB:
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300743 bttv_risc_packed(btv,&buf->top,dma->sglist,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300744 0,bpl,0,0,buf->vb.height >> 1);
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300745 bttv_risc_packed(btv,&buf->bottom,dma->sglist,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300746 bpf,bpl,0,0,buf->vb.height >> 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747 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,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300776 buf->vb.height,/* both_fields */ 0,
777 tvnorm,&buf->crop);
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300778 bttv_risc_planar(btv, &buf->top, dma->sglist,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779 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,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300785 buf->vb.height,0,
786 tvnorm,&buf->crop);
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300787 bttv_risc_planar(btv, &buf->bottom, dma->sglist,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700788 0,buf->vb.width,0,buf->vb.height,
789 uoffset,voffset,buf->fmt->hshift,
790 buf->fmt->vshift,0);
791 break;
792 case V4L2_FIELD_INTERLACED:
793 bttv_calc_geo(btv,&buf->geo,buf->vb.width,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300794 buf->vb.height,1,
795 tvnorm,&buf->crop);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 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,
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300800 dma->sglist,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801 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,
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300807 dma->sglist,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808 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,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300817 buf->vb.height,1,
818 tvnorm,&buf->crop);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 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,
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300823 dma->sglist,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700824 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,
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300831 dma->sglist,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700832 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,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300849 1,tvnorm,&buf->crop);
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300850 bttv_risc_packed(btv, &buf->top, dma->sglist,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300851 /* offset */ 0, RAW_BPL, /* padding */ 0,
852 /* skip_lines */ 0, RAW_LINES);
Mauro Carvalho Chehabc1accaa2007-08-23 16:37:49 -0300853 bttv_risc_packed(btv, &buf->bottom, dma->sglist,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300854 buf->vb.size/2 , RAW_BPL, 0, 0, RAW_LINES);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 }
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 */
866int
867bttv_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 */
Joe Perches8af443e2011-08-21 19:56:48 -0300873 dprintk("%d: overlay fields: %s format: %s size: %dx%d\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 btv->c.nr, v4l2_field_names[buf->vb.field],
Joe Perches8af443e2011-08-21 19:56:48 -0300875 fmt->name, ov->w.width, ov->w.height);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700876
877 /* calculate geometry */
878 bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
Michael Schimeke5bd0262007-01-18 16:17:39 -0300879 V4L2_FIELD_HAS_BOTH(ov->field),
880 &bttv_tvnorms[ov->tvnorm],&buf->crop);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881
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;
890 case V4L2_FIELD_INTERLACED:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891 bttv_risc_overlay(btv, &buf->top, fmt, ov, 0, 1);
892 bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 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 */