diff options
Diffstat (limited to 'drivers/media/video/cx88/cx88-mpeg.c')
-rw-r--r-- | drivers/media/video/cx88/cx88-mpeg.c | 52 |
1 files changed, 42 insertions, 10 deletions
diff --git a/drivers/media/video/cx88/cx88-mpeg.c b/drivers/media/video/cx88/cx88-mpeg.c index 07aae1899e17..9ade2ae91e9b 100644 --- a/drivers/media/video/cx88/cx88-mpeg.c +++ b/drivers/media/video/cx88/cx88-mpeg.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: cx88-mpeg.c,v 1.25 2005/03/07 14:18:00 kraxel Exp $ | 2 | * $Id: cx88-mpeg.c,v 1.26 2005/06/03 13:31:51 mchehab Exp $ |
3 | * | 3 | * |
4 | * Support for the mpeg transport stream transfers | 4 | * Support for the mpeg transport stream transfers |
5 | * PCI function #2 of the cx2388x. | 5 | * PCI function #2 of the cx2388x. |
@@ -55,7 +55,7 @@ static int cx8802_start_dma(struct cx8802_dev *dev, | |||
55 | { | 55 | { |
56 | struct cx88_core *core = dev->core; | 56 | struct cx88_core *core = dev->core; |
57 | 57 | ||
58 | dprintk(1, "cx8802_start_mpegport_dma %d\n", buf->vb.width); | 58 | dprintk(0, "cx8802_start_dma %d\n", buf->vb.width); |
59 | 59 | ||
60 | /* setup fifo + format */ | 60 | /* setup fifo + format */ |
61 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], | 61 | cx88_sram_channel_setup(core, &cx88_sram_channels[SRAM_CH28], |
@@ -100,18 +100,21 @@ static int cx8802_start_dma(struct cx8802_dev *dev, | |||
100 | q->count = 1; | 100 | q->count = 1; |
101 | 101 | ||
102 | /* enable irqs */ | 102 | /* enable irqs */ |
103 | dprintk( 0, "setting the interrupt mask\n" ); | ||
103 | cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04); | 104 | cx_set(MO_PCI_INTMSK, core->pci_irqmask | 0x04); |
104 | cx_write(MO_TS_INTMSK, 0x1f0011); | 105 | cx_set(MO_TS_INTMSK, 0x1f0011); |
106 | //cx_write(MO_TS_INTMSK, 0x0f0011); | ||
105 | 107 | ||
106 | /* start dma */ | 108 | /* start dma */ |
107 | cx_write(MO_DEV_CNTRL2, (1<<5)); /* FIXME: s/write/set/ ??? */ | 109 | cx_set(MO_DEV_CNTRL2, (1<<5)); |
108 | cx_write(MO_TS_DMACNTRL, 0x11); | 110 | cx_set(MO_TS_DMACNTRL, 0x11); |
109 | return 0; | 111 | return 0; |
110 | } | 112 | } |
111 | 113 | ||
112 | static int cx8802_stop_dma(struct cx8802_dev *dev) | 114 | static int cx8802_stop_dma(struct cx8802_dev *dev) |
113 | { | 115 | { |
114 | struct cx88_core *core = dev->core; | 116 | struct cx88_core *core = dev->core; |
117 | dprintk( 0, "cx8802_stop_dma\n" ); | ||
115 | 118 | ||
116 | /* stop dma */ | 119 | /* stop dma */ |
117 | cx_clear(MO_TS_DMACNTRL, 0x11); | 120 | cx_clear(MO_TS_DMACNTRL, 0x11); |
@@ -131,8 +134,12 @@ static int cx8802_restart_queue(struct cx8802_dev *dev, | |||
131 | struct cx88_buffer *buf; | 134 | struct cx88_buffer *buf; |
132 | struct list_head *item; | 135 | struct list_head *item; |
133 | 136 | ||
137 | dprintk( 0, "cx8802_restart_queue\n" ); | ||
134 | if (list_empty(&q->active)) | 138 | if (list_empty(&q->active)) |
139 | { | ||
140 | dprintk( 0, "cx8802_restart_queue: queue is empty\n" ); | ||
135 | return 0; | 141 | return 0; |
142 | } | ||
136 | 143 | ||
137 | buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); | 144 | buf = list_entry(q->active.next, struct cx88_buffer, vb.queue); |
138 | dprintk(2,"restart_queue [%p/%d]: restart dma\n", | 145 | dprintk(2,"restart_queue [%p/%d]: restart dma\n", |
@@ -182,27 +189,32 @@ void cx8802_buf_queue(struct cx8802_dev *dev, struct cx88_buffer *buf) | |||
182 | struct cx88_buffer *prev; | 189 | struct cx88_buffer *prev; |
183 | struct cx88_dmaqueue *q = &dev->mpegq; | 190 | struct cx88_dmaqueue *q = &dev->mpegq; |
184 | 191 | ||
192 | dprintk( 1, "cx8802_buf_queue\n" ); | ||
185 | /* add jump to stopper */ | 193 | /* add jump to stopper */ |
186 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); | 194 | buf->risc.jmp[0] = cpu_to_le32(RISC_JUMP | RISC_IRQ1 | RISC_CNT_INC); |
187 | buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); | 195 | buf->risc.jmp[1] = cpu_to_le32(q->stopper.dma); |
188 | 196 | ||
189 | if (list_empty(&q->active)) { | 197 | if (list_empty(&q->active)) { |
198 | dprintk( 0, "queue is empty - first active\n" ); | ||
190 | list_add_tail(&buf->vb.queue,&q->active); | 199 | list_add_tail(&buf->vb.queue,&q->active); |
191 | cx8802_start_dma(dev, q, buf); | 200 | cx8802_start_dma(dev, q, buf); |
192 | buf->vb.state = STATE_ACTIVE; | 201 | buf->vb.state = STATE_ACTIVE; |
193 | buf->count = q->count++; | 202 | buf->count = q->count++; |
194 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); | 203 | mod_timer(&q->timeout, jiffies+BUFFER_TIMEOUT); |
195 | dprintk(2,"[%p/%d] %s - first active\n", | 204 | dprintk(0,"[%p/%d] %s - first active\n", |
196 | buf, buf->vb.i, __FUNCTION__); | 205 | buf, buf->vb.i, __FUNCTION__); |
206 | //udelay(100); | ||
197 | 207 | ||
198 | } else { | 208 | } else { |
209 | dprintk( 1, "queue is not empty - append to active\n" ); | ||
199 | prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue); | 210 | prev = list_entry(q->active.prev, struct cx88_buffer, vb.queue); |
200 | list_add_tail(&buf->vb.queue,&q->active); | 211 | list_add_tail(&buf->vb.queue,&q->active); |
201 | buf->vb.state = STATE_ACTIVE; | 212 | buf->vb.state = STATE_ACTIVE; |
202 | buf->count = q->count++; | 213 | buf->count = q->count++; |
203 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); | 214 | prev->risc.jmp[1] = cpu_to_le32(buf->risc.dma); |
204 | dprintk(2,"[%p/%d] %s - append to active\n", | 215 | dprintk( 1, "[%p/%d] %s - append to active\n", |
205 | buf, buf->vb.i, __FUNCTION__); | 216 | buf, buf->vb.i, __FUNCTION__); |
217 | //udelay(100); | ||
206 | } | 218 | } |
207 | } | 219 | } |
208 | 220 | ||
@@ -224,7 +236,10 @@ static void do_cancel_buffers(struct cx8802_dev *dev, char *reason, int restart) | |||
224 | buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); | 236 | buf, buf->vb.i, reason, (unsigned long)buf->risc.dma); |
225 | } | 237 | } |
226 | if (restart) | 238 | if (restart) |
239 | { | ||
240 | dprintk(0, "restarting queue\n" ); | ||
227 | cx8802_restart_queue(dev,q); | 241 | cx8802_restart_queue(dev,q); |
242 | } | ||
228 | spin_unlock_irqrestore(&dev->slock,flags); | 243 | spin_unlock_irqrestore(&dev->slock,flags); |
229 | } | 244 | } |
230 | 245 | ||
@@ -232,6 +247,7 @@ void cx8802_cancel_buffers(struct cx8802_dev *dev) | |||
232 | { | 247 | { |
233 | struct cx88_dmaqueue *q = &dev->mpegq; | 248 | struct cx88_dmaqueue *q = &dev->mpegq; |
234 | 249 | ||
250 | dprintk( 1, "cx8802_cancel_buffers" ); | ||
235 | del_timer_sync(&q->timeout); | 251 | del_timer_sync(&q->timeout); |
236 | cx8802_stop_dma(dev); | 252 | cx8802_stop_dma(dev); |
237 | do_cancel_buffers(dev,"cancel",0); | 253 | do_cancel_buffers(dev,"cancel",0); |
@@ -241,7 +257,7 @@ static void cx8802_timeout(unsigned long data) | |||
241 | { | 257 | { |
242 | struct cx8802_dev *dev = (struct cx8802_dev*)data; | 258 | struct cx8802_dev *dev = (struct cx8802_dev*)data; |
243 | 259 | ||
244 | dprintk(1, "%s\n",__FUNCTION__); | 260 | dprintk(0, "%s\n",__FUNCTION__); |
245 | 261 | ||
246 | if (debug) | 262 | if (debug) |
247 | cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); | 263 | cx88_sram_channel_dump(dev->core, &cx88_sram_channels[SRAM_CH28]); |
@@ -254,12 +270,17 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) | |||
254 | struct cx88_core *core = dev->core; | 270 | struct cx88_core *core = dev->core; |
255 | u32 status, mask, count; | 271 | u32 status, mask, count; |
256 | 272 | ||
273 | dprintk( 1, "cx8802_mpeg_irq\n" ); | ||
257 | status = cx_read(MO_TS_INTSTAT); | 274 | status = cx_read(MO_TS_INTSTAT); |
258 | mask = cx_read(MO_TS_INTMSK); | 275 | mask = cx_read(MO_TS_INTMSK); |
259 | if (0 == (status & mask)) | 276 | if (0 == (status & mask)) |
260 | return; | 277 | return; |
261 | 278 | ||
262 | cx_write(MO_TS_INTSTAT, status); | 279 | cx_write(MO_TS_INTSTAT, status); |
280 | #if 0 | ||
281 | cx88_print_irqbits(core->name, "irq mpeg ", | ||
282 | cx88_mpeg_irqs, status, mask); | ||
283 | #endif | ||
263 | if (debug || (status & mask & ~0xff)) | 284 | if (debug || (status & mask & ~0xff)) |
264 | cx88_print_irqbits(core->name, "irq mpeg ", | 285 | cx88_print_irqbits(core->name, "irq mpeg ", |
265 | cx88_mpeg_irqs, status, mask); | 286 | cx88_mpeg_irqs, status, mask); |
@@ -273,6 +294,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) | |||
273 | 294 | ||
274 | /* risc1 y */ | 295 | /* risc1 y */ |
275 | if (status & 0x01) { | 296 | if (status & 0x01) { |
297 | dprintk( 1, "wake up\n" ); | ||
276 | spin_lock(&dev->slock); | 298 | spin_lock(&dev->slock); |
277 | count = cx_read(MO_TS_GPCNT); | 299 | count = cx_read(MO_TS_GPCNT); |
278 | cx88_wakeup(dev->core, &dev->mpegq, count); | 300 | cx88_wakeup(dev->core, &dev->mpegq, count); |
@@ -288,6 +310,7 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) | |||
288 | 310 | ||
289 | /* other general errors */ | 311 | /* other general errors */ |
290 | if (status & 0x1f0100) { | 312 | if (status & 0x1f0100) { |
313 | dprintk( 0, "general errors: 0x%08x\n", status & 0x1f0100 ); | ||
291 | spin_lock(&dev->slock); | 314 | spin_lock(&dev->slock); |
292 | cx8802_stop_dma(dev); | 315 | cx8802_stop_dma(dev); |
293 | cx8802_restart_queue(dev,&dev->mpegq); | 316 | cx8802_restart_queue(dev,&dev->mpegq); |
@@ -295,6 +318,8 @@ static void cx8802_mpeg_irq(struct cx8802_dev *dev) | |||
295 | } | 318 | } |
296 | } | 319 | } |
297 | 320 | ||
321 | #define MAX_IRQ_LOOP 10 | ||
322 | |||
298 | static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) | 323 | static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) |
299 | { | 324 | { |
300 | struct cx8802_dev *dev = dev_id; | 325 | struct cx8802_dev *dev = dev_id; |
@@ -302,10 +327,13 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
302 | u32 status; | 327 | u32 status; |
303 | int loop, handled = 0; | 328 | int loop, handled = 0; |
304 | 329 | ||
305 | for (loop = 0; loop < 10; loop++) { | 330 | for (loop = 0; loop < MAX_IRQ_LOOP; loop++) { |
306 | status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04); | 331 | status = cx_read(MO_PCI_INTSTAT) & (core->pci_irqmask | 0x04); |
307 | if (0 == status) | 332 | if (0 == status) |
308 | goto out; | 333 | goto out; |
334 | dprintk( 1, "cx8802_irq\n" ); | ||
335 | dprintk( 1, " loop: %d/%d\n", loop, MAX_IRQ_LOOP ); | ||
336 | dprintk( 1, " status: %d\n", status ); | ||
309 | handled = 1; | 337 | handled = 1; |
310 | cx_write(MO_PCI_INTSTAT, status); | 338 | cx_write(MO_PCI_INTSTAT, status); |
311 | 339 | ||
@@ -314,7 +342,8 @@ static irqreturn_t cx8802_irq(int irq, void *dev_id, struct pt_regs *regs) | |||
314 | if (status & 0x04) | 342 | if (status & 0x04) |
315 | cx8802_mpeg_irq(dev); | 343 | cx8802_mpeg_irq(dev); |
316 | }; | 344 | }; |
317 | if (10 == loop) { | 345 | if (MAX_IRQ_LOOP == loop) { |
346 | dprintk( 0, "clearing mask\n" ); | ||
318 | printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n", | 347 | printk(KERN_WARNING "%s/0: irq loop -- clearing mask\n", |
319 | core->name); | 348 | core->name); |
320 | cx_write(MO_PCI_INTMSK,0); | 349 | cx_write(MO_PCI_INTMSK,0); |
@@ -378,6 +407,7 @@ int cx8802_init_common(struct cx8802_dev *dev) | |||
378 | 407 | ||
379 | void cx8802_fini_common(struct cx8802_dev *dev) | 408 | void cx8802_fini_common(struct cx8802_dev *dev) |
380 | { | 409 | { |
410 | dprintk( 2, "cx8802_fini_common\n" ); | ||
381 | cx8802_stop_dma(dev); | 411 | cx8802_stop_dma(dev); |
382 | pci_disable_device(dev->pci); | 412 | pci_disable_device(dev->pci); |
383 | 413 | ||
@@ -399,6 +429,7 @@ int cx8802_suspend_common(struct pci_dev *pci_dev, pm_message_t state) | |||
399 | /* stop mpeg dma */ | 429 | /* stop mpeg dma */ |
400 | spin_lock(&dev->slock); | 430 | spin_lock(&dev->slock); |
401 | if (!list_empty(&dev->mpegq.active)) { | 431 | if (!list_empty(&dev->mpegq.active)) { |
432 | dprintk( 2, "suspend\n" ); | ||
402 | printk("%s: suspend mpeg\n", core->name); | 433 | printk("%s: suspend mpeg\n", core->name); |
403 | cx8802_stop_dma(dev); | 434 | cx8802_stop_dma(dev); |
404 | del_timer(&dev->mpegq.timeout); | 435 | del_timer(&dev->mpegq.timeout); |
@@ -463,4 +494,5 @@ EXPORT_SYMBOL(cx8802_resume_common); | |||
463 | * Local variables: | 494 | * Local variables: |
464 | * c-basic-offset: 8 | 495 | * c-basic-offset: 8 |
465 | * End: | 496 | * End: |
497 | * kate: eol "unix"; indent-width 3; remove-trailing-space on; replace-trailing-space-save on; tab-width 8; replace-tabs off; space-indent off; mixed-indent off | ||
466 | */ | 498 | */ |