diff options
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-irq.c')
-rw-r--r-- | drivers/media/video/ivtv/ivtv-irq.c | 234 |
1 files changed, 141 insertions, 93 deletions
diff --git a/drivers/media/video/ivtv/ivtv-irq.c b/drivers/media/video/ivtv/ivtv-irq.c index 8644f3dda31e..9695e5356163 100644 --- a/drivers/media/video/ivtv/ivtv-irq.c +++ b/drivers/media/video/ivtv/ivtv-irq.c | |||
@@ -60,18 +60,18 @@ static void ivtv_pio_work_handler(struct ivtv *itv) | |||
60 | buf = list_entry(s->q_dma.list.next, struct ivtv_buffer, list); | 60 | buf = list_entry(s->q_dma.list.next, struct ivtv_buffer, list); |
61 | list_for_each(p, &s->q_dma.list) { | 61 | list_for_each(p, &s->q_dma.list) { |
62 | struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list); | 62 | struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list); |
63 | u32 size = s->PIOarray[i].size & 0x3ffff; | 63 | u32 size = s->sg_processing[i].size & 0x3ffff; |
64 | 64 | ||
65 | /* Copy the data from the card to the buffer */ | 65 | /* Copy the data from the card to the buffer */ |
66 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI) { | 66 | if (s->type == IVTV_DEC_STREAM_TYPE_VBI) { |
67 | memcpy_fromio(buf->buf, itv->dec_mem + s->PIOarray[i].src - IVTV_DECODER_OFFSET, size); | 67 | memcpy_fromio(buf->buf, itv->dec_mem + s->sg_processing[i].src - IVTV_DECODER_OFFSET, size); |
68 | } | 68 | } |
69 | else { | 69 | else { |
70 | memcpy_fromio(buf->buf, itv->enc_mem + s->PIOarray[i].src, size); | 70 | memcpy_fromio(buf->buf, itv->enc_mem + s->sg_processing[i].src, size); |
71 | } | 71 | } |
72 | if (s->PIOarray[i].size & 0x80000000) | ||
73 | break; | ||
74 | i++; | 72 | i++; |
73 | if (i == s->sg_processing_size) | ||
74 | break; | ||
75 | } | 75 | } |
76 | write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); | 76 | write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44); |
77 | } | 77 | } |
@@ -105,7 +105,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA | |||
105 | u32 offset, size; | 105 | u32 offset, size; |
106 | u32 UVoffset = 0, UVsize = 0; | 106 | u32 UVoffset = 0, UVsize = 0; |
107 | int skip_bufs = s->q_predma.buffers; | 107 | int skip_bufs = s->q_predma.buffers; |
108 | int idx = s->SG_length; | 108 | int idx = s->sg_pending_size; |
109 | int rc; | 109 | int rc; |
110 | 110 | ||
111 | /* sanity checks */ | 111 | /* sanity checks */ |
@@ -123,7 +123,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA | |||
123 | case IVTV_ENC_STREAM_TYPE_MPG: | 123 | case IVTV_ENC_STREAM_TYPE_MPG: |
124 | offset = data[1]; | 124 | offset = data[1]; |
125 | size = data[2]; | 125 | size = data[2]; |
126 | s->dma_pts = 0; | 126 | s->pending_pts = 0; |
127 | break; | 127 | break; |
128 | 128 | ||
129 | case IVTV_ENC_STREAM_TYPE_YUV: | 129 | case IVTV_ENC_STREAM_TYPE_YUV: |
@@ -131,13 +131,13 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA | |||
131 | size = data[2]; | 131 | size = data[2]; |
132 | UVoffset = data[3]; | 132 | UVoffset = data[3]; |
133 | UVsize = data[4]; | 133 | UVsize = data[4]; |
134 | s->dma_pts = ((u64) data[5] << 32) | data[6]; | 134 | s->pending_pts = ((u64) data[5] << 32) | data[6]; |
135 | break; | 135 | break; |
136 | 136 | ||
137 | case IVTV_ENC_STREAM_TYPE_PCM: | 137 | case IVTV_ENC_STREAM_TYPE_PCM: |
138 | offset = data[1] + 12; | 138 | offset = data[1] + 12; |
139 | size = data[2] - 12; | 139 | size = data[2] - 12; |
140 | s->dma_pts = read_dec(offset - 8) | | 140 | s->pending_pts = read_dec(offset - 8) | |
141 | ((u64)(read_dec(offset - 12)) << 32); | 141 | ((u64)(read_dec(offset - 12)) << 32); |
142 | if (itv->has_cx23415) | 142 | if (itv->has_cx23415) |
143 | offset += IVTV_DECODER_OFFSET; | 143 | offset += IVTV_DECODER_OFFSET; |
@@ -150,13 +150,13 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA | |||
150 | IVTV_DEBUG_INFO("VBI offset == 0\n"); | 150 | IVTV_DEBUG_INFO("VBI offset == 0\n"); |
151 | return -1; | 151 | return -1; |
152 | } | 152 | } |
153 | s->dma_pts = read_enc(offset - 4) | ((u64)read_enc(offset - 8) << 32); | 153 | s->pending_pts = read_enc(offset - 4) | ((u64)read_enc(offset - 8) << 32); |
154 | break; | 154 | break; |
155 | 155 | ||
156 | case IVTV_DEC_STREAM_TYPE_VBI: | 156 | case IVTV_DEC_STREAM_TYPE_VBI: |
157 | size = read_dec(itv->vbi.dec_start + 4) + 8; | 157 | size = read_dec(itv->vbi.dec_start + 4) + 8; |
158 | offset = read_dec(itv->vbi.dec_start) + itv->vbi.dec_start; | 158 | offset = read_dec(itv->vbi.dec_start) + itv->vbi.dec_start; |
159 | s->dma_pts = 0; | 159 | s->pending_pts = 0; |
160 | offset += IVTV_DECODER_OFFSET; | 160 | offset += IVTV_DECODER_OFFSET; |
161 | break; | 161 | break; |
162 | default: | 162 | default: |
@@ -165,17 +165,17 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA | |||
165 | } | 165 | } |
166 | 166 | ||
167 | /* if this is the start of the DMA then fill in the magic cookie */ | 167 | /* if this is the start of the DMA then fill in the magic cookie */ |
168 | if (s->SG_length == 0) { | 168 | if (s->sg_pending_size == 0) { |
169 | if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM || | 169 | if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM || |
170 | s->type == IVTV_DEC_STREAM_TYPE_VBI)) { | 170 | s->type == IVTV_DEC_STREAM_TYPE_VBI)) { |
171 | s->dma_backup = read_dec(offset - IVTV_DECODER_OFFSET); | 171 | s->pending_backup = read_dec(offset - IVTV_DECODER_OFFSET); |
172 | write_dec_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset - IVTV_DECODER_OFFSET); | 172 | write_dec_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset - IVTV_DECODER_OFFSET); |
173 | } | 173 | } |
174 | else { | 174 | else { |
175 | s->dma_backup = read_enc(offset); | 175 | s->pending_backup = read_enc(offset); |
176 | write_enc_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset); | 176 | write_enc_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset); |
177 | } | 177 | } |
178 | s->dma_offset = offset; | 178 | s->pending_offset = offset; |
179 | } | 179 | } |
180 | 180 | ||
181 | bytes_needed = size; | 181 | bytes_needed = size; |
@@ -202,7 +202,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA | |||
202 | } | 202 | } |
203 | s->buffers_stolen = rc; | 203 | s->buffers_stolen = rc; |
204 | 204 | ||
205 | /* got the buffers, now fill in SGarray (DMA) */ | 205 | /* got the buffers, now fill in sg_pending */ |
206 | buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list); | 206 | buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list); |
207 | memset(buf->buf, 0, 128); | 207 | memset(buf->buf, 0, 128); |
208 | list_for_each(p, &s->q_predma.list) { | 208 | list_for_each(p, &s->q_predma.list) { |
@@ -210,9 +210,9 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA | |||
210 | 210 | ||
211 | if (skip_bufs-- > 0) | 211 | if (skip_bufs-- > 0) |
212 | continue; | 212 | continue; |
213 | s->SGarray[idx].dst = cpu_to_le32(buf->dma_handle); | 213 | s->sg_pending[idx].dst = buf->dma_handle; |
214 | s->SGarray[idx].src = cpu_to_le32(offset); | 214 | s->sg_pending[idx].src = offset; |
215 | s->SGarray[idx].size = cpu_to_le32(s->buf_size); | 215 | s->sg_pending[idx].size = s->buf_size; |
216 | buf->bytesused = (size < s->buf_size) ? size : s->buf_size; | 216 | buf->bytesused = (size < s->buf_size) ? size : s->buf_size; |
217 | buf->dma_xfer_cnt = s->dma_xfer_cnt; | 217 | buf->dma_xfer_cnt = s->dma_xfer_cnt; |
218 | 218 | ||
@@ -230,7 +230,7 @@ static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MA | |||
230 | } | 230 | } |
231 | idx++; | 231 | idx++; |
232 | } | 232 | } |
233 | s->SG_length = idx; | 233 | s->sg_pending_size = idx; |
234 | return 0; | 234 | return 0; |
235 | } | 235 | } |
236 | 236 | ||
@@ -332,9 +332,9 @@ void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock) | |||
332 | offset = uv_offset; | 332 | offset = uv_offset; |
333 | y_done = 1; | 333 | y_done = 1; |
334 | } | 334 | } |
335 | s->SGarray[idx].src = cpu_to_le32(buf->dma_handle); | 335 | s->sg_pending[idx].src = buf->dma_handle; |
336 | s->SGarray[idx].dst = cpu_to_le32(offset); | 336 | s->sg_pending[idx].dst = offset; |
337 | s->SGarray[idx].size = cpu_to_le32(buf->bytesused); | 337 | s->sg_pending[idx].size = buf->bytesused; |
338 | 338 | ||
339 | offset += buf->bytesused; | 339 | offset += buf->bytesused; |
340 | bytes_written += buf->bytesused; | 340 | bytes_written += buf->bytesused; |
@@ -343,10 +343,7 @@ void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock) | |||
343 | ivtv_buf_sync_for_device(s, buf); | 343 | ivtv_buf_sync_for_device(s, buf); |
344 | idx++; | 344 | idx++; |
345 | } | 345 | } |
346 | s->SG_length = idx; | 346 | s->sg_pending_size = idx; |
347 | |||
348 | /* Mark last buffer size for Interrupt flag */ | ||
349 | s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000); | ||
350 | 347 | ||
351 | /* Sync Hardware SG List of buffers */ | 348 | /* Sync Hardware SG List of buffers */ |
352 | ivtv_stream_sync_for_device(s); | 349 | ivtv_stream_sync_for_device(s); |
@@ -362,6 +359,34 @@ void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock) | |||
362 | spin_unlock_irqrestore(&itv->dma_reg_lock, flags); | 359 | spin_unlock_irqrestore(&itv->dma_reg_lock, flags); |
363 | } | 360 | } |
364 | 361 | ||
362 | static void ivtv_dma_enc_start_xfer(struct ivtv_stream *s) | ||
363 | { | ||
364 | struct ivtv *itv = s->itv; | ||
365 | |||
366 | s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src); | ||
367 | s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst); | ||
368 | s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000); | ||
369 | s->sg_processed++; | ||
370 | /* Sync Hardware SG List of buffers */ | ||
371 | ivtv_stream_sync_for_device(s); | ||
372 | write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR); | ||
373 | write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER); | ||
374 | } | ||
375 | |||
376 | static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s) | ||
377 | { | ||
378 | struct ivtv *itv = s->itv; | ||
379 | |||
380 | s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src); | ||
381 | s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst); | ||
382 | s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000); | ||
383 | s->sg_processed++; | ||
384 | /* Sync Hardware SG List of buffers */ | ||
385 | ivtv_stream_sync_for_device(s); | ||
386 | write_reg(s->sg_handle, IVTV_REG_DECDMAADDR); | ||
387 | write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); | ||
388 | } | ||
389 | |||
365 | /* start the encoder DMA */ | 390 | /* start the encoder DMA */ |
366 | static void ivtv_dma_enc_start(struct ivtv_stream *s) | 391 | static void ivtv_dma_enc_start(struct ivtv_stream *s) |
367 | { | 392 | { |
@@ -375,8 +400,7 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) | |||
375 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); | 400 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); |
376 | 401 | ||
377 | if (ivtv_use_dma(s)) | 402 | if (ivtv_use_dma(s)) |
378 | s->SGarray[s->SG_length - 1].size = | 403 | s->sg_pending[s->sg_pending_size - 1].size += 256; |
379 | cpu_to_le32(le32_to_cpu(s->SGarray[s->SG_length - 1].size) + 256); | ||
380 | 404 | ||
381 | /* If this is an MPEG stream, and VBI data is also pending, then append the | 405 | /* If this is an MPEG stream, and VBI data is also pending, then append the |
382 | VBI DMA to the MPEG DMA and transfer both sets of data at once. | 406 | VBI DMA to the MPEG DMA and transfer both sets of data at once. |
@@ -387,45 +411,39 @@ static void ivtv_dma_enc_start(struct ivtv_stream *s) | |||
387 | sure we only use the MPEG DMA to transfer the VBI DMA if both are in | 411 | sure we only use the MPEG DMA to transfer the VBI DMA if both are in |
388 | use. This way no conflicts occur. */ | 412 | use. This way no conflicts occur. */ |
389 | clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags); | 413 | clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags); |
390 | if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->SG_length && | 414 | if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->sg_pending_size && |
391 | s->SG_length + s_vbi->SG_length <= s->buffers) { | 415 | s->sg_pending_size + s_vbi->sg_pending_size <= s->buffers) { |
392 | ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused); | 416 | ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused); |
393 | if (ivtv_use_dma(s_vbi)) | 417 | if (ivtv_use_dma(s_vbi)) |
394 | s_vbi->SGarray[s_vbi->SG_length - 1].size = cpu_to_le32(le32_to_cpu(s_vbi->SGarray[s->SG_length - 1].size) + 256); | 418 | s_vbi->sg_pending[s_vbi->sg_pending_size - 1].size += 256; |
395 | for (i = 0; i < s_vbi->SG_length; i++) { | 419 | for (i = 0; i < s_vbi->sg_pending_size; i++) { |
396 | s->SGarray[s->SG_length++] = s_vbi->SGarray[i]; | 420 | s->sg_pending[s->sg_pending_size++] = s_vbi->sg_pending[i]; |
397 | } | 421 | } |
398 | itv->vbi.dma_offset = s_vbi->dma_offset; | 422 | s_vbi->dma_offset = s_vbi->pending_offset; |
399 | s_vbi->SG_length = 0; | 423 | s_vbi->sg_pending_size = 0; |
400 | s_vbi->dma_xfer_cnt++; | 424 | s_vbi->dma_xfer_cnt++; |
401 | set_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags); | 425 | set_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags); |
402 | IVTV_DEBUG_HI_DMA("include DMA for %s\n", s->name); | 426 | IVTV_DEBUG_HI_DMA("include DMA for %s\n", s->name); |
403 | } | 427 | } |
404 | 428 | ||
405 | /* Mark last buffer size for Interrupt flag */ | ||
406 | s->SGarray[s->SG_length - 1].size |= cpu_to_le32(0x80000000); | ||
407 | s->dma_xfer_cnt++; | 429 | s->dma_xfer_cnt++; |
408 | 430 | memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_element) * s->sg_pending_size); | |
409 | if (s->type == IVTV_ENC_STREAM_TYPE_VBI) | 431 | s->sg_processing_size = s->sg_pending_size; |
410 | set_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); | 432 | s->sg_pending_size = 0; |
411 | else | 433 | s->sg_processed = 0; |
412 | clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); | 434 | s->dma_offset = s->pending_offset; |
435 | s->dma_backup = s->pending_backup; | ||
436 | s->dma_pts = s->pending_pts; | ||
413 | 437 | ||
414 | if (ivtv_use_pio(s)) { | 438 | if (ivtv_use_pio(s)) { |
415 | for (i = 0; i < s->SG_length; i++) { | ||
416 | s->PIOarray[i].src = le32_to_cpu(s->SGarray[i].src); | ||
417 | s->PIOarray[i].size = le32_to_cpu(s->SGarray[i].size); | ||
418 | } | ||
419 | set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags); | 439 | set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags); |
420 | set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags); | 440 | set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags); |
421 | set_bit(IVTV_F_I_PIO, &itv->i_flags); | 441 | set_bit(IVTV_F_I_PIO, &itv->i_flags); |
422 | itv->cur_pio_stream = s->type; | 442 | itv->cur_pio_stream = s->type; |
423 | } | 443 | } |
424 | else { | 444 | else { |
425 | /* Sync Hardware SG List of buffers */ | 445 | itv->dma_retries = 0; |
426 | ivtv_stream_sync_for_device(s); | 446 | ivtv_dma_enc_start_xfer(s); |
427 | write_reg(s->SG_handle, IVTV_REG_ENCDMAADDR); | ||
428 | write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER); | ||
429 | set_bit(IVTV_F_I_DMA, &itv->i_flags); | 447 | set_bit(IVTV_F_I_DMA, &itv->i_flags); |
430 | itv->cur_dma_stream = s->type; | 448 | itv->cur_dma_stream = s->type; |
431 | itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); | 449 | itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); |
@@ -439,10 +457,15 @@ static void ivtv_dma_dec_start(struct ivtv_stream *s) | |||
439 | 457 | ||
440 | if (s->q_predma.bytesused) | 458 | if (s->q_predma.bytesused) |
441 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); | 459 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused); |
460 | s->dma_xfer_cnt++; | ||
461 | memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_element) * s->sg_pending_size); | ||
462 | s->sg_processing_size = s->sg_pending_size; | ||
463 | s->sg_pending_size = 0; | ||
464 | s->sg_processed = 0; | ||
465 | |||
442 | IVTV_DEBUG_HI_DMA("start DMA for %s\n", s->name); | 466 | IVTV_DEBUG_HI_DMA("start DMA for %s\n", s->name); |
443 | /* put SG Handle into register 0x0c */ | 467 | itv->dma_retries = 0; |
444 | write_reg(s->SG_handle, IVTV_REG_DECDMAADDR); | 468 | ivtv_dma_dec_start_xfer(s); |
445 | write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER); | ||
446 | set_bit(IVTV_F_I_DMA, &itv->i_flags); | 469 | set_bit(IVTV_F_I_DMA, &itv->i_flags); |
447 | itv->cur_dma_stream = s->type; | 470 | itv->cur_dma_stream = s->type; |
448 | itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); | 471 | itv->dma_timer.expires = jiffies + msecs_to_jiffies(100); |
@@ -453,27 +476,42 @@ static void ivtv_irq_dma_read(struct ivtv *itv) | |||
453 | { | 476 | { |
454 | struct ivtv_stream *s = NULL; | 477 | struct ivtv_stream *s = NULL; |
455 | struct ivtv_buffer *buf; | 478 | struct ivtv_buffer *buf; |
456 | int hw_stream_type; | 479 | int hw_stream_type = 0; |
457 | 480 | ||
458 | IVTV_DEBUG_HI_IRQ("DEC DMA READ\n"); | 481 | IVTV_DEBUG_HI_IRQ("DEC DMA READ\n"); |
459 | del_timer(&itv->dma_timer); | 482 | if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream < 0) { |
460 | if (read_reg(IVTV_REG_DMASTATUS) & 0x14) { | 483 | del_timer(&itv->dma_timer); |
461 | IVTV_DEBUG_WARN("DEC DMA ERROR %x\n", read_reg(IVTV_REG_DMASTATUS)); | 484 | return; |
462 | write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); | ||
463 | } | 485 | } |
486 | |||
464 | if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { | 487 | if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { |
465 | if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) { | 488 | s = &itv->streams[itv->cur_dma_stream]; |
466 | s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV]; | 489 | ivtv_stream_sync_for_cpu(s); |
467 | hw_stream_type = 2; | 490 | |
491 | if (read_reg(IVTV_REG_DMASTATUS) & 0x14) { | ||
492 | IVTV_DEBUG_WARN("DEC DMA ERROR %x (xfer %d of %d, retry %d)\n", | ||
493 | read_reg(IVTV_REG_DMASTATUS), | ||
494 | s->sg_processed, s->sg_processing_size, itv->dma_retries); | ||
495 | write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); | ||
496 | if (itv->dma_retries == 3) { | ||
497 | itv->dma_retries = 0; | ||
498 | } | ||
499 | else { | ||
500 | /* Retry, starting with the first xfer segment. | ||
501 | Just retrying the current segment is not sufficient. */ | ||
502 | s->sg_processed = 0; | ||
503 | itv->dma_retries++; | ||
504 | } | ||
468 | } | 505 | } |
469 | else { | 506 | if (s->sg_processed < s->sg_processing_size) { |
470 | s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG]; | 507 | /* DMA next buffer */ |
471 | hw_stream_type = 0; | 508 | ivtv_dma_dec_start_xfer(s); |
509 | return; | ||
472 | } | 510 | } |
511 | if (s->type == IVTV_DEC_STREAM_TYPE_YUV) | ||
512 | hw_stream_type = 2; | ||
473 | IVTV_DEBUG_HI_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused); | 513 | IVTV_DEBUG_HI_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused); |
474 | 514 | ||
475 | ivtv_stream_sync_for_cpu(s); | ||
476 | |||
477 | /* For some reason must kick the firmware, like PIO mode, | 515 | /* For some reason must kick the firmware, like PIO mode, |
478 | I think this tells the firmware we are done and the size | 516 | I think this tells the firmware we are done and the size |
479 | of the xfer so it can calculate what we need next. | 517 | of the xfer so it can calculate what we need next. |
@@ -490,6 +528,7 @@ static void ivtv_irq_dma_read(struct ivtv *itv) | |||
490 | } | 528 | } |
491 | wake_up(&s->waitq); | 529 | wake_up(&s->waitq); |
492 | } | 530 | } |
531 | del_timer(&itv->dma_timer); | ||
493 | clear_bit(IVTV_F_I_UDMA, &itv->i_flags); | 532 | clear_bit(IVTV_F_I_UDMA, &itv->i_flags); |
494 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); | 533 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); |
495 | itv->cur_dma_stream = -1; | 534 | itv->cur_dma_stream = -1; |
@@ -501,33 +540,44 @@ static void ivtv_irq_enc_dma_complete(struct ivtv *itv) | |||
501 | u32 data[CX2341X_MBOX_MAX_DATA]; | 540 | u32 data[CX2341X_MBOX_MAX_DATA]; |
502 | struct ivtv_stream *s; | 541 | struct ivtv_stream *s; |
503 | 542 | ||
504 | del_timer(&itv->dma_timer); | ||
505 | ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); | 543 | ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); |
506 | IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d\n", data[0], data[1]); | 544 | IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream); |
507 | if (test_and_clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags)) | 545 | if (itv->cur_dma_stream < 0) { |
508 | data[1] = 3; | 546 | del_timer(&itv->dma_timer); |
509 | else if (data[1] > 2) | ||
510 | return; | 547 | return; |
511 | s = &itv->streams[ivtv_stream_map[data[1]]]; | 548 | } |
549 | s = &itv->streams[itv->cur_dma_stream]; | ||
550 | ivtv_stream_sync_for_cpu(s); | ||
551 | |||
512 | if (data[0] & 0x18) { | 552 | if (data[0] & 0x18) { |
513 | IVTV_DEBUG_WARN("ENC DMA ERROR %x\n", data[0]); | 553 | IVTV_DEBUG_WARN("ENC DMA ERROR %x (offset %08x, xfer %d of %d, retry %d)\n", data[0], |
554 | s->dma_offset, s->sg_processed, s->sg_processing_size, itv->dma_retries); | ||
514 | write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); | 555 | write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); |
515 | ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, data[1]); | 556 | if (itv->dma_retries == 3) { |
557 | itv->dma_retries = 0; | ||
558 | } | ||
559 | else { | ||
560 | /* Retry, starting with the first xfer segment. | ||
561 | Just retrying the current segment is not sufficient. */ | ||
562 | s->sg_processed = 0; | ||
563 | itv->dma_retries++; | ||
564 | } | ||
516 | } | 565 | } |
517 | s->SG_length = 0; | 566 | if (s->sg_processed < s->sg_processing_size) { |
567 | /* DMA next buffer */ | ||
568 | ivtv_dma_enc_start_xfer(s); | ||
569 | return; | ||
570 | } | ||
571 | del_timer(&itv->dma_timer); | ||
518 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); | 572 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); |
519 | itv->cur_dma_stream = -1; | 573 | itv->cur_dma_stream = -1; |
520 | dma_post(s); | 574 | dma_post(s); |
521 | ivtv_stream_sync_for_cpu(s); | ||
522 | if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) { | 575 | if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) { |
523 | u32 tmp; | ||
524 | |||
525 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; | 576 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; |
526 | tmp = s->dma_offset; | ||
527 | s->dma_offset = itv->vbi.dma_offset; | ||
528 | dma_post(s); | 577 | dma_post(s); |
529 | s->dma_offset = tmp; | ||
530 | } | 578 | } |
579 | s->sg_processing_size = 0; | ||
580 | s->sg_processed = 0; | ||
531 | wake_up(&itv->dma_waitq); | 581 | wake_up(&itv->dma_waitq); |
532 | } | 582 | } |
533 | 583 | ||
@@ -541,8 +591,7 @@ static void ivtv_irq_enc_pio_complete(struct ivtv *itv) | |||
541 | } | 591 | } |
542 | s = &itv->streams[itv->cur_pio_stream]; | 592 | s = &itv->streams[itv->cur_pio_stream]; |
543 | IVTV_DEBUG_HI_IRQ("ENC PIO COMPLETE %s\n", s->name); | 593 | IVTV_DEBUG_HI_IRQ("ENC PIO COMPLETE %s\n", s->name); |
544 | s->SG_length = 0; | 594 | s->sg_pending_size = 0; |
545 | clear_bit(IVTV_F_I_ENC_VBI, &itv->i_flags); | ||
546 | clear_bit(IVTV_F_I_PIO, &itv->i_flags); | 595 | clear_bit(IVTV_F_I_PIO, &itv->i_flags); |
547 | itv->cur_pio_stream = -1; | 596 | itv->cur_pio_stream = -1; |
548 | dma_post(s); | 597 | dma_post(s); |
@@ -554,13 +603,8 @@ static void ivtv_irq_enc_pio_complete(struct ivtv *itv) | |||
554 | ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2); | 603 | ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2); |
555 | clear_bit(IVTV_F_I_PIO, &itv->i_flags); | 604 | clear_bit(IVTV_F_I_PIO, &itv->i_flags); |
556 | if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) { | 605 | if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) { |
557 | u32 tmp; | ||
558 | |||
559 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; | 606 | s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI]; |
560 | tmp = s->dma_offset; | ||
561 | s->dma_offset = itv->vbi.dma_offset; | ||
562 | dma_post(s); | 607 | dma_post(s); |
563 | s->dma_offset = tmp; | ||
564 | } | 608 | } |
565 | wake_up(&itv->dma_waitq); | 609 | wake_up(&itv->dma_waitq); |
566 | } | 610 | } |
@@ -572,19 +616,23 @@ static void ivtv_irq_dma_err(struct ivtv *itv) | |||
572 | del_timer(&itv->dma_timer); | 616 | del_timer(&itv->dma_timer); |
573 | ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); | 617 | ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data); |
574 | IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1], | 618 | IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1], |
575 | read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream); | 619 | read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream); |
620 | write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); | ||
576 | if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && | 621 | if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && |
577 | itv->cur_dma_stream >= 0 && itv->cur_dma_stream < IVTV_MAX_STREAMS) { | 622 | itv->cur_dma_stream >= 0 && itv->cur_dma_stream < IVTV_MAX_STREAMS) { |
578 | struct ivtv_stream *s = &itv->streams[itv->cur_dma_stream]; | 623 | struct ivtv_stream *s = &itv->streams[itv->cur_dma_stream]; |
579 | 624 | ||
580 | /* retry */ | 625 | /* retry */ |
581 | write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS); | ||
582 | if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) | 626 | if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) |
583 | ivtv_dma_dec_start(s); | 627 | ivtv_dma_dec_start(s); |
584 | else | 628 | else |
585 | ivtv_dma_enc_start(s); | 629 | ivtv_dma_enc_start(s); |
586 | return; | 630 | return; |
587 | } | 631 | } |
632 | if (test_bit(IVTV_F_I_UDMA, &itv->i_flags)) { | ||
633 | ivtv_udma_start(itv); | ||
634 | return; | ||
635 | } | ||
588 | clear_bit(IVTV_F_I_UDMA, &itv->i_flags); | 636 | clear_bit(IVTV_F_I_UDMA, &itv->i_flags); |
589 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); | 637 | clear_bit(IVTV_F_I_DMA, &itv->i_flags); |
590 | itv->cur_dma_stream = -1; | 638 | itv->cur_dma_stream = -1; |
@@ -628,14 +676,14 @@ static void ivtv_irq_enc_vbi_cap(struct ivtv *itv) | |||
628 | DMA the data. Since at most four VBI DMA buffers are available, | 676 | DMA the data. Since at most four VBI DMA buffers are available, |
629 | we just drop the old requests when there are already three | 677 | we just drop the old requests when there are already three |
630 | requests queued. */ | 678 | requests queued. */ |
631 | if (s->SG_length > 2) { | 679 | if (s->sg_pending_size > 2) { |
632 | struct list_head *p; | 680 | struct list_head *p; |
633 | list_for_each(p, &s->q_predma.list) { | 681 | list_for_each(p, &s->q_predma.list) { |
634 | struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list); | 682 | struct ivtv_buffer *buf = list_entry(p, struct ivtv_buffer, list); |
635 | ivtv_buf_sync_for_cpu(s, buf); | 683 | ivtv_buf_sync_for_cpu(s, buf); |
636 | } | 684 | } |
637 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0); | 685 | ivtv_queue_move(s, &s->q_predma, NULL, &s->q_free, 0); |
638 | s->SG_length = 0; | 686 | s->sg_pending_size = 0; |
639 | } | 687 | } |
640 | /* if we can append the data, and the MPEG stream isn't capturing, | 688 | /* if we can append the data, and the MPEG stream isn't capturing, |
641 | then start a DMA request for just the VBI data. */ | 689 | then start a DMA request for just the VBI data. */ |