aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/mantis
diff options
context:
space:
mode:
authorMarko Ristola <marko.ristola@kolumbus.fi>2010-08-07 07:16:15 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2011-09-25 07:43:06 -0400
commit79d06d4dff733ee472e1f8933a33317a18195c0c (patch)
treedfede2845ccd5d1505e5fd5f60a0ad92be4e64a2 /drivers/media/dvb/mantis
parentfa0d11873943b29d6c8f57a7d54f77d0439acfd9 (diff)
[media] Refactor Mantis DMA transfer to deliver 16Kb TS data per interrupt
With VDR streaming HDTV into network, generating an interrupt once per 16kb, implemented in this patch, seems to support more robust throughput with HDTV. Fix leaking almost 64kb data from the previous TS after changing the TS. One effect of the old version was, that the DMA transfer and driver's DMA buffer access might happen at the same time - a race condition. Signed-off-by: Marko M. Ristola <marko.ristola@kolumbus.fi> Reviewed-by: Manu Abraham <manu@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/dvb/mantis')
-rw-r--r--drivers/media/dvb/mantis/hopper_cards.c2
-rw-r--r--drivers/media/dvb/mantis/mantis_cards.c2
-rw-r--r--drivers/media/dvb/mantis/mantis_common.h5
-rw-r--r--drivers/media/dvb/mantis/mantis_dma.c92
4 files changed, 38 insertions, 63 deletions
diff --git a/drivers/media/dvb/mantis/hopper_cards.c b/drivers/media/dvb/mantis/hopper_cards.c
index 8bbeebc4ffb1..71622f65c037 100644
--- a/drivers/media/dvb/mantis/hopper_cards.c
+++ b/drivers/media/dvb/mantis/hopper_cards.c
@@ -126,7 +126,7 @@ static irqreturn_t hopper_irq_handler(int irq, void *dev_id)
126 } 126 }
127 if (stat & MANTIS_INT_RISCI) { 127 if (stat & MANTIS_INT_RISCI) {
128 dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); 128 dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
129 mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28; 129 mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
130 tasklet_schedule(&mantis->tasklet); 130 tasklet_schedule(&mantis->tasklet);
131 } 131 }
132 if (stat & MANTIS_INT_I2CDONE) { 132 if (stat & MANTIS_INT_I2CDONE) {
diff --git a/drivers/media/dvb/mantis/mantis_cards.c b/drivers/media/dvb/mantis/mantis_cards.c
index e6c8368782e0..c2bb90b3e529 100644
--- a/drivers/media/dvb/mantis/mantis_cards.c
+++ b/drivers/media/dvb/mantis/mantis_cards.c
@@ -134,7 +134,7 @@ static irqreturn_t mantis_irq_handler(int irq, void *dev_id)
134 } 134 }
135 if (stat & MANTIS_INT_RISCI) { 135 if (stat & MANTIS_INT_RISCI) {
136 dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]); 136 dprintk(MANTIS_DEBUG, 0, "<%s>", label[8]);
137 mantis->finished_block = (stat & MANTIS_INT_RISCSTAT) >> 28; 137 mantis->busy_block = (stat & MANTIS_INT_RISCSTAT) >> 28;
138 tasklet_schedule(&mantis->tasklet); 138 tasklet_schedule(&mantis->tasklet);
139 } 139 }
140 if (stat & MANTIS_INT_I2CDONE) { 140 if (stat & MANTIS_INT_I2CDONE) {
diff --git a/drivers/media/dvb/mantis/mantis_common.h b/drivers/media/dvb/mantis/mantis_common.h
index 49dbca145bb8..f2410cf0a6bf 100644
--- a/drivers/media/dvb/mantis/mantis_common.h
+++ b/drivers/media/dvb/mantis/mantis_common.h
@@ -123,11 +123,8 @@ struct mantis_pci {
123 unsigned int num; 123 unsigned int num;
124 124
125 /* RISC Core */ 125 /* RISC Core */
126 u32 finished_block; 126 u32 busy_block;
127 u32 last_block; 127 u32 last_block;
128 u32 line_bytes;
129 u32 line_count;
130 u32 risc_pos;
131 u8 *buf_cpu; 128 u8 *buf_cpu;
132 dma_addr_t buf_dma; 129 dma_addr_t buf_dma;
133 u32 *risc_cpu; 130 u32 *risc_cpu;
diff --git a/drivers/media/dvb/mantis/mantis_dma.c b/drivers/media/dvb/mantis/mantis_dma.c
index 46202a4012aa..c61ca7d3daea 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);