aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/mantis/mantis_dma.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/mantis/mantis_dma.c')
-rw-r--r--drivers/media/dvb/mantis/mantis_dma.c92
1 files changed, 35 insertions, 57 deletions
diff --git a/drivers/media/dvb/mantis/mantis_dma.c b/drivers/media/dvb/mantis/mantis_dma.c
index 46202a4012a..c61ca7d3dae 100644
--- a/drivers/media/dvb/mantis/mantis_dma.c
+++ b/drivers/media/dvb/mantis/mantis_dma.c
@@ -43,13 +43,17 @@
43#define RISC_IRQ (0x01 << 24) 43#define RISC_IRQ (0x01 << 24)
44 44
45#define RISC_STATUS(status) ((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16)) 45#define RISC_STATUS(status) ((((~status) & 0x0f) << 20) | ((status & 0x0f) << 16))
46#define RISC_FLUSH() (mantis->risc_pos = 0) 46#define RISC_FLUSH(risc_pos) (risc_pos = 0)
47#define RISC_INSTR(opcode) (mantis->risc_cpu[mantis->risc_pos++] = cpu_to_le32(opcode)) 47#define RISC_INSTR(risc_pos, opcode) (mantis->risc_cpu[risc_pos++] = cpu_to_le32(opcode))
48 48
49#define MANTIS_BUF_SIZE (64 * 1024) 49#define MANTIS_BUF_SIZE (64 * 1024)
50#define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE >> 4) 50#define MANTIS_BLOCK_BYTES (MANTIS_BUF_SIZE / 4)
51#define MANTIS_BLOCK_COUNT (1 << 4) 51#define MANTIS_DMA_TR_BYTES (2 * 1024) /* upper limit: 4095 bytes. */
52#define MANTIS_RISC_SIZE PAGE_SIZE 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. */
53 57
54int mantis_dma_exit(struct mantis_pci *mantis) 58int mantis_dma_exit(struct mantis_pci *mantis)
55{ 59{
@@ -124,27 +128,6 @@ err:
124 return -ENOMEM; 128 return -ENOMEM;
125} 129}
126 130
127static inline int mantis_calc_lines(struct mantis_pci *mantis)
128{
129 mantis->line_bytes = MANTIS_BLOCK_BYTES;
130 mantis->line_count = MANTIS_BLOCK_COUNT;
131
132 while (mantis->line_bytes > 4095) {
133 mantis->line_bytes >>= 1;
134 mantis->line_count <<= 1;
135 }
136
137 dprintk(MANTIS_DEBUG, 1, "Mantis RISC block bytes=[%d], line bytes=[%d], line count=[%d]",
138 MANTIS_BLOCK_BYTES, mantis->line_bytes, mantis->line_count);
139
140 if (mantis->line_count > 255) {
141 dprintk(MANTIS_ERROR, 1, "Buffer size error");
142 return -EINVAL;
143 }
144
145 return 0;
146}
147
148int mantis_dma_init(struct mantis_pci *mantis) 131int mantis_dma_init(struct mantis_pci *mantis)
149{ 132{
150 int err = 0; 133 int err = 0;
@@ -158,12 +141,6 @@ int mantis_dma_init(struct mantis_pci *mantis)
158 141
159 goto err; 142 goto err;
160 } 143 }
161 err = mantis_calc_lines(mantis);
162 if (err < 0) {
163 dprintk(MANTIS_ERROR, 1, "Mantis calc lines failed");
164
165 goto err;
166 }
167 144
168 return 0; 145 return 0;
169err: 146err:
@@ -174,31 +151,32 @@ EXPORT_SYMBOL_GPL(mantis_dma_init);
174static inline void mantis_risc_program(struct mantis_pci *mantis) 151static inline void mantis_risc_program(struct mantis_pci *mantis)
175{ 152{
176 u32 buf_pos = 0; 153 u32 buf_pos = 0;
177 u32 line; 154 u32 line, step;
155 u32 risc_pos;
178 156
179 dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program"); 157 dprintk(MANTIS_DEBUG, 1, "Mantis create RISC program");
180 RISC_FLUSH(); 158 RISC_FLUSH(risc_pos);
181 159
182 dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u", 160 dprintk(MANTIS_DEBUG, 1, "risc len lines %u, bytes per line %u, bytes per DMA tr %u",
183 mantis->line_count, mantis->line_bytes); 161 MANTIS_BLOCK_COUNT, MANTIS_BLOCK_BYTES, MANTIS_DMA_TR_BYTES);
184 162
185 for (line = 0; line < mantis->line_count; line++) { 163 for (line = 0; line < MANTIS_BLOCK_COUNT; line++) {
186 dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d]", line); 164 for (step = 0; step < MANTIS_DMA_TR_UNITS; step++) {
187 if (!(buf_pos % MANTIS_BLOCK_BYTES)) { 165 dprintk(MANTIS_DEBUG, 1, "RISC PROG line=[%d], step=[%d]", line, step);
188 RISC_INSTR(RISC_WRITE | 166 if (step == 0) {
189 RISC_IRQ | 167 RISC_INSTR(risc_pos, RISC_WRITE |
190 RISC_STATUS(((buf_pos / MANTIS_BLOCK_BYTES) + 168 RISC_IRQ |
191 (MANTIS_BLOCK_COUNT - 1)) % 169 RISC_STATUS(line) |
192 MANTIS_BLOCK_COUNT) | 170 MANTIS_DMA_TR_BYTES);
193 mantis->line_bytes); 171 } else {
194 } else { 172 RISC_INSTR(risc_pos, RISC_WRITE | MANTIS_DMA_TR_BYTES);
195 RISC_INSTR(RISC_WRITE | mantis->line_bytes); 173 }
196 } 174 RISC_INSTR(risc_pos, mantis->buf_dma + buf_pos);
197 RISC_INSTR(mantis->buf_dma + buf_pos); 175 buf_pos += MANTIS_DMA_TR_BYTES;
198 buf_pos += mantis->line_bytes; 176 }
199 } 177 }
200 RISC_INSTR(RISC_JUMP); 178 RISC_INSTR(risc_pos, RISC_JUMP);
201 RISC_INSTR(mantis->risc_dma); 179 RISC_INSTR(risc_pos, mantis->risc_dma);
202} 180}
203 181
204void mantis_dma_start(struct mantis_pci *mantis) 182void mantis_dma_start(struct mantis_pci *mantis)
@@ -210,7 +188,7 @@ void mantis_dma_start(struct mantis_pci *mantis)
210 mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR); 188 mmwrite(mmread(MANTIS_GPIF_ADDR) | MANTIS_GPIF_HIFRDWRN, MANTIS_GPIF_ADDR);
211 189
212 mmwrite(0, MANTIS_DMA_CTL); 190 mmwrite(0, MANTIS_DMA_CTL);
213 mantis->last_block = mantis->finished_block = 0; 191 mantis->last_block = mantis->busy_block = 0;
214 192
215 mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK); 193 mmwrite(mmread(MANTIS_INT_MASK) | MANTIS_INT_RISCI, MANTIS_INT_MASK);
216 194
@@ -245,9 +223,9 @@ void mantis_dma_xfer(unsigned long data)
245 struct mantis_pci *mantis = (struct mantis_pci *) data; 223 struct mantis_pci *mantis = (struct mantis_pci *) data;
246 struct mantis_hwconfig *config = mantis->hwconfig; 224 struct mantis_hwconfig *config = mantis->hwconfig;
247 225
248 while (mantis->last_block != mantis->finished_block) { 226 while (mantis->last_block != mantis->busy_block) {
249 dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]", 227 dprintk(MANTIS_DEBUG, 1, "last block=[%d] finished block=[%d]",
250 mantis->last_block, mantis->finished_block); 228 mantis->last_block, mantis->busy_block);
251 229
252 (config->ts_size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter) 230 (config->ts_size ? dvb_dmx_swfilter_204 : dvb_dmx_swfilter)
253 (&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES); 231 (&mantis->demux, &mantis->buf_cpu[mantis->last_block * MANTIS_BLOCK_BYTES], MANTIS_BLOCK_BYTES);