@@ -601,6 +601,25 @@ static void cx23885_risc_disasm(struct cx23885_tsport *port,
601
601
}
602
602
}
603
603
604
+ static void cx23885_clear_bridge_error (struct cx23885_dev * dev )
605
+ {
606
+ uint32_t reg1_val = cx_read (TC_REQ ); /* read-only */
607
+ uint32_t reg2_val = cx_read (TC_REQ_SET );
608
+
609
+ if (reg1_val && reg2_val ) {
610
+ cx_write (TC_REQ , reg1_val );
611
+ cx_write (TC_REQ_SET , reg2_val );
612
+ cx_read (VID_B_DMA );
613
+ cx_read (VBI_B_DMA );
614
+ cx_read (VID_C_DMA );
615
+ cx_read (VBI_C_DMA );
616
+
617
+ dev_info (& dev -> pci -> dev ,
618
+ "dma in progress detected 0x%08x 0x%08x, clearing\n" ,
619
+ reg1_val , reg2_val );
620
+ }
621
+ }
622
+
604
623
static void cx23885_shutdown (struct cx23885_dev * dev )
605
624
{
606
625
/* disable RISC controller */
@@ -646,6 +665,8 @@ static void cx23885_reset(struct cx23885_dev *dev)
646
665
cx_write (CLK_DELAY , cx_read (CLK_DELAY ) & 0x80000000 );
647
666
cx_write (PAD_CTRL , 0x00500300 );
648
667
668
+ /* clear dma in progress */
669
+ cx23885_clear_bridge_error (dev );
649
670
mdelay (100 );
650
671
651
672
cx23885_sram_channel_setup (dev , & dev -> sram_channels [SRAM_CH01 ],
@@ -662,6 +683,11 @@ static void cx23885_reset(struct cx23885_dev *dev)
662
683
cx23885_sram_channel_setup (dev , & dev -> sram_channels [SRAM_CH09 ], 128 , 0 );
663
684
664
685
cx23885_gpio_setup (dev );
686
+
687
+ cx23885_irq_get_mask (dev );
688
+
689
+ /* clear dma in progress */
690
+ cx23885_clear_bridge_error (dev );
665
691
}
666
692
667
693
@@ -676,6 +702,8 @@ static int cx23885_pci_quirks(struct cx23885_dev *dev)
676
702
if (dev -> bridge == CX23885_BRIDGE_885 )
677
703
cx_clear (RDR_TLCTL0 , 1 << 4 );
678
704
705
+ /* clear dma in progress */
706
+ cx23885_clear_bridge_error (dev );
679
707
return 0 ;
680
708
}
681
709
@@ -1352,6 +1380,9 @@ int cx23885_start_dma(struct cx23885_tsport *port,
1352
1380
dprintk (1 , "%s() w: %d, h: %d, f: %d\n" , __func__ ,
1353
1381
dev -> width , dev -> height , dev -> field );
1354
1382
1383
+ /* clear dma in progress */
1384
+ cx23885_clear_bridge_error (dev );
1385
+
1355
1386
/* Stop the fifo and risc engine for this port */
1356
1387
cx_clear (port -> reg_dma_ctl , port -> dma_ctl_val );
1357
1388
@@ -1432,39 +1463,67 @@ int cx23885_start_dma(struct cx23885_tsport *port,
1432
1463
case CX23885_BRIDGE_888 :
1433
1464
/* enable irqs */
1434
1465
dprintk (1 , "%s() enabling TS int's and DMA\n" , __func__ );
1466
+ /* clear dma in progress */
1467
+ cx23885_clear_bridge_error (dev );
1435
1468
cx_set (port -> reg_ts_int_msk , port -> ts_int_msk_val );
1436
1469
cx_set (port -> reg_dma_ctl , port -> dma_ctl_val );
1470
+
1471
+ /* clear dma in progress */
1472
+ cx23885_clear_bridge_error (dev );
1437
1473
cx23885_irq_add (dev , port -> pci_irqmask );
1438
1474
cx23885_irq_enable_all (dev );
1475
+
1476
+ /* clear dma in progress */
1477
+ cx23885_clear_bridge_error (dev );
1439
1478
break ;
1440
1479
default :
1441
1480
BUG ();
1442
1481
}
1443
1482
1444
1483
cx_set (DEV_CNTRL2 , (1 <<5 )); /* Enable RISC controller */
1484
+ /* clear dma in progress */
1485
+ cx23885_clear_bridge_error (dev );
1445
1486
1446
1487
if (cx23885_boards [dev -> board ].portb == CX23885_MPEG_ENCODER )
1447
1488
cx23885_av_clk (dev , 1 );
1448
1489
1449
1490
if (debug > 4 )
1450
1491
cx23885_tsport_reg_dump (port );
1451
1492
1493
+ cx23885_irq_get_mask (dev );
1494
+
1495
+ /* clear dma in progress */
1496
+ cx23885_clear_bridge_error (dev );
1497
+
1452
1498
return 0 ;
1453
1499
}
1454
1500
1455
1501
static int cx23885_stop_dma (struct cx23885_tsport * port )
1456
1502
{
1457
1503
struct cx23885_dev * dev = port -> dev ;
1458
1504
u32 reg ;
1505
+ int delay = 0 ;
1506
+ uint32_t reg1_val ;
1507
+ uint32_t reg2_val ;
1459
1508
1460
1509
dprintk (1 , "%s()\n" , __func__ );
1461
1510
1462
1511
/* Stop interrupts and DMA */
1463
1512
cx_clear (port -> reg_ts_int_msk , port -> ts_int_msk_val );
1464
1513
cx_clear (port -> reg_dma_ctl , port -> dma_ctl_val );
1514
+ /* just in case wait for any dma to complete before allowing dealloc */
1515
+ mdelay (20 );
1516
+ for (delay = 0 ; delay < 100 ; delay ++ ) {
1517
+ reg1_val = cx_read (TC_REQ );
1518
+ reg2_val = cx_read (TC_REQ_SET );
1519
+ if (reg1_val == 0 || reg2_val == 0 )
1520
+ break ;
1521
+ mdelay (1 );
1522
+ }
1523
+ dev_dbg (& dev -> pci -> dev , "delay=%d reg1=0x%08x reg2=0x%08x\n" ,
1524
+ delay , reg1_val , reg2_val );
1465
1525
1466
1526
if (cx23885_boards [dev -> board ].portb == CX23885_MPEG_ENCODER ) {
1467
-
1468
1527
reg = cx_read (PAD_CTRL );
1469
1528
1470
1529
/* Set TS1_OE */
@@ -1475,7 +1534,6 @@ static int cx23885_stop_dma(struct cx23885_tsport *port)
1475
1534
cx_write (PAD_CTRL , reg );
1476
1535
cx_write (port -> reg_src_sel , 0 );
1477
1536
cx_write (port -> reg_gen_ctrl , 8 );
1478
-
1479
1537
}
1480
1538
1481
1539
if (cx23885_boards [dev -> board ].portb == CX23885_MPEG_ENCODER )
0 commit comments