root/drivers/media/pci/b2c2/flexcop-dma.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. flexcop_dma_allocate
  2. flexcop_dma_free
  3. flexcop_dma_config
  4. flexcop_dma_xfer_control
  5. flexcop_dma_remap
  6. flexcop_dma_control_size_irq
  7. flexcop_dma_control_timer_irq
  8. flexcop_dma_config_timer

   1 // SPDX-License-Identifier: GPL-2.0
   2 /*
   3  * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
   4  * flexcop-dma.c - configuring and controlling the DMA of the FlexCop
   5  * see flexcop.c for copyright information
   6  */
   7 #include "flexcop.h"
   8 
   9 int flexcop_dma_allocate(struct pci_dev *pdev,
  10                 struct flexcop_dma *dma, u32 size)
  11 {
  12         u8 *tcpu;
  13         dma_addr_t tdma = 0;
  14 
  15         if (size % 2) {
  16                 err("dma buffersize has to be even.");
  17                 return -EINVAL;
  18         }
  19 
  20         tcpu = pci_alloc_consistent(pdev, size, &tdma);
  21         if (tcpu != NULL) {
  22                 dma->pdev = pdev;
  23                 dma->cpu_addr0 = tcpu;
  24                 dma->dma_addr0 = tdma;
  25                 dma->cpu_addr1 = tcpu + size/2;
  26                 dma->dma_addr1 = tdma + size/2;
  27                 dma->size = size/2;
  28                 return 0;
  29         }
  30         return -ENOMEM;
  31 }
  32 EXPORT_SYMBOL(flexcop_dma_allocate);
  33 
  34 void flexcop_dma_free(struct flexcop_dma *dma)
  35 {
  36         pci_free_consistent(dma->pdev, dma->size*2,
  37                         dma->cpu_addr0, dma->dma_addr0);
  38         memset(dma, 0, sizeof(struct flexcop_dma));
  39 }
  40 EXPORT_SYMBOL(flexcop_dma_free);
  41 
  42 int flexcop_dma_config(struct flexcop_device *fc,
  43                 struct flexcop_dma *dma,
  44                 flexcop_dma_index_t dma_idx)
  45 {
  46         flexcop_ibi_value v0x0, v0x4, v0xc;
  47 
  48         v0x0.raw = v0x4.raw = v0xc.raw = 0;
  49         v0x0.dma_0x0.dma_address0 = dma->dma_addr0 >> 2;
  50         v0xc.dma_0xc.dma_address1 = dma->dma_addr1 >> 2;
  51         v0x4.dma_0x4_write.dma_addr_size = dma->size / 4;
  52 
  53         if ((dma_idx & FC_DMA_1) == dma_idx) {
  54                 fc->write_ibi_reg(fc, dma1_000, v0x0);
  55                 fc->write_ibi_reg(fc, dma1_004, v0x4);
  56                 fc->write_ibi_reg(fc, dma1_00c, v0xc);
  57         } else if ((dma_idx & FC_DMA_2) == dma_idx) {
  58                 fc->write_ibi_reg(fc, dma2_010, v0x0);
  59                 fc->write_ibi_reg(fc, dma2_014, v0x4);
  60                 fc->write_ibi_reg(fc, dma2_01c, v0xc);
  61         } else {
  62                 err("either DMA1 or DMA2 can be configured within one %s call.",
  63                         __func__);
  64                 return -EINVAL;
  65         }
  66 
  67         return 0;
  68 }
  69 EXPORT_SYMBOL(flexcop_dma_config);
  70 
  71 /* start the DMA transfers, but not the DMA IRQs */
  72 int flexcop_dma_xfer_control(struct flexcop_device *fc,
  73                 flexcop_dma_index_t dma_idx,
  74                 flexcop_dma_addr_index_t index,
  75                 int onoff)
  76 {
  77         flexcop_ibi_value v0x0, v0xc;
  78         flexcop_ibi_register r0x0, r0xc;
  79 
  80         if ((dma_idx & FC_DMA_1) == dma_idx) {
  81                 r0x0 = dma1_000;
  82                 r0xc = dma1_00c;
  83         } else if ((dma_idx & FC_DMA_2) == dma_idx) {
  84                 r0x0 = dma2_010;
  85                 r0xc = dma2_01c;
  86         } else {
  87                 err("transfer DMA1 or DMA2 can be started within one %s call.",
  88                         __func__);
  89                 return -EINVAL;
  90         }
  91 
  92         v0x0 = fc->read_ibi_reg(fc, r0x0);
  93         v0xc = fc->read_ibi_reg(fc, r0xc);
  94 
  95         deb_rdump("reg: %03x: %x\n", r0x0, v0x0.raw);
  96         deb_rdump("reg: %03x: %x\n", r0xc, v0xc.raw);
  97 
  98         if (index & FC_DMA_SUBADDR_0)
  99                 v0x0.dma_0x0.dma_0start = onoff;
 100 
 101         if (index & FC_DMA_SUBADDR_1)
 102                 v0xc.dma_0xc.dma_1start = onoff;
 103 
 104         fc->write_ibi_reg(fc, r0x0, v0x0);
 105         fc->write_ibi_reg(fc, r0xc, v0xc);
 106 
 107         deb_rdump("reg: %03x: %x\n", r0x0, v0x0.raw);
 108         deb_rdump("reg: %03x: %x\n", r0xc, v0xc.raw);
 109         return 0;
 110 }
 111 EXPORT_SYMBOL(flexcop_dma_xfer_control);
 112 
 113 static int flexcop_dma_remap(struct flexcop_device *fc,
 114                 flexcop_dma_index_t dma_idx,
 115                 int onoff)
 116 {
 117         flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_00c : dma2_01c;
 118         flexcop_ibi_value v = fc->read_ibi_reg(fc, r);
 119 
 120         deb_info("%s\n", __func__);
 121         v.dma_0xc.remap_enable = onoff;
 122         fc->write_ibi_reg(fc, r, v);
 123         return 0;
 124 }
 125 
 126 int flexcop_dma_control_size_irq(struct flexcop_device *fc,
 127                 flexcop_dma_index_t no,
 128                 int onoff)
 129 {
 130         flexcop_ibi_value v = fc->read_ibi_reg(fc, ctrl_208);
 131 
 132         if (no & FC_DMA_1)
 133                 v.ctrl_208.DMA1_IRQ_Enable_sig = onoff;
 134 
 135         if (no & FC_DMA_2)
 136                 v.ctrl_208.DMA2_IRQ_Enable_sig = onoff;
 137 
 138         fc->write_ibi_reg(fc, ctrl_208, v);
 139         return 0;
 140 }
 141 EXPORT_SYMBOL(flexcop_dma_control_size_irq);
 142 
 143 int flexcop_dma_control_timer_irq(struct flexcop_device *fc,
 144                 flexcop_dma_index_t no,
 145                 int onoff)
 146 {
 147         flexcop_ibi_value v = fc->read_ibi_reg(fc, ctrl_208);
 148 
 149         if (no & FC_DMA_1)
 150                 v.ctrl_208.DMA1_Timer_Enable_sig = onoff;
 151 
 152         if (no & FC_DMA_2)
 153                 v.ctrl_208.DMA2_Timer_Enable_sig = onoff;
 154 
 155         fc->write_ibi_reg(fc, ctrl_208, v);
 156         return 0;
 157 }
 158 EXPORT_SYMBOL(flexcop_dma_control_timer_irq);
 159 
 160 /* 1 cycles = 1.97 msec */
 161 int flexcop_dma_config_timer(struct flexcop_device *fc,
 162                 flexcop_dma_index_t dma_idx, u8 cycles)
 163 {
 164         flexcop_ibi_register r = (dma_idx & FC_DMA_1) ? dma1_004 : dma2_014;
 165         flexcop_ibi_value v = fc->read_ibi_reg(fc, r);
 166 
 167         flexcop_dma_remap(fc, dma_idx, 0);
 168 
 169         deb_info("%s\n", __func__);
 170         v.dma_0x4_write.dmatimer = cycles;
 171         fc->write_ibi_reg(fc, r, v);
 172         return 0;
 173 }
 174 EXPORT_SYMBOL(flexcop_dma_config_timer);
 175 

/* [<][>][^][v][top][bottom][index][help] */