diff --git a/drivers/media/pci/tbsmod/tbsmod-io.h b/drivers/media/pci/tbsmod/tbsmod-io.h index a8a36f1eeeaf..daf7386eb510 100644 --- a/drivers/media/pci/tbsmod/tbsmod-io.h +++ b/drivers/media/pci/tbsmod/tbsmod-io.h @@ -106,14 +106,23 @@ enum{ AD9789_BITS_SIGNATURE_1 = 0x53 }; +#define DMA_STATUS 0x00 #define DMA_GO 0x00 #define DMA_SIZE 0x04 +#define DMA_SIZE_TOTAL 0x04 #define DMA_ADDR_HIGH 0x08 #define DMA_ADDR_LOW 0x0c + +#define DMA_ADDR_CELL 0x48 + + #define DMA_DELAY 0x14 #define DMA_DELAYSHORT 0x18 #define DMA_SPEED_CTRL 0x20 #define DMA_INT_MONITOR 0x1c +#define DMARD_SPEED 0x54 //addĦĦ6032 +#define EMPTY_PACKAGE_SPEED 0x58 //addĦĦ6032 +#define DMARD_SIZE 0x5C //addĦĦ6032 #define DMA_FRAME_CNT 0x24 diff --git a/drivers/media/pci/tbsmod/tbsmod.c b/drivers/media/pci/tbsmod/tbsmod.c index 02f36ed917d2..b0d5d996a516 100644 --- a/drivers/media/pci/tbsmod/tbsmod.c +++ b/drivers/media/pci/tbsmod/tbsmod.c @@ -2273,23 +2273,53 @@ static void start_dma_transfer(struct mod_channel *pchannel) { struct tbs_pcie_dev *dev=pchannel->dev; u32 speedctrl; - + u32 dmard_speedctrl; + u32 tmp0; + u32 empty_packet_size = 7; + u32 empty_packet_speed; + /* PikoTV 20200306 */ + TBS_PCIE_WRITE(Int_adapter, 0x04, 0x00000000); // disable interrupts. if(pchannel->input_bitrate){ // Kbit if (pchannel->input_bitrate > PIKOTV_MBKB_THRESHOLD) { - speedctrl = div_u64(1000000000ULL * BLOCKSIZE(dev->cardid), (pchannel->input_bitrate) * 1024); + if(dev->cardid == 0x6032) + speedctrl = div_u64(1000000000ULL * CELLSIZE, (pchannel->input_bitrate) * 1024); + else + speedctrl = div_u64(1000000000ULL * BLOCKSIZE(dev->cardid), (pchannel->input_bitrate) * 1024); + dmard_speedctrl = div_u64(1000000000ULL * 128* (1<input_bitrate) * 1000); + pchannel->input_bitrate = pchannel->input_bitrate/1024; } else// Mbit { - speedctrl = div_u64(1000000000ULL * BLOCKSIZE(dev->cardid), (pchannel->input_bitrate) * 1024*1024); + if(dev->cardid == 0x6032) + speedctrl = div_u64(1000000000ULL * CELLSIZE, (pchannel->input_bitrate) * 1024*1024); + else + speedctrl = div_u64(1000000000ULL * BLOCKSIZE(dev->cardid), (pchannel->input_bitrate) * 1024*1024); + dmard_speedctrl = div_u64(1000000000ULL * 128* (1<input_bitrate) * 1000*1000); } - //printk("ioctl 0x20 speedctrl: %d \n", speedctrl); + if(dev->cardid == 0x6032) + { + tmp0 = TBS_PCIE_READ((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), 0x14); + tmp0 = div_u64(tmp0*188*8, 1000*1000); + printk("bitrate: %d \n", tmp0); + if(tmp0 > pchannel->input_bitrate + 3) + empty_packet_size = tmp0 - pchannel->input_bitrate -1; + else empty_packet_size = 2; + + printk("empty_packet_size: %d \n", empty_packet_size); + empty_packet_speed = div_u64(1000000000ULL * 188, empty_packet_size * 2 * 1000*1000); + + TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMARD_SPEED, (dmard_speedctrl)); + TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMARD_SIZE, (FPGA_BLK)); //0 1 2 3 + TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), EMPTY_PACKAGE_SPEED, (empty_packet_speed)); //2M + } TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_SPEED_CTRL, (speedctrl)); TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_INT_MONITOR, (2*speedctrl)); + if(dev->cardid == 0x690b) { //speedctrl =div_u64(speedctrl,BLOCKCEEL ); @@ -2304,19 +2334,19 @@ static void start_dma_transfer(struct mod_channel *pchannel) } } - TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_SIZE, (BLOCKSIZE(dev->cardid))); - TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_ADDR_HIGH, 0); - TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_ADDR_LOW, pchannel->dmaphy); + //TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_SIZE, (BLOCKSIZE(dev->cardid))); + //TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_ADDR_HIGH, 0); + //TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_ADDR_LOW, pchannel->dmaphy); TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_GO, (1)); - //debug - //tmp0 = TBS_PCIE_READ((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), 0X20); - //printk("0x20: %x \n", tmp0); + tmp0 = TBS_PCIE_READ((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), 0x2c); + if(tmp0 !=0) + { + //printk("dma_stop: %x \n", tmp0); + TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_GO, (1)); + } - if(dev->cardid != 0x6032) - TBS_PCIE_WRITE(Int_adapter, 0x04, (0x00000001)); - - TBS_PCIE_WRITE(Int_adapter, 0x18+pchannel->channel_index*4, (1)); + TBS_PCIE_WRITE(Int_adapter, 0x04, 0x00000001); // enable int } static int tbsmod_open(struct inode *inode, struct file *filp) @@ -2341,6 +2371,8 @@ static int tbsmod_open(struct inode *inode, struct file *filp) printk("%s srate:%d\n", __func__, dev->srate); */ pchannel->dma_start_flag = 0; + pchannel->dma_num = 0; + kfifo_reset(&pchannel->fifo); spin_lock_init(&pchannel->adap_lock); //enable rf @@ -2382,14 +2414,17 @@ static ssize_t tbsmod_write(struct file *file, const char __user *ptr, size_t si struct mod_channel *pchannel = (struct mod_channel *)file->private_data; int count; int i = 0; + + if (pchannel->dma_start_flag == 0) + { + start_dma_transfer(pchannel); + pchannel->dma_start_flag = 1; + } + count = kfifo_avail(&pchannel->fifo); while (count < size) { - if (pchannel->dma_start_flag == 0) - { - start_dma_transfer(pchannel); - pchannel->dma_start_flag = 1; - } + msleep(10); count = kfifo_avail(&pchannel->fifo); i++; @@ -2693,8 +2728,9 @@ static int tbsmod_release(struct inode *inode, struct file *file) u8 buff[4] = {0,0,0,0}; //printk("%s\n", __func__); + TBS_PCIE_WRITE(Int_adapter, 0x04, 0); // disable int TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_GO, (0)); - TBS_PCIE_WRITE(Int_adapter, 0x18+pchannel->channel_index*4, (0)); + //TBS_PCIE_WRITE(Int_adapter, 0x18+pchannel->channel_index*4, (0)); pchannel->dma_start_flag = 0; //disable rf @@ -2715,6 +2751,7 @@ static int tbsmod_release(struct inode *inode, struct file *file) ad9789_wt_nBytes(dev, 1, AD9789_CHANNEL_ENABLE, buff); } + TBS_PCIE_WRITE(Int_adapter, 0x04, 0x00000001); // enable int return 0; } @@ -3071,25 +3108,94 @@ static void sdi_chip_reset(struct tbs_pcie_dev *dev,int sdi_base_addr) } void channelprocess(struct tbs_pcie_dev *dev,u8 index){ - struct mod_channel *pchannel = (struct mod_channel *)&dev->channel[index]; - int count = 0; - int ret; - u32 delay; - //TBS_PCIE_READ((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), 0x00); - spin_lock(&pchannel->adap_lock); - TBS_PCIE_READ((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), 0x00); - if(dev->cardid != 0x6032) - TBS_PCIE_WRITE(Int_adapter, 0x00, (0x10<channel[index]; + int count = 0; + int ret; + u32 delay; + u32 iNum; + u32 iNext; + u32 block_num = 0; + unsigned long flags; + //TBS_PCIE_READ((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), 0x00); + spin_lock_irqsave(&pchannel->adap_lock,flags); + + TBS_PCIE_READ((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), 0x00); + + if(dev->cardid == 0x6032) + { + while(1){ + count = kfifo_len(&pchannel->fifo); + if (count >= CELLSIZE){ + + iNum = TBS_PCIE_READ((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), 0x50); + if(iNum == 0xffffffff){ + printk("erroriNum %ld\n",iNum); + } + if(iNum > DMATOTAL){ + //printk("iNum_v %ld\n",iNum); + iNext = 0; + } + else { + iNext = DMATOTAL - iNum; + } + //printk("DMATOTAL, iNext,iNum %ld,%ld,%ld\n",DMATOTAL,iNext,iNum); + if(iNext > CELLSIZE){ + block_num = 1; + ret = kfifo_out(&pchannel->fifo, ((void *)pchannel->dmavirt + pchannel->dma_num*CELLSIZE ), CELLSIZE); + + if(pchannel->dma_num>14) + pchannel->dma_num=0; + else + pchannel->dma_num +=1; + + TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)),0x50,CELLSIZE); + } + else { + break; + } + + } + else if(block_num == 0){ + //printk("dma%d status 22 %d\n", pchannel->channel_index, count); + if (pchannel->dma_start_flag == 0){ + spin_unlock(&pchannel->adap_lock); + return ; + } + + /* PikoTV 20200306 */ + if (pchannel->input_bitrate > PIKOTV_MBKB_THRESHOLD) + { + // Kbit + delay = div_u64(1000000000ULL * CELLSIZE, (pchannel->input_bitrate) * 1024*3); + } + else + { + // Mbit + delay = div_u64(1000000000ULL * CELLSIZE, (pchannel->input_bitrate) * 1024*1024*3); + } + //printk("%s 0x18 delayshort: %d \n", __func__,delay); + TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_DELAYSHORT, (delay)); + //TBS_PCIE_WRITE(Int_adapter, 0x04, 0x00000001); + } + break; + + } + + } + else + { + TBS_PCIE_WRITE(Int_adapter, 0x00, (0x10<channel_index*4, (0)); count = kfifo_len(&pchannel->fifo); if (count >= BLOCKSIZE(dev->cardid)){ //printk("dma%d status 11 %d\n",pchannel->channel_index,count); ret = kfifo_out(&pchannel->fifo, ((void *)(pchannel->dmavirt) ), BLOCKSIZE(dev->cardid)); - start_dma_transfer(pchannel); + //start_dma_transfer(pchannel); + TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_GO, (1)); }else{ //printk("dma%d status 22 %d\n", pchannel->channel_index, count); if (pchannel->dma_start_flag == 0){ - spin_unlock(&pchannel->adap_lock); + spin_unlock_irqrestore(&pchannel->adap_lock,flags); return ; } @@ -3108,7 +3214,8 @@ void channelprocess(struct tbs_pcie_dev *dev,u8 index){ TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, pchannel->channel_index)), DMA_DELAYSHORT, (delay)); //TBS_PCIE_WRITE(Int_adapter, 0x04, 0x00000001); } - spin_unlock(&pchannel->adap_lock); + } + spin_unlock_irqrestore(&pchannel->adap_lock,flags); } static irqreturn_t tbsmod_irq(int irq, void *dev_id) @@ -3122,7 +3229,7 @@ static irqreturn_t tbsmod_irq(int irq, void *dev_id) stat16 = TBS_PCIE_READ(Int_adapter, 0x18); else stat16 = 0; - TBS_PCIE_WRITE(Int_adapter, 0x04, 0x00000001); + //TBS_PCIE_WRITE(Int_adapter, 0x04, 0x00000001); if((stat == 0x0) && (stat16 == 0x0)) @@ -3259,7 +3366,7 @@ static irqreturn_t tbsmod_irq(int irq, void *dev_id) } } - //TBS_PCIE_WRITE(Int_adapter, 0x04, 0x00000001); + TBS_PCIE_WRITE(Int_adapter, 0x04, 0x00000001); // enable int return IRQ_HANDLED; } @@ -3276,7 +3383,7 @@ static void tbsmod_remove(struct pci_dev *pdev) kfifo_free(&dev->channel[i].fifo); // device_destroy(mod_cdev_class, dev->channel[i].devno); if (dev->channel[i].dmavirt){ - dma_free_coherent(&dev->pdev->dev, DMASIZE, dev->channel[i].dmavirt, dev->channel[i].dmaphy); + dma_free_coherent(&dev->pdev->dev, DMATOTAL, dev->channel[i].dmavirt, dev->channel[i].dmaphy); dev->channel[i].dmavirt = NULL; } } @@ -3454,7 +3561,7 @@ static int tbsmod_probe(struct pci_dev *pdev, } for(i=0;imods_num;i++){ - dev->channel[i].dmavirt = dma_alloc_coherent(&dev->pdev->dev, DMASIZE, &dev->channel[i].dmaphy, GFP_KERNEL); + dev->channel[i].dmavirt = dma_alloc_coherent(&dev->pdev->dev, DMATOTAL, &dev->channel[i].dmaphy, GFP_KERNEL); if (!dev->channel[i].dmavirt) { printk(" allocate memory failed\n"); @@ -3479,6 +3586,20 @@ static int tbsmod_probe(struct pci_dev *pdev, ret = kfifo_alloc(&dev->channel[i].fifo, FIFOSIZE, GFP_KERNEL); if (ret != 0) goto fail3; + + if(dev->cardid == 0x6032) + { + TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, i)), DMA_SIZE_TOTAL, DMATOTAL); + TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, i)), DMA_ADDR_CELL, CELLSIZE); + } + else + { + TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, i)), DMA_SIZE, (BLOCKSIZE(dev->cardid))); + } + TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, i)), DMA_ADDR_HIGH, 0); + TBS_PCIE_WRITE((DMA_BASEADDRESS(dev->cardid, i)), DMA_ADDR_LOW, dev->channel[i].dmaphy); + + TBS_PCIE_WRITE(Int_adapter, 0x18+i*4, (1)); } dev->modulation =QAM_256; diff --git a/drivers/media/pci/tbsmod/tbsmod.h b/drivers/media/pci/tbsmod/tbsmod.h index 924f6fd4c478..8e9e771d52fc 100644 --- a/drivers/media/pci/tbsmod/tbsmod.h +++ b/drivers/media/pci/tbsmod/tbsmod.h @@ -8,11 +8,18 @@ #define CHANNELS 32 #define FIFOSIZE (2048 * 1024) -#define DMASIZE (32 * 1024) #define BLOCKSIZE(id) (188*32) + +#define FPGA_BLK 4 +#define CELLSIZE (32 * 188) +#define DMATOTAL (CELLSIZE * 16) + + //#define BLOCKSIZE(id) ((id==0x6008)?(188*32):(188*96)) #define BLOCKCEEL (32) +#define TBSMOD_DMA_IF(_n) (0x0010 << _n) +#define TBSMOD_DMA_IF16(_n) (0x10000 <<( _n -16)) struct mod_channel { @@ -21,11 +28,11 @@ struct mod_channel dma_addr_t dmaphy; dev_t devno; u8 dma_start_flag; + u8 dma_num; struct kfifo fifo; u8 channel_index; u32 input_bitrate; spinlock_t adap_lock; // dma lock - };