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