xref: /openbmc/linux/drivers/media/pci/ivtv/ivtv-yuv.c (revision 4f3db074)
1 /*
2     yuv support
3 
4     Copyright (C) 2007  Ian Armstrong <ian@iarmst.demon.co.uk>
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 #include "ivtv-driver.h"
22 #include "ivtv-udma.h"
23 #include "ivtv-yuv.h"
24 
25 /* YUV buffer offsets */
26 const u32 yuv_offset[IVTV_YUV_BUFFERS] = {
27 	0x001a8600,
28 	0x00240400,
29 	0x002d8200,
30 	0x00370000,
31 	0x00029000,
32 	0x000C0E00,
33 	0x006B0400,
34 	0x00748200
35 };
36 
37 static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
38 				  struct ivtv_dma_frame *args)
39 {
40 	struct ivtv_dma_page_info y_dma;
41 	struct ivtv_dma_page_info uv_dma;
42 	struct yuv_playback_info *yi = &itv->yuv_info;
43 	u8 frame = yi->draw_frame;
44 	struct yuv_frame_info *f = &yi->new_frame_info[frame];
45 	int i;
46 	int y_pages, uv_pages;
47 	unsigned long y_buffer_offset, uv_buffer_offset;
48 	int y_decode_height, uv_decode_height, y_size;
49 
50 	y_buffer_offset = IVTV_DECODER_OFFSET + yuv_offset[frame];
51 	uv_buffer_offset = y_buffer_offset + IVTV_YUV_BUFFER_UV_OFFSET;
52 
53 	y_decode_height = uv_decode_height = f->src_h + f->src_y;
54 
55 	if (f->offset_y)
56 		y_buffer_offset += 720 * 16;
57 
58 	if (y_decode_height & 15)
59 		y_decode_height = (y_decode_height + 16) & ~15;
60 
61 	if (uv_decode_height & 31)
62 		uv_decode_height = (uv_decode_height + 32) & ~31;
63 
64 	y_size = 720 * y_decode_height;
65 
66 	/* Still in USE */
67 	if (dma->SG_length || dma->page_count) {
68 		IVTV_DEBUG_WARN
69 		    ("prep_user_dma: SG_length %d page_count %d still full?\n",
70 		     dma->SG_length, dma->page_count);
71 		return -EBUSY;
72 	}
73 
74 	ivtv_udma_get_page_info (&y_dma, (unsigned long)args->y_source, 720 * y_decode_height);
75 	ivtv_udma_get_page_info (&uv_dma, (unsigned long)args->uv_source, 360 * uv_decode_height);
76 
77 	/* Get user pages for DMA Xfer */
78 	down_read(&current->mm->mmap_sem);
79 	y_pages = get_user_pages(current, current->mm, y_dma.uaddr, y_dma.page_count, 0, 1, &dma->map[0], NULL);
80 	uv_pages = 0; /* silence gcc. value is set and consumed only if: */
81 	if (y_pages == y_dma.page_count) {
82 		uv_pages = get_user_pages(current, current->mm,
83 					  uv_dma.uaddr, uv_dma.page_count, 0, 1,
84 					  &dma->map[y_pages], NULL);
85 	}
86 	up_read(&current->mm->mmap_sem);
87 
88 	if (y_pages != y_dma.page_count || uv_pages != uv_dma.page_count) {
89 		int rc = -EFAULT;
90 
91 		if (y_pages == y_dma.page_count) {
92 			IVTV_DEBUG_WARN
93 				("failed to map uv user pages, returned %d "
94 				 "expecting %d\n", uv_pages, uv_dma.page_count);
95 
96 			if (uv_pages >= 0) {
97 				for (i = 0; i < uv_pages; i++)
98 					put_page(dma->map[y_pages + i]);
99 				rc = -EFAULT;
100 			} else {
101 				rc = uv_pages;
102 			}
103 		} else {
104 			IVTV_DEBUG_WARN
105 				("failed to map y user pages, returned %d "
106 				 "expecting %d\n", y_pages, y_dma.page_count);
107 		}
108 		if (y_pages >= 0) {
109 			for (i = 0; i < y_pages; i++)
110 				put_page(dma->map[i]);
111 			/*
112 			 * Inherit the -EFAULT from rc's
113 			 * initialization, but allow it to be
114 			 * overriden by uv_pages above if it was an
115 			 * actual errno.
116 			 */
117 		} else {
118 			rc = y_pages;
119 		}
120 		return rc;
121 	}
122 
123 	dma->page_count = y_pages + uv_pages;
124 
125 	/* Fill & map SG List */
126 	if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) {
127 		IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n");
128 		for (i = 0; i < dma->page_count; i++) {
129 			put_page(dma->map[i]);
130 		}
131 		dma->page_count = 0;
132 		return -ENOMEM;
133 	}
134 	dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
135 
136 	/* Fill SG Array with new values */
137 	ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
138 
139 	/* If we've offset the y plane, ensure top area is blanked */
140 	if (f->offset_y && yi->blanking_dmaptr) {
141 		dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16);
142 		dma->SGarray[dma->SG_length].src = cpu_to_le32(yi->blanking_dmaptr);
143 		dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DECODER_OFFSET + yuv_offset[frame]);
144 		dma->SG_length++;
145 	}
146 
147 	/* Tag SG Array with Interrupt Bit */
148 	dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000);
149 
150 	ivtv_udma_sync_for_device(itv);
151 	return 0;
152 }
153 
154 /* We rely on a table held in the firmware - Quick check. */
155 int ivtv_yuv_filter_check(struct ivtv *itv)
156 {
157 	int i, y, uv;
158 
159 	for (i = 0, y = 16, uv = 4; i < 16; i++, y += 24, uv += 12) {
160 		if ((read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + y) != i << 16) ||
161 		    (read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + uv) != i << 16)) {
162 			IVTV_WARN ("YUV filter table not found in firmware.\n");
163 			return -1;
164 		}
165 	}
166 	return 0;
167 }
168 
169 static void ivtv_yuv_filter(struct ivtv *itv, int h_filter, int v_filter_1, int v_filter_2)
170 {
171 	u32 i, line;
172 
173 	/* If any filter is -1, then don't update it */
174 	if (h_filter > -1) {
175 		if (h_filter > 4)
176 			h_filter = 4;
177 		i = IVTV_YUV_HORIZONTAL_FILTER_OFFSET + (h_filter * 384);
178 		for (line = 0; line < 16; line++) {
179 			write_reg(read_dec(i), 0x02804);
180 			write_reg(read_dec(i), 0x0281c);
181 			i += 4;
182 			write_reg(read_dec(i), 0x02808);
183 			write_reg(read_dec(i), 0x02820);
184 			i += 4;
185 			write_reg(read_dec(i), 0x0280c);
186 			write_reg(read_dec(i), 0x02824);
187 			i += 4;
188 			write_reg(read_dec(i), 0x02810);
189 			write_reg(read_dec(i), 0x02828);
190 			i += 4;
191 			write_reg(read_dec(i), 0x02814);
192 			write_reg(read_dec(i), 0x0282c);
193 			i += 8;
194 			write_reg(0, 0x02818);
195 			write_reg(0, 0x02830);
196 		}
197 		IVTV_DEBUG_YUV("h_filter -> %d\n", h_filter);
198 	}
199 
200 	if (v_filter_1 > -1) {
201 		if (v_filter_1 > 4)
202 			v_filter_1 = 4;
203 		i = IVTV_YUV_VERTICAL_FILTER_OFFSET + (v_filter_1 * 192);
204 		for (line = 0; line < 16; line++) {
205 			write_reg(read_dec(i), 0x02900);
206 			i += 4;
207 			write_reg(read_dec(i), 0x02904);
208 			i += 8;
209 			write_reg(0, 0x02908);
210 		}
211 		IVTV_DEBUG_YUV("v_filter_1 -> %d\n", v_filter_1);
212 	}
213 
214 	if (v_filter_2 > -1) {
215 		if (v_filter_2 > 4)
216 			v_filter_2 = 4;
217 		i = IVTV_YUV_VERTICAL_FILTER_OFFSET + (v_filter_2 * 192);
218 		for (line = 0; line < 16; line++) {
219 			write_reg(read_dec(i), 0x0290c);
220 			i += 4;
221 			write_reg(read_dec(i), 0x02910);
222 			i += 8;
223 			write_reg(0, 0x02914);
224 		}
225 		IVTV_DEBUG_YUV("v_filter_2 -> %d\n", v_filter_2);
226 	}
227 }
228 
229 static void ivtv_yuv_handle_horizontal(struct ivtv *itv, struct yuv_frame_info *f)
230 {
231 	struct yuv_playback_info *yi = &itv->yuv_info;
232 	u32 reg_2834, reg_2838, reg_283c;
233 	u32 reg_2844, reg_2854, reg_285c;
234 	u32 reg_2864, reg_2874, reg_2890;
235 	u32 reg_2870, reg_2870_base, reg_2870_offset;
236 	int x_cutoff;
237 	int h_filter;
238 	u32 master_width;
239 
240 	IVTV_DEBUG_WARN
241 	    ("Adjust to width %d src_w %d dst_w %d src_x %d dst_x %d\n",
242 	     f->tru_w, f->src_w, f->dst_w, f->src_x, f->dst_x);
243 
244 	/* How wide is the src image */
245 	x_cutoff = f->src_w + f->src_x;
246 
247 	/* Set the display width */
248 	reg_2834 = f->dst_w;
249 	reg_2838 = reg_2834;
250 
251 	/* Set the display position */
252 	reg_2890 = f->dst_x;
253 
254 	/* Index into the image horizontally */
255 	reg_2870 = 0;
256 
257 	/* 2870 is normally fudged to align video coords with osd coords.
258 	   If running full screen, it causes an unwanted left shift
259 	   Remove the fudge if we almost fill the screen.
260 	   Gradually adjust the offset to avoid the video 'snapping'
261 	   left/right if it gets dragged through this region.
262 	   Only do this if osd is full width. */
263 	if (f->vis_w == 720) {
264 		if ((f->tru_x - f->pan_x > -1) && (f->tru_x - f->pan_x <= 40) && (f->dst_w >= 680))
265 			reg_2870 = 10 - (f->tru_x - f->pan_x) / 4;
266 		else if ((f->tru_x - f->pan_x < 0) && (f->tru_x - f->pan_x >= -20) && (f->dst_w >= 660))
267 			reg_2870 = (10 + (f->tru_x - f->pan_x) / 2);
268 
269 		if (f->dst_w >= f->src_w)
270 			reg_2870 = reg_2870 << 16 | reg_2870;
271 		else
272 			reg_2870 = ((reg_2870 & ~1) << 15) | (reg_2870 & ~1);
273 	}
274 
275 	if (f->dst_w < f->src_w)
276 		reg_2870 = 0x000d000e - reg_2870;
277 	else
278 		reg_2870 = 0x0012000e - reg_2870;
279 
280 	/* We're also using 2870 to shift the image left (src_x & negative dst_x) */
281 	reg_2870_offset = (f->src_x * ((f->dst_w << 21) / f->src_w)) >> 19;
282 
283 	if (f->dst_w >= f->src_w) {
284 		x_cutoff &= ~1;
285 		master_width = (f->src_w * 0x00200000) / (f->dst_w);
286 		if (master_width * f->dst_w != f->src_w * 0x00200000)
287 			master_width++;
288 		reg_2834 = (reg_2834 << 16) | x_cutoff;
289 		reg_2838 = (reg_2838 << 16) | x_cutoff;
290 		reg_283c = master_width >> 2;
291 		reg_2844 = master_width >> 2;
292 		reg_2854 = master_width;
293 		reg_285c = master_width >> 1;
294 		reg_2864 = master_width >> 1;
295 
296 		/* We also need to factor in the scaling
297 		   (src_w - dst_w) / (src_w / 4) */
298 		if (f->dst_w > f->src_w)
299 			reg_2870_base = ((f->dst_w - f->src_w)<<16) / (f->src_w <<14);
300 		else
301 			reg_2870_base = 0;
302 
303 		reg_2870 += (((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 2) + (reg_2870_base << 17 | reg_2870_base);
304 		reg_2874 = 0;
305 	} else if (f->dst_w < f->src_w / 2) {
306 		master_width = (f->src_w * 0x00080000) / f->dst_w;
307 		if (master_width * f->dst_w != f->src_w * 0x00080000)
308 			master_width++;
309 		reg_2834 = (reg_2834 << 16) | x_cutoff;
310 		reg_2838 = (reg_2838 << 16) | x_cutoff;
311 		reg_283c = master_width >> 2;
312 		reg_2844 = master_width >> 1;
313 		reg_2854 = master_width;
314 		reg_285c = master_width >> 1;
315 		reg_2864 = master_width >> 1;
316 		reg_2870 += ((reg_2870_offset << 15) & 0xFFFF0000) | reg_2870_offset;
317 		reg_2870 += (5 - (((f->src_w + f->src_w / 2) - 1) / f->dst_w)) << 16;
318 		reg_2874 = 0x00000012;
319 	} else {
320 		master_width = (f->src_w * 0x00100000) / f->dst_w;
321 		if (master_width * f->dst_w != f->src_w * 0x00100000)
322 			master_width++;
323 		reg_2834 = (reg_2834 << 16) | x_cutoff;
324 		reg_2838 = (reg_2838 << 16) | x_cutoff;
325 		reg_283c = master_width >> 2;
326 		reg_2844 = master_width >> 1;
327 		reg_2854 = master_width;
328 		reg_285c = master_width >> 1;
329 		reg_2864 = master_width >> 1;
330 		reg_2870 += ((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 1;
331 		reg_2870 += (5 - (((f->src_w * 3) - 1) / f->dst_w)) << 16;
332 		reg_2874 = 0x00000001;
333 	}
334 
335 	/* Select the horizontal filter */
336 	if (f->src_w == f->dst_w) {
337 		/* An exact size match uses filter 0 */
338 		h_filter = 0;
339 	} else {
340 		/* Figure out which filter to use */
341 		h_filter = ((f->src_w << 16) / f->dst_w) >> 15;
342 		h_filter = (h_filter >> 1) + (h_filter & 1);
343 		/* Only an exact size match can use filter 0 */
344 		h_filter += !h_filter;
345 	}
346 
347 	write_reg(reg_2834, 0x02834);
348 	write_reg(reg_2838, 0x02838);
349 	IVTV_DEBUG_YUV("Update reg 0x2834 %08x->%08x 0x2838 %08x->%08x\n",
350 		       yi->reg_2834, reg_2834, yi->reg_2838, reg_2838);
351 
352 	write_reg(reg_283c, 0x0283c);
353 	write_reg(reg_2844, 0x02844);
354 
355 	IVTV_DEBUG_YUV("Update reg 0x283c %08x->%08x 0x2844 %08x->%08x\n",
356 		       yi->reg_283c, reg_283c, yi->reg_2844, reg_2844);
357 
358 	write_reg(0x00080514, 0x02840);
359 	write_reg(0x00100514, 0x02848);
360 	IVTV_DEBUG_YUV("Update reg 0x2840 %08x->%08x 0x2848 %08x->%08x\n",
361 		       yi->reg_2840, 0x00080514, yi->reg_2848, 0x00100514);
362 
363 	write_reg(reg_2854, 0x02854);
364 	IVTV_DEBUG_YUV("Update reg 0x2854 %08x->%08x \n",
365 		       yi->reg_2854, reg_2854);
366 
367 	write_reg(reg_285c, 0x0285c);
368 	write_reg(reg_2864, 0x02864);
369 	IVTV_DEBUG_YUV("Update reg 0x285c %08x->%08x 0x2864 %08x->%08x\n",
370 		       yi->reg_285c, reg_285c, yi->reg_2864, reg_2864);
371 
372 	write_reg(reg_2874, 0x02874);
373 	IVTV_DEBUG_YUV("Update reg 0x2874 %08x->%08x\n",
374 		       yi->reg_2874, reg_2874);
375 
376 	write_reg(reg_2870, 0x02870);
377 	IVTV_DEBUG_YUV("Update reg 0x2870 %08x->%08x\n",
378 		       yi->reg_2870, reg_2870);
379 
380 	write_reg(reg_2890, 0x02890);
381 	IVTV_DEBUG_YUV("Update reg 0x2890 %08x->%08x\n",
382 		       yi->reg_2890, reg_2890);
383 
384 	/* Only update the filter if we really need to */
385 	if (h_filter != yi->h_filter) {
386 		ivtv_yuv_filter(itv, h_filter, -1, -1);
387 		yi->h_filter = h_filter;
388 	}
389 }
390 
391 static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *f)
392 {
393 	struct yuv_playback_info *yi = &itv->yuv_info;
394 	u32 master_height;
395 	u32 reg_2918, reg_291c, reg_2920, reg_2928;
396 	u32 reg_2930, reg_2934, reg_293c;
397 	u32 reg_2940, reg_2944, reg_294c;
398 	u32 reg_2950, reg_2954, reg_2958, reg_295c;
399 	u32 reg_2960, reg_2964, reg_2968, reg_296c;
400 	u32 reg_289c;
401 	u32 src_major_y, src_minor_y;
402 	u32 src_major_uv, src_minor_uv;
403 	u32 reg_2964_base, reg_2968_base;
404 	int v_filter_1, v_filter_2;
405 
406 	IVTV_DEBUG_WARN
407 	    ("Adjust to height %d src_h %d dst_h %d src_y %d dst_y %d\n",
408 	     f->tru_h, f->src_h, f->dst_h, f->src_y, f->dst_y);
409 
410 	/* What scaling mode is being used... */
411 	IVTV_DEBUG_YUV("Scaling mode Y: %s\n",
412 		       f->interlaced_y ? "Interlaced" : "Progressive");
413 
414 	IVTV_DEBUG_YUV("Scaling mode UV: %s\n",
415 		       f->interlaced_uv ? "Interlaced" : "Progressive");
416 
417 	/* What is the source video being treated as... */
418 	IVTV_DEBUG_WARN("Source video: %s\n",
419 			f->interlaced ? "Interlaced" : "Progressive");
420 
421 	/* We offset into the image using two different index methods, so split
422 	   the y source coord into two parts. */
423 	if (f->src_y < 8) {
424 		src_minor_uv = f->src_y;
425 		src_major_uv = 0;
426 	} else {
427 		src_minor_uv = 8;
428 		src_major_uv = f->src_y - 8;
429 	}
430 
431 	src_minor_y = src_minor_uv;
432 	src_major_y = src_major_uv;
433 
434 	if (f->offset_y)
435 		src_minor_y += 16;
436 
437 	if (f->interlaced_y)
438 		reg_2918 = (f->dst_h << 16) | (f->src_h + src_minor_y);
439 	else
440 		reg_2918 = (f->dst_h << 16) | ((f->src_h + src_minor_y) << 1);
441 
442 	if (f->interlaced_uv)
443 		reg_291c = (f->dst_h << 16) | ((f->src_h + src_minor_uv) >> 1);
444 	else
445 		reg_291c = (f->dst_h << 16) | (f->src_h + src_minor_uv);
446 
447 	reg_2964_base = (src_minor_y * ((f->dst_h << 16) / f->src_h)) >> 14;
448 	reg_2968_base = (src_minor_uv * ((f->dst_h << 16) / f->src_h)) >> 14;
449 
450 	if (f->dst_h / 2 >= f->src_h && !f->interlaced_y) {
451 		master_height = (f->src_h * 0x00400000) / f->dst_h;
452 		if ((f->src_h * 0x00400000) - (master_height * f->dst_h) >= f->dst_h / 2)
453 			master_height++;
454 		reg_2920 = master_height >> 2;
455 		reg_2928 = master_height >> 3;
456 		reg_2930 = master_height;
457 		reg_2940 = master_height >> 1;
458 		reg_2964_base >>= 3;
459 		reg_2968_base >>= 3;
460 		reg_296c = 0x00000000;
461 	} else if (f->dst_h >= f->src_h) {
462 		master_height = (f->src_h * 0x00400000) / f->dst_h;
463 		master_height = (master_height >> 1) + (master_height & 1);
464 		reg_2920 = master_height >> 2;
465 		reg_2928 = master_height >> 2;
466 		reg_2930 = master_height;
467 		reg_2940 = master_height >> 1;
468 		reg_296c = 0x00000000;
469 		if (f->interlaced_y) {
470 			reg_2964_base >>= 3;
471 		} else {
472 			reg_296c++;
473 			reg_2964_base >>= 2;
474 		}
475 		if (f->interlaced_uv)
476 			reg_2928 >>= 1;
477 		reg_2968_base >>= 3;
478 	} else if (f->dst_h >= f->src_h / 2) {
479 		master_height = (f->src_h * 0x00200000) / f->dst_h;
480 		master_height = (master_height >> 1) + (master_height & 1);
481 		reg_2920 = master_height >> 2;
482 		reg_2928 = master_height >> 2;
483 		reg_2930 = master_height;
484 		reg_2940 = master_height;
485 		reg_296c = 0x00000101;
486 		if (f->interlaced_y) {
487 			reg_2964_base >>= 2;
488 		} else {
489 			reg_296c++;
490 			reg_2964_base >>= 1;
491 		}
492 		if (f->interlaced_uv)
493 			reg_2928 >>= 1;
494 		reg_2968_base >>= 2;
495 	} else {
496 		master_height = (f->src_h * 0x00100000) / f->dst_h;
497 		master_height = (master_height >> 1) + (master_height & 1);
498 		reg_2920 = master_height >> 2;
499 		reg_2928 = master_height >> 2;
500 		reg_2930 = master_height;
501 		reg_2940 = master_height;
502 		reg_2964_base >>= 1;
503 		reg_2968_base >>= 2;
504 		reg_296c = 0x00000102;
505 	}
506 
507 	/* FIXME These registers change depending on scaled / unscaled output
508 	   We really need to work out what they should be */
509 	if (f->src_h == f->dst_h) {
510 		reg_2934 = 0x00020000;
511 		reg_293c = 0x00100000;
512 		reg_2944 = 0x00040000;
513 		reg_294c = 0x000b0000;
514 	} else {
515 		reg_2934 = 0x00000FF0;
516 		reg_293c = 0x00000FF0;
517 		reg_2944 = 0x00000FF0;
518 		reg_294c = 0x00000FF0;
519 	}
520 
521 	/* The first line to be displayed */
522 	reg_2950 = 0x00010000 + src_major_y;
523 	if (f->interlaced_y)
524 		reg_2950 += 0x00010000;
525 	reg_2954 = reg_2950 + 1;
526 
527 	reg_2958 = 0x00010000 + (src_major_y >> 1);
528 	if (f->interlaced_uv)
529 		reg_2958 += 0x00010000;
530 	reg_295c = reg_2958 + 1;
531 
532 	if (yi->decode_height == 480)
533 		reg_289c = 0x011e0017;
534 	else
535 		reg_289c = 0x01500017;
536 
537 	if (f->dst_y < 0)
538 		reg_289c = (reg_289c - ((f->dst_y & ~1)<<15))-(f->dst_y >>1);
539 	else
540 		reg_289c = (reg_289c + ((f->dst_y & ~1)<<15))+(f->dst_y >>1);
541 
542 	/* How much of the source to decode.
543 	   Take into account the source offset */
544 	reg_2960 = ((src_minor_y + f->src_h + src_major_y) - 1) |
545 		(((src_minor_uv + f->src_h + src_major_uv - 1) & ~1) << 15);
546 
547 	/* Calculate correct value for register 2964 */
548 	if (f->src_h == f->dst_h) {
549 		reg_2964 = 1;
550 	} else {
551 		reg_2964 = 2 + ((f->dst_h << 1) / f->src_h);
552 		reg_2964 = (reg_2964 >> 1) + (reg_2964 & 1);
553 	}
554 	reg_2968 = (reg_2964 << 16) + reg_2964 + (reg_2964 >> 1);
555 	reg_2964 = (reg_2964 << 16) + reg_2964 + (reg_2964 * 46 / 94);
556 
557 	/* Okay, we've wasted time working out the correct value,
558 	   but if we use it, it fouls the the window alignment.
559 	   Fudge it to what we want... */
560 	reg_2964 = 0x00010001 + ((reg_2964 & 0x0000FFFF) - (reg_2964 >> 16));
561 	reg_2968 = 0x00010001 + ((reg_2968 & 0x0000FFFF) - (reg_2968 >> 16));
562 
563 	/* Deviate further from what it should be. I find the flicker headache
564 	   inducing so try to reduce it slightly. Leave 2968 as-is otherwise
565 	   colours foul. */
566 	if ((reg_2964 != 0x00010001) && (f->dst_h / 2 <= f->src_h))
567 		reg_2964 = (reg_2964 & 0xFFFF0000) + ((reg_2964 & 0x0000FFFF) / 2);
568 
569 	if (!f->interlaced_y)
570 		reg_2964 -= 0x00010001;
571 	if (!f->interlaced_uv)
572 		reg_2968 -= 0x00010001;
573 
574 	reg_2964 += ((reg_2964_base << 16) | reg_2964_base);
575 	reg_2968 += ((reg_2968_base << 16) | reg_2968_base);
576 
577 	/* Select the vertical filter */
578 	if (f->src_h == f->dst_h) {
579 		/* An exact size match uses filter 0/1 */
580 		v_filter_1 = 0;
581 		v_filter_2 = 1;
582 	} else {
583 		/* Figure out which filter to use */
584 		v_filter_1 = ((f->src_h << 16) / f->dst_h) >> 15;
585 		v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1);
586 		/* Only an exact size match can use filter 0 */
587 		v_filter_1 += !v_filter_1;
588 		v_filter_2 = v_filter_1;
589 	}
590 
591 	write_reg(reg_2934, 0x02934);
592 	write_reg(reg_293c, 0x0293c);
593 	IVTV_DEBUG_YUV("Update reg 0x2934 %08x->%08x 0x293c %08x->%08x\n",
594 		       yi->reg_2934, reg_2934, yi->reg_293c, reg_293c);
595 	write_reg(reg_2944, 0x02944);
596 	write_reg(reg_294c, 0x0294c);
597 	IVTV_DEBUG_YUV("Update reg 0x2944 %08x->%08x 0x294c %08x->%08x\n",
598 		       yi->reg_2944, reg_2944, yi->reg_294c, reg_294c);
599 
600 	/* Ensure 2970 is 0 (does it ever change ?) */
601 /*	write_reg(0,0x02970); */
602 /*	IVTV_DEBUG_YUV("Update reg 0x2970 %08x->%08x\n", yi->reg_2970, 0); */
603 
604 	write_reg(reg_2930, 0x02938);
605 	write_reg(reg_2930, 0x02930);
606 	IVTV_DEBUG_YUV("Update reg 0x2930 %08x->%08x 0x2938 %08x->%08x\n",
607 		       yi->reg_2930, reg_2930, yi->reg_2938, reg_2930);
608 
609 	write_reg(reg_2928, 0x02928);
610 	write_reg(reg_2928 + 0x514, 0x0292C);
611 	IVTV_DEBUG_YUV("Update reg 0x2928 %08x->%08x 0x292c %08x->%08x\n",
612 		       yi->reg_2928, reg_2928, yi->reg_292c, reg_2928 + 0x514);
613 
614 	write_reg(reg_2920, 0x02920);
615 	write_reg(reg_2920 + 0x514, 0x02924);
616 	IVTV_DEBUG_YUV("Update reg 0x2920 %08x->%08x 0x2924 %08x->%08x\n",
617 		       yi->reg_2920, reg_2920, yi->reg_2924, reg_2920 + 0x514);
618 
619 	write_reg(reg_2918, 0x02918);
620 	write_reg(reg_291c, 0x0291C);
621 	IVTV_DEBUG_YUV("Update reg 0x2918 %08x->%08x 0x291C %08x->%08x\n",
622 		       yi->reg_2918, reg_2918, yi->reg_291c, reg_291c);
623 
624 	write_reg(reg_296c, 0x0296c);
625 	IVTV_DEBUG_YUV("Update reg 0x296c %08x->%08x\n",
626 		       yi->reg_296c, reg_296c);
627 
628 	write_reg(reg_2940, 0x02948);
629 	write_reg(reg_2940, 0x02940);
630 	IVTV_DEBUG_YUV("Update reg 0x2940 %08x->%08x 0x2948 %08x->%08x\n",
631 		       yi->reg_2940, reg_2940, yi->reg_2948, reg_2940);
632 
633 	write_reg(reg_2950, 0x02950);
634 	write_reg(reg_2954, 0x02954);
635 	IVTV_DEBUG_YUV("Update reg 0x2950 %08x->%08x 0x2954 %08x->%08x\n",
636 		       yi->reg_2950, reg_2950, yi->reg_2954, reg_2954);
637 
638 	write_reg(reg_2958, 0x02958);
639 	write_reg(reg_295c, 0x0295C);
640 	IVTV_DEBUG_YUV("Update reg 0x2958 %08x->%08x 0x295C %08x->%08x\n",
641 		       yi->reg_2958, reg_2958, yi->reg_295c, reg_295c);
642 
643 	write_reg(reg_2960, 0x02960);
644 	IVTV_DEBUG_YUV("Update reg 0x2960 %08x->%08x \n",
645 		       yi->reg_2960, reg_2960);
646 
647 	write_reg(reg_2964, 0x02964);
648 	write_reg(reg_2968, 0x02968);
649 	IVTV_DEBUG_YUV("Update reg 0x2964 %08x->%08x 0x2968 %08x->%08x\n",
650 		       yi->reg_2964, reg_2964, yi->reg_2968, reg_2968);
651 
652 	write_reg(reg_289c, 0x0289c);
653 	IVTV_DEBUG_YUV("Update reg 0x289c %08x->%08x\n",
654 		       yi->reg_289c, reg_289c);
655 
656 	/* Only update filter 1 if we really need to */
657 	if (v_filter_1 != yi->v_filter_1) {
658 		ivtv_yuv_filter(itv, -1, v_filter_1, -1);
659 		yi->v_filter_1 = v_filter_1;
660 	}
661 
662 	/* Only update filter 2 if we really need to */
663 	if (v_filter_2 != yi->v_filter_2) {
664 		ivtv_yuv_filter(itv, -1, -1, v_filter_2);
665 		yi->v_filter_2 = v_filter_2;
666 	}
667 }
668 
669 /* Modify the supplied coordinate information to fit the visible osd area */
670 static u32 ivtv_yuv_window_setup(struct ivtv *itv, struct yuv_frame_info *f)
671 {
672 	struct yuv_frame_info *of = &itv->yuv_info.old_frame_info;
673 	int osd_crop;
674 	u32 osd_scale;
675 	u32 yuv_update = 0;
676 
677 	/* Sorry, but no negative coords for src */
678 	if (f->src_x < 0)
679 		f->src_x = 0;
680 	if (f->src_y < 0)
681 		f->src_y = 0;
682 
683 	/* Can only reduce width down to 1/4 original size */
684 	if ((osd_crop = f->src_w - 4 * f->dst_w) > 0) {
685 		f->src_x += osd_crop / 2;
686 		f->src_w = (f->src_w - osd_crop) & ~3;
687 		f->dst_w = f->src_w / 4;
688 		f->dst_w += f->dst_w & 1;
689 	}
690 
691 	/* Can only reduce height down to 1/4 original size */
692 	if (f->src_h / f->dst_h >= 2) {
693 		/* Overflow may be because we're running progressive,
694 		   so force mode switch */
695 		f->interlaced_y = 1;
696 		/* Make sure we're still within limits for interlace */
697 		if ((osd_crop = f->src_h - 4 * f->dst_h) > 0) {
698 			/* If we reach here we'll have to force the height. */
699 			f->src_y += osd_crop / 2;
700 			f->src_h = (f->src_h - osd_crop) & ~3;
701 			f->dst_h = f->src_h / 4;
702 			f->dst_h += f->dst_h & 1;
703 		}
704 	}
705 
706 	/* If there's nothing to safe to display, we may as well stop now */
707 	if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 ||
708 	    (int)f->src_w <= 2 || (int)f->src_h <= 2) {
709 		return IVTV_YUV_UPDATE_INVALID;
710 	}
711 
712 	/* Ensure video remains inside OSD area */
713 	osd_scale = (f->src_h << 16) / f->dst_h;
714 
715 	if ((osd_crop = f->pan_y - f->dst_y) > 0) {
716 		/* Falls off the upper edge - crop */
717 		f->src_y += (osd_scale * osd_crop) >> 16;
718 		f->src_h -= (osd_scale * osd_crop) >> 16;
719 		f->dst_h -= osd_crop;
720 		f->dst_y = 0;
721 	} else {
722 		f->dst_y -= f->pan_y;
723 	}
724 
725 	if ((osd_crop = f->dst_h + f->dst_y - f->vis_h) > 0) {
726 		/* Falls off the lower edge - crop */
727 		f->dst_h -= osd_crop;
728 		f->src_h -= (osd_scale * osd_crop) >> 16;
729 	}
730 
731 	osd_scale = (f->src_w << 16) / f->dst_w;
732 
733 	if ((osd_crop = f->pan_x - f->dst_x) > 0) {
734 		/* Fall off the left edge - crop */
735 		f->src_x += (osd_scale * osd_crop) >> 16;
736 		f->src_w -= (osd_scale * osd_crop) >> 16;
737 		f->dst_w -= osd_crop;
738 		f->dst_x = 0;
739 	} else {
740 		f->dst_x -= f->pan_x;
741 	}
742 
743 	if ((osd_crop = f->dst_w + f->dst_x - f->vis_w) > 0) {
744 		/* Falls off the right edge - crop */
745 		f->dst_w -= osd_crop;
746 		f->src_w -= (osd_scale * osd_crop) >> 16;
747 	}
748 
749 	if (itv->yuv_info.track_osd) {
750 		/* The OSD can be moved. Track to it */
751 		f->dst_x += itv->yuv_info.osd_x_offset;
752 		f->dst_y += itv->yuv_info.osd_y_offset;
753 	}
754 
755 	/* Width & height for both src & dst must be even.
756 	   Same for coordinates. */
757 	f->dst_w &= ~1;
758 	f->dst_x &= ~1;
759 
760 	f->src_w += f->src_x & 1;
761 	f->src_x &= ~1;
762 
763 	f->src_w &= ~1;
764 	f->dst_w &= ~1;
765 
766 	f->dst_h &= ~1;
767 	f->dst_y &= ~1;
768 
769 	f->src_h += f->src_y & 1;
770 	f->src_y &= ~1;
771 
772 	f->src_h &= ~1;
773 	f->dst_h &= ~1;
774 
775 	/* Due to rounding, we may have reduced the output size to <1/4 of
776 	   the source. Check again, but this time just resize. Don't change
777 	   source coordinates */
778 	if (f->dst_w < f->src_w / 4) {
779 		f->src_w &= ~3;
780 		f->dst_w = f->src_w / 4;
781 		f->dst_w += f->dst_w & 1;
782 	}
783 	if (f->dst_h < f->src_h / 4) {
784 		f->src_h &= ~3;
785 		f->dst_h = f->src_h / 4;
786 		f->dst_h += f->dst_h & 1;
787 	}
788 
789 	/* Check again. If there's nothing to safe to display, stop now */
790 	if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 ||
791 	    (int)f->src_w <= 2 || (int)f->src_h <= 2) {
792 		return IVTV_YUV_UPDATE_INVALID;
793 	}
794 
795 	/* Both x offset & width are linked, so they have to be done together */
796 	if ((of->dst_w != f->dst_w) || (of->src_w != f->src_w) ||
797 	    (of->dst_x != f->dst_x) || (of->src_x != f->src_x) ||
798 	    (of->pan_x != f->pan_x) || (of->vis_w != f->vis_w)) {
799 		yuv_update |= IVTV_YUV_UPDATE_HORIZONTAL;
800 	}
801 
802 	if ((of->src_h != f->src_h) || (of->dst_h != f->dst_h) ||
803 	    (of->dst_y != f->dst_y) || (of->src_y != f->src_y) ||
804 	    (of->pan_y != f->pan_y) || (of->vis_h != f->vis_h) ||
805 	    (of->lace_mode != f->lace_mode) ||
806 	    (of->interlaced_y != f->interlaced_y) ||
807 	    (of->interlaced_uv != f->interlaced_uv)) {
808 		yuv_update |= IVTV_YUV_UPDATE_VERTICAL;
809 	}
810 
811 	return yuv_update;
812 }
813 
814 /* Update the scaling register to the requested value */
815 void ivtv_yuv_work_handler(struct ivtv *itv)
816 {
817 	struct yuv_playback_info *yi = &itv->yuv_info;
818 	struct yuv_frame_info f;
819 	int frame = yi->update_frame;
820 	u32 yuv_update;
821 
822 	IVTV_DEBUG_YUV("Update yuv registers for frame %d\n", frame);
823 	f = yi->new_frame_info[frame];
824 
825 	if (yi->track_osd) {
826 		/* Snapshot the osd pan info */
827 		f.pan_x = yi->osd_x_pan;
828 		f.pan_y = yi->osd_y_pan;
829 		f.vis_w = yi->osd_vis_w;
830 		f.vis_h = yi->osd_vis_h;
831 	} else {
832 		/* Not tracking the osd, so assume full screen */
833 		f.pan_x = 0;
834 		f.pan_y = 0;
835 		f.vis_w = 720;
836 		f.vis_h = yi->decode_height;
837 	}
838 
839 	/* Calculate the display window coordinates. Exit if nothing left */
840 	if (!(yuv_update = ivtv_yuv_window_setup(itv, &f)))
841 		return;
842 
843 	if (yuv_update & IVTV_YUV_UPDATE_INVALID) {
844 		write_reg(0x01008080, 0x2898);
845 	} else if (yuv_update) {
846 		write_reg(0x00108080, 0x2898);
847 
848 		if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL)
849 			ivtv_yuv_handle_horizontal(itv, &f);
850 
851 		if (yuv_update & IVTV_YUV_UPDATE_VERTICAL)
852 			ivtv_yuv_handle_vertical(itv, &f);
853 	}
854 	yi->old_frame_info = f;
855 }
856 
857 static void ivtv_yuv_init(struct ivtv *itv)
858 {
859 	struct yuv_playback_info *yi = &itv->yuv_info;
860 
861 	IVTV_DEBUG_YUV("ivtv_yuv_init\n");
862 
863 	/* Take a snapshot of the current register settings */
864 	yi->reg_2834 = read_reg(0x02834);
865 	yi->reg_2838 = read_reg(0x02838);
866 	yi->reg_283c = read_reg(0x0283c);
867 	yi->reg_2840 = read_reg(0x02840);
868 	yi->reg_2844 = read_reg(0x02844);
869 	yi->reg_2848 = read_reg(0x02848);
870 	yi->reg_2854 = read_reg(0x02854);
871 	yi->reg_285c = read_reg(0x0285c);
872 	yi->reg_2864 = read_reg(0x02864);
873 	yi->reg_2870 = read_reg(0x02870);
874 	yi->reg_2874 = read_reg(0x02874);
875 	yi->reg_2898 = read_reg(0x02898);
876 	yi->reg_2890 = read_reg(0x02890);
877 
878 	yi->reg_289c = read_reg(0x0289c);
879 	yi->reg_2918 = read_reg(0x02918);
880 	yi->reg_291c = read_reg(0x0291c);
881 	yi->reg_2920 = read_reg(0x02920);
882 	yi->reg_2924 = read_reg(0x02924);
883 	yi->reg_2928 = read_reg(0x02928);
884 	yi->reg_292c = read_reg(0x0292c);
885 	yi->reg_2930 = read_reg(0x02930);
886 	yi->reg_2934 = read_reg(0x02934);
887 	yi->reg_2938 = read_reg(0x02938);
888 	yi->reg_293c = read_reg(0x0293c);
889 	yi->reg_2940 = read_reg(0x02940);
890 	yi->reg_2944 = read_reg(0x02944);
891 	yi->reg_2948 = read_reg(0x02948);
892 	yi->reg_294c = read_reg(0x0294c);
893 	yi->reg_2950 = read_reg(0x02950);
894 	yi->reg_2954 = read_reg(0x02954);
895 	yi->reg_2958 = read_reg(0x02958);
896 	yi->reg_295c = read_reg(0x0295c);
897 	yi->reg_2960 = read_reg(0x02960);
898 	yi->reg_2964 = read_reg(0x02964);
899 	yi->reg_2968 = read_reg(0x02968);
900 	yi->reg_296c = read_reg(0x0296c);
901 	yi->reg_2970 = read_reg(0x02970);
902 
903 	yi->v_filter_1 = -1;
904 	yi->v_filter_2 = -1;
905 	yi->h_filter = -1;
906 
907 	/* Set some valid size info */
908 	yi->osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
909 	yi->osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;
910 
911 	/* Bit 2 of reg 2878 indicates current decoder output format
912 	   0 : NTSC    1 : PAL */
913 	if (read_reg(0x2878) & 4)
914 		yi->decode_height = 576;
915 	else
916 		yi->decode_height = 480;
917 
918 	if (!itv->osd_info) {
919 		yi->osd_vis_w = 720 - yi->osd_x_offset;
920 		yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
921 	} else {
922 		/* If no visible size set, assume full size */
923 		if (!yi->osd_vis_w)
924 			yi->osd_vis_w = 720 - yi->osd_x_offset;
925 
926 		if (!yi->osd_vis_h) {
927 			yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
928 		} else if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) {
929 			/* If output video standard has changed, requested height may
930 			   not be legal */
931 			IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
932 					yi->osd_vis_h + yi->osd_y_offset,
933 					yi->decode_height);
934 			yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
935 		}
936 	}
937 
938 	/* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
939 	yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
940 	if (yi->blanking_ptr) {
941 		yi->blanking_dmaptr = pci_map_single(itv->pdev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
942 	} else {
943 		yi->blanking_dmaptr = 0;
944 		IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
945 	}
946 
947 	/* Enable YUV decoder output */
948 	write_reg_sync(0x01, IVTV_REG_VDM);
949 
950 	set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
951 	atomic_set(&yi->next_dma_frame, 0);
952 }
953 
954 /* Get next available yuv buffer on PVR350 */
955 static void ivtv_yuv_next_free(struct ivtv *itv)
956 {
957 	int draw, display;
958 	struct yuv_playback_info *yi = &itv->yuv_info;
959 
960 	if (atomic_read(&yi->next_dma_frame) == -1)
961 		ivtv_yuv_init(itv);
962 
963 	draw = atomic_read(&yi->next_fill_frame);
964 	display = atomic_read(&yi->next_dma_frame);
965 
966 	if (display > draw)
967 		display -= IVTV_YUV_BUFFERS;
968 
969 	if (draw - display >= yi->max_frames_buffered)
970 		draw = (u8)(draw - 1) % IVTV_YUV_BUFFERS;
971 	else
972 		yi->new_frame_info[draw].update = 0;
973 
974 	yi->draw_frame = draw;
975 }
976 
977 /* Set up frame according to ivtv_dma_frame parameters */
978 static void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
979 {
980 	struct yuv_playback_info *yi = &itv->yuv_info;
981 	u8 frame = yi->draw_frame;
982 	u8 last_frame = (u8)(frame - 1) % IVTV_YUV_BUFFERS;
983 	struct yuv_frame_info *nf = &yi->new_frame_info[frame];
984 	struct yuv_frame_info *of = &yi->new_frame_info[last_frame];
985 	int lace_threshold = yi->lace_threshold;
986 
987 	/* Preserve old update flag in case we're overwriting a queued frame */
988 	int update = nf->update;
989 
990 	/* Take a snapshot of the yuv coordinate information */
991 	nf->src_x = args->src.left;
992 	nf->src_y = args->src.top;
993 	nf->src_w = args->src.width;
994 	nf->src_h = args->src.height;
995 	nf->dst_x = args->dst.left;
996 	nf->dst_y = args->dst.top;
997 	nf->dst_w = args->dst.width;
998 	nf->dst_h = args->dst.height;
999 	nf->tru_x = args->dst.left;
1000 	nf->tru_w = args->src_width;
1001 	nf->tru_h = args->src_height;
1002 
1003 	/* Are we going to offset the Y plane */
1004 	nf->offset_y = (nf->tru_h + nf->src_x < 512 - 16) ? 1 : 0;
1005 
1006 	nf->update = 0;
1007 	nf->interlaced_y = 0;
1008 	nf->interlaced_uv = 0;
1009 	nf->delay = 0;
1010 	nf->sync_field = 0;
1011 	nf->lace_mode = yi->lace_mode & IVTV_YUV_MODE_MASK;
1012 
1013 	if (lace_threshold < 0)
1014 		lace_threshold = yi->decode_height - 1;
1015 
1016 	/* Work out the lace settings */
1017 	switch (nf->lace_mode) {
1018 	case IVTV_YUV_MODE_PROGRESSIVE: /* Progressive mode */
1019 		nf->interlaced = 0;
1020 		if (nf->tru_h < 512 || (nf->tru_h > 576 && nf->tru_h < 1021))
1021 			nf->interlaced_y = 0;
1022 		else
1023 			nf->interlaced_y = 1;
1024 
1025 		if (nf->tru_h < 1021 && (nf->dst_h >= nf->src_h / 2))
1026 			nf->interlaced_uv = 0;
1027 		else
1028 			nf->interlaced_uv = 1;
1029 		break;
1030 
1031 	case IVTV_YUV_MODE_AUTO:
1032 		if (nf->tru_h <= lace_threshold || nf->tru_h > 576 || nf->tru_w > 720) {
1033 			nf->interlaced = 0;
1034 			if ((nf->tru_h < 512) ||
1035 			    (nf->tru_h > 576 && nf->tru_h < 1021) ||
1036 			    (nf->tru_w > 720 && nf->tru_h < 1021))
1037 				nf->interlaced_y = 0;
1038 			else
1039 				nf->interlaced_y = 1;
1040 			if (nf->tru_h < 1021 && (nf->dst_h >= nf->src_h / 2))
1041 				nf->interlaced_uv = 0;
1042 			else
1043 				nf->interlaced_uv = 1;
1044 		} else {
1045 			nf->interlaced = 1;
1046 			nf->interlaced_y = 1;
1047 			nf->interlaced_uv = 1;
1048 		}
1049 		break;
1050 
1051 	case IVTV_YUV_MODE_INTERLACED: /* Interlace mode */
1052 	default:
1053 		nf->interlaced = 1;
1054 		nf->interlaced_y = 1;
1055 		nf->interlaced_uv = 1;
1056 		break;
1057 	}
1058 
1059 	if (memcmp(&yi->old_frame_info_args, nf, sizeof(*nf))) {
1060 		yi->old_frame_info_args = *nf;
1061 		nf->update = 1;
1062 		IVTV_DEBUG_YUV("Requesting reg update for frame %d\n", frame);
1063 	}
1064 
1065 	nf->update |= update;
1066 	nf->sync_field = yi->lace_sync_field;
1067 	nf->delay = nf->sync_field != of->sync_field;
1068 }
1069 
1070 /* Frame is complete & ready for display */
1071 void ivtv_yuv_frame_complete(struct ivtv *itv)
1072 {
1073 	atomic_set(&itv->yuv_info.next_fill_frame,
1074 			(itv->yuv_info.draw_frame + 1) % IVTV_YUV_BUFFERS);
1075 }
1076 
1077 static int ivtv_yuv_udma_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
1078 {
1079 	DEFINE_WAIT(wait);
1080 	int rc = 0;
1081 	int got_sig = 0;
1082 	/* DMA the frame */
1083 	mutex_lock(&itv->udma.lock);
1084 
1085 	if ((rc = ivtv_yuv_prep_user_dma(itv, &itv->udma, args)) != 0) {
1086 		mutex_unlock(&itv->udma.lock);
1087 		return rc;
1088 	}
1089 
1090 	ivtv_udma_prepare(itv);
1091 	prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
1092 	/* if no UDMA is pending and no UDMA is in progress, then the DMA
1093 	   is finished */
1094 	while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) ||
1095 	       test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
1096 		/* don't interrupt if the DMA is in progress but break off
1097 		   a still pending DMA. */
1098 		got_sig = signal_pending(current);
1099 		if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
1100 			break;
1101 		got_sig = 0;
1102 		schedule();
1103 	}
1104 	finish_wait(&itv->dma_waitq, &wait);
1105 
1106 	/* Unmap Last DMA Xfer */
1107 	ivtv_udma_unmap(itv);
1108 
1109 	if (got_sig) {
1110 		IVTV_DEBUG_INFO("User stopped YUV UDMA\n");
1111 		mutex_unlock(&itv->udma.lock);
1112 		return -EINTR;
1113 	}
1114 
1115 	ivtv_yuv_frame_complete(itv);
1116 
1117 	mutex_unlock(&itv->udma.lock);
1118 	return rc;
1119 }
1120 
1121 /* Setup frame according to V4L2 parameters */
1122 void ivtv_yuv_setup_stream_frame(struct ivtv *itv)
1123 {
1124 	struct yuv_playback_info *yi = &itv->yuv_info;
1125 	struct ivtv_dma_frame dma_args;
1126 
1127 	ivtv_yuv_next_free(itv);
1128 
1129 	/* Copy V4L2 parameters to an ivtv_dma_frame struct... */
1130 	dma_args.y_source = NULL;
1131 	dma_args.uv_source = NULL;
1132 	dma_args.src.left = 0;
1133 	dma_args.src.top = 0;
1134 	dma_args.src.width = yi->v4l2_src_w;
1135 	dma_args.src.height = yi->v4l2_src_h;
1136 	dma_args.dst = yi->main_rect;
1137 	dma_args.src_width = yi->v4l2_src_w;
1138 	dma_args.src_height = yi->v4l2_src_h;
1139 
1140 	/* ... and use the same setup routine as ivtv_yuv_prep_frame */
1141 	ivtv_yuv_setup_frame(itv, &dma_args);
1142 
1143 	if (!itv->dma_data_req_offset)
1144 		itv->dma_data_req_offset = yuv_offset[yi->draw_frame];
1145 }
1146 
1147 /* Attempt to dma a frame from a user buffer */
1148 int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src)
1149 {
1150 	struct yuv_playback_info *yi = &itv->yuv_info;
1151 	struct ivtv_dma_frame dma_args;
1152 	int res;
1153 
1154 	ivtv_yuv_setup_stream_frame(itv);
1155 
1156 	/* We only need to supply source addresses for this */
1157 	dma_args.y_source = src;
1158 	dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31);
1159 	/* Wait for frame DMA. Note that serialize_lock is locked,
1160 	   so to allow other processes to access the driver while
1161 	   we are waiting unlock first and later lock again. */
1162 	mutex_unlock(&itv->serialize_lock);
1163 	res = ivtv_yuv_udma_frame(itv, &dma_args);
1164 	mutex_lock(&itv->serialize_lock);
1165 	return res;
1166 }
1167 
1168 /* IVTV_IOC_DMA_FRAME ioctl handler */
1169 int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
1170 {
1171 	int res;
1172 
1173 /*	IVTV_DEBUG_INFO("yuv_prep_frame\n"); */
1174 	ivtv_yuv_next_free(itv);
1175 	ivtv_yuv_setup_frame(itv, args);
1176 	/* Wait for frame DMA. Note that serialize_lock is locked,
1177 	   so to allow other processes to access the driver while
1178 	   we are waiting unlock first and later lock again. */
1179 	mutex_unlock(&itv->serialize_lock);
1180 	res = ivtv_yuv_udma_frame(itv, args);
1181 	mutex_lock(&itv->serialize_lock);
1182 	return res;
1183 }
1184 
1185 void ivtv_yuv_close(struct ivtv *itv)
1186 {
1187 	struct yuv_playback_info *yi = &itv->yuv_info;
1188 	int h_filter, v_filter_1, v_filter_2;
1189 
1190 	IVTV_DEBUG_YUV("ivtv_yuv_close\n");
1191 	mutex_unlock(&itv->serialize_lock);
1192 	ivtv_waitq(&itv->vsync_waitq);
1193 	mutex_lock(&itv->serialize_lock);
1194 
1195 	yi->running = 0;
1196 	atomic_set(&yi->next_dma_frame, -1);
1197 	atomic_set(&yi->next_fill_frame, 0);
1198 
1199 	/* Reset registers we have changed so mpeg playback works */
1200 
1201 	/* If we fully restore this register, the display may remain active.
1202 	   Restore, but set one bit to blank the video. Firmware will always
1203 	   clear this bit when needed, so not a problem. */
1204 	write_reg(yi->reg_2898 | 0x01000000, 0x2898);
1205 
1206 	write_reg(yi->reg_2834, 0x02834);
1207 	write_reg(yi->reg_2838, 0x02838);
1208 	write_reg(yi->reg_283c, 0x0283c);
1209 	write_reg(yi->reg_2840, 0x02840);
1210 	write_reg(yi->reg_2844, 0x02844);
1211 	write_reg(yi->reg_2848, 0x02848);
1212 	write_reg(yi->reg_2854, 0x02854);
1213 	write_reg(yi->reg_285c, 0x0285c);
1214 	write_reg(yi->reg_2864, 0x02864);
1215 	write_reg(yi->reg_2870, 0x02870);
1216 	write_reg(yi->reg_2874, 0x02874);
1217 	write_reg(yi->reg_2890, 0x02890);
1218 	write_reg(yi->reg_289c, 0x0289c);
1219 
1220 	write_reg(yi->reg_2918, 0x02918);
1221 	write_reg(yi->reg_291c, 0x0291c);
1222 	write_reg(yi->reg_2920, 0x02920);
1223 	write_reg(yi->reg_2924, 0x02924);
1224 	write_reg(yi->reg_2928, 0x02928);
1225 	write_reg(yi->reg_292c, 0x0292c);
1226 	write_reg(yi->reg_2930, 0x02930);
1227 	write_reg(yi->reg_2934, 0x02934);
1228 	write_reg(yi->reg_2938, 0x02938);
1229 	write_reg(yi->reg_293c, 0x0293c);
1230 	write_reg(yi->reg_2940, 0x02940);
1231 	write_reg(yi->reg_2944, 0x02944);
1232 	write_reg(yi->reg_2948, 0x02948);
1233 	write_reg(yi->reg_294c, 0x0294c);
1234 	write_reg(yi->reg_2950, 0x02950);
1235 	write_reg(yi->reg_2954, 0x02954);
1236 	write_reg(yi->reg_2958, 0x02958);
1237 	write_reg(yi->reg_295c, 0x0295c);
1238 	write_reg(yi->reg_2960, 0x02960);
1239 	write_reg(yi->reg_2964, 0x02964);
1240 	write_reg(yi->reg_2968, 0x02968);
1241 	write_reg(yi->reg_296c, 0x0296c);
1242 	write_reg(yi->reg_2970, 0x02970);
1243 
1244 	/* Prepare to restore filters */
1245 
1246 	/* First the horizontal filter */
1247 	if ((yi->reg_2834 & 0x0000FFFF) == (yi->reg_2834 >> 16)) {
1248 		/* An exact size match uses filter 0 */
1249 		h_filter = 0;
1250 	} else {
1251 		/* Figure out which filter to use */
1252 		h_filter = ((yi->reg_2834 << 16) / (yi->reg_2834 >> 16)) >> 15;
1253 		h_filter = (h_filter >> 1) + (h_filter & 1);
1254 		/* Only an exact size match can use filter 0. */
1255 		h_filter += !h_filter;
1256 	}
1257 
1258 	/* Now the vertical filter */
1259 	if ((yi->reg_2918 & 0x0000FFFF) == (yi->reg_2918 >> 16)) {
1260 		/* An exact size match uses filter 0/1 */
1261 		v_filter_1 = 0;
1262 		v_filter_2 = 1;
1263 	} else {
1264 		/* Figure out which filter to use */
1265 		v_filter_1 = ((yi->reg_2918 << 16) / (yi->reg_2918 >> 16)) >> 15;
1266 		v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1);
1267 		/* Only an exact size match can use filter 0 */
1268 		v_filter_1 += !v_filter_1;
1269 		v_filter_2 = v_filter_1;
1270 	}
1271 
1272 	/* Now restore the filters */
1273 	ivtv_yuv_filter(itv, h_filter, v_filter_1, v_filter_2);
1274 
1275 	/* and clear a few registers */
1276 	write_reg(0, 0x02814);
1277 	write_reg(0, 0x0282c);
1278 	write_reg(0, 0x02904);
1279 	write_reg(0, 0x02910);
1280 
1281 	/* Release the blanking buffer */
1282 	if (yi->blanking_ptr) {
1283 		kfree(yi->blanking_ptr);
1284 		yi->blanking_ptr = NULL;
1285 		pci_unmap_single(itv->pdev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
1286 	}
1287 
1288 	/* Invalidate the old dimension information */
1289 	yi->old_frame_info.src_w = 0;
1290 	yi->old_frame_info.src_h = 0;
1291 	yi->old_frame_info_args.src_w = 0;
1292 	yi->old_frame_info_args.src_h = 0;
1293 
1294 	/* All done. */
1295 	clear_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
1296 }
1297