4 * Copyright (C) 2014 Akihiro Tsukada <tskd08@gmail.com>
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation version 2.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 #include <linux/dma-mapping.h>
17 #include <linux/kernel.h>
18 #include <linux/pci.h>
22 #define PT3_ACCESS_UNIT (TS_PACKET_SZ * 128)
23 #define PT3_BUF_CANARY (0x74)
25 static u32
get_dma_base(int idx
)
29 i
= (idx
== 1 || idx
== 2) ? 3 - idx
: idx
;
30 return REG_DMA_BASE
+ 0x18 * i
;
33 int pt3_stop_dma(struct pt3_adapter
*adap
)
35 struct pt3_board
*pt3
= adap
->dvb_adap
.priv
;
40 base
= get_dma_base(adap
->adap_idx
);
41 stat
= ioread32(pt3
->regs
[0] + base
+ OFST_STATUS
);
45 iowrite32(0x02, pt3
->regs
[0] + base
+ OFST_DMA_CTL
);
46 for (retry
= 0; retry
< 5; retry
++) {
47 stat
= ioread32(pt3
->regs
[0] + base
+ OFST_STATUS
);
55 int pt3_start_dma(struct pt3_adapter
*adap
)
57 struct pt3_board
*pt3
= adap
->dvb_adap
.priv
;
58 u32 base
= get_dma_base(adap
->adap_idx
);
60 iowrite32(0x02, pt3
->regs
[0] + base
+ OFST_DMA_CTL
);
61 iowrite32(lower_32_bits(adap
->desc_buf
[0].b_addr
),
62 pt3
->regs
[0] + base
+ OFST_DMA_DESC_L
);
63 iowrite32(upper_32_bits(adap
->desc_buf
[0].b_addr
),
64 pt3
->regs
[0] + base
+ OFST_DMA_DESC_H
);
65 iowrite32(0x01, pt3
->regs
[0] + base
+ OFST_DMA_CTL
);
70 static u8
*next_unit(struct pt3_adapter
*adap
, int *idx
, int *ofs
)
72 *ofs
+= PT3_ACCESS_UNIT
;
73 if (*ofs
>= DATA_BUF_SZ
) {
76 if (*idx
== adap
->num_bufs
)
79 return &adap
->buffer
[*idx
].data
[*ofs
];
82 int pt3_proc_dma(struct pt3_adapter
*adap
)
89 if (adap
->buffer
[idx
].data
[ofs
] == PT3_BUF_CANARY
)
92 while (*next_unit(adap
, &idx
, &ofs
) != PT3_BUF_CANARY
) {
95 p
= &adap
->buffer
[adap
->buf_idx
].data
[adap
->buf_ofs
];
96 if (adap
->num_discard
> 0)
98 else if (adap
->buf_ofs
+ PT3_ACCESS_UNIT
> DATA_BUF_SZ
) {
99 dvb_dmx_swfilter_packets(&adap
->demux
, p
,
100 (DATA_BUF_SZ
- adap
->buf_ofs
) / TS_PACKET_SZ
);
101 dvb_dmx_swfilter_packets(&adap
->demux
,
102 adap
->buffer
[idx
].data
, ofs
/ TS_PACKET_SZ
);
104 dvb_dmx_swfilter_packets(&adap
->demux
, p
,
105 PT3_ACCESS_UNIT
/ TS_PACKET_SZ
);
114 void pt3_init_dmabuf(struct pt3_adapter
*adap
)
121 p
= adap
->buffer
[0].data
;
122 /* mark the whole buffers as "not written yet" */
123 while (idx
< adap
->num_bufs
) {
124 p
[ofs
] = PT3_BUF_CANARY
;
125 ofs
+= PT3_ACCESS_UNIT
;
126 if (ofs
>= DATA_BUF_SZ
) {
129 p
= adap
->buffer
[idx
].data
;
136 void pt3_free_dmabuf(struct pt3_adapter
*adap
)
138 struct pt3_board
*pt3
;
141 pt3
= adap
->dvb_adap
.priv
;
142 for (i
= 0; i
< adap
->num_bufs
; i
++)
143 dma_free_coherent(&pt3
->pdev
->dev
, DATA_BUF_SZ
,
144 adap
->buffer
[i
].data
, adap
->buffer
[i
].b_addr
);
147 for (i
= 0; i
< adap
->num_desc_bufs
; i
++)
148 dma_free_coherent(&pt3
->pdev
->dev
, PAGE_SIZE
,
149 adap
->desc_buf
[i
].descs
, adap
->desc_buf
[i
].b_addr
);
150 adap
->num_desc_bufs
= 0;
154 int pt3_alloc_dmabuf(struct pt3_adapter
*adap
)
156 struct pt3_board
*pt3
;
161 dma_addr_t data_addr
, desc_addr
;
164 pt3
= adap
->dvb_adap
.priv
;
166 adap
->num_desc_bufs
= 0;
167 for (i
= 0; i
< pt3
->num_bufs
; i
++) {
168 p
= dma_alloc_coherent(&pt3
->pdev
->dev
, DATA_BUF_SZ
,
169 &adap
->buffer
[i
].b_addr
, GFP_KERNEL
);
172 adap
->buffer
[i
].data
= p
;
175 pt3_init_dmabuf(adap
);
177 /* build circular-linked pointers (xfer_desc) to the data buffers*/
181 DIV_ROUND_UP(adap
->num_bufs
* DATA_BUF_XFERS
, DESCS_IN_PAGE
);
182 for (i
= 0; i
< num_desc_bufs
; i
++) {
183 p
= dma_alloc_coherent(&pt3
->pdev
->dev
, PAGE_SIZE
,
184 &desc_addr
, GFP_KERNEL
);
187 adap
->num_desc_bufs
++;
188 adap
->desc_buf
[i
].descs
= p
;
189 adap
->desc_buf
[i
].b_addr
= desc_addr
;
192 d
= &adap
->desc_buf
[i
- 1].descs
[DESCS_IN_PAGE
- 1];
193 d
->next_l
= lower_32_bits(desc_addr
);
194 d
->next_h
= upper_32_bits(desc_addr
);
196 for (j
= 0; j
< DESCS_IN_PAGE
; j
++) {
197 data_addr
= adap
->buffer
[idx
].b_addr
+ ofs
;
198 d
= &adap
->desc_buf
[i
].descs
[j
];
199 d
->addr_l
= lower_32_bits(data_addr
);
200 d
->addr_h
= upper_32_bits(data_addr
);
201 d
->size
= DATA_XFER_SZ
;
203 desc_addr
+= sizeof(struct xfer_desc
);
204 d
->next_l
= lower_32_bits(desc_addr
);
205 d
->next_h
= upper_32_bits(desc_addr
);
208 if (ofs
>= DATA_BUF_SZ
) {
211 if (idx
>= adap
->num_bufs
) {
212 desc_addr
= adap
->desc_buf
[0].b_addr
;
213 d
->next_l
= lower_32_bits(desc_addr
);
214 d
->next_h
= upper_32_bits(desc_addr
);
223 pt3_free_dmabuf(adap
);