2 * Linux driver for digital TV devices equipped with B2C2 FlexcopII(b)/III
3 * flexcop-dma.c - configuring and controlling the DMA of the FlexCop
4 * see flexcop.c for copyright information
8 int flexcop_dma_allocate(struct pci_dev
*pdev
,
9 struct flexcop_dma
*dma
, u32 size
)
15 err("dma buffersize has to be even.");
19 if ((tcpu
= pci_alloc_consistent(pdev
, size
, &tdma
)) != NULL
) {
21 dma
->cpu_addr0
= tcpu
;
22 dma
->dma_addr0
= tdma
;
23 dma
->cpu_addr1
= tcpu
+ size
/2;
24 dma
->dma_addr1
= tdma
+ size
/2;
30 EXPORT_SYMBOL(flexcop_dma_allocate
);
32 void flexcop_dma_free(struct flexcop_dma
*dma
)
34 pci_free_consistent(dma
->pdev
, dma
->size
*2,
35 dma
->cpu_addr0
, dma
->dma_addr0
);
36 memset(dma
,0,sizeof(struct flexcop_dma
));
38 EXPORT_SYMBOL(flexcop_dma_free
);
40 int flexcop_dma_config(struct flexcop_device
*fc
,
41 struct flexcop_dma
*dma
,
42 flexcop_dma_index_t dma_idx
)
44 flexcop_ibi_value v0x0
,v0x4
,v0xc
;
45 v0x0
.raw
= v0x4
.raw
= v0xc
.raw
= 0;
47 v0x0
.dma_0x0
.dma_address0
= dma
->dma_addr0
>> 2;
48 v0xc
.dma_0xc
.dma_address1
= dma
->dma_addr1
>> 2;
49 v0x4
.dma_0x4_write
.dma_addr_size
= dma
->size
/ 4;
51 if ((dma_idx
& FC_DMA_1
) == dma_idx
) {
52 fc
->write_ibi_reg(fc
,dma1_000
,v0x0
);
53 fc
->write_ibi_reg(fc
,dma1_004
,v0x4
);
54 fc
->write_ibi_reg(fc
,dma1_00c
,v0xc
);
55 } else if ((dma_idx
& FC_DMA_2
) == dma_idx
) {
56 fc
->write_ibi_reg(fc
,dma2_010
,v0x0
);
57 fc
->write_ibi_reg(fc
,dma2_014
,v0x4
);
58 fc
->write_ibi_reg(fc
,dma2_01c
,v0xc
);
60 err("either DMA1 or DMA2 can be configured within one flexcop_dma_config call.");
66 EXPORT_SYMBOL(flexcop_dma_config
);
68 /* start the DMA transfers, but not the DMA IRQs */
69 int flexcop_dma_xfer_control(struct flexcop_device
*fc
,
70 flexcop_dma_index_t dma_idx
,
71 flexcop_dma_addr_index_t index
,
74 flexcop_ibi_value v0x0
,v0xc
;
75 flexcop_ibi_register r0x0
,r0xc
;
77 if ((dma_idx
& FC_DMA_1
) == dma_idx
) {
80 } else if ((dma_idx
& FC_DMA_2
) == dma_idx
) {
84 err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call.");
88 v0x0
= fc
->read_ibi_reg(fc
,r0x0
);
89 v0xc
= fc
->read_ibi_reg(fc
,r0xc
);
91 deb_rdump("reg: %03x: %x\n",r0x0
,v0x0
.raw
);
92 deb_rdump("reg: %03x: %x\n",r0xc
,v0xc
.raw
);
94 if (index
& FC_DMA_SUBADDR_0
)
95 v0x0
.dma_0x0
.dma_0start
= onoff
;
97 if (index
& FC_DMA_SUBADDR_1
)
98 v0xc
.dma_0xc
.dma_1start
= onoff
;
100 fc
->write_ibi_reg(fc
,r0x0
,v0x0
);
101 fc
->write_ibi_reg(fc
,r0xc
,v0xc
);
103 deb_rdump("reg: %03x: %x\n",r0x0
,v0x0
.raw
);
104 deb_rdump("reg: %03x: %x\n",r0xc
,v0xc
.raw
);
107 EXPORT_SYMBOL(flexcop_dma_xfer_control
);
109 static int flexcop_dma_remap(struct flexcop_device
*fc
,
110 flexcop_dma_index_t dma_idx
,
113 flexcop_ibi_register r
= (dma_idx
& FC_DMA_1
) ? dma1_00c
: dma2_01c
;
114 flexcop_ibi_value v
= fc
->read_ibi_reg(fc
,r
);
115 deb_info("%s\n",__func__
);
116 v
.dma_0xc
.remap_enable
= onoff
;
117 fc
->write_ibi_reg(fc
,r
,v
);
121 int flexcop_dma_control_size_irq(struct flexcop_device
*fc
,
122 flexcop_dma_index_t no
,
125 flexcop_ibi_value v
= fc
->read_ibi_reg(fc
,ctrl_208
);
128 v
.ctrl_208
.DMA1_IRQ_Enable_sig
= onoff
;
131 v
.ctrl_208
.DMA2_IRQ_Enable_sig
= onoff
;
133 fc
->write_ibi_reg(fc
,ctrl_208
,v
);
136 EXPORT_SYMBOL(flexcop_dma_control_size_irq
);
138 int flexcop_dma_control_timer_irq(struct flexcop_device
*fc
,
139 flexcop_dma_index_t no
,
142 flexcop_ibi_value v
= fc
->read_ibi_reg(fc
,ctrl_208
);
145 v
.ctrl_208
.DMA1_Timer_Enable_sig
= onoff
;
148 v
.ctrl_208
.DMA2_Timer_Enable_sig
= onoff
;
150 fc
->write_ibi_reg(fc
,ctrl_208
,v
);
153 EXPORT_SYMBOL(flexcop_dma_control_timer_irq
);
155 /* 1 cycles = 1.97 msec */
156 int flexcop_dma_config_timer(struct flexcop_device
*fc
,
157 flexcop_dma_index_t dma_idx
, u8 cycles
)
159 flexcop_ibi_register r
= (dma_idx
& FC_DMA_1
) ? dma1_004
: dma2_014
;
160 flexcop_ibi_value v
= fc
->read_ibi_reg(fc
,r
);
162 flexcop_dma_remap(fc
,dma_idx
,0);
164 deb_info("%s\n",__func__
);
165 v
.dma_0x4_write
.dmatimer
= cycles
;
166 fc
->write_ibi_reg(fc
,r
,v
);
169 EXPORT_SYMBOL(flexcop_dma_config_timer
);