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