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