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 tcpu
= dma_alloc_coherent(&pdev
->dev
, size
, &tdma
, GFP_KERNEL
);
23 dma
->cpu_addr0
= tcpu
;
24 dma
->dma_addr0
= tdma
;
25 dma
->cpu_addr1
= tcpu
+ size
/2;
26 dma
->dma_addr1
= tdma
+ size
/2;
32 EXPORT_SYMBOL(flexcop_dma_allocate
);
34 void flexcop_dma_free(struct flexcop_dma
*dma
)
36 dma_free_coherent(&dma
->pdev
->dev
, dma
->size
* 2, dma
->cpu_addr0
,
38 memset(dma
, 0, sizeof(struct flexcop_dma
));
40 EXPORT_SYMBOL(flexcop_dma_free
);
42 int flexcop_dma_config(struct flexcop_device
*fc
,
43 struct flexcop_dma
*dma
,
44 flexcop_dma_index_t dma_idx
)
46 flexcop_ibi_value v0x0
, v0x4
, v0xc
;
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;
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
);
62 err("either DMA1 or DMA2 can be configured within one %s call.",
69 EXPORT_SYMBOL(flexcop_dma_config
);
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
,
77 flexcop_ibi_value v0x0
, v0xc
;
78 flexcop_ibi_register r0x0
, r0xc
;
80 if ((dma_idx
& FC_DMA_1
) == dma_idx
) {
83 } else if ((dma_idx
& FC_DMA_2
) == dma_idx
) {
87 err("transfer DMA1 or DMA2 can be started within one %s call.",
92 v0x0
= fc
->read_ibi_reg(fc
, r0x0
);
93 v0xc
= fc
->read_ibi_reg(fc
, r0xc
);
95 deb_rdump("reg: %03x: %x\n", r0x0
, v0x0
.raw
);
96 deb_rdump("reg: %03x: %x\n", r0xc
, v0xc
.raw
);
98 if (index
& FC_DMA_SUBADDR_0
)
99 v0x0
.dma_0x0
.dma_0start
= onoff
;
101 if (index
& FC_DMA_SUBADDR_1
)
102 v0xc
.dma_0xc
.dma_1start
= onoff
;
104 fc
->write_ibi_reg(fc
, r0x0
, v0x0
);
105 fc
->write_ibi_reg(fc
, r0xc
, v0xc
);
107 deb_rdump("reg: %03x: %x\n", r0x0
, v0x0
.raw
);
108 deb_rdump("reg: %03x: %x\n", r0xc
, v0xc
.raw
);
111 EXPORT_SYMBOL(flexcop_dma_xfer_control
);
113 static int flexcop_dma_remap(struct flexcop_device
*fc
,
114 flexcop_dma_index_t dma_idx
,
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
);
120 deb_info("%s\n", __func__
);
121 v
.dma_0xc
.remap_enable
= onoff
;
122 fc
->write_ibi_reg(fc
, r
, v
);
126 int flexcop_dma_control_size_irq(struct flexcop_device
*fc
,
127 flexcop_dma_index_t no
,
130 flexcop_ibi_value v
= fc
->read_ibi_reg(fc
, ctrl_208
);
133 v
.ctrl_208
.DMA1_IRQ_Enable_sig
= onoff
;
136 v
.ctrl_208
.DMA2_IRQ_Enable_sig
= onoff
;
138 fc
->write_ibi_reg(fc
, ctrl_208
, v
);
141 EXPORT_SYMBOL(flexcop_dma_control_size_irq
);
143 int flexcop_dma_control_timer_irq(struct flexcop_device
*fc
,
144 flexcop_dma_index_t no
,
147 flexcop_ibi_value v
= fc
->read_ibi_reg(fc
, ctrl_208
);
150 v
.ctrl_208
.DMA1_Timer_Enable_sig
= onoff
;
153 v
.ctrl_208
.DMA2_Timer_Enable_sig
= onoff
;
155 fc
->write_ibi_reg(fc
, ctrl_208
, v
);
158 EXPORT_SYMBOL(flexcop_dma_control_timer_irq
);
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
)
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
);
167 flexcop_dma_remap(fc
, dma_idx
, 0);
169 deb_info("%s\n", __func__
);
170 v
.dma_0x4_write
.dmatimer
= cycles
;
171 fc
->write_ibi_reg(fc
, r
, v
);
174 EXPORT_SYMBOL(flexcop_dma_config_timer
);