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