diff options
author | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-06-14 15:35:57 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2012-08-13 22:30:06 -0400 |
commit | 25aee3debe0464f6c680173041fa3de30ec9ff54 (patch) | |
tree | e2b14f952a0831399f9cbb444cfb9c7980b6485b /drivers/media/pci/mantis/mantis_dma.c | |
parent | 786baecfe78f8e25547c628b48a60fc8e5636056 (diff) |
[media] Rename media/dvb as media/pci
The remaining dvb drivers are pci, so rename them to match the
bus.
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/pci/mantis/mantis_dma.c')
-rw-r--r-- | drivers/media/pci/mantis/mantis_dma.c | 230 |
1 files changed, 230 insertions, 0 deletions
diff --git a/drivers/media/pci/mantis/mantis_dma.c b/drivers/media/pci/mantis/mantis_dma.c new file mode 100644 index 00000000000..566c407175a --- /dev/null +++ b/drivers/media/pci/mantis/mantis_dma.c | |||
@@ -0,0 +1,230 @@ | |||
1 | /* | ||
2 | Mantis PCI bridge driver | ||
3 | |||
4 | Copyright (C) Manu Abraham (abraham.manu@gmail.com) | ||
5 | |||
6 | This program is free software; you can redistribute it and/or modify | ||
7 | it under the terms of the GNU General Public License as published by | ||
8 | the Free Software Foundation; either version 2 of the License, or | ||
9 | (at your option) any later version. | ||
10 | |||
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. | ||
15 | |||
16 | You should have received a copy of the GNU General Public License | ||
17 | along with this program; if not, write to the Free Software | ||
18 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <asm/page.h> | ||
23 | #include <linux/vmalloc.h> | ||
24 | #include <linux/pci.h> | ||
25 | |||
26 | #include <asm/irq.h> | ||
27 | #include <linux/signal.h> | ||
28 | #include <linux/sched.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | |||
31 | #include "dmxdev.h" | ||
32 | #include "dvbdev.h" | ||
33 | #include "dvb_demux.h" | ||
34 | #include "dvb_frontend.h" | ||
35 | #include "dvb_net.h" | ||
36 | |||
37 | #include "mantis_common.h" | ||
38 | #include "mantis_reg.h" | ||
39 | #include "mantis_dma.h" | ||
40 | |||
41 | #define RISC_WRITE (0x01 << 28) | ||
42 | #define RISC_JUMP (0x07 << 28) | ||
43 | #define RISC_IRQ (0x01 << 24) | ||
44 | |||
45 | #define RISC_STATUS(status) ((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16)) | ||
46 | #define RISC_FLUSH(risc_pos) (risc_pos = 0) | ||
47 | #define RISC_INSTR(risc_pos, opcode) (mantis->risc_cpu[risc_pos++] = cpu_to_le32(opcode)) | ||
48 | |||
49 | #define MANTIS_BUF_SIZE (64 * 1024) | ||
50 | #define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE / 4) | ||
51 | #define MANTIS_DMA_TR_BYTES (2 * 1024) /* upper limit: 4095 bytes. */ | ||
52 | #define MANTIS_BLOCK_COUNT (MANTIS_BUF_SIZE / MANTIS_BLOCK_BYTES) | ||
53 | |||
54 | #define MANTIS_DMA_TR_UNITS (MANTIS_BLOCK_BYTES / MANTIS_DMA_TR_BYTES) | ||
55 | /* MANTIS_BUF_SIZE / MANTIS_DMA_TR_UNITS must not exceed MANTIS_RISC_SIZE (4k RISC cmd buffer) */ | ||
56 | #define MANTIS_RISC_SIZE PAGE_SIZE /* RISC program must fit here. */ | ||
57 | |||
58 | int mantis_dma_exit(struct mantis_pci *mantis) | ||
59 | { | ||
60 | if (mantis->buf_cpu) { | ||
61 | dprintk(MANTIS_ERROR, 1, | ||
62 | "DMA=0x%lx cpu=0x%p size=%d", | ||
63 | (unsigned long) mantis->buf_dma, | ||
64 | mantis->buf_cpu, | ||
65 | MANTIS_BUF_SIZE); | ||
66 | |||
67 | pci_free_consistent(mantis->pdev, MANTIS_BUF_SIZE, | ||
68 | mantis->buf_cpu, mantis->buf_dma); | ||
69 | |||
70 | mantis->buf_cpu = NULL; | ||
71 | } | ||
72 | if (mantis->risc_cpu) { | ||
73 | dprintk(MANTIS_ERROR, 1, | ||
74 | "RISC=0x%lx cpu=0x%p size=%lx", | ||
75 | (unsigned long) mantis->risc_dma, | ||
76 | mantis->risc_cpu, | ||
77 | MANTIS_RISC_SIZE); | ||
78 | |||
79 | pci_free_consistent(mantis->pdev, MANTIS_RISC_SIZE, | ||
80 | mantis->risc_cpu, mantis->risc_dma); | ||
81 | |||
82 | mantis->risc_cpu = NULL; | ||
83 | } | ||
84 | |||
85 | return 0; | ||
86 | } | ||
87 | EXPORT_SYMBOL_GPL(mantis_dma_exit); | ||
88 | |||
89 | static inline int mantis_alloc_buffers(struct mantis_pci *mantis) | ||
90 | { | ||
91 | if (!mantis->buf_cpu) { | ||
92 | mantis->buf_cpu = pci_alloc_consistent(mantis->pdev, | ||
93 | MANTIS_BUF_SIZE, | ||
94 | &mantis->buf_dma); | ||
95 | if (!mantis->buf_cpu) { | ||
96 | dprintk(MANTIS_ERROR, 1, | ||
97 | "DMA buffer allocation failed"); | ||
98 | |||
99 | goto err; | ||
100 | } | ||
101 | dprintk(MANTIS_ERROR, 1, | ||
102 | "DMA=0x%lx cpu=0x%p size=%d", | ||
103 | (unsigned long) mantis->buf_dma, | ||
104 | mantis->buf_cpu, MANTIS_BUF_SIZE); | ||
105 | } | ||
106 | if (!mantis->risc_cpu) { | ||
107 | mantis->risc_cpu = pci_alloc_consistent(mantis->pdev, | ||
108 | MANTIS_RISC_SIZE, | ||
109 | &mantis->risc_dma); | ||
110 | |||
111 | if (!mantis->risc_cpu) { | ||
112 | dprintk(MANTIS_ERROR, 1, | ||
113 | "RISC program allocation failed"); | ||
114 | |||
115 | mantis_dma_exit(mantis); | ||
116 | |||
117 | goto err; | ||
118 | } | ||
119 | dprintk(MANTIS_ERROR, 1, | ||
120 | "RISC=0x%lx cpu=0x%p size=%lx", | ||
121 | (unsigned long) mantis->risc_dma, | ||
122 | mantis->risc_cpu, MANTIS_RISC_SIZE); | ||
123 | } | ||
124 | |||
125 | return 0; | ||
126 | err: | ||
127 | dprintk(MANTIS_ERROR, 1, "Out of memory (?) ....."); | ||
128 | return -ENOMEM; | ||
129 | } | ||
130 | |||
131 | int mantis_dma_init(struct mantis_pci *mantis) | ||
132 | { | ||
133 | int err = 0; | ||
134 | |||
135 | dprintk(MANTIS_DEBUG, 1, "Mantis DMA init"); | ||
136 | if (mantis_alloc_buffers(mantis) < 0) { | ||
137 | dprintk(MANTIS_ERROR, 1, "Error allocating DMA buffer"); | ||
138 | |||
139 | /* Stop RISC Engine */ | ||
140 | mmwrite(0, MANTIS_DMA_CTL); | ||
141 | |||
142 | goto err; | ||
143 | } | ||
144 | |||
145 | return 0; | ||
146 | err: | ||
147 | return err; | ||
148 | } | ||
149 | EXPORT_SYMBOL_GPL(mantis_dma_init); | ||
150 | |||
151 | static inline void mantis_risc_program(struct mantis_pci *mantis) | ||
152 | { | ||
153 | u32 buf_pos = 0; | ||
154 | u32 line, step; | ||
155 | u32 risc_pos; | ||
156 | |||
157 | dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program"); | ||
158 | RISC_FLUSH(risc_pos); | ||
159 | |||
160 | dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u, bytes per DMA tr %u", | ||
161 | MANTIS_BLOCK_COUNT, MANTIS_BLOCK_BYTES, MANTIS_DMA_TR_BYTES); | ||
162 | |||
163 | for (line = 0; line < MANTIS_BLOCK_COUNT; line++) { | ||
164 | for (step = 0; step < MANTIS_DMA_TR_UNITS; step++) { | ||
165 | dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d], step=[%d]", line, step); | ||
166 | if (step == 0) { | ||
167 | RISC_INSTR(risc_pos, RISC_WRITE | | ||
168 | RISC_IRQ | | ||
169 | RISC_STATUS(line) | | ||
170 | MANTIS_DMA_TR_BYTES); | ||
171 | } else { | ||
172 | RISC_INSTR(risc_pos, RISC_WRITE | MANTIS_DMA_TR_BYTES); | ||
173 | } | ||
174 | RISC_INSTR(risc_pos, mantis->buf_dma + buf_pos); | ||
175 | buf_pos += MANTIS_DMA_TR_BYTES; | ||
176 | } | ||
177 | } | ||
178 | RISC_INSTR(risc_pos, RISC_JUMP); | ||
179 | RISC_INSTR(risc_pos, mantis->risc_dma); | ||
180 | } | ||
181 | |||
182 | void mantis_dma_start(struct mantis_pci *mantis) | ||
183 | { | ||
184 | dprintk(MANTIS_DEBUG, 1, "Mantis Start DMA engine"); | ||
185 | |||
186 | mantis_risc_program(mantis); | ||
187 | mmwrite(mantis->risc_dma, MANTIS_RISC_START); | ||
188 | mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); | ||
189 | |||
190 | mmwrite(0, MANTIS_DMA_CTL); | ||
191 | mantis->last_block = mantis->busy_block = 0; | ||
192 | |||
193 | mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK); | ||
194 | |||
195 | mmwrite(MANTIS_FIFO_EN | MANTIS_DCAP_EN | ||
196 | | MANTIS_RISC_EN, MANTIS_DMA_CTL); | ||
197 | |||
198 | } | ||
199 | |||
200 | void mantis_dma_stop(struct mantis_pci *mantis) | ||
201 | { | ||
202 | dprintk(MANTIS_DEBUG, 1, "Mantis Stop DMA engine"); | ||
203 | |||
204 | mmwrite((mmread(MANTIS_GPIF_ADDR) & (~(MANTIS_GPIF_HIFRDWRN))), MANTIS_GPIF_ADDR); | ||
205 | |||
206 | mmwrite((mmread(MANTIS_DMA_CTL) & ~(MANTIS_FIFO_EN | | ||
207 | MANTIS_DCAP_EN | | ||
208 | MANTIS_RISC_EN)), MANTIS_DMA_CTL); | ||
209 | |||
210 | mmwrite(mmread(MANTIS_INT_STAT), MANTIS_INT_STAT); | ||
211 | |||
212 | mmwrite(mmread(MANTIS_INT_MASK) & ~(MANTIS_INT_RISCI | | ||
213 | MANTIS_INT_RISCEN), MANTIS_INT_MASK); | ||
214 | } | ||
215 | |||
216 | |||
217 | void mantis_dma_xfer(unsigned long data) | ||
218 | { | ||
219 | struct mantis_pci *mantis = (struct mantis_pci *) data; | ||
220 | struct mantis_hwconfig *config = mantis->hwconfig; | ||
221 | |||
222 | while (mantis->last_block != mantis->busy_block) { | ||
223 | dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]", | ||
224 | mantis->last_block, mantis->busy_block); | ||
225 | |||
226 | (config->ts_size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter) | ||
227 | (&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES); | ||
228 | mantis->last_block = (mantis->last_block + 1) % MANTIS_BLOCK_COUNT; | ||
229 | } | ||
230 | } | ||