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