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