aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-yuv.c
diff options
context:
space:
mode:
authorIan Armstrong <ian@iarmst.demon.co.uk>2007-11-13 17:15:25 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:03:11 -0500
commit2b057e8dc6cc8318956fef92b77a4e86985e84d9 (patch)
treee6e7e7a05691d898a73722bbccb70ebc26772151 /drivers/media/video/ivtv/ivtv-yuv.c
parent368f080b6870e65d43c346e085e8f81ade5d3e07 (diff)
V4L/DVB (6719): ivtv: ivtv-yuv clean-up + source cropping bug-fix
ivtv-yuv code clean up & reformat. Includes minor changes to some debug lines. Also fixes a bug found during the reformatting, which would cause the incorrect amount of yuv data to be sent to the card if source cropping coordinates were used. Apart from the bug-fix, there should be no functional difference to the previous version. Signed-off-by: Ian Armstrong <ian@iarmst.demon.co.uk> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-yuv.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-yuv.c635
1 files changed, 320 insertions, 315 deletions
diff --git a/drivers/media/video/ivtv/ivtv-yuv.c b/drivers/media/video/ivtv/ivtv-yuv.c
index 711ce5b5a20f..85183480a225 100644
--- a/drivers/media/video/ivtv/ivtv-yuv.c
+++ b/drivers/media/video/ivtv/ivtv-yuv.c
@@ -35,7 +35,7 @@ const u32 yuv_offset[IVTV_YUV_BUFFERS] = {
35}; 35};
36 36
37static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma, 37static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
38 struct ivtv_dma_frame *args) 38 struct ivtv_dma_frame *args)
39{ 39{
40 struct ivtv_dma_page_info y_dma; 40 struct ivtv_dma_page_info y_dma;
41 struct ivtv_dma_page_info uv_dma; 41 struct ivtv_dma_page_info uv_dma;
@@ -50,7 +50,7 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
50 y_buffer_offset = IVTV_DECODER_OFFSET + yuv_offset[frame]; 50 y_buffer_offset = IVTV_DECODER_OFFSET + yuv_offset[frame];
51 uv_buffer_offset = y_buffer_offset + IVTV_YUV_BUFFER_UV_OFFSET; 51 uv_buffer_offset = y_buffer_offset + IVTV_YUV_BUFFER_UV_OFFSET;
52 52
53 y_decode_height = uv_decode_height = f->src_h + f->src_x; 53 y_decode_height = uv_decode_height = f->src_h + f->src_y;
54 54
55 if (f->offset_y) 55 if (f->offset_y)
56 y_buffer_offset += 720 * 16; 56 y_buffer_offset += 720 * 16;
@@ -65,8 +65,9 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
65 65
66 /* Still in USE */ 66 /* Still in USE */
67 if (dma->SG_length || dma->page_count) { 67 if (dma->SG_length || dma->page_count) {
68 IVTV_DEBUG_WARN("prep_user_dma: SG_length %d page_count %d still full?\n", 68 IVTV_DEBUG_WARN
69 dma->SG_length, dma->page_count); 69 ("prep_user_dma: SG_length %d page_count %d still full?\n",
70 dma->SG_length, dma->page_count);
70 return -EBUSY; 71 return -EBUSY;
71 } 72 }
72 73
@@ -82,8 +83,9 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
82 dma->page_count = y_dma.page_count + uv_dma.page_count; 83 dma->page_count = y_dma.page_count + uv_dma.page_count;
83 84
84 if (y_pages + uv_pages != dma->page_count) { 85 if (y_pages + uv_pages != dma->page_count) {
85 IVTV_DEBUG_WARN("failed to map user pages, returned %d instead of %d\n", 86 IVTV_DEBUG_WARN
86 y_pages + uv_pages, dma->page_count); 87 ("failed to map user pages, returned %d instead of %d\n",
88 y_pages + uv_pages, dma->page_count);
87 89
88 for (i = 0; i < dma->page_count; i++) { 90 for (i = 0; i < dma->page_count; i++) {
89 put_page(dma->map[i]); 91 put_page(dma->map[i]);
@@ -104,12 +106,12 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
104 dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE); 106 dma->SG_length = pci_map_sg(itv->dev, dma->SGlist, dma->page_count, PCI_DMA_TODEVICE);
105 107
106 /* Fill SG Array with new values */ 108 /* Fill SG Array with new values */
107 ivtv_udma_fill_sg_array (dma, y_buffer_offset, uv_buffer_offset, y_size); 109 ivtv_udma_fill_sg_array(dma, y_buffer_offset, uv_buffer_offset, y_size);
108 110
109 /* If we've offset the y plane, ensure top area is blanked */ 111 /* If we've offset the y plane, ensure top area is blanked */
110 if (f->offset_y && itv->yuv_info.blanking_dmaptr) { 112 if (f->offset_y && yi->blanking_dmaptr) {
111 dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16); 113 dma->SGarray[dma->SG_length].size = cpu_to_le32(720*16);
112 dma->SGarray[dma->SG_length].src = cpu_to_le32(itv->yuv_info.blanking_dmaptr); 114 dma->SGarray[dma->SG_length].src = cpu_to_le32(yi->blanking_dmaptr);
113 dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DECODER_OFFSET + yuv_offset[frame]); 115 dma->SGarray[dma->SG_length].dst = cpu_to_le32(IVTV_DECODER_OFFSET + yuv_offset[frame]);
114 dma->SG_length++; 116 dma->SG_length++;
115 } 117 }
@@ -124,11 +126,11 @@ static int ivtv_yuv_prep_user_dma(struct ivtv *itv, struct ivtv_user_dma *dma,
124/* We rely on a table held in the firmware - Quick check. */ 126/* We rely on a table held in the firmware - Quick check. */
125int ivtv_yuv_filter_check(struct ivtv *itv) 127int ivtv_yuv_filter_check(struct ivtv *itv)
126{ 128{
127 int i, offset_y, offset_uv; 129 int i, y, uv;
128 130
129 for (i=0, offset_y = 16, offset_uv = 4; i<16; i++, offset_y += 24, offset_uv += 12) { 131 for (i = 0, y = 16, uv = 4; i < 16; i++, y += 24, uv += 12) {
130 if ((read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + offset_y) != i << 16) || 132 if ((read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + y) != i << 16) ||
131 (read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + offset_uv) != i << 16)) { 133 (read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + uv) != i << 16)) {
132 IVTV_WARN ("YUV filter table not found in firmware.\n"); 134 IVTV_WARN ("YUV filter table not found in firmware.\n");
133 return -1; 135 return -1;
134 } 136 }
@@ -138,69 +140,67 @@ int ivtv_yuv_filter_check(struct ivtv *itv)
138 140
139static void ivtv_yuv_filter(struct ivtv *itv, int h_filter, int v_filter_1, int v_filter_2) 141static void ivtv_yuv_filter(struct ivtv *itv, int h_filter, int v_filter_1, int v_filter_2)
140{ 142{
141 int filter_index, filter_line; 143 u32 i, line;
142 144
143 /* If any filter is -1, then don't update it */ 145 /* If any filter is -1, then don't update it */
144 if (h_filter > -1) { 146 if (h_filter > -1) {
145 if (h_filter > 4) h_filter = 4; 147 if (h_filter > 4)
146 filter_index = h_filter * 384; 148 h_filter = 4;
147 filter_line = 0; 149 i = IVTV_YUV_HORIZONTAL_FILTER_OFFSET + (h_filter * 384);
148 while (filter_line < 16) { 150 for (line = 0; line < 16; line++) {
149 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02804); 151 write_reg(read_dec(i), 0x02804);
150 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x0281c); 152 write_reg(read_dec(i), 0x0281c);
151 filter_index += 4; 153 i += 4;
152 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02808); 154 write_reg(read_dec(i), 0x02808);
153 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02820); 155 write_reg(read_dec(i), 0x02820);
154 filter_index += 4; 156 i += 4;
155 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x0280c); 157 write_reg(read_dec(i), 0x0280c);
156 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02824); 158 write_reg(read_dec(i), 0x02824);
157 filter_index += 4; 159 i += 4;
158 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02810); 160 write_reg(read_dec(i), 0x02810);
159 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02828); 161 write_reg(read_dec(i), 0x02828);
160 filter_index += 4; 162 i += 4;
161 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x02814); 163 write_reg(read_dec(i), 0x02814);
162 write_reg(read_dec(IVTV_YUV_HORIZONTAL_FILTER_OFFSET + filter_index), 0x0282c); 164 write_reg(read_dec(i), 0x0282c);
163 filter_index += 8; 165 i += 8;
164 write_reg(0, 0x02818); 166 write_reg(0, 0x02818);
165 write_reg(0, 0x02830); 167 write_reg(0, 0x02830);
166 filter_line ++;
167 } 168 }
168 IVTV_DEBUG_YUV("h_filter -> %d\n",h_filter); 169 IVTV_DEBUG_YUV("h_filter -> %d\n", h_filter);
169 } 170 }
170 171
171 if (v_filter_1 > -1) { 172 if (v_filter_1 > -1) {
172 if (v_filter_1 > 4) v_filter_1 = 4; 173 if (v_filter_1 > 4)
173 filter_index = v_filter_1 * 192; 174 v_filter_1 = 4;
174 filter_line = 0; 175 i = IVTV_YUV_VERTICAL_FILTER_OFFSET + (v_filter_1 * 192);
175 while (filter_line < 16) { 176 for (line = 0; line < 16; line++) {
176 write_reg(read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + filter_index), 0x02900); 177 write_reg(read_dec(i), 0x02900);
177 filter_index += 4; 178 i += 4;
178 write_reg(read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + filter_index), 0x02904); 179 write_reg(read_dec(i), 0x02904);
179 filter_index += 8; 180 i += 8;
180 write_reg(0, 0x02908); 181 write_reg(0, 0x02908);
181 filter_line ++;
182 } 182 }
183 IVTV_DEBUG_YUV("v_filter_1 -> %d\n",v_filter_1); 183 IVTV_DEBUG_YUV("v_filter_1 -> %d\n", v_filter_1);
184 } 184 }
185 185
186 if (v_filter_2 > -1) { 186 if (v_filter_2 > -1) {
187 if (v_filter_2 > 4) v_filter_2 = 4; 187 if (v_filter_2 > 4)
188 filter_index = v_filter_2 * 192; 188 v_filter_2 = 4;
189 filter_line = 0; 189 i = IVTV_YUV_VERTICAL_FILTER_OFFSET + (v_filter_2 * 192);
190 while (filter_line < 16) { 190 for (line = 0; line < 16; line++) {
191 write_reg(read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + filter_index), 0x0290c); 191 write_reg(read_dec(i), 0x0290c);
192 filter_index += 4; 192 i += 4;
193 write_reg(read_dec(IVTV_YUV_VERTICAL_FILTER_OFFSET + filter_index), 0x02910); 193 write_reg(read_dec(i), 0x02910);
194 filter_index += 8; 194 i += 8;
195 write_reg(0, 0x02914); 195 write_reg(0, 0x02914);
196 filter_line ++;
197 } 196 }
198 IVTV_DEBUG_YUV("v_filter_2 -> %d\n",v_filter_2); 197 IVTV_DEBUG_YUV("v_filter_2 -> %d\n", v_filter_2);
199 } 198 }
200} 199}
201 200
202static void ivtv_yuv_handle_horizontal(struct ivtv *itv, struct yuv_frame_info *window) 201static void ivtv_yuv_handle_horizontal(struct ivtv *itv, struct yuv_frame_info *f)
203{ 202{
203 struct yuv_playback_info *yi = &itv->yuv_info;
204 u32 reg_2834, reg_2838, reg_283c; 204 u32 reg_2834, reg_2838, reg_283c;
205 u32 reg_2844, reg_2854, reg_285c; 205 u32 reg_2844, reg_2854, reg_285c;
206 u32 reg_2864, reg_2874, reg_2890; 206 u32 reg_2864, reg_2874, reg_2890;
@@ -209,18 +209,19 @@ static void ivtv_yuv_handle_horizontal(struct ivtv *itv, struct yuv_frame_info *
209 int h_filter; 209 int h_filter;
210 u32 master_width; 210 u32 master_width;
211 211
212 IVTV_DEBUG_WARN( "Need to adjust to width %d src_w %d dst_w %d src_x %d dst_x %d\n", 212 IVTV_DEBUG_WARN
213 window->tru_w, window->src_w, window->dst_w,window->src_x, window->dst_x); 213 ("Adjust to width %d src_w %d dst_w %d src_x %d dst_x %d\n",
214 f->tru_w, f->src_w, f->dst_w, f->src_x, f->dst_x);
214 215
215 /* How wide is the src image */ 216 /* How wide is the src image */
216 x_cutoff = window->src_w + window->src_x; 217 x_cutoff = f->src_w + f->src_x;
217 218
218 /* Set the display width */ 219 /* Set the display width */
219 reg_2834 = window->dst_w; 220 reg_2834 = f->dst_w;
220 reg_2838 = reg_2834; 221 reg_2838 = reg_2834;
221 222
222 /* Set the display position */ 223 /* Set the display position */
223 reg_2890 = window->dst_x; 224 reg_2890 = f->dst_x;
224 225
225 /* Index into the image horizontally */ 226 /* Index into the image horizontally */
226 reg_2870 = 0; 227 reg_2870 = 0;
@@ -231,32 +232,31 @@ static void ivtv_yuv_handle_horizontal(struct ivtv *itv, struct yuv_frame_info *
231 Gradually adjust the offset to avoid the video 'snapping' 232 Gradually adjust the offset to avoid the video 'snapping'
232 left/right if it gets dragged through this region. 233 left/right if it gets dragged through this region.
233 Only do this if osd is full width. */ 234 Only do this if osd is full width. */
234 if (window->vis_w == 720) { 235 if (f->vis_w == 720) {
235 if ((window->tru_x - window->pan_x > -1) && (window->tru_x - window->pan_x <= 40) && (window->dst_w >= 680)){ 236 if ((f->tru_x - f->pan_x > -1) && (f->tru_x - f->pan_x <= 40) && (f->dst_w >= 680))
236 reg_2870 = 10 - (window->tru_x - window->pan_x) / 4; 237 reg_2870 = 10 - (f->tru_x - f->pan_x) / 4;
237 } 238 else if ((f->tru_x - f->pan_x < 0) && (f->tru_x - f->pan_x >= -20) && (f->dst_w >= 660))
238 else if ((window->tru_x - window->pan_x < 0) && (window->tru_x - window->pan_x >= -20) && (window->dst_w >= 660)) { 239 reg_2870 = (10 + (f->tru_x - f->pan_x) / 2);
239 reg_2870 = (10 + (window->tru_x - window->pan_x) / 2);
240 }
241 240
242 if (window->dst_w >= window->src_w) 241 if (f->dst_w >= f->src_w)
243 reg_2870 = reg_2870 << 16 | reg_2870; 242 reg_2870 = reg_2870 << 16 | reg_2870;
244 else 243 else
245 reg_2870 = ((reg_2870 & ~1) << 15) | (reg_2870 & ~1); 244 reg_2870 = ((reg_2870 & ~1) << 15) | (reg_2870 & ~1);
246 } 245 }
247 246
248 if (window->dst_w < window->src_w) 247 if (f->dst_w < f->src_w)
249 reg_2870 = 0x000d000e - reg_2870; 248 reg_2870 = 0x000d000e - reg_2870;
250 else 249 else
251 reg_2870 = 0x0012000e - reg_2870; 250 reg_2870 = 0x0012000e - reg_2870;
252 251
253 /* We're also using 2870 to shift the image left (src_x & negative dst_x) */ 252 /* We're also using 2870 to shift the image left (src_x & negative dst_x) */
254 reg_2870_offset = (window->src_x*((window->dst_w << 21)/window->src_w))>>19; 253 reg_2870_offset = (f->src_x * ((f->dst_w << 21) / f->src_w)) >> 19;
255 254
256 if (window->dst_w >= window->src_w) { 255 if (f->dst_w >= f->src_w) {
257 x_cutoff &= ~1; 256 x_cutoff &= ~1;
258 master_width = (window->src_w * 0x00200000) / (window->dst_w); 257 master_width = (f->src_w * 0x00200000) / (f->dst_w);
259 if (master_width * window->dst_w != window->src_w * 0x00200000) master_width ++; 258 if (master_width * f->dst_w != f->src_w * 0x00200000)
259 master_width++;
260 reg_2834 = (reg_2834 << 16) | x_cutoff; 260 reg_2834 = (reg_2834 << 16) | x_cutoff;
261 reg_2838 = (reg_2838 << 16) | x_cutoff; 261 reg_2838 = (reg_2838 << 16) | x_cutoff;
262 reg_283c = master_width >> 2; 262 reg_283c = master_width >> 2;
@@ -267,17 +267,17 @@ static void ivtv_yuv_handle_horizontal(struct ivtv *itv, struct yuv_frame_info *
267 267
268 /* We also need to factor in the scaling 268 /* We also need to factor in the scaling
269 (src_w - dst_w) / (src_w / 4) */ 269 (src_w - dst_w) / (src_w / 4) */
270 if (window->dst_w > window->src_w) 270 if (f->dst_w > f->src_w)
271 reg_2870_base = ((window->dst_w - window->src_w)<<16) / (window->src_w <<14); 271 reg_2870_base = ((f->dst_w - f->src_w)<<16) / (f->src_w <<14);
272 else 272 else
273 reg_2870_base = 0; 273 reg_2870_base = 0;
274 274
275 reg_2870 += (((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 2) + (reg_2870_base << 17 | reg_2870_base); 275 reg_2870 += (((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 2) + (reg_2870_base << 17 | reg_2870_base);
276 reg_2874 = 0; 276 reg_2874 = 0;
277 } 277 } else if (f->dst_w < f->src_w / 2) {
278 else if (window->dst_w < window->src_w / 2) { 278 master_width = (f->src_w * 0x00080000) / f->dst_w;
279 master_width = (window->src_w * 0x00080000) / window->dst_w; 279 if (master_width * f->dst_w != f->src_w * 0x00080000)
280 if (master_width * window->dst_w != window->src_w * 0x00080000) master_width ++; 280 master_width++;
281 reg_2834 = (reg_2834 << 16) | x_cutoff; 281 reg_2834 = (reg_2834 << 16) | x_cutoff;
282 reg_2838 = (reg_2838 << 16) | x_cutoff; 282 reg_2838 = (reg_2838 << 16) | x_cutoff;
283 reg_283c = master_width >> 2; 283 reg_283c = master_width >> 2;
@@ -285,13 +285,13 @@ static void ivtv_yuv_handle_horizontal(struct ivtv *itv, struct yuv_frame_info *
285 reg_2854 = master_width; 285 reg_2854 = master_width;
286 reg_285c = master_width >> 1; 286 reg_285c = master_width >> 1;
287 reg_2864 = master_width >> 1; 287 reg_2864 = master_width >> 1;
288 reg_2870 += (((reg_2870_offset << 15) & 0xFFFF0000) | reg_2870_offset); 288 reg_2870 += ((reg_2870_offset << 15) & 0xFFFF0000) | reg_2870_offset;
289 reg_2870 += (5 - (((window->src_w + window->src_w / 2) - 1) / window->dst_w)) << 16; 289 reg_2870 += (5 - (((f->src_w + f->src_w / 2) - 1) / f->dst_w)) << 16;
290 reg_2874 = 0x00000012; 290 reg_2874 = 0x00000012;
291 } 291 } else {
292 else { 292 master_width = (f->src_w * 0x00100000) / f->dst_w;
293 master_width = (window->src_w * 0x00100000) / window->dst_w; 293 if (master_width * f->dst_w != f->src_w * 0x00100000)
294 if (master_width * window->dst_w != window->src_w * 0x00100000) master_width ++; 294 master_width++;
295 reg_2834 = (reg_2834 << 16) | x_cutoff; 295 reg_2834 = (reg_2834 << 16) | x_cutoff;
296 reg_2838 = (reg_2838 << 16) | x_cutoff; 296 reg_2838 = (reg_2838 << 16) | x_cutoff;
297 reg_283c = master_width >> 2; 297 reg_283c = master_width >> 2;
@@ -299,62 +299,70 @@ static void ivtv_yuv_handle_horizontal(struct ivtv *itv, struct yuv_frame_info *
299 reg_2854 = master_width; 299 reg_2854 = master_width;
300 reg_285c = master_width >> 1; 300 reg_285c = master_width >> 1;
301 reg_2864 = master_width >> 1; 301 reg_2864 = master_width >> 1;
302 reg_2870 += (((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 1); 302 reg_2870 += ((reg_2870_offset << 14) & 0xFFFF0000) | reg_2870_offset >> 1;
303 reg_2870 += (5 - (((window->src_w * 3) - 1) / window->dst_w)) << 16; 303 reg_2870 += (5 - (((f->src_w * 3) - 1) / f->dst_w)) << 16;
304 reg_2874 = 0x00000001; 304 reg_2874 = 0x00000001;
305 } 305 }
306 306
307 /* Select the horizontal filter */ 307 /* Select the horizontal filter */
308 if (window->src_w == window->dst_w) { 308 if (f->src_w == f->dst_w) {
309 /* An exact size match uses filter 0 */ 309 /* An exact size match uses filter 0 */
310 h_filter = 0; 310 h_filter = 0;
311 } 311 } else {
312 else {
313 /* Figure out which filter to use */ 312 /* Figure out which filter to use */
314 h_filter = ((window->src_w << 16) / window->dst_w) >> 15; 313 h_filter = ((f->src_w << 16) / f->dst_w) >> 15;
315 h_filter = (h_filter >> 1) + (h_filter & 1); 314 h_filter = (h_filter >> 1) + (h_filter & 1);
316 /* Only an exact size match can use filter 0 */ 315 /* Only an exact size match can use filter 0 */
317 if (h_filter == 0) h_filter = 1; 316 h_filter += !h_filter;
318 } 317 }
319 318
320 write_reg(reg_2834, 0x02834); 319 write_reg(reg_2834, 0x02834);
321 write_reg(reg_2838, 0x02838); 320 write_reg(reg_2838, 0x02838);
322 IVTV_DEBUG_YUV("Update reg 0x2834 %08x->%08x 0x2838 %08x->%08x\n",itv->yuv_info.reg_2834, reg_2834, itv->yuv_info.reg_2838, reg_2838); 321 IVTV_DEBUG_YUV("Update reg 0x2834 %08x->%08x 0x2838 %08x->%08x\n",
322 yi->reg_2834, reg_2834, yi->reg_2838, reg_2838);
323 323
324 write_reg(reg_283c, 0x0283c); 324 write_reg(reg_283c, 0x0283c);
325 write_reg(reg_2844, 0x02844); 325 write_reg(reg_2844, 0x02844);
326 326
327 IVTV_DEBUG_YUV("Update reg 0x283c %08x->%08x 0x2844 %08x->%08x\n",itv->yuv_info.reg_283c, reg_283c, itv->yuv_info.reg_2844, reg_2844); 327 IVTV_DEBUG_YUV("Update reg 0x283c %08x->%08x 0x2844 %08x->%08x\n",
328 yi->reg_283c, reg_283c, yi->reg_2844, reg_2844);
328 329
329 write_reg(0x00080514, 0x02840); 330 write_reg(0x00080514, 0x02840);
330 write_reg(0x00100514, 0x02848); 331 write_reg(0x00100514, 0x02848);
331 IVTV_DEBUG_YUV("Update reg 0x2840 %08x->%08x 0x2848 %08x->%08x\n",itv->yuv_info.reg_2840, 0x00080514, itv->yuv_info.reg_2848, 0x00100514); 332 IVTV_DEBUG_YUV("Update reg 0x2840 %08x->%08x 0x2848 %08x->%08x\n",
333 yi->reg_2840, 0x00080514, yi->reg_2848, 0x00100514);
332 334
333 write_reg(reg_2854, 0x02854); 335 write_reg(reg_2854, 0x02854);
334 IVTV_DEBUG_YUV("Update reg 0x2854 %08x->%08x \n",itv->yuv_info.reg_2854, reg_2854); 336 IVTV_DEBUG_YUV("Update reg 0x2854 %08x->%08x \n",
337 yi->reg_2854, reg_2854);
335 338
336 write_reg(reg_285c, 0x0285c); 339 write_reg(reg_285c, 0x0285c);
337 write_reg(reg_2864, 0x02864); 340 write_reg(reg_2864, 0x02864);
338 IVTV_DEBUG_YUV("Update reg 0x285c %08x->%08x 0x2864 %08x->%08x\n",itv->yuv_info.reg_285c, reg_285c, itv->yuv_info.reg_2864, reg_2864); 341 IVTV_DEBUG_YUV("Update reg 0x285c %08x->%08x 0x2864 %08x->%08x\n",
342 yi->reg_285c, reg_285c, yi->reg_2864, reg_2864);
339 343
340 write_reg(reg_2874, 0x02874); 344 write_reg(reg_2874, 0x02874);
341 IVTV_DEBUG_YUV("Update reg 0x2874 %08x->%08x\n",itv->yuv_info.reg_2874, reg_2874); 345 IVTV_DEBUG_YUV("Update reg 0x2874 %08x->%08x\n",
346 yi->reg_2874, reg_2874);
342 347
343 write_reg(reg_2870, 0x02870); 348 write_reg(reg_2870, 0x02870);
344 IVTV_DEBUG_YUV("Update reg 0x2870 %08x->%08x\n",itv->yuv_info.reg_2870, reg_2870); 349 IVTV_DEBUG_YUV("Update reg 0x2870 %08x->%08x\n",
350 yi->reg_2870, reg_2870);
345 351
346 write_reg( reg_2890,0x02890); 352 write_reg(reg_2890, 0x02890);
347 IVTV_DEBUG_YUV("Update reg 0x2890 %08x->%08x\n",itv->yuv_info.reg_2890, reg_2890); 353 IVTV_DEBUG_YUV("Update reg 0x2890 %08x->%08x\n",
354 yi->reg_2890, reg_2890);
348 355
349 /* Only update the filter if we really need to */ 356 /* Only update the filter if we really need to */
350 if (h_filter != itv->yuv_info.h_filter) { 357 if (h_filter != yi->h_filter) {
351 ivtv_yuv_filter (itv,h_filter,-1,-1); 358 ivtv_yuv_filter(itv, h_filter, -1, -1);
352 itv->yuv_info.h_filter = h_filter; 359 yi->h_filter = h_filter;
353 } 360 }
354} 361}
355 362
356static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *window) 363static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *f)
357{ 364{
365 struct yuv_playback_info *yi = &itv->yuv_info;
358 u32 master_height; 366 u32 master_height;
359 u32 reg_2918, reg_291c, reg_2920, reg_2928; 367 u32 reg_2918, reg_291c, reg_2920, reg_2928;
360 u32 reg_2930, reg_2934, reg_293c; 368 u32 reg_2930, reg_2934, reg_293c;
@@ -362,69 +370,59 @@ static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *wi
362 u32 reg_2950, reg_2954, reg_2958, reg_295c; 370 u32 reg_2950, reg_2954, reg_2958, reg_295c;
363 u32 reg_2960, reg_2964, reg_2968, reg_296c; 371 u32 reg_2960, reg_2964, reg_2968, reg_296c;
364 u32 reg_289c; 372 u32 reg_289c;
365 u32 src_y_major_y, src_y_minor_y; 373 u32 src_major_y, src_minor_y;
366 u32 src_y_major_uv, src_y_minor_uv; 374 u32 src_major_uv, src_minor_uv;
367 u32 reg_2964_base, reg_2968_base; 375 u32 reg_2964_base, reg_2968_base;
368 int v_filter_1, v_filter_2; 376 int v_filter_1, v_filter_2;
369 377
370 IVTV_DEBUG_WARN("Need to adjust to height %d src_h %d dst_h %d src_y %d dst_y %d\n", 378 IVTV_DEBUG_WARN
371 window->tru_h, window->src_h, window->dst_h,window->src_y, window->dst_y); 379 ("Adjust to height %d src_h %d dst_h %d src_y %d dst_y %d\n",
380 f->tru_h, f->src_h, f->dst_h, f->src_y, f->dst_y);
372 381
373 /* What scaling mode is being used... */ 382 /* What scaling mode is being used... */
374 if (window->interlaced_y) { 383 IVTV_DEBUG_YUV("Scaling mode Y: %s\n",
375 IVTV_DEBUG_YUV("Scaling mode Y: Interlaced\n"); 384 f->interlaced_y ? "Interlaced" : "Progressive");
376 }
377 else {
378 IVTV_DEBUG_YUV("Scaling mode Y: Progressive\n");
379 }
380 385
381 if (window->interlaced_uv) { 386 IVTV_DEBUG_YUV("Scaling mode UV: %s\n",
382 IVTV_DEBUG_YUV("Scaling mode UV: Interlaced\n"); 387 f->interlaced_uv ? "Interlaced" : "Progressive");
383 }
384 else {
385 IVTV_DEBUG_YUV("Scaling mode UV: Progressive\n");
386 }
387 388
388 /* What is the source video being treated as... */ 389 /* What is the source video being treated as... */
389 if (window->interlaced) { 390 IVTV_DEBUG_WARN("Source video: %s\n",
390 IVTV_DEBUG_WARN("Source video: Interlaced\n"); 391 f->interlaced ? "Interlaced" : "Progressive");
391 }
392 else {
393 IVTV_DEBUG_WARN("Source video: Non-interlaced\n");
394 }
395 392
396 /* We offset into the image using two different index methods, so split 393 /* We offset into the image using two different index methods, so split
397 the y source coord into two parts. */ 394 the y source coord into two parts. */
398 if (window->src_y < 8) { 395 if (f->src_y < 8) {
399 src_y_minor_uv = window->src_y; 396 src_minor_uv = f->src_y;
400 src_y_major_uv = 0; 397 src_major_uv = 0;
401 } 398 } else {
402 else { 399 src_minor_uv = 8;
403 src_y_minor_uv = 8; 400 src_major_uv = f->src_y - 8;
404 src_y_major_uv = window->src_y - 8;
405 } 401 }
406 402
407 src_y_minor_y = src_y_minor_uv; 403 src_minor_y = src_minor_uv;
408 src_y_major_y = src_y_major_uv; 404 src_major_y = src_major_uv;
409 405
410 if (window->offset_y) src_y_minor_y += 16; 406 if (f->offset_y)
407 src_minor_y += 16;
411 408
412 if (window->interlaced_y) 409 if (f->interlaced_y)
413 reg_2918 = (window->dst_h << 16) | (window->src_h + src_y_minor_y); 410 reg_2918 = (f->dst_h << 16) | (f->src_h + src_minor_y);
414 else 411 else
415 reg_2918 = (window->dst_h << 16) | ((window->src_h + src_y_minor_y) << 1); 412 reg_2918 = (f->dst_h << 16) | ((f->src_h + src_minor_y) << 1);
416 413
417 if (window->interlaced_uv) 414 if (f->interlaced_uv)
418 reg_291c = (window->dst_h << 16) | ((window->src_h + src_y_minor_uv) >> 1); 415 reg_291c = (f->dst_h << 16) | ((f->src_h + src_minor_uv) >> 1);
419 else 416 else
420 reg_291c = (window->dst_h << 16) | (window->src_h + src_y_minor_uv); 417 reg_291c = (f->dst_h << 16) | (f->src_h + src_minor_uv);
421 418
422 reg_2964_base = (src_y_minor_y * ((window->dst_h << 16)/window->src_h)) >> 14; 419 reg_2964_base = (src_minor_y * ((f->dst_h << 16) / f->src_h)) >> 14;
423 reg_2968_base = (src_y_minor_uv * ((window->dst_h << 16)/window->src_h)) >> 14; 420 reg_2968_base = (src_minor_uv * ((f->dst_h << 16) / f->src_h)) >> 14;
424 421
425 if (window->dst_h / 2 >= window->src_h && !window->interlaced_y) { 422 if (f->dst_h / 2 >= f->src_h && !f->interlaced_y) {
426 master_height = (window->src_h * 0x00400000) / window->dst_h; 423 master_height = (f->src_h * 0x00400000) / f->dst_h;
427 if ((window->src_h * 0x00400000) - (master_height * window->dst_h) >= window->dst_h / 2) master_height ++; 424 if ((f->src_h * 0x00400000) - (master_height * f->dst_h) >= f->dst_h / 2)
425 master_height++;
428 reg_2920 = master_height >> 2; 426 reg_2920 = master_height >> 2;
429 reg_2928 = master_height >> 3; 427 reg_2928 = master_height >> 3;
430 reg_2930 = master_height; 428 reg_2930 = master_height;
@@ -432,45 +430,42 @@ static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *wi
432 reg_2964_base >>= 3; 430 reg_2964_base >>= 3;
433 reg_2968_base >>= 3; 431 reg_2968_base >>= 3;
434 reg_296c = 0x00000000; 432 reg_296c = 0x00000000;
435 } 433 } else if (f->dst_h >= f->src_h) {
436 else if (window->dst_h >= window->src_h) { 434 master_height = (f->src_h * 0x00400000) / f->dst_h;
437 master_height = (window->src_h * 0x00400000) / window->dst_h;
438 master_height = (master_height >> 1) + (master_height & 1); 435 master_height = (master_height >> 1) + (master_height & 1);
439 reg_2920 = master_height >> 2; 436 reg_2920 = master_height >> 2;
440 reg_2928 = master_height >> 2; 437 reg_2928 = master_height >> 2;
441 reg_2930 = master_height; 438 reg_2930 = master_height;
442 reg_2940 = master_height >> 1; 439 reg_2940 = master_height >> 1;
443 reg_296c = 0x00000000; 440 reg_296c = 0x00000000;
444 if (window->interlaced_y) { 441 if (f->interlaced_y) {
445 reg_2964_base >>= 3; 442 reg_2964_base >>= 3;
446 } 443 } else {
447 else { 444 reg_296c++;
448 reg_296c ++;
449 reg_2964_base >>= 2; 445 reg_2964_base >>= 2;
450 } 446 }
451 if (window->interlaced_uv) reg_2928 >>= 1; 447 if (f->interlaced_uv)
448 reg_2928 >>= 1;
452 reg_2968_base >>= 3; 449 reg_2968_base >>= 3;
453 } 450 } else if (f->dst_h >= f->src_h / 2) {
454 else if (window->dst_h >= window->src_h / 2) { 451 master_height = (f->src_h * 0x00200000) / f->dst_h;
455 master_height = (window->src_h * 0x00200000) / window->dst_h;
456 master_height = (master_height >> 1) + (master_height & 1); 452 master_height = (master_height >> 1) + (master_height & 1);
457 reg_2920 = master_height >> 2; 453 reg_2920 = master_height >> 2;
458 reg_2928 = master_height >> 2; 454 reg_2928 = master_height >> 2;
459 reg_2930 = master_height; 455 reg_2930 = master_height;
460 reg_2940 = master_height; 456 reg_2940 = master_height;
461 reg_296c = 0x00000101; 457 reg_296c = 0x00000101;
462 if (window->interlaced_y) { 458 if (f->interlaced_y) {
463 reg_2964_base >>= 2; 459 reg_2964_base >>= 2;
464 } 460 } else {
465 else { 461 reg_296c++;
466 reg_296c ++;
467 reg_2964_base >>= 1; 462 reg_2964_base >>= 1;
468 } 463 }
469 if (window->interlaced_uv) reg_2928 >>= 1; 464 if (f->interlaced_uv)
465 reg_2928 >>= 1;
470 reg_2968_base >>= 2; 466 reg_2968_base >>= 2;
471 } 467 } else {
472 else { 468 master_height = (f->src_h * 0x00100000) / f->dst_h;
473 master_height = (window->src_h * 0x00100000) / window->dst_h;
474 master_height = (master_height >> 1) + (master_height & 1); 469 master_height = (master_height >> 1) + (master_height & 1);
475 reg_2920 = master_height >> 2; 470 reg_2920 = master_height >> 2;
476 reg_2928 = master_height >> 2; 471 reg_2928 = master_height >> 2;
@@ -483,13 +478,12 @@ static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *wi
483 478
484 /* FIXME These registers change depending on scaled / unscaled output 479 /* FIXME These registers change depending on scaled / unscaled output
485 We really need to work out what they should be */ 480 We really need to work out what they should be */
486 if (window->src_h == window->dst_h){ 481 if (f->src_h == f->dst_h) {
487 reg_2934 = 0x00020000; 482 reg_2934 = 0x00020000;
488 reg_293c = 0x00100000; 483 reg_293c = 0x00100000;
489 reg_2944 = 0x00040000; 484 reg_2944 = 0x00040000;
490 reg_294c = 0x000b0000; 485 reg_294c = 0x000b0000;
491 } 486 } else {
492 else {
493 reg_2934 = 0x00000FF0; 487 reg_2934 = 0x00000FF0;
494 reg_293c = 0x00000FF0; 488 reg_293c = 0x00000FF0;
495 reg_2944 = 0x00000FF0; 489 reg_2944 = 0x00000FF0;
@@ -497,34 +491,36 @@ static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *wi
497 } 491 }
498 492
499 /* The first line to be displayed */ 493 /* The first line to be displayed */
500 reg_2950 = 0x00010000 + src_y_major_y; 494 reg_2950 = 0x00010000 + src_major_y;
501 if (window->interlaced_y) reg_2950 += 0x00010000; 495 if (f->interlaced_y)
496 reg_2950 += 0x00010000;
502 reg_2954 = reg_2950 + 1; 497 reg_2954 = reg_2950 + 1;
503 498
504 reg_2958 = 0x00010000 + (src_y_major_y >> 1); 499 reg_2958 = 0x00010000 + (src_major_y >> 1);
505 if (window->interlaced_uv) reg_2958 += 0x00010000; 500 if (f->interlaced_uv)
501 reg_2958 += 0x00010000;
506 reg_295c = reg_2958 + 1; 502 reg_295c = reg_2958 + 1;
507 503
508 if (itv->yuv_info.decode_height == 480) 504 if (yi->decode_height == 480)
509 reg_289c = 0x011e0017; 505 reg_289c = 0x011e0017;
510 else 506 else
511 reg_289c = 0x01500017; 507 reg_289c = 0x01500017;
512 508
513 if (window->dst_y < 0) 509 if (f->dst_y < 0)
514 reg_289c = (reg_289c - ((window->dst_y & ~1)<<15))-(window->dst_y >>1); 510 reg_289c = (reg_289c - ((f->dst_y & ~1)<<15))-(f->dst_y >>1);
515 else 511 else
516 reg_289c = (reg_289c + ((window->dst_y & ~1)<<15))+(window->dst_y >>1); 512 reg_289c = (reg_289c + ((f->dst_y & ~1)<<15))+(f->dst_y >>1);
517 513
518 /* How much of the source to decode. 514 /* How much of the source to decode.
519 Take into account the source offset */ 515 Take into account the source offset */
520 reg_2960 = ((src_y_minor_y + window->src_h + src_y_major_y) - 1 ) | 516 reg_2960 = ((src_minor_y + f->src_h + src_major_y) - 1) |
521 ((((src_y_minor_uv + window->src_h + src_y_major_uv) - 1) & ~1) << 15); 517 (((src_minor_uv + f->src_h + src_major_uv - 1) & ~1) << 15);
522 518
523 /* Calculate correct value for register 2964 */ 519 /* Calculate correct value for register 2964 */
524 if (window->src_h == window->dst_h) 520 if (f->src_h == f->dst_h) {
525 reg_2964 = 1; 521 reg_2964 = 1;
526 else { 522 } else {
527 reg_2964 = 2 + ((window->dst_h << 1) / window->src_h); 523 reg_2964 = 2 + ((f->dst_h << 1) / f->src_h);
528 reg_2964 = (reg_2964 >> 1) + (reg_2964 & 1); 524 reg_2964 = (reg_2964 >> 1) + (reg_2964 & 1);
529 } 525 }
530 reg_2968 = (reg_2964 << 16) + reg_2964 + (reg_2964 >> 1); 526 reg_2968 = (reg_2964 << 16) + reg_2964 + (reg_2964 >> 1);
@@ -539,94 +535,107 @@ static void ivtv_yuv_handle_vertical(struct ivtv *itv, struct yuv_frame_info *wi
539 /* Deviate further from what it should be. I find the flicker headache 535 /* Deviate further from what it should be. I find the flicker headache
540 inducing so try to reduce it slightly. Leave 2968 as-is otherwise 536 inducing so try to reduce it slightly. Leave 2968 as-is otherwise
541 colours foul. */ 537 colours foul. */
542 if ((reg_2964 != 0x00010001) && (window->dst_h / 2 <= window->src_h)) 538 if ((reg_2964 != 0x00010001) && (f->dst_h / 2 <= f->src_h))
543 reg_2964 = (reg_2964 & 0xFFFF0000) + ((reg_2964 & 0x0000FFFF)/2); 539 reg_2964 = (reg_2964 & 0xFFFF0000) + ((reg_2964 & 0x0000FFFF) / 2);
544 540
545 if (!window->interlaced_y) reg_2964 -= 0x00010001; 541 if (!f->interlaced_y)
546 if (!window->interlaced_uv) reg_2968 -= 0x00010001; 542 reg_2964 -= 0x00010001;
543 if (!f->interlaced_uv)
544 reg_2968 -= 0x00010001;
547 545
548 reg_2964 += ((reg_2964_base << 16) | reg_2964_base); 546 reg_2964 += ((reg_2964_base << 16) | reg_2964_base);
549 reg_2968 += ((reg_2968_base << 16) | reg_2968_base); 547 reg_2968 += ((reg_2968_base << 16) | reg_2968_base);
550 548
551 /* Select the vertical filter */ 549 /* Select the vertical filter */
552 if (window->src_h == window->dst_h) { 550 if (f->src_h == f->dst_h) {
553 /* An exact size match uses filter 0/1 */ 551 /* An exact size match uses filter 0/1 */
554 v_filter_1 = 0; 552 v_filter_1 = 0;
555 v_filter_2 = 1; 553 v_filter_2 = 1;
556 } 554 } else {
557 else {
558 /* Figure out which filter to use */ 555 /* Figure out which filter to use */
559 v_filter_1 = ((window->src_h << 16) / window->dst_h) >> 15; 556 v_filter_1 = ((f->src_h << 16) / f->dst_h) >> 15;
560 v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1); 557 v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1);
561 /* Only an exact size match can use filter 0 */ 558 /* Only an exact size match can use filter 0 */
562 if (v_filter_1 == 0) v_filter_1 = 1; 559 v_filter_1 += !v_filter_1;
563 v_filter_2 = v_filter_1; 560 v_filter_2 = v_filter_1;
564 } 561 }
565 562
566 write_reg(reg_2934, 0x02934); 563 write_reg(reg_2934, 0x02934);
567 write_reg(reg_293c, 0x0293c); 564 write_reg(reg_293c, 0x0293c);
568 IVTV_DEBUG_YUV("Update reg 0x2934 %08x->%08x 0x293c %08x->%08x\n",itv->yuv_info.reg_2934, reg_2934, itv->yuv_info.reg_293c, reg_293c); 565 IVTV_DEBUG_YUV("Update reg 0x2934 %08x->%08x 0x293c %08x->%08x\n",
566 yi->reg_2934, reg_2934, yi->reg_293c, reg_293c);
569 write_reg(reg_2944, 0x02944); 567 write_reg(reg_2944, 0x02944);
570 write_reg(reg_294c, 0x0294c); 568 write_reg(reg_294c, 0x0294c);
571 IVTV_DEBUG_YUV("Update reg 0x2944 %08x->%08x 0x294c %08x->%08x\n",itv->yuv_info.reg_2944, reg_2944, itv->yuv_info.reg_294c, reg_294c); 569 IVTV_DEBUG_YUV("Update reg 0x2944 %08x->%08x 0x294c %08x->%08x\n",
570 yi->reg_2944, reg_2944, yi->reg_294c, reg_294c);
572 571
573 /* Ensure 2970 is 0 (does it ever change ?) */ 572 /* Ensure 2970 is 0 (does it ever change ?) */
574/* write_reg(0,0x02970); */ 573/* write_reg(0,0x02970); */
575/* IVTV_DEBUG_YUV("Update reg 0x2970 %08x->%08x\n",itv->yuv_info.reg_2970, 0); */ 574/* IVTV_DEBUG_YUV("Update reg 0x2970 %08x->%08x\n", yi->reg_2970, 0); */
576 575
577 write_reg(reg_2930, 0x02938); 576 write_reg(reg_2930, 0x02938);
578 write_reg(reg_2930, 0x02930); 577 write_reg(reg_2930, 0x02930);
579 IVTV_DEBUG_YUV("Update reg 0x2930 %08x->%08x 0x2938 %08x->%08x\n",itv->yuv_info.reg_2930, reg_2930, itv->yuv_info.reg_2938, reg_2930); 578 IVTV_DEBUG_YUV("Update reg 0x2930 %08x->%08x 0x2938 %08x->%08x\n",
579 yi->reg_2930, reg_2930, yi->reg_2938, reg_2930);
580 580
581 write_reg(reg_2928, 0x02928); 581 write_reg(reg_2928, 0x02928);
582 write_reg(reg_2928+0x514, 0x0292C); 582 write_reg(reg_2928 + 0x514, 0x0292C);
583 IVTV_DEBUG_YUV("Update reg 0x2928 %08x->%08x 0x292c %08x->%08x\n",itv->yuv_info.reg_2928, reg_2928, itv->yuv_info.reg_292c, reg_2928+0x514); 583 IVTV_DEBUG_YUV("Update reg 0x2928 %08x->%08x 0x292c %08x->%08x\n",
584 yi->reg_2928, reg_2928, yi->reg_292c, reg_2928 + 0x514);
584 585
585 write_reg(reg_2920, 0x02920); 586 write_reg(reg_2920, 0x02920);
586 write_reg(reg_2920+0x514, 0x02924); 587 write_reg(reg_2920 + 0x514, 0x02924);
587 IVTV_DEBUG_YUV("Update reg 0x2920 %08x->%08x 0x2924 %08x->%08x\n",itv->yuv_info.reg_2920, reg_2920, itv->yuv_info.reg_2924, 0x514+reg_2920); 588 IVTV_DEBUG_YUV("Update reg 0x2920 %08x->%08x 0x2924 %08x->%08x\n",
589 yi->reg_2920, reg_2920, yi->reg_2924, reg_2920 + 0x514);
588 590
589 write_reg (reg_2918,0x02918); 591 write_reg(reg_2918, 0x02918);
590 write_reg (reg_291c,0x0291C); 592 write_reg(reg_291c, 0x0291C);
591 IVTV_DEBUG_YUV("Update reg 0x2918 %08x->%08x 0x291C %08x->%08x\n",itv->yuv_info.reg_2918,reg_2918,itv->yuv_info.reg_291c,reg_291c); 593 IVTV_DEBUG_YUV("Update reg 0x2918 %08x->%08x 0x291C %08x->%08x\n",
594 yi->reg_2918, reg_2918, yi->reg_291c, reg_291c);
592 595
593 write_reg(reg_296c, 0x0296c); 596 write_reg(reg_296c, 0x0296c);
594 IVTV_DEBUG_YUV("Update reg 0x296c %08x->%08x\n",itv->yuv_info.reg_296c, reg_296c); 597 IVTV_DEBUG_YUV("Update reg 0x296c %08x->%08x\n",
598 yi->reg_296c, reg_296c);
595 599
596 write_reg(reg_2940, 0x02948); 600 write_reg(reg_2940, 0x02948);
597 write_reg(reg_2940, 0x02940); 601 write_reg(reg_2940, 0x02940);
598 IVTV_DEBUG_YUV("Update reg 0x2940 %08x->%08x 0x2948 %08x->%08x\n",itv->yuv_info.reg_2940, reg_2940, itv->yuv_info.reg_2948, reg_2940); 602 IVTV_DEBUG_YUV("Update reg 0x2940 %08x->%08x 0x2948 %08x->%08x\n",
603 yi->reg_2940, reg_2940, yi->reg_2948, reg_2940);
599 604
600 write_reg(reg_2950, 0x02950); 605 write_reg(reg_2950, 0x02950);
601 write_reg(reg_2954, 0x02954); 606 write_reg(reg_2954, 0x02954);
602 IVTV_DEBUG_YUV("Update reg 0x2950 %08x->%08x 0x2954 %08x->%08x\n",itv->yuv_info.reg_2950, reg_2950, itv->yuv_info.reg_2954, reg_2954); 607 IVTV_DEBUG_YUV("Update reg 0x2950 %08x->%08x 0x2954 %08x->%08x\n",
608 yi->reg_2950, reg_2950, yi->reg_2954, reg_2954);
603 609
604 write_reg(reg_2958, 0x02958); 610 write_reg(reg_2958, 0x02958);
605 write_reg(reg_295c, 0x0295C); 611 write_reg(reg_295c, 0x0295C);
606 IVTV_DEBUG_YUV("Update reg 0x2958 %08x->%08x 0x295C %08x->%08x\n",itv->yuv_info.reg_2958, reg_2958, itv->yuv_info.reg_295c, reg_295c); 612 IVTV_DEBUG_YUV("Update reg 0x2958 %08x->%08x 0x295C %08x->%08x\n",
613 yi->reg_2958, reg_2958, yi->reg_295c, reg_295c);
607 614
608 write_reg(reg_2960, 0x02960); 615 write_reg(reg_2960, 0x02960);
609 IVTV_DEBUG_YUV("Update reg 0x2960 %08x->%08x \n",itv->yuv_info.reg_2960, reg_2960); 616 IVTV_DEBUG_YUV("Update reg 0x2960 %08x->%08x \n",
617 yi->reg_2960, reg_2960);
610 618
611 write_reg(reg_2964, 0x02964); 619 write_reg(reg_2964, 0x02964);
612 write_reg(reg_2968, 0x02968); 620 write_reg(reg_2968, 0x02968);
613 IVTV_DEBUG_YUV("Update reg 0x2964 %08x->%08x 0x2968 %08x->%08x\n",itv->yuv_info.reg_2964, reg_2964, itv->yuv_info.reg_2968, reg_2968); 621 IVTV_DEBUG_YUV("Update reg 0x2964 %08x->%08x 0x2968 %08x->%08x\n",
622 yi->reg_2964, reg_2964, yi->reg_2968, reg_2968);
614 623
615 write_reg( reg_289c,0x0289c); 624 write_reg(reg_289c, 0x0289c);
616 IVTV_DEBUG_YUV("Update reg 0x289c %08x->%08x\n",itv->yuv_info.reg_289c, reg_289c); 625 IVTV_DEBUG_YUV("Update reg 0x289c %08x->%08x\n",
626 yi->reg_289c, reg_289c);
617 627
618 /* Only update filter 1 if we really need to */ 628 /* Only update filter 1 if we really need to */
619 if (v_filter_1 != itv->yuv_info.v_filter_1) { 629 if (v_filter_1 != yi->v_filter_1) {
620 ivtv_yuv_filter (itv,-1,v_filter_1,-1); 630 ivtv_yuv_filter(itv, -1, v_filter_1, -1);
621 itv->yuv_info.v_filter_1 = v_filter_1; 631 yi->v_filter_1 = v_filter_1;
622 } 632 }
623 633
624 /* Only update filter 2 if we really need to */ 634 /* Only update filter 2 if we really need to */
625 if (v_filter_2 != itv->yuv_info.v_filter_2) { 635 if (v_filter_2 != yi->v_filter_2) {
626 ivtv_yuv_filter (itv,-1,-1,v_filter_2); 636 ivtv_yuv_filter(itv, -1, -1, v_filter_2);
627 itv->yuv_info.v_filter_2 = v_filter_2; 637 yi->v_filter_2 = v_filter_2;
628 } 638 }
629
630} 639}
631 640
632/* Modify the supplied coordinate information to fit the visible osd area */ 641/* Modify the supplied coordinate information to fit the visible osd area */
@@ -668,7 +677,7 @@ static u32 ivtv_yuv_window_setup(struct ivtv *itv, struct yuv_frame_info *f)
668 677
669 /* If there's nothing to safe to display, we may as well stop now */ 678 /* If there's nothing to safe to display, we may as well stop now */
670 if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 || 679 if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 ||
671 (int)f->src_w <= 2 || (int)f->src_h <= 2) { 680 (int)f->src_w <= 2 || (int)f->src_h <= 2) {
672 return IVTV_YUV_UPDATE_INVALID; 681 return IVTV_YUV_UPDATE_INVALID;
673 } 682 }
674 683
@@ -749,23 +758,23 @@ static u32 ivtv_yuv_window_setup(struct ivtv *itv, struct yuv_frame_info *f)
749 758
750 /* Check again. If there's nothing to safe to display, stop now */ 759 /* Check again. If there's nothing to safe to display, stop now */
751 if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 || 760 if ((int)f->dst_w <= 2 || (int)f->dst_h <= 2 ||
752 (int)f->src_w <= 2 || (int)f->src_h <= 2) { 761 (int)f->src_w <= 2 || (int)f->src_h <= 2) {
753 return IVTV_YUV_UPDATE_INVALID; 762 return IVTV_YUV_UPDATE_INVALID;
754 } 763 }
755 764
756 /* Both x offset & width are linked, so they have to be done together */ 765 /* Both x offset & width are linked, so they have to be done together */
757 if ((of->dst_w != f->dst_w) || (of->src_w != f->src_w) || 766 if ((of->dst_w != f->dst_w) || (of->src_w != f->src_w) ||
758 (of->dst_x != f->dst_x) || (of->src_x != f->src_x) || 767 (of->dst_x != f->dst_x) || (of->src_x != f->src_x) ||
759 (of->pan_x != f->pan_x) || (of->vis_w != f->vis_w)) { 768 (of->pan_x != f->pan_x) || (of->vis_w != f->vis_w)) {
760 yuv_update |= IVTV_YUV_UPDATE_HORIZONTAL; 769 yuv_update |= IVTV_YUV_UPDATE_HORIZONTAL;
761 } 770 }
762 771
763 if ((of->src_h != f->src_h) || (of->dst_h != f->dst_h) || 772 if ((of->src_h != f->src_h) || (of->dst_h != f->dst_h) ||
764 (of->dst_y != f->dst_y) || (of->src_y != f->src_y) || 773 (of->dst_y != f->dst_y) || (of->src_y != f->src_y) ||
765 (of->pan_y != f->pan_y) || (of->vis_h != f->vis_h) || 774 (of->pan_y != f->pan_y) || (of->vis_h != f->vis_h) ||
766 (of->lace_mode != f->lace_mode) || 775 (of->lace_mode != f->lace_mode) ||
767 (of->interlaced_y != f->interlaced_y) || 776 (of->interlaced_y != f->interlaced_y) ||
768 (of->interlaced_uv != f->interlaced_uv)) { 777 (of->interlaced_uv != f->interlaced_uv)) {
769 yuv_update |= IVTV_YUV_UPDATE_VERTICAL; 778 yuv_update |= IVTV_YUV_UPDATE_VERTICAL;
770 } 779 }
771 780
@@ -773,24 +782,24 @@ static u32 ivtv_yuv_window_setup(struct ivtv *itv, struct yuv_frame_info *f)
773} 782}
774 783
775/* Update the scaling register to the requested value */ 784/* Update the scaling register to the requested value */
776void ivtv_yuv_work_handler (struct ivtv *itv) 785void ivtv_yuv_work_handler(struct ivtv *itv)
777{ 786{
778 struct yuv_playback_info *yi = &itv->yuv_info; 787 struct yuv_playback_info *yi = &itv->yuv_info;
779 struct yuv_frame_info f; 788 struct yuv_frame_info f;
780 int frame = yi->update_frame; 789 int frame = yi->update_frame;
781 u32 yuv_update; 790 u32 yuv_update;
782 791
783/* IVTV_DEBUG_YUV("Update yuv registers for frame %d\n",frame); */ 792 IVTV_DEBUG_YUV("Update yuv registers for frame %d\n", frame);
784 f = yi->new_frame_info[frame]; 793 f = yi->new_frame_info[frame];
785 794
786 /* Update the osd pan info */ 795 /* Update the osd pan info */
787 f.pan_x = itv->yuv_info.osd_x_pan; 796 f.pan_x = yi->osd_x_pan;
788 f.pan_y = itv->yuv_info.osd_y_pan; 797 f.pan_y = yi->osd_y_pan;
789 f.vis_w = itv->yuv_info.osd_vis_w; 798 f.vis_w = yi->osd_vis_w;
790 f.vis_h = itv->yuv_info.osd_vis_h; 799 f.vis_h = yi->osd_vis_h;
791 800
792 /* Calculate the display window coordinates. Exit if nothing left */ 801 /* Calculate the display window coordinates. Exit if nothing left */
793 if (!(yuv_update = ivtv_yuv_window_setup (itv, &f))) 802 if (!(yuv_update = ivtv_yuv_window_setup(itv, &f)))
794 return; 803 return;
795 804
796 if (yuv_update & IVTV_YUV_UPDATE_INVALID) { 805 if (yuv_update & IVTV_YUV_UPDATE_INVALID) {
@@ -807,7 +816,7 @@ void ivtv_yuv_work_handler (struct ivtv *itv)
807 yi->old_frame_info = f; 816 yi->old_frame_info = f;
808} 817}
809 818
810static void ivtv_yuv_init (struct ivtv *itv) 819static void ivtv_yuv_init(struct ivtv *itv)
811{ 820{
812 struct yuv_playback_info *yi = &itv->yuv_info; 821 struct yuv_playback_info *yi = &itv->yuv_info;
813 822
@@ -876,25 +885,23 @@ static void ivtv_yuv_init (struct ivtv *itv)
876 if (!yi->osd_vis_w) 885 if (!yi->osd_vis_w)
877 yi->osd_vis_w = 720 - yi->osd_x_offset; 886 yi->osd_vis_w = 720 - yi->osd_x_offset;
878 887
879 if (!yi->osd_vis_h) 888 if (!yi->osd_vis_h) {
880 yi->osd_vis_h = yi->decode_height - yi->osd_y_offset; 889 yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
881 else { 890 } else if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) {
882 /* If output video standard has changed, requested height may 891 /* If output video standard has changed, requested height may
883 not be legal */ 892 not be legal */
884 if (yi->osd_vis_h + yi->osd_y_offset > yi->decode_height) { 893 IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n",
885 IVTV_DEBUG_WARN("Clipping yuv output - fb size (%d) exceeds video standard limit (%d)\n", 894 yi->osd_vis_h + yi->osd_y_offset,
886 yi->osd_vis_h + yi->osd_y_offset, 895 yi->decode_height);
887 yi->decode_height); 896 yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
888 yi->osd_vis_h = yi->decode_height - yi->osd_y_offset;
889 }
890 } 897 }
891 } 898 }
892 899
893 /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */ 900 /* We need a buffer for blanking when Y plane is offset - non-fatal if we can't get one */
894 yi->blanking_ptr = kzalloc(720*16, GFP_KERNEL); 901 yi->blanking_ptr = kzalloc(720 * 16, GFP_KERNEL);
895 if (yi->blanking_ptr) 902 if (yi->blanking_ptr) {
896 yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE); 903 yi->blanking_dmaptr = pci_map_single(itv->dev, yi->blanking_ptr, 720*16, PCI_DMA_TODEVICE);
897 else { 904 } else {
898 yi->blanking_dmaptr = 0; 905 yi->blanking_dmaptr = 0;
899 IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n"); 906 IVTV_DEBUG_WARN("Failed to allocate yuv blanking buffer\n");
900 } 907 }
@@ -993,8 +1000,8 @@ void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
993 if (nf->tru_h <= lace_threshold || nf->tru_h > 576 || nf->tru_w > 720) { 1000 if (nf->tru_h <= lace_threshold || nf->tru_h > 576 || nf->tru_w > 720) {
994 nf->interlaced = 0; 1001 nf->interlaced = 0;
995 if ((nf->tru_h < 512) || 1002 if ((nf->tru_h < 512) ||
996 (nf->tru_h > 576 && nf->tru_h < 1021) || 1003 (nf->tru_h > 576 && nf->tru_h < 1021) ||
997 (nf->tru_w > 720 && nf->tru_h < 1021)) 1004 (nf->tru_w > 720 && nf->tru_h < 1021))
998 nf->interlaced_y = 0; 1005 nf->interlaced_y = 0;
999 else 1006 else
1000 nf->interlaced_y = 1; 1007 nf->interlaced_y = 1;
@@ -1020,7 +1027,7 @@ void ivtv_yuv_setup_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
1020 if (memcmp(&yi->old_frame_info_args, nf, sizeof(*nf))) { 1027 if (memcmp(&yi->old_frame_info_args, nf, sizeof(*nf))) {
1021 yi->old_frame_info_args = *nf; 1028 yi->old_frame_info_args = *nf;
1022 nf->update = 1; 1029 nf->update = 1;
1023/* IVTV_DEBUG_YUV ("Requesting register update for frame %d\n",frame); */ 1030 IVTV_DEBUG_YUV("Requesting reg update for frame %d\n", frame);
1024 } 1031 }
1025 1032
1026 nf->update |= update; 1033 nf->update |= update;
@@ -1051,10 +1058,10 @@ int ivtv_yuv_udma_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
1051 ivtv_udma_prepare(itv); 1058 ivtv_udma_prepare(itv);
1052 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE); 1059 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
1053 /* if no UDMA is pending and no UDMA is in progress, then the DMA 1060 /* if no UDMA is pending and no UDMA is in progress, then the DMA
1054 is finished */ 1061 is finished */
1055 while (itv->i_flags & (IVTV_F_I_UDMA_PENDING | IVTV_F_I_UDMA)) { 1062 while (itv->i_flags & (IVTV_F_I_UDMA_PENDING | IVTV_F_I_UDMA)) {
1056 /* don't interrupt if the DMA is in progress but break off 1063 /* don't interrupt if the DMA is in progress but break off
1057 a still pending DMA. */ 1064 a still pending DMA. */
1058 got_sig = signal_pending(current); 1065 got_sig = signal_pending(current);
1059 if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags)) 1066 if (got_sig && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
1060 break; 1067 break;
@@ -1121,7 +1128,7 @@ int ivtv_yuv_udma_stream_frame(struct ivtv *itv, void *src)
1121/* IVTV_IOC_DMA_FRAME ioctl handler */ 1128/* IVTV_IOC_DMA_FRAME ioctl handler */
1122int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args) 1129int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
1123{ 1130{
1124 IVTV_DEBUG_INFO("yuv_prep_frame\n"); 1131/* IVTV_DEBUG_INFO("yuv_prep_frame\n"); */
1125 1132
1126 ivtv_yuv_next_free(itv); 1133 ivtv_yuv_next_free(itv);
1127 ivtv_yuv_setup_frame(itv, args); 1134 ivtv_yuv_setup_frame(itv, args);
@@ -1130,91 +1137,90 @@ int ivtv_yuv_prep_frame(struct ivtv *itv, struct ivtv_dma_frame *args)
1130 1137
1131void ivtv_yuv_close(struct ivtv *itv) 1138void ivtv_yuv_close(struct ivtv *itv)
1132{ 1139{
1140 struct yuv_playback_info *yi = &itv->yuv_info;
1133 int h_filter, v_filter_1, v_filter_2; 1141 int h_filter, v_filter_1, v_filter_2;
1134 1142
1135 IVTV_DEBUG_YUV("ivtv_yuv_close\n"); 1143 IVTV_DEBUG_YUV("ivtv_yuv_close\n");
1136 ivtv_waitq(&itv->vsync_waitq); 1144 ivtv_waitq(&itv->vsync_waitq);
1137 1145
1138 atomic_set(&itv->yuv_info.next_dma_frame, -1); 1146 atomic_set(&yi->next_dma_frame, -1);
1139 atomic_set(&itv->yuv_info.next_fill_frame, 0); 1147 atomic_set(&yi->next_fill_frame, 0);
1140 1148
1141 /* Reset registers we have changed so mpeg playback works */ 1149 /* Reset registers we have changed so mpeg playback works */
1142 1150
1143 /* If we fully restore this register, the display may remain active. 1151 /* If we fully restore this register, the display may remain active.
1144 Restore, but set one bit to blank the video. Firmware will always 1152 Restore, but set one bit to blank the video. Firmware will always
1145 clear this bit when needed, so not a problem. */ 1153 clear this bit when needed, so not a problem. */
1146 write_reg(itv->yuv_info.reg_2898 | 0x01000000, 0x2898); 1154 write_reg(yi->reg_2898 | 0x01000000, 0x2898);
1147 1155
1148 write_reg(itv->yuv_info.reg_2834, 0x02834); 1156 write_reg(yi->reg_2834, 0x02834);
1149 write_reg(itv->yuv_info.reg_2838, 0x02838); 1157 write_reg(yi->reg_2838, 0x02838);
1150 write_reg(itv->yuv_info.reg_283c, 0x0283c); 1158 write_reg(yi->reg_283c, 0x0283c);
1151 write_reg(itv->yuv_info.reg_2840, 0x02840); 1159 write_reg(yi->reg_2840, 0x02840);
1152 write_reg(itv->yuv_info.reg_2844, 0x02844); 1160 write_reg(yi->reg_2844, 0x02844);
1153 write_reg(itv->yuv_info.reg_2848, 0x02848); 1161 write_reg(yi->reg_2848, 0x02848);
1154 write_reg(itv->yuv_info.reg_2854, 0x02854); 1162 write_reg(yi->reg_2854, 0x02854);
1155 write_reg(itv->yuv_info.reg_285c, 0x0285c); 1163 write_reg(yi->reg_285c, 0x0285c);
1156 write_reg(itv->yuv_info.reg_2864, 0x02864); 1164 write_reg(yi->reg_2864, 0x02864);
1157 write_reg(itv->yuv_info.reg_2870, 0x02870); 1165 write_reg(yi->reg_2870, 0x02870);
1158 write_reg(itv->yuv_info.reg_2874, 0x02874); 1166 write_reg(yi->reg_2874, 0x02874);
1159 write_reg(itv->yuv_info.reg_2890, 0x02890); 1167 write_reg(yi->reg_2890, 0x02890);
1160 write_reg(itv->yuv_info.reg_289c, 0x0289c); 1168 write_reg(yi->reg_289c, 0x0289c);
1161 1169
1162 write_reg(itv->yuv_info.reg_2918, 0x02918); 1170 write_reg(yi->reg_2918, 0x02918);
1163 write_reg(itv->yuv_info.reg_291c, 0x0291c); 1171 write_reg(yi->reg_291c, 0x0291c);
1164 write_reg(itv->yuv_info.reg_2920, 0x02920); 1172 write_reg(yi->reg_2920, 0x02920);
1165 write_reg(itv->yuv_info.reg_2924, 0x02924); 1173 write_reg(yi->reg_2924, 0x02924);
1166 write_reg(itv->yuv_info.reg_2928, 0x02928); 1174 write_reg(yi->reg_2928, 0x02928);
1167 write_reg(itv->yuv_info.reg_292c, 0x0292c); 1175 write_reg(yi->reg_292c, 0x0292c);
1168 write_reg(itv->yuv_info.reg_2930, 0x02930); 1176 write_reg(yi->reg_2930, 0x02930);
1169 write_reg(itv->yuv_info.reg_2934, 0x02934); 1177 write_reg(yi->reg_2934, 0x02934);
1170 write_reg(itv->yuv_info.reg_2938, 0x02938); 1178 write_reg(yi->reg_2938, 0x02938);
1171 write_reg(itv->yuv_info.reg_293c, 0x0293c); 1179 write_reg(yi->reg_293c, 0x0293c);
1172 write_reg(itv->yuv_info.reg_2940, 0x02940); 1180 write_reg(yi->reg_2940, 0x02940);
1173 write_reg(itv->yuv_info.reg_2944, 0x02944); 1181 write_reg(yi->reg_2944, 0x02944);
1174 write_reg(itv->yuv_info.reg_2948, 0x02948); 1182 write_reg(yi->reg_2948, 0x02948);
1175 write_reg(itv->yuv_info.reg_294c, 0x0294c); 1183 write_reg(yi->reg_294c, 0x0294c);
1176 write_reg(itv->yuv_info.reg_2950, 0x02950); 1184 write_reg(yi->reg_2950, 0x02950);
1177 write_reg(itv->yuv_info.reg_2954, 0x02954); 1185 write_reg(yi->reg_2954, 0x02954);
1178 write_reg(itv->yuv_info.reg_2958, 0x02958); 1186 write_reg(yi->reg_2958, 0x02958);
1179 write_reg(itv->yuv_info.reg_295c, 0x0295c); 1187 write_reg(yi->reg_295c, 0x0295c);
1180 write_reg(itv->yuv_info.reg_2960, 0x02960); 1188 write_reg(yi->reg_2960, 0x02960);
1181 write_reg(itv->yuv_info.reg_2964, 0x02964); 1189 write_reg(yi->reg_2964, 0x02964);
1182 write_reg(itv->yuv_info.reg_2968, 0x02968); 1190 write_reg(yi->reg_2968, 0x02968);
1183 write_reg(itv->yuv_info.reg_296c, 0x0296c); 1191 write_reg(yi->reg_296c, 0x0296c);
1184 write_reg(itv->yuv_info.reg_2970, 0x02970); 1192 write_reg(yi->reg_2970, 0x02970);
1185 1193
1186 /* Prepare to restore filters */ 1194 /* Prepare to restore filters */
1187 1195
1188 /* First the horizontal filter */ 1196 /* First the horizontal filter */
1189 if ((itv->yuv_info.reg_2834 & 0x0000FFFF) == (itv->yuv_info.reg_2834 >> 16)) { 1197 if ((yi->reg_2834 & 0x0000FFFF) == (yi->reg_2834 >> 16)) {
1190 /* An exact size match uses filter 0 */ 1198 /* An exact size match uses filter 0 */
1191 h_filter = 0; 1199 h_filter = 0;
1192 } 1200 } else {
1193 else {
1194 /* Figure out which filter to use */ 1201 /* Figure out which filter to use */
1195 h_filter = ((itv->yuv_info.reg_2834 << 16) / (itv->yuv_info.reg_2834 >> 16)) >> 15; 1202 h_filter = ((yi->reg_2834 << 16) / (yi->reg_2834 >> 16)) >> 15;
1196 h_filter = (h_filter >> 1) + (h_filter & 1); 1203 h_filter = (h_filter >> 1) + (h_filter & 1);
1197 /* Only an exact size match can use filter 0. */ 1204 /* Only an exact size match can use filter 0. */
1198 if (h_filter < 1) h_filter = 1; 1205 h_filter += !h_filter;
1199 } 1206 }
1200 1207
1201 /* Now the vertical filter */ 1208 /* Now the vertical filter */
1202 if ((itv->yuv_info.reg_2918 & 0x0000FFFF) == (itv->yuv_info.reg_2918 >> 16)) { 1209 if ((yi->reg_2918 & 0x0000FFFF) == (yi->reg_2918 >> 16)) {
1203 /* An exact size match uses filter 0/1 */ 1210 /* An exact size match uses filter 0/1 */
1204 v_filter_1 = 0; 1211 v_filter_1 = 0;
1205 v_filter_2 = 1; 1212 v_filter_2 = 1;
1206 } 1213 } else {
1207 else {
1208 /* Figure out which filter to use */ 1214 /* Figure out which filter to use */
1209 v_filter_1 = ((itv->yuv_info.reg_2918 << 16) / (itv->yuv_info.reg_2918 >> 16)) >> 15; 1215 v_filter_1 = ((yi->reg_2918 << 16) / (yi->reg_2918 >> 16)) >> 15;
1210 v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1); 1216 v_filter_1 = (v_filter_1 >> 1) + (v_filter_1 & 1);
1211 /* Only an exact size match can use filter 0 */ 1217 /* Only an exact size match can use filter 0 */
1212 if (v_filter_1 == 0) v_filter_1 = 1; 1218 v_filter_1 += !v_filter_1;
1213 v_filter_2 = v_filter_1; 1219 v_filter_2 = v_filter_1;
1214 } 1220 }
1215 1221
1216 /* Now restore the filters */ 1222 /* Now restore the filters */
1217 ivtv_yuv_filter (itv,h_filter,v_filter_1,v_filter_2); 1223 ivtv_yuv_filter(itv, h_filter, v_filter_1, v_filter_2);
1218 1224
1219 /* and clear a few registers */ 1225 /* and clear a few registers */
1220 write_reg(0, 0x02814); 1226 write_reg(0, 0x02814);
@@ -1223,19 +1229,18 @@ void ivtv_yuv_close(struct ivtv *itv)
1223 write_reg(0, 0x02910); 1229 write_reg(0, 0x02910);
1224 1230
1225 /* Release the blanking buffer */ 1231 /* Release the blanking buffer */
1226 if (itv->yuv_info.blanking_ptr) { 1232 if (yi->blanking_ptr) {
1227 kfree (itv->yuv_info.blanking_ptr); 1233 kfree(yi->blanking_ptr);
1228 itv->yuv_info.blanking_ptr = NULL; 1234 yi->blanking_ptr = NULL;
1229 pci_unmap_single(itv->dev, itv->yuv_info.blanking_dmaptr, 720*16, PCI_DMA_TODEVICE); 1235 pci_unmap_single(itv->dev, yi->blanking_dmaptr, 720*16, PCI_DMA_TODEVICE);
1230 } 1236 }
1231 1237
1232 /* Invalidate the old dimension information */ 1238 /* Invalidate the old dimension information */
1233 itv->yuv_info.old_frame_info.src_w = 0; 1239 yi->old_frame_info.src_w = 0;
1234 itv->yuv_info.old_frame_info.src_h = 0; 1240 yi->old_frame_info.src_h = 0;
1235 itv->yuv_info.old_frame_info_args.src_w = 0; 1241 yi->old_frame_info_args.src_w = 0;
1236 itv->yuv_info.old_frame_info_args.src_h = 0; 1242 yi->old_frame_info_args.src_h = 0;
1237 1243
1238 /* All done. */ 1244 /* All done. */
1239 clear_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags); 1245 clear_bit(IVTV_F_I_DECODING_YUV, &itv->i_flags);
1240} 1246}
1241