@@ -304,11 +304,6 @@ struct ipu_task_entry {
304
304
atomic_t res_get ;
305
305
306
306
struct ipu_task_entry * parent ;
307
- char * vditmpbuf [2 ];
308
- u32 old_save_lines ;
309
- u32 old_size ;
310
- bool buf1filled ;
311
- bool buf0filled ;
312
307
313
308
vdoa_handle_t vdoa_handle ;
314
309
struct vdoa_output_mem {
@@ -1721,7 +1716,7 @@ static int queue_split_task(struct ipu_task_entry *t,
1721
1716
{
1722
1717
int err [4 ];
1723
1718
int ret = 0 ;
1724
- int i , j ;
1719
+ int i , j , invert ;
1725
1720
struct ipu_task_entry * tsk = NULL ;
1726
1721
struct mutex * lock = & t -> split_lock ;
1727
1722
struct mutex * vdic_lock = & t -> vdic_lock ;
@@ -1738,6 +1733,11 @@ static int queue_split_task(struct ipu_task_entry *t,
1738
1733
sp_task [j ].task_no = t -> task_no ;
1739
1734
}
1740
1735
1736
+ /* Note: When deinterlace is active, insert UP_STRIPE before DOWN_STRIPE.
1737
+ * This will avoid the "tearing line" problem formerly addressed by ENGR00161315
1738
+ */
1739
+ invert = (t -> input .deinterlace .enable ) ? (UP_STRIPE | DOWN_STRIPE ) : 0 ;
1740
+
1741
1741
if (t -> set .split_mode == RL_SPLIT ) {
1742
1742
i = 0 ;
1743
1743
err [i ] = create_split_task (RIGHT_STRIPE , & sp_task [i ]);
@@ -1747,26 +1747,26 @@ static int queue_split_task(struct ipu_task_entry *t,
1747
1747
err [i ] = create_split_task (LEFT_STRIPE , & sp_task [i ]);
1748
1748
} else if (t -> set .split_mode == UD_SPLIT ) {
1749
1749
i = 0 ;
1750
- err [i ] = create_split_task (DOWN_STRIPE , & sp_task [i ]);
1750
+ err [i ] = create_split_task (DOWN_STRIPE ^ invert , & sp_task [i ]);
1751
1751
if (err [i ] < 0 )
1752
1752
goto err_start ;
1753
1753
i = 1 ;
1754
- err [i ] = create_split_task (UP_STRIPE , & sp_task [i ]);
1754
+ err [i ] = create_split_task (UP_STRIPE ^ invert , & sp_task [i ]);
1755
1755
} else {
1756
1756
i = 0 ;
1757
- err [i ] = create_split_task (RIGHT_STRIPE | DOWN_STRIPE , & sp_task [i ]);
1757
+ err [i ] = create_split_task (( RIGHT_STRIPE | DOWN_STRIPE ) ^ invert , & sp_task [i ]);
1758
1758
if (err [i ] < 0 )
1759
1759
goto err_start ;
1760
1760
i = 1 ;
1761
- err [i ] = create_split_task (LEFT_STRIPE | DOWN_STRIPE , & sp_task [i ]);
1761
+ err [i ] = create_split_task (( LEFT_STRIPE | DOWN_STRIPE ) ^ invert , & sp_task [i ]);
1762
1762
if (err [i ] < 0 )
1763
1763
goto err_start ;
1764
1764
i = 2 ;
1765
- err [i ] = create_split_task (RIGHT_STRIPE | UP_STRIPE , & sp_task [i ]);
1765
+ err [i ] = create_split_task (( RIGHT_STRIPE | UP_STRIPE ) ^ invert , & sp_task [i ]);
1766
1766
if (err [i ] < 0 )
1767
1767
goto err_start ;
1768
1768
i = 3 ;
1769
- err [i ] = create_split_task (LEFT_STRIPE | UP_STRIPE , & sp_task [i ]);
1769
+ err [i ] = create_split_task (( LEFT_STRIPE | UP_STRIPE ) ^ invert , & sp_task [i ]);
1770
1770
}
1771
1771
1772
1772
err_start :
@@ -2407,219 +2407,11 @@ static irqreturn_t task_irq_handler(int irq, void *dev_id)
2407
2407
return IRQ_HANDLED ;
2408
2408
}
2409
2409
2410
- /* Fix deinterlace up&down split mode medium line */
2411
- static void vdi_split_process (struct ipu_soc * ipu , struct ipu_task_entry * t )
2412
- {
2413
- u32 vdi_size ;
2414
- u32 vdi_save_lines ;
2415
- u32 stripe_mode ;
2416
- u32 task_no ;
2417
- u32 i , offset_addr ;
2418
- u32 line_size ;
2419
- unsigned char * base_off ;
2420
- struct ipu_task_entry * parent = t -> parent ;
2421
- struct mutex * lock = & parent -> vdic_lock ;
2422
-
2423
- if (!parent ) {
2424
- dev_err (t -> dev , "ERR[0x%x]invalid parent\n" , t -> task_no );
2425
- return ;
2426
- }
2427
- mutex_lock (lock );
2428
- stripe_mode = t -> task_no & 0xf ;
2429
- task_no = t -> task_no >> 4 ;
2430
-
2431
- /* Save both luma and chroma part for interleaved YUV(e.g. YUYV).
2432
- * Save luma part for non-interleaved and partial-interleaved
2433
- * YUV format (e.g NV12 and YV12). */
2434
- if (t -> output .format == IPU_PIX_FMT_YUYV ||
2435
- t -> output .format == IPU_PIX_FMT_UYVY )
2436
- line_size = t -> output .crop .w * fmt_to_bpp (t -> output .format )/8 ;
2437
- else
2438
- line_size = t -> output .crop .w ;
2439
-
2440
- vdi_save_lines = (t -> output .crop .h - t -> set .sp_setting .ud_split_line )/2 ;
2441
- vdi_size = vdi_save_lines * line_size ;
2442
- if (vdi_save_lines <= 0 ) {
2443
- dev_err (t -> dev , "[0x%p] vdi_save_line error\n" , (void * )t );
2444
- mutex_unlock (lock );
2445
- return ;
2446
- }
2447
-
2448
- /*check vditmpbuf buffer have alloced or buffer size is changed */
2449
- if ((vdi_save_lines != parent -> old_save_lines ) ||
2450
- (vdi_size != parent -> old_size )) {
2451
- if (parent -> vditmpbuf [0 ] != NULL )
2452
- kfree (parent -> vditmpbuf [0 ]);
2453
- if (parent -> vditmpbuf [1 ] != NULL )
2454
- kfree (parent -> vditmpbuf [1 ]);
2455
-
2456
- parent -> vditmpbuf [0 ] = kmalloc (vdi_size , GFP_KERNEL );
2457
- if (parent -> vditmpbuf [0 ] == NULL ) {
2458
- dev_err (t -> dev ,
2459
- "[0x%p]Falied Alloc vditmpbuf[0]\n" , (void * )t );
2460
- mutex_unlock (lock );
2461
- return ;
2462
- }
2463
- memset (parent -> vditmpbuf [0 ], 0 , vdi_size );
2464
-
2465
- parent -> vditmpbuf [1 ] = kmalloc (vdi_size , GFP_KERNEL );
2466
- if (parent -> vditmpbuf [1 ] == NULL ) {
2467
- dev_err (t -> dev ,
2468
- "[0x%p]Falied Alloc vditmpbuf[1]\n" , (void * )t );
2469
- mutex_unlock (lock );
2470
- return ;
2471
- }
2472
- memset (parent -> vditmpbuf [1 ], 0 , vdi_size );
2473
-
2474
- parent -> old_save_lines = vdi_save_lines ;
2475
- parent -> old_size = vdi_size ;
2476
- }
2477
-
2478
- if (pfn_valid (t -> output .paddr >> PAGE_SHIFT )) {
2479
- base_off = page_address (pfn_to_page (t -> output .paddr >> PAGE_SHIFT ));
2480
- base_off += t -> output .paddr & ((1 << PAGE_SHIFT ) - 1 );
2481
- } else {
2482
- base_off = (char * )ioremap_nocache (t -> output .paddr ,
2483
- t -> output .width * t -> output .height *
2484
- fmt_to_bpp (t -> output .format )/8 );
2485
- }
2486
- if (base_off == NULL ) {
2487
- dev_err (t -> dev , "ERR[0x%p]Failed get virtual address\n" , t );
2488
- mutex_unlock (lock );
2489
- return ;
2490
- }
2491
-
2492
- /* UP stripe or UP&LEFT stripe */
2493
- if ((stripe_mode == UP_STRIPE ) ||
2494
- (stripe_mode == (UP_STRIPE | LEFT_STRIPE ))) {
2495
- if (!parent -> buf0filled ) {
2496
- offset_addr = t -> set .o_off +
2497
- t -> set .sp_setting .ud_split_line * t -> set .ostride ;
2498
- dmac_flush_range (base_off + offset_addr ,
2499
- base_off + offset_addr + vdi_size );
2500
- outer_flush_range (t -> output .paddr + offset_addr ,
2501
- t -> output .paddr + offset_addr + vdi_size );
2502
-
2503
- for (i = 0 ; i < vdi_save_lines ; i ++ )
2504
- memcpy (parent -> vditmpbuf [0 ] + i * line_size ,
2505
- base_off + offset_addr +
2506
- i * t -> set .ostride , line_size );
2507
- parent -> buf0filled = true;
2508
- } else {
2509
- offset_addr = t -> set .o_off + (t -> output .crop .h -
2510
- vdi_save_lines ) * t -> set .ostride ;
2511
- for (i = 0 ; i < vdi_save_lines ; i ++ )
2512
- memcpy (base_off + offset_addr + i * t -> set .ostride ,
2513
- parent -> vditmpbuf [0 ] + i * line_size , line_size );
2514
-
2515
- dmac_flush_range (base_off + offset_addr ,
2516
- base_off + offset_addr + i * t -> set .ostride );
2517
- outer_flush_range (t -> output .paddr + offset_addr ,
2518
- t -> output .paddr + offset_addr + i * t -> set .ostride );
2519
- parent -> buf0filled = false;
2520
- }
2521
- }
2522
- /*Down stripe or Down&Left stripe*/
2523
- else if ((stripe_mode == DOWN_STRIPE ) ||
2524
- (stripe_mode == (DOWN_STRIPE | LEFT_STRIPE ))) {
2525
- if (!parent -> buf0filled ) {
2526
- offset_addr = t -> set .o_off + vdi_save_lines * t -> set .ostride ;
2527
- dmac_flush_range (base_off + offset_addr ,
2528
- base_off + offset_addr + vdi_size );
2529
- outer_flush_range (t -> output .paddr + offset_addr ,
2530
- t -> output .paddr + offset_addr + vdi_size );
2531
-
2532
- for (i = 0 ; i < vdi_save_lines ; i ++ )
2533
- memcpy (parent -> vditmpbuf [0 ] + i * line_size ,
2534
- base_off + offset_addr + i * t -> set .ostride ,
2535
- line_size );
2536
- parent -> buf0filled = true;
2537
- } else {
2538
- offset_addr = t -> set .o_off ;
2539
- for (i = 0 ; i < vdi_save_lines ; i ++ )
2540
- memcpy (base_off + offset_addr + i * t -> set .ostride ,
2541
- parent -> vditmpbuf [0 ] + i * line_size ,
2542
- line_size );
2543
-
2544
- dmac_flush_range (base_off + offset_addr ,
2545
- base_off + offset_addr + i * t -> set .ostride );
2546
- outer_flush_range (t -> output .paddr + offset_addr ,
2547
- t -> output .paddr + offset_addr + i * t -> set .ostride );
2548
- parent -> buf0filled = false;
2549
- }
2550
- }
2551
- /*Up&Right stripe*/
2552
- else if (stripe_mode == (UP_STRIPE | RIGHT_STRIPE )) {
2553
- if (!parent -> buf1filled ) {
2554
- offset_addr = t -> set .o_off +
2555
- t -> set .sp_setting .ud_split_line * t -> set .ostride ;
2556
- dmac_flush_range (base_off + offset_addr ,
2557
- base_off + offset_addr + vdi_size );
2558
- outer_flush_range (t -> output .paddr + offset_addr ,
2559
- t -> output .paddr + offset_addr + vdi_size );
2560
-
2561
- for (i = 0 ; i < vdi_save_lines ; i ++ )
2562
- memcpy (parent -> vditmpbuf [1 ] + i * line_size ,
2563
- base_off + offset_addr + i * t -> set .ostride ,
2564
- line_size );
2565
- parent -> buf1filled = true;
2566
- } else {
2567
- offset_addr = t -> set .o_off +
2568
- (t -> output .crop .h - vdi_save_lines )* t -> set .ostride ;
2569
- for (i = 0 ; i < vdi_save_lines ; i ++ )
2570
- memcpy (base_off + offset_addr + i * t -> set .ostride ,
2571
- parent -> vditmpbuf [1 ] + i * line_size ,
2572
- line_size );
2573
-
2574
- dmac_flush_range (base_off + offset_addr ,
2575
- base_off + offset_addr + i * t -> set .ostride );
2576
- outer_flush_range (t -> output .paddr + offset_addr ,
2577
- t -> output .paddr + offset_addr + i * t -> set .ostride );
2578
- parent -> buf1filled = false;
2579
- }
2580
- }
2581
- /*Down stripe or Down&Right stript*/
2582
- else if (stripe_mode == (DOWN_STRIPE | RIGHT_STRIPE )) {
2583
- if (!parent -> buf1filled ) {
2584
- offset_addr = t -> set .o_off + vdi_save_lines * t -> set .ostride ;
2585
- dmac_flush_range (base_off + offset_addr ,
2586
- base_off + offset_addr + vdi_save_lines * t -> set .ostride );
2587
- outer_flush_range (t -> output .paddr + offset_addr ,
2588
- t -> output .paddr + offset_addr + vdi_save_lines * t -> set .ostride );
2589
-
2590
- for (i = 0 ; i < vdi_save_lines ; i ++ )
2591
- memcpy (parent -> vditmpbuf [1 ] + i * line_size ,
2592
- base_off + offset_addr + i * t -> set .ostride ,
2593
- line_size );
2594
- parent -> buf1filled = true;
2595
- } else {
2596
- offset_addr = t -> set .o_off ;
2597
- for (i = 0 ; i < vdi_save_lines ; i ++ )
2598
- memcpy (base_off + offset_addr + i * t -> set .ostride ,
2599
- parent -> vditmpbuf [1 ] + i * line_size ,
2600
- line_size );
2601
-
2602
- dmac_flush_range (base_off + offset_addr ,
2603
- base_off + offset_addr + vdi_save_lines * t -> set .ostride );
2604
- outer_flush_range (t -> output .paddr + offset_addr ,
2605
- t -> output .paddr + offset_addr + vdi_save_lines * t -> set .ostride );
2606
- parent -> buf1filled = false;
2607
- }
2608
- }
2609
- if (!pfn_valid (t -> output .paddr >> PAGE_SHIFT ))
2610
- iounmap (base_off );
2611
- mutex_unlock (lock );
2612
- }
2613
-
2614
2410
static void do_task_release (struct ipu_task_entry * t , int fail )
2615
2411
{
2616
2412
int ret ;
2617
2413
struct ipu_soc * ipu = t -> ipu ;
2618
2414
2619
- if (t -> input .deinterlace .enable && !fail &&
2620
- (t -> task_no & (UP_STRIPE | DOWN_STRIPE )))
2621
- vdi_split_process (ipu , t );
2622
-
2623
2415
ipu_free_irq (ipu , t -> irq , t );
2624
2416
2625
2417
if (t -> vdoa_dma .vaddr )
@@ -3180,9 +2972,6 @@ static void wait_split_task_complete(struct ipu_task_entry *parent,
3180
2972
kref_put (& tsk -> refcount , task_mem_free );
3181
2973
}
3182
2974
3183
- kfree (parent -> vditmpbuf [0 ]);
3184
- kfree (parent -> vditmpbuf [1 ]);
3185
-
3186
2975
if (ret < 0 )
3187
2976
parent -> state = STATE_TIMEOUT ;
3188
2977
else
0 commit comments