1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21#include "ivtv-driver.h"
22#include "ivtv-udma.h"
23#include "ivtv-yuv.h"
24
25
26const u32 yuv_offset[IVTV_YUV_BUFFERS] = {
27 0x001a8600,
28 0x00240400,
29 0x002d8200,
30 0x00370000,
31 0x00029000,
32 0x000C0E00,
33 0x006B0400,
34 0x00748200
35};
36
37static 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
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
78 y_pages = get_user_pages_unlocked(y_dma.uaddr,
79 y_dma.page_count, 0, 1, &dma->map[0]);
80 uv_pages = 0;
81 if (y_pages == y_dma.page_count) {
82 uv_pages = get_user_pages_unlocked(uv_dma.uaddr,
83 uv_dma.page_count, 0, 1, &dma->map[y_pages]);
84 }
85
86 if (y_pages != y_dma.page_count || uv_pages != uv_dma.page_count) {
87 int rc = -EFAULT;
88
89 if (y_pages == y_dma.page_count) {
90 IVTV_DEBUG_WARN
91 ("failed to map uv user pages, returned %d "
92 "expecting %d\n", uv_pages, uv_dma.page_count);
93
94 if (uv_pages >= 0) {
95 for (i = 0; i < uv_pages; i++)
96 put_page(dma->map[y_pages + i]);
97 rc = -EFAULT;
98 } else {
99 rc = uv_pages;
100 }
101 } else {
102 IVTV_DEBUG_WARN
103 ("failed to map y user pages, returned %d "
104 "expecting %d\n", y_pages, y_dma.page_count);
105 }
106 if (y_pages >= 0) {
107 for (i = 0; i < y_pages; i++)
108 put_page(dma->map[i]);
109
110
111
112
113
114
115 } else {
116 rc = y_pages;
117 }
118 return rc;
119 }
120
121 dma->page_count = y_pages + uv_pages;
122
123
124 if (ivtv_udma_fill_sg_list (dma, &uv_dma, ivtv_udma_fill_sg_list (dma, &y_dma, 0)) < 0) {
125 IVTV_DEBUG_WARN("could not allocate bounce buffers for highmem userspace buffers\n");
126 for (i = 0; i < dma->page_count; i++) {
127 put_page(dma->map[i]);
128 }
129 dma->page_count = 0;
130 return -ENOMEM;
131 }
132 dma->SG_length = pci_map_sg(itv->pdev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
133
134
135 ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
136
137
138 if (f->offset_y && yi->blanking_dmaptr) {
139 dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16);
140 dma->SGarray[dma->SG_length].src = cpu_to_le32(yi->blanking_dmaptr);
141 dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DECODER_OFFSET + yuv_offset[frame]);
142 dma->SG_length++;
143 }
144
145
146 dma->SGarray[dma->SG_length - 1].size |= cpu_to_le32(0x80000000);
147
148 ivtv_udma_sync_for_device(itv);
149 return 0;
150}
151
152
153int ivtv_yuv_filter_check(struct ivtv *itv)
154{
155 int i, y, uv;
156
157 for (i = 0, y = 16, uv = 4; i < 16; i++, y += 24, uv += 12) {
158 if ((read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + y) != i << 16) ||
159 (read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + uv) != i << 16)) {
160 IVTV_WARN ("YUV filter table not found in firmware.\n");
161 return -1;
162 }
163 }
164 return 0;
165}
166
167static void ivtv_yuv_filter(struct ivtv *itv, int h_filter, int v_filter_1, int v_filter_2)
168{
169 u32 i, line;
170
171
172 if (h_filter > -1) {
173 if (h_filter > 4)
174 h_filter = 4;
175 i = IVTV_YUV_HORIZONTAL_FILTER_OFFSET + (h_filter * 384);
176 for (line = 0; line < 16; line++) {
177 write_reg(read_dec(i), 0x02804);
178 write_reg(read_dec(i), 0x0281c);
179 i += 4;
180 write_reg(read_dec(i), 0x02808);
181 write_reg(read_dec(i), 0x02820);
182 i += 4;
183 write_reg(read_dec(i), 0x0280c);
184 write_reg(read_dec(i), 0x02824);
185 i += 4;
186 write_reg(read_dec(i), 0x02810);
187 write_reg(read_dec(i), 0x02828);
188 i += 4;
189 write_reg(read_dec(i), 0x02814);
190 write_reg(read_dec(i), 0x0282c);
191 i += 8;
192 write_reg(0, 0x02818);
193 write_reg(0, 0x02830);
194 }
195 IVTV_DEBUG_YUV("h_filter -> %d\n", h_filter);
196 }
197
198 if (v_filter_1 > -1) {
199 if (v_filter_1 > 4)
200 v_filter_1 = 4;
201 i = IVTV_YUV_VERTICAL_FILTER_OFFSET + (v_filter_1 * 192);
202 for (line = 0; line < 16; line++) {
203 write_reg(read_dec(i), 0x02900);
204 i += 4;
205 write_reg(read_dec(i), 0x02904);
206 i += 8;
207 write_reg(0, 0x02908);
208 }
209 IVTV_DEBUG_YUV("v_filter_1 -> %d\n", v_filter_1);
210 }
211
212 if (v_filter_2 > -1) {
213 if (v_filter_2 > 4)
214 v_filter_2 = 4;
215 i = IVTV_YUV_VERTICAL_FILTER_OFFSET + (v_filter_2 * 192);
216 for (line = 0; line < 16; line++) {
217 write_reg(read_dec(i), 0x0290c);
218 i += 4;
219 write_reg(read_dec(i), 0x02910);
220 i += 8;
221 write_reg(0, 0x02914);
222 }
223 IVTV_DEBUG_YUV("v_filter_2 -> %d\n", v_filter_2);
224 }
225}
226
227static void ivtv_yuv_handle_horizontal(struct ivtv *itv, struct yuv_frame_info *f)
228{
229 struct yuv_playback_info *yi = &itv->yuv_info;
230 u32 reg_2834, reg_2838, reg_283c;
231 u32 reg_2844, reg_2854, reg_285c;
232 u32 reg_2864, reg_2874, reg_2890;
233 u32 reg_2870, reg_2870_base, reg_2870_offset;
234 int x_cutoff;
235 int h_filter;
236 u32 master_width;
237
238 IVTV_DEBUG_WARN
239 ("Adjust to width %d src_w %d dst_w %d src_x %d dst_x %d\n",
240 f->tru_w, f->src_w, f->dst_w, f->src_x, f->dst_x);
241
242
243 x_cutoff = f->src_w + f->src_x;
244
245
246 reg_2834 = f->dst_w;
247 reg_2838 = reg_2834;
248
249
250 reg_2890 = f->dst_x;
251
252
253 reg_2870 = 0;
254
255
256
257
258
259
260
261 if (f->vis_w == 720) {
262 if ((f->tru_x - f->pan_x > -1) && (f->tru_x - f->pan_x <= 40) && (f->dst_w >= 680))
263 reg_2870 = 10 - (f->tru_x - f->pan_x) / 4;
264 else if ((f->tru_x - f->pan_x < 0) && (f->tru_x - f->pan_x >= -20) && (f->dst_w >= 660))
265 reg_2870 = (10 + (f->tru_x - f->pan_x) / 2);
266
267 if (f->dst_w >= f->src_w)
268 reg_2870 = reg_2870 << 16 | reg_2870;
269 else
270 reg_2870 = ((reg_2870 & ~1) << 15) | (reg_2870 & ~1);
271 }
272
273 if (f->dst_w < f->src_w)
274 reg_2870 = 0x000d000e - reg_2870;
275 else
276 reg_2870 = 0x0012000e - reg_2870;
277
278
279 reg_2870_offset = (f->src_x * ((f->dst_w << 21) / f->src_w)) >> 19;
280
281 if (f->dst_w >= f->src_w) {
282 x_cutoff &= ~1;
283 master_width = (f->src_w * 0x00200000) / (f->dst_w);
284 if (master_width * f->dst_w != f->src_w * 0x00200000)
285 master_width++;
286 reg_2834 = (reg_2834 << 16) | x_cutoff;
287 reg_2838 = (reg_2838 << 16) | x_cutoff;
288 reg_283c = master_width >> 2;
289 reg_2844 = master_width >> 2;
290 reg_2854 = master_width;
291 reg_285c = master_width >> 1;
292 reg_2864 = master_width >> 1;
293
294
295
296 if (f->dst_w > f->src_w)
297 reg_2870_base = ((f->dst_w - f->src_w)<<16) / (f->src_w <<14);
298 else
299 reg_2870_base = 0;
300
301 reg_2870 += (((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 2) + (reg_2870_base << 17 | reg_2870_base);
302 reg_2874 = 0;
303 } else if (f->dst_w < f->src_w / 2) {
304 master_width = (f->src_w * 0x00080000) / f->dst_w;
305 if (master_width * f->dst_w != f->src_w * 0x00080000)
306 master_width++;
307 reg_2834 = (reg_2834 << 16) | x_cutoff;
308 reg_2838 = (reg_2838 << 16) | x_cutoff;
309 reg_283c = master_width >> 2;
310 reg_2844 = master_width >> 1;
311 reg_2854 = master_width;
312 reg_285c = master_width >> 1;
313 reg_2864 = master_width >> 1;
314 reg_2870 += ((reg_2870_offset << 15) & 0xFFFF0000) | reg_2870_offset;
315 reg_2870 += (5 - (((f->src_w + f->src_w / 2) - 1) / f->dst_w)) << 16;
316 reg_2874 = 0x00000012;
317 } else {
318 master_width = (f->src_w * 0x00100000) / f->dst_w;
319 if (master_width * f->dst_w != f->src_w * 0x00100000)
320 master_width++;
321 reg_2834 = (reg_2834 << 16) | x_cutoff;
322 reg_2838 = (reg_2838 << 16) | x_cutoff;
323 reg_283c = master_width >> 2;
324 reg_2844 = master_width >> 1;
325 reg_2854 = master_width;
326 reg_285c = master_width >> 1;
327 reg_2864 = master_width >> 1;
328 reg_2870 += ((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 1;
329 reg_2870 += (5 - (((f->src_w * 3) - 1) / f->dst_w)) << 16;
330 reg_2874 = 0x00000001;
331 }
332
333
334 if (f->src_w == f->dst_w) {
335
336 h_filter = 0;
337 } else {
338
339 h_filter = ((f->src_w << 16) / f->dst_w) >> 15;
340 h_filter = (h_filter >> 1) + (h_filter & 1);
341
342 h_filter += !h_filter;
343 }
344
345 write_reg(reg_2834, 0x02834);
346 write_reg(reg_2838, 0x02838);
347 IVTV_DEBUG_YUV("Update reg 0x2834 %08x->%08x 0x2838 %08x->%08x\n",
348 yi->reg_2834, reg_2834, yi->reg_2838, reg_2838);
349
350 write_reg(reg_283c, 0x0283c);
351 write_reg(reg_2844, 0x02844);
352
353 IVTV_DEBUG_YUV("Update reg 0x283c %08x->%08x 0x2844 %08x->%08x\n",
354 yi->reg_283c, reg_283c, yi->reg_2844, reg_2844);
355
356 write_reg(0x00080514, 0x02840);
357 write_reg(0x00100514, 0x02848);
358 IVTV_DEBUG_YUV("Update reg 0x2840 %08x->%08x 0x2848 %08x->%08x\n",
359 yi->reg_2840, 0x00080514, yi->reg_2848, 0x00100514);
360
361 write_reg(reg_2854, 0x02854);
362 IVTV_DEBUG_YUV("Update reg 0x2854 %08x->%08x \n",
363 yi->reg_2854, reg_2854);
364
365 write_reg(reg_285c, 0x0285c);
366 write_reg(reg_2864, 0x02864);
367 IVTV_DEBUG_YUV("Update reg 0x285c %08x->%08x 0x2864 %08x->%08x\n",
368 yi->reg_285c, reg_285c, yi->reg_2864, reg_2864);
369
370 write_reg(reg_2874, 0x02874);
371 IVTV_DEBUG_YUV("Update reg 0x2874 %08x->%08x\n",
372 yi->reg_2874, reg_2874);
373
374 write_reg(reg_2870, 0x02870);
375 IVTV_DEBUG_YUV("Update reg 0x2870 %08x->%08x\n",
376 yi->reg_2870, reg_2870);
377
378 write_reg(reg_2890, 0x02890);
379 IVTV_DEBUG_YUV("Update reg 0x2890 %08x->%08x\n",
380 yi->reg_2890, reg_2890);
381
382
383 if (h_filter != yi->h_filter) {
384 ivtv_yuv_filter(itv, h_filter, -1, -1);
385 yi->h_filter = h_filter;
386 }
387}
388
389static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *f)
390{
391 struct yuv_playback_info *yi = &itv->yuv_info;
392 u32 master_height;
393 u32 reg_2918, reg_291c, reg_2920, reg_2928;
394 u32 reg_2930, reg_2934, reg_293c;
395 u32 reg_2940, reg_2944, reg_294c;
396 u32 reg_2950, reg_2954, reg_2958, reg_295c;
397 u32 reg_2960, reg_2964, reg_2968, reg_296c;
398 u32 reg_289c;
399 u32 src_major_y, src_minor_y;
400 u32 src_major_uv, src_minor_uv;
401 u32 reg_2964_base, reg_2968_base;
402 int v_filter_1, v_filter_2;
403
404 IVTV_DEBUG_WARN
405 ("Adjust to height %d src_h %d dst_h %d src_y %d dst_y %d\n",
406 f->tru_h, f->src_h, f->dst_h, f->src_y, f->dst_y);
407
408
409 IVTV_DEBUG_YUV("Scaling mode Y: %s\n",
410 f->interlaced_y ? "Interlaced" : "Progressive");
411
412 IVTV_DEBUG_YUV("Scaling mode UV: %s\n",
413 f->interlaced_uv ? "Interlaced" : "Progressive");
414
415
416 IVTV_DEBUG_WARN("Source video: %s\n",
417 f->interlaced ? "Interlaced" : "Progressive");
418
419
420
421 if (f->src_y < 8) {
422 src_minor_uv = f->src_y;
423 src_major_uv = 0;
424 } else {
425 src_minor_uv = 8;
426 src_major_uv = f->src_y - 8;
427 }
428
429 src_minor_y = src_minor_uv;
430 src_major_y = src_major_uv;
431
432 if (f->offset_y)
433 src_minor_y += 16;
434
435 if (f->interlaced_y)
436 reg_2918 = (f->dst_h << 16) | (f->src_h + src_minor_y);
437 else
438 reg_2918 = (f->dst_h << 16) | ((f->src_h + src_minor_y) << 1);
439
440 if (f->interlaced_uv)
441 reg_291c = (f->dst_h << 16) | ((f->src_h + src_minor_uv) >> 1);
442 else
443 reg_291c = (f->dst_h << 16) | (f->src_h + src_minor_uv);
444
445 reg_2964_base = (src_minor_y * ((f->dst_h << 16) / f->src_h)) >> 14;
446 reg_2968_base = (src_minor_uv * ((f->dst_h << 16) / f->src_h)) >> 14;
447
448 if (f->dst_h / 2 >= f->src_h && !f->interlaced_y) {
449 master_height = (f->src_h * 0x00400000) / f->dst_h;
450 if ((f->src_h * 0x00400000) - (master_height * f->dst_h) >= f->dst_h / 2)
451 master_height++;
452 reg_2920 = master_height >> 2;
453 reg_2928 = master_height >> 3;
454 reg_2930 = master_height;
455 reg_2940 = master_height >> 1;
456 reg_2964_base >>= 3;
457 reg_2968_base >>= 3;
458 reg_296c = 0x00000000;
459 } else if (f->dst_h >= f->src_h) {
460 master_height = (f->src_h * 0x00400000) / f->dst_h;
461 master_height = (master_height >> 1) + (master_height & 1);
462 reg_2920 = master_height >> 2;
463 reg_2928 = master_height >> 2;
464 reg_2930 = master_height;
465 reg_2940 = master_height >> 1;
466 reg_296c = 0x00000000;
467 if (f->interlaced_y) {
468 reg_2964_base >>= 3;
469 } else {
470 reg_296c++;
471 reg_2964_base >>= 2;
472 }
473 if (f->interlaced_uv)
474 reg_2928 >>= 1;
475 reg_2968_base >>= 3;
476 } else if (f->dst_h >= f->src_h / 2) {
477 master_height = (f->src_h * 0x00200000) / f->dst_h;
478 master_height = (master_height >> 1) + (master_height & 1);
479 reg_2920 = master_height >> 2;
480 reg_2928 = master_height >> 2;
481 reg_2930 = master_height;
482 reg_2940 = master_height;
483 reg_296c = 0x00000101;
484 if (f->interlaced_y) {
485 reg_2964_base >>= 2;
486 } else {
487 reg_296c++;
488 reg_2964_base >>= 1;
489 }
490 if (f->interlaced_uv)
491 reg_2928 >>= 1;
492 reg_2968_base >>= 2;
493 } else {
494 master_height = (f->src_h * 0x00100000) / f->dst_h;
495 master_height = (master_height >> 1) + (master_height & 1);
496 reg_2920 = master_height >> 2;
497 reg_2928 = master_height >> 2;
498 reg_2930 = master_height;
499 reg_2940 = master_height;
500 reg_2964_base >>= 1;
501 reg_2968_base >>= 2;
502 reg_296c = 0x00000102;
503 }
504
505
506
507 if (f->src_h == f->dst_h) {
508 reg_2934 = 0x00020000;
509 reg_293c = 0x00100000;
510 reg_2944 = 0x00040000;
511 reg_294c = 0x000b0000;
512 } else {
513 reg_2934 = 0x00000FF0;
514 reg_293c = 0x00000FF0;
515 reg_2944 = 0x00000FF0;
516 reg_294c = 0x00000FF0;
517 }
518
519
520 reg_2950 = 0x00010000 + src_major_y;
521 if (f->interlaced_y)
522 reg_2950 += 0x00010000;
523 reg_2954 = reg_2950 + 1;
524
525 reg_2958 = 0x00010000 + (src_major_y >> 1);
526 if (f->interlaced_uv)
527 reg_2958 += 0x00010000;
528 reg_295c = reg_2958 + 1;
529
530 if (yi->decode_height == 480)
531 reg_289c = 0x011e0017;
532 else
533 reg_289c = 0x01500017;
534
535 if (f->dst_y < 0)
536 reg_289c = (reg_289c - ((f->dst_y & ~1)<<15))-(f->dst_y >>1);
537 else
538 reg_289c = (reg_289c + ((f->dst_y & ~1)<<15))+(f->dst_y >>1);
539
540
541
542 reg_2960 = ((src_minor_y + f->src_h + src_major_y) - 1) |
543 (((src_minor_uv + f->src_h + src_major_uv - 1) & ~1) << 15);
544
545
546 if (f->src_h == f->dst_h) {
547 reg_2964 = 1;
548 } else {
549 reg_2964 = 2 + ((f->dst_h << 1) / f->src_h);
550 reg_2964 = (reg_2964 >> 1) + (reg_2964 & 1);
551 }
552 reg_2968 = (reg_2964 << 16) + reg_2964 + (reg_2964 >> 1);
553 reg_2964 = (reg_2964 << 16) + reg_2964 + (reg_2964 * 46 / 94);
554
555
556
557
558 reg_2964 = 0x00010001 + ((reg_2964 & 0x0000FFFF) - (reg_2964 >> 16));
559 reg_2968 = 0x00010001 + ((reg_2968 & 0x0000FFFF) - (reg_2968 >> 16));
560
561
562
563
564 if ((reg_2964 != 0x00010001) && (f->dst_h / 2 <= f->src_h))
565 reg_2964 = (reg_2964 & 0xFFFF0000) + ((reg_2964 & 0x0000FFFF) / 2);
566
567 if (!f->interlaced_y)
568 reg_2964 -= 0x00010001;
569 if (!f->interlaced_uv)
570 reg_2968 -= 0x00010001;
571
572 reg_2964 += ((reg_2964_base << 16) | reg_2964_base);
573 reg_2968 += ((reg_2968_base << 16) | reg_2968_base);
574
575
576 if (f->src_h == f->dst_h) {
577
578 v_filter_1 = 0;
579 v_filter_2 = 1;
580 } else {
581
582 v_filter_1 = ((f->src_h << 16) / f->dst_h) >> 15;
583 v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1);
584
585 v_filter_1 += !v_filter_1;
586 v_filter_2 = v_filter_1;
587 }
588
589 write_reg(reg_2934, 0x02934);
590 write_reg(reg_293c, 0x0293c);
591 IVTV_DEBUG_YUV("Update reg 0x2934 %08x->%08x 0x293c %08x->%08x\n",
592 yi->reg_2934, reg_2934, yi->reg_293c, reg_293c);
593 write_reg(reg_2944, 0x02944);
594 write_reg(reg_294c, 0x0294c);
595 IVTV_DEBUG_YUV("Update reg 0x2944 %08x->%08x 0x294c %08x->%08x\n",
596 yi->reg_2944, reg_2944, yi->reg_294c, reg_294c);
597
598
599
600
601
602 write_reg(reg_2930, 0x02938);
603 write_reg(reg_2930, 0x02930);
604 IVTV_DEBUG_YUV("Update reg 0x2930 %08x->%08x 0x2938 %08x->%08x\n",
605 yi->reg_2930, reg_2930, yi->reg_2938, reg_2930);
606
607 write_reg(reg_2928, 0x02928);
608 write_reg(reg_2928 + 0x514, 0x0292C);
609 IVTV_DEBUG_YUV("Update reg 0x2928 %08x->%08x 0x292c %08x->%08x\n",
610 yi->reg_2928, reg_2928, yi->reg_292c, reg_2928 + 0x514);
611
612 write_reg(reg_2920, 0x02920);
613 write_reg(reg_2920 + 0x514, 0x02924);
614 IVTV_DEBUG_YUV("Update reg 0x2920 %08x->%08x 0x2924 %08x->%08x\n",
615 yi->reg_2920, reg_2920, yi->reg_2924, reg_2920 + 0x514);
616
617 write_reg(reg_2918, 0x02918);
618 write_reg(reg_291c, 0x0291C);
619 IVTV_DEBUG_YUV("Update reg 0x2918 %08x->%08x 0x291C %08x->%08x\n",
620 yi->reg_2918, reg_2918, yi->reg_291c, reg_291c);
621
622 write_reg(reg_296c, 0x0296c);
623 IVTV_DEBUG_YUV("Update reg 0x296c %08x->%08x\n",
624 yi->reg_296c, reg_296c);
625
626 write_reg(reg_2940, 0x02948);
627 write_reg(reg_2940, 0x02940);
628 IVTV_DEBUG_YUV("Update reg 0x2940 %08x->%08x 0x2948 %08x->%08x\n",
629 yi->reg_2940, reg_2940, yi->reg_2948, reg_2940);
630
631 write_reg(reg_2950, 0x02950);
632 write_reg(reg_2954, 0x02954);
633 IVTV_DEBUG_YUV("Update reg 0x2950 %08x->%08x 0x2954 %08x->%08x\n",
634 yi->reg_2950, reg_2950, yi->reg_2954, reg_2954);
635
636 write_reg(reg_2958, 0x02958);
637 write_reg(reg_295c, 0x0295C);
638 IVTV_DEBUG_YUV("Update reg 0x2958 %08x->%08x 0x295C %08x->%08x\n",
639 yi->reg_2958, reg_2958, yi->reg_295c, reg_295c);
640
641 write_reg(reg_2960, 0x02960);
642 IVTV_DEBUG_YUV("Update reg 0x2960 %08x->%08x \n",
643 yi->reg_2960, reg_2960);
644
645 write_reg(reg_2964, 0x02964);
646 write_reg(reg_2968, 0x02968);
647 IVTV_DEBUG_YUV("Update reg 0x2964 %08x->%08x 0x2968 %08x->%08x\n",
648 yi->reg_2964, reg_2964, yi->reg_2968, reg_2968);
649
650 write_reg(reg_289c, 0x0289c);
651 IVTV_DEBUG_YUV("Update reg 0x289c %08x->%08x\n",
652 yi->reg_289c, reg_289c);
653
654
655 if (v_filter_1 != yi->v_filter_1) {
656 ivtv_yuv_filter(itv, -1, v_filter_1, -1);
657 yi->v_filter_1 = v_filter_1;
658 }
659
660
661 if (v_filter_2 != yi->v_filter_2) {
662 ivtv_yuv_filter(itv, -1, -1, v_filter_2);
663 yi->v_filter_2 = v_filter_2;
664 }
665}
666
667
668static u32 ivtv_yuv_window_setup(struct ivtv *itv, struct yuv_frame_info *f)
669{
670 struct yuv_frame_info *of = &itv->yuv_info.old_frame_info;
671 int osd_crop;
672 u32 osd_scale;
673 u32 yuv_update = 0;
674
675
676 if (f->src_x < 0)
677 f->src_x = 0;
678 if (f->src_y < 0)
679 f->src_y = 0;
680
681
682 if ((osd_crop = f->src_w - 4 * f->dst_w) > 0) {
683 f->src_x += osd_crop / 2;
684 f->src_w = (f->src_w - osd_crop) & ~3;
685 f->dst_w = f->src_w / 4;
686 f->dst_w += f->dst_w & 1;
687 }
688
689
690 if (f->src_h / f->dst_h >= 2) {
691
692
693 f->interlaced_y = 1;
694
695 if ((osd_crop = f->src_h - 4 * f->dst_h) > 0) {
696
697 f->src_y += osd_crop / 2;
698 f->src_h = (f->src_h - osd_crop) & ~3;
699 f->dst_h = f->src_h / 4;
700 f->dst_h += f->dst_h & 1;
701 }
702 }
703
704
705 if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 ||
706 (int)f->src_w <= 2 || (int)f->src_h <= 2) {
707 return IVTV_YUV_UPDATE_INVALID;
708 }
709
710
711 osd_scale = (f->src_h << 16) / f->dst_h;
712
713 if ((osd_crop = f->pan_y - f->dst_y) > 0) {
714
715 f->src_y += (osd_scale * osd_crop) >> 16;
716 f->src_h -= (osd_scale * osd_crop) >> 16;
717 f->dst_h -= osd_crop;
718 f->dst_y = 0;
719 } else {
720 f->dst_y -= f->pan_y;
721 }
722
723 if ((osd_crop = f->dst_h + f->dst_y - f->vis_h) > 0) {
724
725 f->dst_h -= osd_crop;
726 f->src_h -= (osd_scale * osd_crop) >> 16;
727 }
728
729 osd_scale = (f->src_w << 16) / f->dst_w;
730
731 if ((osd_crop = f->pan_x - f->dst_x) > 0) {
732
733 f->src_x += (osd_scale * osd_crop) >> 16;
734 f->src_w -= (osd_scale * osd_crop) >> 16;
735 f->dst_w -= osd_crop;
736 f->dst_x = 0;
737 } else {
738 f->dst_x -= f->pan_x;
739 }
740
741 if ((osd_crop = f->dst_w + f->dst_x - f->vis_w) > 0) {
742
743 f->dst_w -= osd_crop;
744 f->src_w -= (osd_scale * osd_crop) >> 16;
745 }
746
747 if (itv->yuv_info.track_osd) {
748
749 f->dst_x += itv->yuv_info.osd_x_offset;
750 f->dst_y += itv->yuv_info.osd_y_offset;
751 }
752
753
754
755 f->dst_w &= ~1;
756 f->dst_x &= ~1;
757
758 f->src_w += f->src_x & 1;
759 f->src_x &= ~1;
760
761 f->src_w &= ~1;
762 f->dst_w &= ~1;
763
764 f->dst_h &= ~1;
765 f->dst_y &= ~1;
766
767 f->src_h += f->src_y & 1;
768 f->src_y &= ~1;
769
770 f->src_h &= ~1;
771 f->dst_h &= ~1;
772
773
774
775
776 if (f->dst_w < f->src_w / 4) {
777 f->src_w &= ~3;
778 f->dst_w = f->src_w / 4;
779 f->dst_w += f->dst_w & 1;
780 }
781 if (f->dst_h < f->src_h / 4) {
782 f->src_h &= ~3;
783 f->dst_h = f->src_h / 4;
784 f->dst_h += f->dst_h & 1;
785 }
786
787
788 if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 ||
789 (int)f->src_w <= 2 || (int)f->src_h <= 2) {
790 return IVTV_YUV_UPDATE_INVALID;
791 }
792
793
794 if ((of->dst_w != f->dst_w) || (of->src_w != f->src_w) ||
795 (of->dst_x != f->dst_x) || (of->src_x != f->src_x) ||
796 (of->pan_x != f->pan_x) || (of->vis_w != f->vis_w)) {
797 yuv_update |= IVTV_YUV_UPDATE_HORIZONTAL;
798 }
799
800 if ((of->src_h != f->src_h) || (of->dst_h != f->dst_h) ||
801 (of->dst_y != f->dst_y) || (of->src_y != f->src_y) ||
802 (of->pan_y != f->pan_y) || (of->vis_h != f->vis_h) ||
803 (of->lace_mode != f->lace_mode) ||
804 (of->interlaced_y != f->interlaced_y) ||
805 (of->interlaced_uv != f->interlaced_uv)) {
806 yuv_update |= IVTV_YUV_UPDATE_VERTICAL;
807 }
808
809 return yuv_update;
810}
811
812
813void ivtv_yuv_work_handler(struct ivtv *itv)
814{
815 struct yuv_playback_info *yi = &itv->yuv_info;
816 struct yuv_frame_info f;
817 int frame = yi->update_frame;
818 u32 yuv_update;
819
820 IVTV_DEBUG_YUV("Update yuv registers for frame %d\n", frame);
821 f = yi->new_frame_info[frame];
822
823 if (yi->track_osd) {
824
825 f.pan_x = yi->osd_x_pan;
826 f.pan_y = yi->osd_y_pan;
827 f.vis_w = yi->osd_vis_w;
828 f.vis_h = yi->osd_vis_h;
829 } else {
830
831 f.pan_x = 0;
832 f.pan_y = 0;
833 f.vis_w = 720;
834 f.vis_h = yi->decode_height;
835 }
836
837
838 if (!(yuv_update = ivtv_yuv_window_setup(itv, &f)))
839 return;
840
841 if (yuv_update & IVTV_YUV_UPDATE_INVALID) {
842 write_reg(0x01008080, 0x2898);
843 } else if (yuv_update) {
844 write_reg(0x00108080, 0x2898);
845
846 if (yuv_update & IVTV_YUV_UPDATE_HORIZONTAL)
847 ivtv_yuv_handle_horizontal(itv, &f);
848
849 if (yuv_update & IVTV_YUV_UPDATE_VERTICAL)
850 ivtv_yuv_handle_vertical(itv, &f);
851 }
852 yi->old_frame_info = f;
853}
854
855static void ivtv_yuv_init(struct ivtv *itv)
856{
857 struct yuv_playback_info *yi = &itv->yuv_info;
858
859 IVTV_DEBUG_YUV("ivtv_yuv_init\n");
860
861
862 yi->reg_2834 = read_reg(0x02834);
863 yi->reg_2838 = read_reg(0x02838);
864 yi->reg_283c = read_reg(0x0283c);
865 yi->reg_2840 = read_reg(0x02840);
866 yi->reg_2844 = read_reg(0x02844);
867 yi->reg_2848 = read_reg(0x02848);
868 yi->reg_2854 = read_reg(0x02854);
869 yi->reg_285c = read_reg(0x0285c);
870 yi->reg_2864 = read_reg(0x02864);
871 yi->reg_2870 = read_reg(0x02870);
872 yi->reg_2874 = read_reg(0x02874);
873 yi->reg_2898 = read_reg(0x02898);
874 yi->reg_2890 = read_reg(0x02890);
875
876 yi->reg_289c = read_reg(0x0289c);
877 yi->reg_2918 = read_reg(0x02918);
878 yi->reg_291c = read_reg(0x0291c);
879 yi->reg_2920 = read_reg(0x02920);
880 yi->reg_2924 = read_reg(0x02924);
881 yi->reg_2928 = read_reg(0x02928);
882 yi->reg_292c = read_reg(0x0292c);
883 yi->reg_2930 = read_reg(0x02930);
884 yi->reg_2934 = read_reg(0x02934);
885 yi->reg_2938 = read_reg(0x02938);
886 yi->reg_293c = read_reg(0x0293c);
887 yi->reg_2940 = read_reg(0x02940);
888 yi->reg_2944 = read_reg(0x02944);
889 yi->reg_2948 = read_reg(0x02948);
890 yi->reg_294c = read_reg(0x0294c);
891 yi->reg_2950 = read_reg(0x02950);
892 yi->reg_2954 = read_reg(0x02954);
893 yi->reg_2958 = read_reg(0x02958);
894 yi->reg_295c = read_reg(0x0295c);
895 yi->reg_2960 = read_reg(0x02960);
896 yi->reg_2964 = read_reg(0x02964);
897 yi->reg_2968 = read_reg(0x02968);
898 yi->reg_296c = read_reg(0x0296c);
899 yi->reg_2970 = read_reg(0x02970);
900
901 yi->v_filter_1 = -1;
902 yi->v_filter_2 = -1;
903 yi->h_filter = -1;
904
905
906 yi->osd_x_offset = read_reg(0x02a04) & 0x00000FFF;
907 yi->osd_y_offset = (read_reg(0x02a04) >> 16) & 0x00000FFF;
908
909
910
911 if (read_reg(0x2878) & 4)
912 yi->decode_height = 576;
913 else
914 yi->decode_height = 480;
915
916 if (!itv->osd_info) {
917 yi->osd_vis_w = 720 - yi->osd_x_offset;
918 yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
919 } else {
920
921 if (!yi->osd_vis_w)
922 yi->osd_vis_w = 720 - yi->osd_x_offset;
923
924 if (!yi->osd_vis_h) {
925 yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
926 } else if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) {
927
928
929 IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
930 yi->osd_vis_h + yi->osd_y_offset,
931 yi->decode_height);
932 yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
933 }
934 }
935
936
937 yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL|__GFP_NOWARN);
938 if (yi->blanking_ptr) {
939 yi->blanking_dmaptr = pci_map_single(itv->pdev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
940 } else {
941 yi->blanking_dmaptr = 0;
942 IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
943 }
944
945
946 write_reg_sync(0x01, IVTV_REG_VDM);
947
948 set_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
949 atomic_set(&yi->next_dma_frame, 0);
950}
951
952
953static void ivtv_yuv_next_free(struct ivtv *itv)
954{
955 int draw, display;
956 struct yuv_playback_info *yi = &itv->yuv_info;
957
958 if (atomic_read(&yi->next_dma_frame) == -1)
959 ivtv_yuv_init(itv);
960
961 draw = atomic_read(&yi->next_fill_frame);
962 display = atomic_read(&yi->next_dma_frame);
963
964 if (display > draw)
965 display -= IVTV_YUV_BUFFERS;
966
967 if (draw - display >= yi->max_frames_buffered)
968 draw = (u8)(draw - 1) % IVTV_YUV_BUFFERS;
969 else
970 yi->new_frame_info[draw].update = 0;
971
972 yi->draw_frame = draw;
973}
974
975
976static void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
977{
978 struct yuv_playback_info *yi = &itv->yuv_info;
979 u8 frame = yi->draw_frame;
980 u8 last_frame = (u8)(frame - 1) % IVTV_YUV_BUFFERS;
981 struct yuv_frame_info *nf = &yi->new_frame_info[frame];
982 struct yuv_frame_info *of = &yi->new_frame_info[last_frame];
983 int lace_threshold = yi->lace_threshold;
984
985
986 int update = nf->update;
987
988
989 nf->src_x = args->src.left;
990 nf->src_y = args->src.top;
991 nf->src_w = args->src.width;
992 nf->src_h = args->src.height;
993 nf->dst_x = args->dst.left;
994 nf->dst_y = args->dst.top;
995 nf->dst_w = args->dst.width;
996 nf->dst_h = args->dst.height;
997 nf->tru_x = args->dst.left;
998 nf->tru_w = args->src_width;
999 nf->tru_h = args->src_height;
1000
1001
1002 nf->offset_y = (nf->tru_h + nf->src_x < 512 - 16) ? 1 : 0;
1003
1004 nf->update = 0;
1005 nf->interlaced_y = 0;
1006 nf->interlaced_uv = 0;
1007 nf->delay = 0;
1008 nf->sync_field = 0;
1009 nf->lace_mode = yi->lace_mode & IVTV_YUV_MODE_MASK;
1010
1011 if (lace_threshold < 0)
1012 lace_threshold = yi->decode_height - 1;
1013
1014
1015 switch (nf->lace_mode) {
1016 case IVTV_YUV_MODE_PROGRESSIVE:
1017 nf->interlaced = 0;
1018 if (nf->tru_h < 512 || (nf->tru_h > 576 && nf->tru_h < 1021))
1019 nf->interlaced_y = 0;
1020 else
1021 nf->interlaced_y = 1;
1022
1023 if (nf->tru_h < 1021 && (nf->dst_h >= nf->src_h / 2))
1024 nf->interlaced_uv = 0;
1025 else
1026 nf->interlaced_uv = 1;
1027 break;
1028
1029 case IVTV_YUV_MODE_AUTO:
1030 if (nf->tru_h <= lace_threshold || nf->tru_h > 576 || nf->tru_w > 720) {
1031 nf->interlaced = 0;
1032 if ((nf->tru_h < 512) ||
1033 (nf->tru_h > 576 && nf->tru_h < 1021) ||
1034 (nf->tru_w > 720 && nf->tru_h < 1021))
1035 nf->interlaced_y = 0;
1036 else
1037 nf->interlaced_y = 1;
1038 if (nf->tru_h < 1021 && (nf->dst_h >= nf->src_h / 2))
1039 nf->interlaced_uv = 0;
1040 else
1041 nf->interlaced_uv = 1;
1042 } else {
1043 nf->interlaced = 1;
1044 nf->interlaced_y = 1;
1045 nf->interlaced_uv = 1;
1046 }
1047 break;
1048
1049 case IVTV_YUV_MODE_INTERLACED:
1050 default:
1051 nf->interlaced = 1;
1052 nf->interlaced_y = 1;
1053 nf->interlaced_uv = 1;
1054 break;
1055 }
1056
1057 if (memcmp(&yi->old_frame_info_args, nf, sizeof(*nf))) {
1058 yi->old_frame_info_args = *nf;
1059 nf->update = 1;
1060 IVTV_DEBUG_YUV("Requesting reg update for frame %d\n", frame);
1061 }
1062
1063 nf->update |= update;
1064 nf->sync_field = yi->lace_sync_field;
1065 nf->delay = nf->sync_field != of->sync_field;
1066}
1067
1068
1069void ivtv_yuv_frame_complete(struct ivtv *itv)
1070{
1071 atomic_set(&itv->yuv_info.next_fill_frame,
1072 (itv->yuv_info.draw_frame + 1) % IVTV_YUV_BUFFERS);
1073}
1074
1075static int ivtv_yuv_udma_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
1076{
1077 DEFINE_WAIT(wait);
1078 int rc = 0;
1079 int got_sig = 0;
1080
1081 mutex_lock(&itv->udma.lock);
1082
1083 if ((rc = ivtv_yuv_prep_user_dma(itv, &itv->udma, args)) != 0) {
1084 mutex_unlock(&itv->udma.lock);
1085 return rc;
1086 }
1087
1088 ivtv_udma_prepare(itv);
1089 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
1090
1091
1092 while (test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags) ||
1093 test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
1094
1095
1096 got_sig = signal_pending(current);
1097 if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
1098 break;
1099 got_sig = 0;
1100 schedule();
1101 }
1102 finish_wait(&itv->dma_waitq, &wait);
1103
1104
1105 ivtv_udma_unmap(itv);
1106
1107 if (got_sig) {
1108 IVTV_DEBUG_INFO("User stopped YUV UDMA\n");
1109 mutex_unlock(&itv->udma.lock);
1110 return -EINTR;
1111 }
1112
1113 ivtv_yuv_frame_complete(itv);
1114
1115 mutex_unlock(&itv->udma.lock);
1116 return rc;
1117}
1118
1119
1120void ivtv_yuv_setup_stream_frame(struct ivtv *itv)
1121{
1122 struct yuv_playback_info *yi = &itv->yuv_info;
1123 struct ivtv_dma_frame dma_args;
1124
1125 ivtv_yuv_next_free(itv);
1126
1127
1128 dma_args.y_source = NULL;
1129 dma_args.uv_source = NULL;
1130 dma_args.src.left = 0;
1131 dma_args.src.top = 0;
1132 dma_args.src.width = yi->v4l2_src_w;
1133 dma_args.src.height = yi->v4l2_src_h;
1134 dma_args.dst = yi->main_rect;
1135 dma_args.src_width = yi->v4l2_src_w;
1136 dma_args.src_height = yi->v4l2_src_h;
1137
1138
1139 ivtv_yuv_setup_frame(itv, &dma_args);
1140
1141 if (!itv->dma_data_req_offset)
1142 itv->dma_data_req_offset = yuv_offset[yi->draw_frame];
1143}
1144
1145
1146int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void __user *src)
1147{
1148 struct yuv_playback_info *yi = &itv->yuv_info;
1149 struct ivtv_dma_frame dma_args;
1150 int res;
1151
1152 ivtv_yuv_setup_stream_frame(itv);
1153
1154
1155 dma_args.y_source = src;
1156 dma_args.uv_source = src + 720 * ((yi->v4l2_src_h + 31) & ~31);
1157
1158
1159
1160 mutex_unlock(&itv->serialize_lock);
1161 res = ivtv_yuv_udma_frame(itv, &dma_args);
1162 mutex_lock(&itv->serialize_lock);
1163 return res;
1164}
1165
1166
1167int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
1168{
1169 int res;
1170
1171
1172 ivtv_yuv_next_free(itv);
1173 ivtv_yuv_setup_frame(itv, args);
1174
1175
1176
1177 mutex_unlock(&itv->serialize_lock);
1178 res = ivtv_yuv_udma_frame(itv, args);
1179 mutex_lock(&itv->serialize_lock);
1180 return res;
1181}
1182
1183void ivtv_yuv_close(struct ivtv *itv)
1184{
1185 struct yuv_playback_info *yi = &itv->yuv_info;
1186 int h_filter, v_filter_1, v_filter_2;
1187
1188 IVTV_DEBUG_YUV("ivtv_yuv_close\n");
1189 mutex_unlock(&itv->serialize_lock);
1190 ivtv_waitq(&itv->vsync_waitq);
1191 mutex_lock(&itv->serialize_lock);
1192
1193 yi->running = 0;
1194 atomic_set(&yi->next_dma_frame, -1);
1195 atomic_set(&yi->next_fill_frame, 0);
1196
1197
1198
1199
1200
1201
1202 write_reg(yi->reg_2898 | 0x01000000, 0x2898);
1203
1204 write_reg(yi->reg_2834, 0x02834);
1205 write_reg(yi->reg_2838, 0x02838);
1206 write_reg(yi->reg_283c, 0x0283c);
1207 write_reg(yi->reg_2840, 0x02840);
1208 write_reg(yi->reg_2844, 0x02844);
1209 write_reg(yi->reg_2848, 0x02848);
1210 write_reg(yi->reg_2854, 0x02854);
1211 write_reg(yi->reg_285c, 0x0285c);
1212 write_reg(yi->reg_2864, 0x02864);
1213 write_reg(yi->reg_2870, 0x02870);
1214 write_reg(yi->reg_2874, 0x02874);
1215 write_reg(yi->reg_2890, 0x02890);
1216 write_reg(yi->reg_289c, 0x0289c);
1217
1218 write_reg(yi->reg_2918, 0x02918);
1219 write_reg(yi->reg_291c, 0x0291c);
1220 write_reg(yi->reg_2920, 0x02920);
1221 write_reg(yi->reg_2924, 0x02924);
1222 write_reg(yi->reg_2928, 0x02928);
1223 write_reg(yi->reg_292c, 0x0292c);
1224 write_reg(yi->reg_2930, 0x02930);
1225 write_reg(yi->reg_2934, 0x02934);
1226 write_reg(yi->reg_2938, 0x02938);
1227 write_reg(yi->reg_293c, 0x0293c);
1228 write_reg(yi->reg_2940, 0x02940);
1229 write_reg(yi->reg_2944, 0x02944);
1230 write_reg(yi->reg_2948, 0x02948);
1231 write_reg(yi->reg_294c, 0x0294c);
1232 write_reg(yi->reg_2950, 0x02950);
1233 write_reg(yi->reg_2954, 0x02954);
1234 write_reg(yi->reg_2958, 0x02958);
1235 write_reg(yi->reg_295c, 0x0295c);
1236 write_reg(yi->reg_2960, 0x02960);
1237 write_reg(yi->reg_2964, 0x02964);
1238 write_reg(yi->reg_2968, 0x02968);
1239 write_reg(yi->reg_296c, 0x0296c);
1240 write_reg(yi->reg_2970, 0x02970);
1241
1242
1243
1244
1245 if ((yi->reg_2834 & 0x0000FFFF) == (yi->reg_2834 >> 16)) {
1246
1247 h_filter = 0;
1248 } else {
1249
1250 h_filter = ((yi->reg_2834 << 16) / (yi->reg_2834 >> 16)) >> 15;
1251 h_filter = (h_filter >> 1) + (h_filter & 1);
1252
1253 h_filter += !h_filter;
1254 }
1255
1256
1257 if ((yi->reg_2918 & 0x0000FFFF) == (yi->reg_2918 >> 16)) {
1258
1259 v_filter_1 = 0;
1260 v_filter_2 = 1;
1261 } else {
1262
1263 v_filter_1 = ((yi->reg_2918 << 16) / (yi->reg_2918 >> 16)) >> 15;
1264 v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1);
1265
1266 v_filter_1 += !v_filter_1;
1267 v_filter_2 = v_filter_1;
1268 }
1269
1270
1271 ivtv_yuv_filter(itv, h_filter, v_filter_1, v_filter_2);
1272
1273
1274 write_reg(0, 0x02814);
1275 write_reg(0, 0x0282c);
1276 write_reg(0, 0x02904);
1277 write_reg(0, 0x02910);
1278
1279
1280 if (yi->blanking_ptr) {
1281 kfree(yi->blanking_ptr);
1282 yi->blanking_ptr = NULL;
1283 pci_unmap_single(itv->pdev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
1284 }
1285
1286
1287 yi->old_frame_info.src_w = 0;
1288 yi->old_frame_info.src_h = 0;
1289 yi->old_frame_info_args.src_w = 0;
1290 yi->old_frame_info_args.src_h = 0;
1291
1292
1293 clear_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
1294}
1295