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
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)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++;
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++;
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++;
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
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)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++;
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 */
220 			*(rp++)=cpu_to_le32(ri | ylen);
221 			*(rp++)=cpu_to_le32(((ylen >> hshift) << 16) |
222 					    (ylen >> hshift));
223 			*(rp++)=cpu_to_le32(sg_dma_address(ysg)+yoffset);
224 			yoffset += ylen;
225 			if (chroma) {
226 				*(rp++)=cpu_to_le32(sg_dma_address(usg)+uoffset);
227 				uoffset += ylen >> hshift;
228 				*(rp++)=cpu_to_le32(sg_dma_address(vsg)+voffset);
229 				voffset += ylen >> hshift;
230 			}
231 		}
232 		yoffset += ypadding;
233 		if (chroma) {
234 			uoffset += cpadding;
235 			voffset += cpadding;
236 		}
237 	}
238 
239 	/* save pointer to jmp instruction address */
240 	risc->jmp = rp;
241 	BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
242 	return 0;
243 }
244 
245 static int
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)246 bttv_risc_overlay(struct bttv *btv, struct btcx_riscmem *risc,
247 		  const struct bttv_format *fmt, struct bttv_overlay *ov,
248 		  int skip_even, int skip_odd)
249 {
250 	int dwords, rc, line, maxy, start, end;
251 	unsigned skip, nskips;
252 	struct btcx_skiplist *skips;
253 	__le32 *rp;
254 	u32 ri,ra;
255 	u32 addr;
256 
257 	/* skip list for window clipping */
258 	if (NULL == (skips = kmalloc(sizeof(*skips) * ov->nclips,GFP_KERNEL)))
259 		return -ENOMEM;
260 
261 	/* estimate risc mem: worst case is (1.5*clip+1) * lines instructions
262 	   + sync + jump (all 2 dwords) */
263 	dwords  = (3 * ov->nclips + 2) *
264 		((skip_even || skip_odd) ? (ov->w.height+1)>>1 :  ov->w.height);
265 	dwords += 4;
266 	if ((rc = btcx_riscmem_alloc(btv->c.pci,risc,dwords*4)) < 0) {
267 		kfree(skips);
268 		return rc;
269 	}
270 
271 	/* sync instruction */
272 	rp = risc->cpu;
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;
328 	BUG_ON((risc->jmp - risc->cpu + 2) * sizeof(*risc->cpu) > risc->size);
329 	kfree(skips);
330 	return 0;
331 }
332 
333 /* ---------------------------------------------------------- */
334 
335 static void
bttv_calc_geo_old(struct bttv * btv,struct bttv_geometry * geo,int width,int height,int interleaved,const struct bttv_tvnorm * tvnorm)336 bttv_calc_geo_old(struct bttv *btv, struct bttv_geometry *geo,
337 		  int width, int height, int interleaved,
338 		  const struct bttv_tvnorm *tvnorm)
339 {
340 	u32 xsf, sr;
341 	int vdelay;
342 
343 	int swidth       = tvnorm->swidth;
344 	int totalwidth   = tvnorm->totalwidth;
345 	int scaledtwidth = tvnorm->scaledtwidth;
346 
347 	if (btv->input == btv->dig) {
348 		swidth       = 720;
349 		totalwidth   = 858;
350 		scaledtwidth = 858;
351 	}
352 
353 	vdelay = tvnorm->vdelay;
354 
355 	xsf = (width*scaledtwidth)/swidth;
356 	geo->hscale =  ((totalwidth*4096UL)/xsf-4096);
357 	geo->hdelay =  tvnorm->hdelayx1;
358 	geo->hdelay =  (geo->hdelay*width)/swidth;
359 	geo->hdelay &= 0x3fe;
360 	sr = ((tvnorm->sheight >> (interleaved?0:1))*512)/height - 512;
361 	geo->vscale =  (0x10000UL-sr) & 0x1fff;
362 	geo->crop   =  ((width>>8)&0x03) | ((geo->hdelay>>6)&0x0c) |
363 		((tvnorm->sheight>>4)&0x30) | ((vdelay>>2)&0xc0);
364 	geo->vscale |= interleaved ? (BT848_VSCALE_INT<<8) : 0;
365 	geo->vdelay  =  vdelay;
366 	geo->width   =  width;
367 	geo->sheight =  tvnorm->sheight;
368 	geo->vtotal  =  tvnorm->vtotal;
369 
370 	if (btv->opt_combfilter) {
371 		geo->vtc  = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
372 		geo->comb = (width < 769) ? 1 : 0;
373 	} else {
374 		geo->vtc  = 0;
375 		geo->comb = 0;
376 	}
377 }
378 
379 static void
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)380 bttv_calc_geo		(struct bttv *                  btv,
381 			 struct bttv_geometry *         geo,
382 			 unsigned int                   width,
383 			 unsigned int                   height,
384 			 int                            both_fields,
385 			 const struct bttv_tvnorm *     tvnorm,
386 			 const struct v4l2_rect *       crop)
387 {
388 	unsigned int c_width;
389 	unsigned int c_height;
390 	u32 sr;
391 
392 	if ((crop->left == tvnorm->cropcap.defrect.left
393 	     && crop->top == tvnorm->cropcap.defrect.top
394 	     && crop->width == tvnorm->cropcap.defrect.width
395 	     && crop->height == tvnorm->cropcap.defrect.height
396 	     && width <= tvnorm->swidth /* see PAL-Nc et al */)
397 	    || btv->input == btv->dig) {
398 		bttv_calc_geo_old(btv, geo, width, height,
399 				  both_fields, tvnorm);
400 		return;
401 	}
402 
403 	/* For bug compatibility the image size checks permit scale
404 	   factors > 16. See bttv_crop_calc_limits(). */
405 	c_width = min((unsigned int) crop->width, width * 16);
406 	c_height = min((unsigned int) crop->height, height * 16);
407 
408 	geo->width = width;
409 	geo->hscale = (c_width * 4096U + (width >> 1)) / width - 4096;
410 	/* Even to store Cb first, odd for Cr. */
411 	geo->hdelay = ((crop->left * width + c_width) / c_width) & ~1;
412 
413 	geo->sheight = c_height;
414 	geo->vdelay = crop->top - tvnorm->cropcap.bounds.top + MIN_VDELAY;
415 	sr = c_height >> !both_fields;
416 	sr = (sr * 512U + (height >> 1)) / height - 512;
417 	geo->vscale = (0x10000UL - sr) & 0x1fff;
418 	geo->vscale |= both_fields ? (BT848_VSCALE_INT << 8) : 0;
419 	geo->vtotal = tvnorm->vtotal;
420 
421 	geo->crop = (((geo->width   >> 8) & 0x03) |
422 		     ((geo->hdelay  >> 6) & 0x0c) |
423 		     ((geo->sheight >> 4) & 0x30) |
424 		     ((geo->vdelay  >> 2) & 0xc0));
425 
426 	if (btv->opt_combfilter) {
427 		geo->vtc  = (width < 193) ? 2 : ((width < 385) ? 1 : 0);
428 		geo->comb = (width < 769) ? 1 : 0;
429 	} else {
430 		geo->vtc  = 0;
431 		geo->comb = 0;
432 	}
433 }
434 
435 static void
bttv_apply_geo(struct bttv * btv,struct bttv_geometry * geo,int odd)436 bttv_apply_geo(struct bttv *btv, struct bttv_geometry *geo, int odd)
437 {
438 	int off = odd ? 0x80 : 0x00;
439 
440 	if (geo->comb)
441 		btor(BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
442 	else
443 		btand(~BT848_VSCALE_COMB, BT848_E_VSCALE_HI+off);
444 
445 	btwrite(geo->vtc,             BT848_E_VTC+off);
446 	btwrite(geo->hscale >> 8,     BT848_E_HSCALE_HI+off);
447 	btwrite(geo->hscale & 0xff,   BT848_E_HSCALE_LO+off);
448 	btaor((geo->vscale>>8), 0xe0, BT848_E_VSCALE_HI+off);
449 	btwrite(geo->vscale & 0xff,   BT848_E_VSCALE_LO+off);
450 	btwrite(geo->width & 0xff,    BT848_E_HACTIVE_LO+off);
451 	btwrite(geo->hdelay & 0xff,   BT848_E_HDELAY_LO+off);
452 	btwrite(geo->sheight & 0xff,  BT848_E_VACTIVE_LO+off);
453 	btwrite(geo->vdelay & 0xff,   BT848_E_VDELAY_LO+off);
454 	btwrite(geo->crop,            BT848_E_CROP+off);
455 	btwrite(geo->vtotal>>8,       BT848_VTOTAL_HI);
456 	btwrite(geo->vtotal & 0xff,   BT848_VTOTAL_LO);
457 }
458 
459 /* ---------------------------------------------------------- */
460 /* risc group / risc main loop / dma management               */
461 
462 void
bttv_set_dma(struct bttv * btv,int override)463 bttv_set_dma(struct bttv *btv, int override)
464 {
465 	unsigned long cmd;
466 	int capctl;
467 
468 	btv->cap_ctl = 0;
469 	if (NULL != btv->curr.top)      btv->cap_ctl |= 0x02;
470 	if (NULL != btv->curr.bottom)   btv->cap_ctl |= 0x01;
471 	if (NULL != btv->cvbi)          btv->cap_ctl |= 0x0c;
472 
473 	capctl  = 0;
474 	capctl |= (btv->cap_ctl & 0x03) ? 0x03 : 0x00;  /* capture  */
475 	capctl |= (btv->cap_ctl & 0x0c) ? 0x0c : 0x00;  /* vbi data */
476 	capctl |= override;
477 
478 	d2printk("%d: capctl=%x lirq=%d top=%08llx/%08llx even=%08llx/%08llx\n",
479 		 btv->c.nr,capctl,btv->loop_irq,
480 		 btv->cvbi         ? (unsigned long long)btv->cvbi->top.dma            : 0,
481 		 btv->curr.top     ? (unsigned long long)btv->curr.top->top.dma        : 0,
482 		 btv->cvbi         ? (unsigned long long)btv->cvbi->bottom.dma         : 0,
483 		 btv->curr.bottom  ? (unsigned long long)btv->curr.bottom->bottom.dma  : 0);
484 
485 	cmd = BT848_RISC_JUMP;
486 	if (btv->loop_irq) {
487 		cmd |= BT848_RISC_IRQ;
488 		cmd |= (btv->loop_irq  & 0x0f) << 16;
489 		cmd |= (~btv->loop_irq & 0x0f) << 20;
490 	}
491 	if (btv->curr.frame_irq || btv->loop_irq || btv->cvbi) {
492 		mod_timer(&btv->timeout, jiffies+BTTV_TIMEOUT);
493 	} else {
494 		del_timer(&btv->timeout);
495 	}
496 	btv->main.cpu[RISC_SLOT_LOOP] = cpu_to_le32(cmd);
497 
498 	btaor(capctl, ~0x0f, BT848_CAP_CTL);
499 	if (capctl) {
500 		if (btv->dma_on)
501 			return;
502 		btwrite(btv->main.dma, BT848_RISC_STRT_ADD);
503 		btor(3, BT848_GPIO_DMA_CTL);
504 		btv->dma_on = 1;
505 	} else {
506 		if (!btv->dma_on)
507 			return;
508 		btand(~3, BT848_GPIO_DMA_CTL);
509 		btv->dma_on = 0;
510 	}
511 	return;
512 }
513 
514 int
bttv_risc_init_main(struct bttv * btv)515 bttv_risc_init_main(struct bttv *btv)
516 {
517 	int rc;
518 
519 	if ((rc = btcx_riscmem_alloc(btv->c.pci,&btv->main,PAGE_SIZE)) < 0)
520 		return rc;
521 	dprintk("%d: risc main @ %08llx\n",
522 		btv->c.nr, (unsigned long long)btv->main.dma);
523 
524 	btv->main.cpu[0] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
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 
536 	btv->main.cpu[8] = cpu_to_le32(BT848_RISC_SYNC | BT848_RISC_RESYNC |
537 				       BT848_FIFO_STATUS_VRO);
538 	btv->main.cpu[9] = cpu_to_le32(0);
539 
540 	/* bottom field */
541 	btv->main.cpu[10] = cpu_to_le32(BT848_RISC_JUMP);
542 	btv->main.cpu[11] = cpu_to_le32(btv->main.dma + (12<<2));
543 	btv->main.cpu[12] = cpu_to_le32(BT848_RISC_JUMP);
544 	btv->main.cpu[13] = cpu_to_le32(btv->main.dma + (14<<2));
545 
546 	/* jump back to top field */
547 	btv->main.cpu[14] = cpu_to_le32(BT848_RISC_JUMP);
548 	btv->main.cpu[15] = cpu_to_le32(btv->main.dma + (0<<2));
549 
550 	return 0;
551 }
552 
553 int
bttv_risc_hook(struct bttv * btv,int slot,struct btcx_riscmem * risc,int irqflags)554 bttv_risc_hook(struct bttv *btv, int slot, struct btcx_riscmem *risc,
555 	       int irqflags)
556 {
557 	unsigned long cmd;
558 	unsigned long next = btv->main.dma + ((slot+2) << 2);
559 
560 	if (NULL == risc) {
561 		d2printk("%d: risc=%p slot[%d]=NULL\n", btv->c.nr, risc, slot);
562 		btv->main.cpu[slot+1] = cpu_to_le32(next);
563 	} else {
564 		d2printk("%d: risc=%p slot[%d]=%08llx irq=%d\n",
565 			 btv->c.nr, risc, slot,
566 			 (unsigned long long)risc->dma, irqflags);
567 		cmd = BT848_RISC_JUMP;
568 		if (irqflags) {
569 			cmd |= BT848_RISC_IRQ;
570 			cmd |= (irqflags  & 0x0f) << 16;
571 			cmd |= (~irqflags & 0x0f) << 20;
572 		}
573 		risc->jmp[0] = cpu_to_le32(cmd);
574 		risc->jmp[1] = cpu_to_le32(next);
575 		btv->main.cpu[slot+1] = cpu_to_le32(risc->dma);
576 	}
577 	return 0;
578 }
579 
580 void
bttv_dma_free(struct videobuf_queue * q,struct bttv * btv,struct bttv_buffer * buf)581 bttv_dma_free(struct videobuf_queue *q,struct bttv *btv, struct bttv_buffer *buf)
582 {
583 	struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
584 
585 	BUG_ON(in_interrupt());
586 	videobuf_waiton(q, &buf->vb, 0, 0);
587 	videobuf_dma_unmap(q->dev, dma);
588 	videobuf_dma_free(dma);
589 	btcx_riscmem_free(btv->c.pci,&buf->bottom);
590 	btcx_riscmem_free(btv->c.pci,&buf->top);
591 	buf->vb.state = VIDEOBUF_NEEDS_INIT;
592 }
593 
594 int
bttv_buffer_activate_vbi(struct bttv * btv,struct bttv_buffer * vbi)595 bttv_buffer_activate_vbi(struct bttv *btv,
596 			 struct bttv_buffer *vbi)
597 {
598 	struct btcx_riscmem *top;
599 	struct btcx_riscmem *bottom;
600 	int top_irq_flags;
601 	int bottom_irq_flags;
602 
603 	top = NULL;
604 	bottom = NULL;
605 	top_irq_flags = 0;
606 	bottom_irq_flags = 0;
607 
608 	if (vbi) {
609 		unsigned int crop, vdelay;
610 
611 		vbi->vb.state = VIDEOBUF_ACTIVE;
612 		list_del(&vbi->vb.queue);
613 
614 		/* VDELAY is start of video, end of VBI capturing. */
615 		crop = btread(BT848_E_CROP);
616 		vdelay = btread(BT848_E_VDELAY_LO) + ((crop & 0xc0) << 2);
617 
618 		if (vbi->geo.vdelay > vdelay) {
619 			vdelay = vbi->geo.vdelay & 0xfe;
620 			crop = (crop & 0x3f) | ((vbi->geo.vdelay >> 2) & 0xc0);
621 
622 			btwrite(vdelay, BT848_E_VDELAY_LO);
623 			btwrite(crop,	BT848_E_CROP);
624 			btwrite(vdelay, BT848_O_VDELAY_LO);
625 			btwrite(crop,	BT848_O_CROP);
626 		}
627 
628 		if (vbi->vbi_count[0] > 0) {
629 			top = &vbi->top;
630 			top_irq_flags = 4;
631 		}
632 
633 		if (vbi->vbi_count[1] > 0) {
634 			top_irq_flags = 0;
635 			bottom = &vbi->bottom;
636 			bottom_irq_flags = 4;
637 		}
638 	}
639 
640 	bttv_risc_hook(btv, RISC_SLOT_O_VBI, top, top_irq_flags);
641 	bttv_risc_hook(btv, RISC_SLOT_E_VBI, bottom, bottom_irq_flags);
642 
643 	return 0;
644 }
645 
646 int
bttv_buffer_activate_video(struct bttv * btv,struct bttv_buffer_set * set)647 bttv_buffer_activate_video(struct bttv *btv,
648 			   struct bttv_buffer_set *set)
649 {
650 	/* video capture */
651 	if (NULL != set->top  &&  NULL != set->bottom) {
652 		if (set->top == set->bottom) {
653 			set->top->vb.state    = VIDEOBUF_ACTIVE;
654 			if (set->top->vb.queue.next)
655 				list_del(&set->top->vb.queue);
656 		} else {
657 			set->top->vb.state    = VIDEOBUF_ACTIVE;
658 			set->bottom->vb.state = VIDEOBUF_ACTIVE;
659 			if (set->top->vb.queue.next)
660 				list_del(&set->top->vb.queue);
661 			if (set->bottom->vb.queue.next)
662 				list_del(&set->bottom->vb.queue);
663 		}
664 		bttv_apply_geo(btv, &set->top->geo, 1);
665 		bttv_apply_geo(btv, &set->bottom->geo,0);
666 		bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
667 			       set->top_irq);
668 		bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
669 			       set->frame_irq);
670 		btaor((set->top->btformat & 0xf0) | (set->bottom->btformat & 0x0f),
671 		      ~0xff, BT848_COLOR_FMT);
672 		btaor((set->top->btswap & 0x0a) | (set->bottom->btswap & 0x05),
673 		      ~0x0f, BT848_COLOR_CTL);
674 	} else if (NULL != set->top) {
675 		set->top->vb.state  = VIDEOBUF_ACTIVE;
676 		if (set->top->vb.queue.next)
677 			list_del(&set->top->vb.queue);
678 		bttv_apply_geo(btv, &set->top->geo,1);
679 		bttv_apply_geo(btv, &set->top->geo,0);
680 		bttv_risc_hook(btv, RISC_SLOT_O_FIELD, &set->top->top,
681 			       set->frame_irq);
682 		bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL,           0);
683 		btaor(set->top->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
684 		btaor(set->top->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
685 	} else if (NULL != set->bottom) {
686 		set->bottom->vb.state = VIDEOBUF_ACTIVE;
687 		if (set->bottom->vb.queue.next)
688 			list_del(&set->bottom->vb.queue);
689 		bttv_apply_geo(btv, &set->bottom->geo,1);
690 		bttv_apply_geo(btv, &set->bottom->geo,0);
691 		bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
692 		bttv_risc_hook(btv, RISC_SLOT_E_FIELD, &set->bottom->bottom,
693 			       set->frame_irq);
694 		btaor(set->bottom->btformat & 0xff, ~0xff, BT848_COLOR_FMT);
695 		btaor(set->bottom->btswap & 0x0f,   ~0x0f, BT848_COLOR_CTL);
696 	} else {
697 		bttv_risc_hook(btv, RISC_SLOT_O_FIELD, NULL, 0);
698 		bttv_risc_hook(btv, RISC_SLOT_E_FIELD, NULL, 0);
699 	}
700 	return 0;
701 }
702 
703 /* ---------------------------------------------------------- */
704 
705 /* calculate geometry, build risc code */
706 int
bttv_buffer_risc(struct bttv * btv,struct bttv_buffer * buf)707 bttv_buffer_risc(struct bttv *btv, struct bttv_buffer *buf)
708 {
709 	const struct bttv_tvnorm *tvnorm = bttv_tvnorms + buf->tvnorm;
710 	struct videobuf_dmabuf *dma=videobuf_to_dma(&buf->vb);
711 
712 	dprintk("%d: buffer field: %s  format: %s  size: %dx%d\n",
713 		btv->c.nr, v4l2_field_names[buf->vb.field],
714 		buf->fmt->name, buf->vb.width, buf->vb.height);
715 
716 	/* packed pixel modes */
717 	if (buf->fmt->flags & FORMAT_FLAGS_PACKED) {
718 		int bpl = (buf->fmt->depth >> 3) * buf->vb.width;
719 		int bpf = bpl * (buf->vb.height >> 1);
720 
721 		bttv_calc_geo(btv,&buf->geo,buf->vb.width,buf->vb.height,
722 			      V4L2_FIELD_HAS_BOTH(buf->vb.field),
723 			      tvnorm,&buf->crop);
724 
725 		switch (buf->vb.field) {
726 		case V4L2_FIELD_TOP:
727 			bttv_risc_packed(btv,&buf->top,dma->sglist,
728 					 /* offset */ 0,bpl,
729 					 /* padding */ 0,/* skip_lines */ 0,
730 					 buf->vb.height);
731 			break;
732 		case V4L2_FIELD_BOTTOM:
733 			bttv_risc_packed(btv,&buf->bottom,dma->sglist,
734 					 0,bpl,0,0,buf->vb.height);
735 			break;
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("%d: overlay fields: %s format: %s  size: %dx%d\n",
874 		btv->c.nr, v4l2_field_names[buf->vb.field],
875 		fmt->name, ov->w.width, ov->w.height);
876 
877 	/* calculate geometry */
878 	bttv_calc_geo(btv,&buf->geo,ov->w.width,ov->w.height,
879 		      V4L2_FIELD_HAS_BOTH(ov->field),
880 		      &bttv_tvnorms[ov->tvnorm],&buf->crop);
881 
882 	/* build risc code */
883 	switch (ov->field) {
884 	case V4L2_FIELD_TOP:
885 		bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 0);
886 		break;
887 	case V4L2_FIELD_BOTTOM:
888 		bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 0, 0);
889 		break;
890 	case V4L2_FIELD_INTERLACED:
891 		bttv_risc_overlay(btv, &buf->top,    fmt, ov, 0, 1);
892 		bttv_risc_overlay(btv, &buf->bottom, fmt, ov, 1, 0);
893 		break;
894 	default:
895 		BUG();
896 	}
897 
898 	/* copy format info */
899 	buf->btformat = fmt->btformat;
900 	buf->btswap   = fmt->btswap;
901 	buf->vb.field = ov->field;
902 	return 0;
903 }
904 
905 /*
906  * Local variables:
907  * c-basic-offset: 8
908  * End:
909  */
910