1 // SPDX-License-Identifier: GPL-2.0
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
9 int flexcop_dma_allocate(struct pci_dev
*pdev
,
10 struct flexcop_dma
*dma
, u32 size
)
16 err("dma buffersize has to be even.");
20 if ((tcpu
= pci_alloc_consistent(pdev
, size
, &tdma
)) != NULL
) {
22 dma
->cpu_addr0
= tcpu
;
23 dma
->dma_addr0
= tdma
;
24 dma
->cpu_addr1
= tcpu
+ size
/2;
25 dma
->dma_addr1
= tdma
+ size
/2;
31 EXPORT_SYMBOL(flexcop_dma_allocate
);
33 void flexcop_dma_free(struct flexcop_dma
*dma
)
35 pci_free_consistent(dma
->pdev
, dma
->size
*2,
36 dma
->cpu_addr0
, dma
->dma_addr0
);
37 memset(dma
,0,sizeof(struct flexcop_dma
));
39 EXPORT_SYMBOL(flexcop_dma_free
);
41 int flexcop_dma_config(struct flexcop_device
*fc
,
42 struct flexcop_dma
*dma
,
43 flexcop_dma_index_t dma_idx
)
45 flexcop_ibi_value v0x0
,v0x4
,v0xc
;
46 v0x0
.raw
= v0x4
.raw
= v0xc
.raw
= 0;
48 v0x0
.dma_0x0
.dma_address0
= dma
->dma_addr0
>> 2;
49 v0xc
.dma_0xc
.dma_address1
= dma
->dma_addr1
>> 2;
50 v0x4
.dma_0x4_write
.dma_addr_size
= dma
->size
/ 4;
52 if ((dma_idx
& FC_DMA_1
) == dma_idx
) {
53 fc
->write_ibi_reg(fc
,dma1_000
,v0x0
);
54 fc
->write_ibi_reg(fc
,dma1_004
,v0x4
);
55 fc
->write_ibi_reg(fc
,dma1_00c
,v0xc
);
56 } else if ((dma_idx
& FC_DMA_2
) == dma_idx
) {
57 fc
->write_ibi_reg(fc
,dma2_010
,v0x0
);
58 fc
->write_ibi_reg(fc
,dma2_014
,v0x4
);
59 fc
->write_ibi_reg(fc
,dma2_01c
,v0xc
);
61 err("either DMA1 or DMA2 can be configured within one flexcop_dma_config call.");
67 EXPORT_SYMBOL(flexcop_dma_config
);
69 /* start the DMA transfers, but not the DMA IRQs */
70 int flexcop_dma_xfer_control(struct flexcop_device
*fc
,
71 flexcop_dma_index_t dma_idx
,
72 flexcop_dma_addr_index_t index
,
75 flexcop_ibi_value v0x0
,v0xc
;
76 flexcop_ibi_register r0x0
,r0xc
;
78 if ((dma_idx
& FC_DMA_1
) == dma_idx
) {
81 } else if ((dma_idx
& FC_DMA_2
) == dma_idx
) {
85 err("either transfer DMA1 or DMA2 can be started within one flexcop_dma_xfer_control call.");
89 v0x0
= fc
->read_ibi_reg(fc
,r0x0
);
90 v0xc
= fc
->read_ibi_reg(fc
,r0xc
);
92 deb_rdump("reg: %03x: %x\n",r0x0
,v0x0
.raw
);
93 deb_rdump("reg: %03x: %x\n",r0xc
,v0xc
.raw
);
95 if (index
& FC_DMA_SUBADDR_0
)
96 v0x0
.dma_0x0
.dma_0start
= onoff
;
98 if (index
& FC_DMA_SUBADDR_1
)
99 v0xc
.dma_0xc
.dma_1start
= onoff
;
101 fc
->write_ibi_reg(fc
,r0x0
,v0x0
);
102 fc
->write_ibi_reg(fc
,r0xc
,v0xc
);
104 deb_rdump("reg: %03x: %x\n",r0x0
,v0x0
.raw
);
105 deb_rdump("reg: %03x: %x\n",r0xc
,v0xc
.raw
);
108 EXPORT_SYMBOL(flexcop_dma_xfer_control
);
110 static int flexcop_dma_remap(struct flexcop_device
*fc
,
111 flexcop_dma_index_t dma_idx
,
114 flexcop_ibi_register r
= (dma_idx
& FC_DMA_1
) ? dma1_00c
: dma2_01c
;
115 flexcop_ibi_value v
= fc
->read_ibi_reg(fc
,r
);
116 deb_info("%s\n",__func__
);
117 v
.dma_0xc
.remap_enable
= onoff
;
118 fc
->write_ibi_reg(fc
,r
,v
);
122 int flexcop_dma_control_size_irq(struct flexcop_device
*fc
,
123 flexcop_dma_index_t no
,
126 flexcop_ibi_value v
= fc
->read_ibi_reg(fc
,ctrl_208
);
129 v
.ctrl_208
.DMA1_IRQ_Enable_sig
= onoff
;
132 v
.ctrl_208
.DMA2_IRQ_Enable_sig
= onoff
;
134 fc
->write_ibi_reg(fc
,ctrl_208
,v
);
137 EXPORT_SYMBOL(flexcop_dma_control_size_irq
);
139 int flexcop_dma_control_timer_irq(struct flexcop_device
*fc
,
140 flexcop_dma_index_t no
,
143 flexcop_ibi_value v
= fc
->read_ibi_reg(fc
,ctrl_208
);
146 v
.ctrl_208
.DMA1_Timer_Enable_sig
= onoff
;
149 v
.ctrl_208
.DMA2_Timer_Enable_sig
= onoff
;
151 fc
->write_ibi_reg(fc
,ctrl_208
,v
);
154 EXPORT_SYMBOL(flexcop_dma_control_timer_irq
);
156 /* 1 cycles = 1.97 msec */
157 int flexcop_dma_config_timer(struct flexcop_device
*fc
,
158 flexcop_dma_index_t dma_idx
, u8 cycles
)
160 flexcop_ibi_register r
= (dma_idx
& FC_DMA_1
) ? dma1_004
: dma2_014
;
161 flexcop_ibi_value v
= fc
->read_ibi_reg(fc
,r
);
163 flexcop_dma_remap(fc
,dma_idx
,0);
165 deb_info("%s\n",__func__
);
166 v
.dma_0x4_write
.dmatimer
= cycles
;
167 fc
->write_ibi_reg(fc
,r
,v
);
170 EXPORT_SYMBOL(flexcop_dma_config_timer
);