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