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