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