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