blob: 34f3ab82785853634bc3c47deb7587d7590508d3 [file] [log] [blame]
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001/* interrupt handling
2 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
3 Copyright (C) 2004 Chris Kennedy <c@groovy.org>
4 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ivtv-driver.h"
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030022#include "ivtv-queue.h"
23#include "ivtv-udma.h"
24#include "ivtv-irq.h"
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030025#include "ivtv-mailbox.h"
26#include "ivtv-vbi.h"
Hans Verkuil1e13f9e2007-03-10 06:52:02 -030027#include "ivtv-yuv.h"
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030028
29#define DMA_MAGIC_COOKIE 0x000001fe
30
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030031static void ivtv_dma_dec_start(struct ivtv_stream *s);
32
33static const int ivtv_stream_map[] = {
34 IVTV_ENC_STREAM_TYPE_MPG,
35 IVTV_ENC_STREAM_TYPE_YUV,
36 IVTV_ENC_STREAM_TYPE_PCM,
37 IVTV_ENC_STREAM_TYPE_VBI,
38};
39
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030040
Hans Verkuildc02d502007-05-19 14:07:16 -030041static void ivtv_pio_work_handler(struct ivtv *itv)
42{
43 struct ivtv_stream *s = &itv->streams[itv->cur_pio_stream];
44 struct ivtv_buffer *buf;
Hans Verkuildc02d502007-05-19 14:07:16 -030045 int i = 0;
46
Hans Verkuilbd58df62007-07-10 17:47:07 -030047 IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n");
Hans Verkuildc02d502007-05-19 14:07:16 -030048 if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS ||
49 s->v4l2dev == NULL || !ivtv_use_pio(s)) {
50 itv->cur_pio_stream = -1;
51 /* trigger PIO complete user interrupt */
52 write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
53 return;
54 }
Hans Verkuilbd58df62007-07-10 17:47:07 -030055 IVTV_DEBUG_HI_DMA("Process PIO %s\n", s->name);
Trent Piepho805a4392007-10-10 05:37:41 -030056 list_for_each_entry(buf, &s->q_dma.list, list) {
Hans Verkuil37093b12007-07-28 19:45:50 -030057 u32 size = s->sg_processing[i].size & 0x3ffff;
Hans Verkuildc02d502007-05-19 14:07:16 -030058
59 /* Copy the data from the card to the buffer */
60 if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
Hans Verkuil37093b12007-07-28 19:45:50 -030061 memcpy_fromio(buf->buf, itv->dec_mem + s->sg_processing[i].src - IVTV_DECODER_OFFSET, size);
Hans Verkuildc02d502007-05-19 14:07:16 -030062 }
63 else {
Hans Verkuil37093b12007-07-28 19:45:50 -030064 memcpy_fromio(buf->buf, itv->enc_mem + s->sg_processing[i].src, size);
Hans Verkuildc02d502007-05-19 14:07:16 -030065 }
Hans Verkuildc02d502007-05-19 14:07:16 -030066 i++;
Hans Verkuil37093b12007-07-28 19:45:50 -030067 if (i == s->sg_processing_size)
68 break;
Hans Verkuildc02d502007-05-19 14:07:16 -030069 }
70 write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030071}
72
Hans Verkuil1e13f9e2007-03-10 06:52:02 -030073void ivtv_irq_work_handler(struct work_struct *work)
74{
75 struct ivtv *itv = container_of(work, struct ivtv, irq_work_queue);
76
77 DEFINE_WAIT(wait);
78
Hans Verkuild526afe2008-09-03 16:47:14 -030079 if (test_and_clear_bit(IVTV_F_I_WORK_INITED, &itv->i_flags)) {
80 struct sched_param param = { .sched_priority = 99 };
81
82 /* This thread must use the FIFO scheduler as it
83 is realtime sensitive. */
84 sched_setscheduler(current, SCHED_FIFO, &param);
85 }
Hans Verkuildc02d502007-05-19 14:07:16 -030086 if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
87 ivtv_pio_work_handler(itv);
88
Hans Verkuil1e13f9e2007-03-10 06:52:02 -030089 if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags))
Hans Verkuildc02d502007-05-19 14:07:16 -030090 ivtv_vbi_work_handler(itv);
Hans Verkuil1e13f9e2007-03-10 06:52:02 -030091
92 if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
93 ivtv_yuv_work_handler(itv);
94}
95
Hans Verkuil1a0adaf2007-04-27 12:31:25 -030096/* Determine the required DMA size, setup enough buffers in the predma queue and
97 actually copy the data from the card to the buffers in case a PIO transfer is
98 required for this stream.
99 */
100static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MAX_DATA])
101{
102 struct ivtv *itv = s->itv;
103 struct ivtv_buffer *buf;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300104 u32 bytes_needed = 0;
105 u32 offset, size;
106 u32 UVoffset = 0, UVsize = 0;
107 int skip_bufs = s->q_predma.buffers;
Hans Verkuil37093b12007-07-28 19:45:50 -0300108 int idx = s->sg_pending_size;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300109 int rc;
110
111 /* sanity checks */
112 if (s->v4l2dev == NULL) {
113 IVTV_DEBUG_WARN("Stream %s not started\n", s->name);
114 return -1;
115 }
116 if (!test_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
117 IVTV_DEBUG_WARN("Stream %s not open\n", s->name);
118 return -1;
119 }
120
121 /* determine offset, size and PTS for the various streams */
122 switch (s->type) {
123 case IVTV_ENC_STREAM_TYPE_MPG:
124 offset = data[1];
125 size = data[2];
Hans Verkuil37093b12007-07-28 19:45:50 -0300126 s->pending_pts = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300127 break;
128
129 case IVTV_ENC_STREAM_TYPE_YUV:
130 offset = data[1];
131 size = data[2];
132 UVoffset = data[3];
133 UVsize = data[4];
Hans Verkuil37093b12007-07-28 19:45:50 -0300134 s->pending_pts = ((u64) data[5] << 32) | data[6];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300135 break;
136
137 case IVTV_ENC_STREAM_TYPE_PCM:
138 offset = data[1] + 12;
139 size = data[2] - 12;
Hans Verkuil37093b12007-07-28 19:45:50 -0300140 s->pending_pts = read_dec(offset - 8) |
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300141 ((u64)(read_dec(offset - 12)) << 32);
142 if (itv->has_cx23415)
143 offset += IVTV_DECODER_OFFSET;
144 break;
145
146 case IVTV_ENC_STREAM_TYPE_VBI:
147 size = itv->vbi.enc_size * itv->vbi.fpi;
148 offset = read_enc(itv->vbi.enc_start - 4) + 12;
149 if (offset == 12) {
150 IVTV_DEBUG_INFO("VBI offset == 0\n");
151 return -1;
152 }
Hans Verkuil37093b12007-07-28 19:45:50 -0300153 s->pending_pts = read_enc(offset - 4) | ((u64)read_enc(offset - 8) << 32);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300154 break;
155
156 case IVTV_DEC_STREAM_TYPE_VBI:
157 size = read_dec(itv->vbi.dec_start + 4) + 8;
158 offset = read_dec(itv->vbi.dec_start) + itv->vbi.dec_start;
Hans Verkuil37093b12007-07-28 19:45:50 -0300159 s->pending_pts = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300160 offset += IVTV_DECODER_OFFSET;
161 break;
162 default:
163 /* shouldn't happen */
164 return -1;
165 }
166
167 /* if this is the start of the DMA then fill in the magic cookie */
Hans Verkuil51a99c02007-08-18 15:16:00 -0300168 if (s->sg_pending_size == 0 && ivtv_use_dma(s)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300169 if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM ||
170 s->type == IVTV_DEC_STREAM_TYPE_VBI)) {
Hans Verkuil37093b12007-07-28 19:45:50 -0300171 s->pending_backup = read_dec(offset - IVTV_DECODER_OFFSET);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300172 write_dec_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset - IVTV_DECODER_OFFSET);
173 }
174 else {
Hans Verkuil37093b12007-07-28 19:45:50 -0300175 s->pending_backup = read_enc(offset);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300176 write_enc_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset);
177 }
Hans Verkuil37093b12007-07-28 19:45:50 -0300178 s->pending_offset = offset;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300179 }
180
181 bytes_needed = size;
182 if (s->type == IVTV_ENC_STREAM_TYPE_YUV) {
183 /* The size for the Y samples needs to be rounded upwards to a
184 multiple of the buf_size. The UV samples then start in the
185 next buffer. */
186 bytes_needed = s->buf_size * ((bytes_needed + s->buf_size - 1) / s->buf_size);
187 bytes_needed += UVsize;
188 }
189
Hans Verkuilbd58df62007-07-10 17:47:07 -0300190 IVTV_DEBUG_HI_DMA("%s %s: 0x%08x bytes at 0x%08x\n",
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300191 ivtv_use_pio(s) ? "PIO" : "DMA", s->name, bytes_needed, offset);
192
193 rc = ivtv_queue_move(s, &s->q_free, &s->q_full, &s->q_predma, bytes_needed);
194 if (rc < 0) { /* Insufficient buffers */
195 IVTV_DEBUG_WARN("Cannot obtain %d bytes for %s data transfer\n",
196 bytes_needed, s->name);
197 return -1;
198 }
199 if (rc && !s->buffers_stolen && (s->s_flags & IVTV_F_S_APPL_IO)) {
200 IVTV_WARN("All %s stream buffers are full. Dropping data.\n", s->name);
201 IVTV_WARN("Cause: the application is not reading fast enough.\n");
202 }
203 s->buffers_stolen = rc;
204
Hans Verkuil37093b12007-07-28 19:45:50 -0300205 /* got the buffers, now fill in sg_pending */
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300206 buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
207 memset(buf->buf, 0, 128);
Trent Piepho805a4392007-10-10 05:37:41 -0300208 list_for_each_entry(buf, &s->q_predma.list, list) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300209 if (skip_bufs-- > 0)
210 continue;
Hans Verkuil37093b12007-07-28 19:45:50 -0300211 s->sg_pending[idx].dst = buf->dma_handle;
212 s->sg_pending[idx].src = offset;
213 s->sg_pending[idx].size = s->buf_size;
Richard Knutsson14d5deb2007-12-08 10:35:06 -0300214 buf->bytesused = min(size, s->buf_size);
Hans Verkuilf4071b82007-07-28 12:07:12 -0300215 buf->dma_xfer_cnt = s->dma_xfer_cnt;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300216
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300217 s->q_predma.bytesused += buf->bytesused;
218 size -= buf->bytesused;
219 offset += s->buf_size;
220
221 /* Sync SG buffers */
222 ivtv_buf_sync_for_device(s, buf);
223
224 if (size == 0) { /* YUV */
225 /* process the UV section */
226 offset = UVoffset;
227 size = UVsize;
228 }
229 idx++;
230 }
Hans Verkuil37093b12007-07-28 19:45:50 -0300231 s->sg_pending_size = idx;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300232 return 0;
233}
234
235static void dma_post(struct ivtv_stream *s)
236{
237 struct ivtv *itv = s->itv;
238 struct ivtv_buffer *buf = NULL;
239 struct list_head *p;
240 u32 offset;
Al Virob0510f82008-05-21 00:31:41 -0300241 __le32 *u32buf;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300242 int x = 0;
243
Hans Verkuilbd58df62007-07-10 17:47:07 -0300244 IVTV_DEBUG_HI_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA",
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300245 s->name, s->dma_offset);
246 list_for_each(p, &s->q_dma.list) {
247 buf = list_entry(p, struct ivtv_buffer, list);
Al Virob0510f82008-05-21 00:31:41 -0300248 u32buf = (__le32 *)buf->buf;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300249
250 /* Sync Buffer */
251 ivtv_buf_sync_for_cpu(s, buf);
252
Hans Verkuil51a99c02007-08-18 15:16:00 -0300253 if (x == 0 && ivtv_use_dma(s)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300254 offset = s->dma_last_offset;
255 if (u32buf[offset / 4] != DMA_MAGIC_COOKIE)
256 {
257 for (offset = 0; offset < 64; offset++) {
258 if (u32buf[offset] == DMA_MAGIC_COOKIE) {
259 break;
260 }
261 }
262 offset *= 4;
263 if (offset == 256) {
264 IVTV_DEBUG_WARN("%s: Couldn't find start of buffer within the first 256 bytes\n", s->name);
265 offset = s->dma_last_offset;
266 }
267 if (s->dma_last_offset != offset)
268 IVTV_DEBUG_WARN("%s: offset %d -> %d\n", s->name, s->dma_last_offset, offset);
269 s->dma_last_offset = offset;
270 }
271 if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM ||
272 s->type == IVTV_DEC_STREAM_TYPE_VBI)) {
273 write_dec_sync(0, s->dma_offset - IVTV_DECODER_OFFSET);
274 }
275 else {
276 write_enc_sync(0, s->dma_offset);
277 }
278 if (offset) {
279 buf->bytesused -= offset;
280 memcpy(buf->buf, buf->buf + offset, buf->bytesused + offset);
281 }
282 *u32buf = cpu_to_le32(s->dma_backup);
283 }
284 x++;
285 /* flag byteswap ABCD -> DCBA for MPG & VBI data outside irq */
286 if (s->type == IVTV_ENC_STREAM_TYPE_MPG ||
287 s->type == IVTV_ENC_STREAM_TYPE_VBI)
Hans Verkuilf4071b82007-07-28 12:07:12 -0300288 buf->b_flags |= IVTV_F_B_NEED_BUF_SWAP;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300289 }
290 if (buf)
291 buf->bytesused += s->dma_last_offset;
292 if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) {
Trent Piepho805a4392007-10-10 05:37:41 -0300293 list_for_each_entry(buf, &s->q_dma.list, list) {
Hans Verkuildc02d502007-05-19 14:07:16 -0300294 /* Parse and Groom VBI Data */
295 s->q_dma.bytesused -= buf->bytesused;
296 ivtv_process_vbi_data(itv, buf, 0, s->type);
297 s->q_dma.bytesused += buf->bytesused;
298 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300299 if (s->id == -1) {
300 ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
301 return;
302 }
303 }
304 ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused);
305 if (s->id != -1)
306 wake_up(&s->waitq);
307}
308
309void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock)
310{
311 struct ivtv *itv = s->itv;
Ian Armstrong77aded62007-11-05 14:27:09 -0300312 struct yuv_playback_info *yi = &itv->yuv_info;
313 u8 frame = yi->draw_frame;
314 struct yuv_frame_info *f = &yi->new_frame_info[frame];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300315 struct ivtv_buffer *buf;
Ian Armstrong77aded62007-11-05 14:27:09 -0300316 u32 y_size = 720 * ((f->src_h + 31) & ~31);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300317 u32 uv_offset = offset + IVTV_YUV_BUFFER_UV_OFFSET;
318 int y_done = 0;
319 int bytes_written = 0;
320 unsigned long flags = 0;
321 int idx = 0;
322
Hans Verkuilbd58df62007-07-10 17:47:07 -0300323 IVTV_DEBUG_HI_DMA("DEC PREPARE DMA %s: %08x %08x\n", s->name, s->q_predma.bytesused, offset);
Ian Armstrong77aded62007-11-05 14:27:09 -0300324
325 /* Insert buffer block for YUV if needed */
326 if (s->type == IVTV_DEC_STREAM_TYPE_YUV && f->offset_y) {
327 if (yi->blanking_dmaptr) {
328 s->sg_pending[idx].src = yi->blanking_dmaptr;
329 s->sg_pending[idx].dst = offset;
330 s->sg_pending[idx].size = 720 * 16;
331 }
332 offset += 720 * 16;
333 idx++;
334 }
335
Trent Piepho805a4392007-10-10 05:37:41 -0300336 list_for_each_entry(buf, &s->q_predma.list, list) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300337 /* YUV UV Offset from Y Buffer */
Ian Armstrongc240ad02007-10-16 03:21:46 -0300338 if (s->type == IVTV_DEC_STREAM_TYPE_YUV && !y_done &&
339 (bytes_written + buf->bytesused) >= y_size) {
340 s->sg_pending[idx].src = buf->dma_handle;
341 s->sg_pending[idx].dst = offset;
342 s->sg_pending[idx].size = y_size - bytes_written;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300343 offset = uv_offset;
Ian Armstrongc240ad02007-10-16 03:21:46 -0300344 if (s->sg_pending[idx].size != buf->bytesused) {
345 idx++;
346 s->sg_pending[idx].src =
347 buf->dma_handle + s->sg_pending[idx - 1].size;
348 s->sg_pending[idx].dst = offset;
349 s->sg_pending[idx].size =
350 buf->bytesused - s->sg_pending[idx - 1].size;
351 offset += s->sg_pending[idx].size;
352 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300353 y_done = 1;
Ian Armstrongc240ad02007-10-16 03:21:46 -0300354 } else {
355 s->sg_pending[idx].src = buf->dma_handle;
356 s->sg_pending[idx].dst = offset;
357 s->sg_pending[idx].size = buf->bytesused;
358 offset += buf->bytesused;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300359 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300360 bytes_written += buf->bytesused;
361
362 /* Sync SG buffers */
363 ivtv_buf_sync_for_device(s, buf);
364 idx++;
365 }
Hans Verkuil37093b12007-07-28 19:45:50 -0300366 s->sg_pending_size = idx;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300367
368 /* Sync Hardware SG List of buffers */
369 ivtv_stream_sync_for_device(s);
370 if (lock)
371 spin_lock_irqsave(&itv->dma_reg_lock, flags);
372 if (!test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
373 ivtv_dma_dec_start(s);
374 }
375 else {
376 set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
377 }
378 if (lock)
379 spin_unlock_irqrestore(&itv->dma_reg_lock, flags);
380}
381
Hans Verkuil37093b12007-07-28 19:45:50 -0300382static void ivtv_dma_enc_start_xfer(struct ivtv_stream *s)
383{
384 struct ivtv *itv = s->itv;
385
386 s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src);
387 s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst);
388 s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000);
389 s->sg_processed++;
390 /* Sync Hardware SG List of buffers */
391 ivtv_stream_sync_for_device(s);
392 write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR);
393 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
Hans Verkuil2968e312008-04-26 11:22:11 -0300394 itv->dma_timer.expires = jiffies + msecs_to_jiffies(300);
Hans Verkuil9b2e5c62008-04-22 14:42:16 -0300395 add_timer(&itv->dma_timer);
Hans Verkuil37093b12007-07-28 19:45:50 -0300396}
397
398static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s)
399{
400 struct ivtv *itv = s->itv;
401
402 s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src);
403 s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst);
404 s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000);
405 s->sg_processed++;
406 /* Sync Hardware SG List of buffers */
407 ivtv_stream_sync_for_device(s);
408 write_reg(s->sg_handle, IVTV_REG_DECDMAADDR);
409 write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
Hans Verkuil2968e312008-04-26 11:22:11 -0300410 itv->dma_timer.expires = jiffies + msecs_to_jiffies(300);
Hans Verkuil9b2e5c62008-04-22 14:42:16 -0300411 add_timer(&itv->dma_timer);
Hans Verkuil37093b12007-07-28 19:45:50 -0300412}
413
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300414/* start the encoder DMA */
415static void ivtv_dma_enc_start(struct ivtv_stream *s)
416{
417 struct ivtv *itv = s->itv;
418 struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
419 int i;
420
Hans Verkuilbd58df62007-07-10 17:47:07 -0300421 IVTV_DEBUG_HI_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name);
Hans Verkuildc02d502007-05-19 14:07:16 -0300422
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300423 if (s->q_predma.bytesused)
424 ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
Hans Verkuildc02d502007-05-19 14:07:16 -0300425
426 if (ivtv_use_dma(s))
Hans Verkuil37093b12007-07-28 19:45:50 -0300427 s->sg_pending[s->sg_pending_size - 1].size += 256;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300428
429 /* If this is an MPEG stream, and VBI data is also pending, then append the
430 VBI DMA to the MPEG DMA and transfer both sets of data at once.
431
432 VBI DMA is a second class citizen compared to MPEG and mixing them together
433 will confuse the firmware (the end of a VBI DMA is seen as the end of a
434 MPEG DMA, thus effectively dropping an MPEG frame). So instead we make
435 sure we only use the MPEG DMA to transfer the VBI DMA if both are in
436 use. This way no conflicts occur. */
437 clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags);
Hans Verkuil37093b12007-07-28 19:45:50 -0300438 if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->sg_pending_size &&
439 s->sg_pending_size + s_vbi->sg_pending_size <= s->buffers) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300440 ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused);
Hans Verkuildc02d502007-05-19 14:07:16 -0300441 if (ivtv_use_dma(s_vbi))
Hans Verkuil37093b12007-07-28 19:45:50 -0300442 s_vbi->sg_pending[s_vbi->sg_pending_size - 1].size += 256;
443 for (i = 0; i < s_vbi->sg_pending_size; i++) {
444 s->sg_pending[s->sg_pending_size++] = s_vbi->sg_pending[i];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300445 }
Hans Verkuil37093b12007-07-28 19:45:50 -0300446 s_vbi->dma_offset = s_vbi->pending_offset;
447 s_vbi->sg_pending_size = 0;
Hans Verkuilf4071b82007-07-28 12:07:12 -0300448 s_vbi->dma_xfer_cnt++;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300449 set_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags);
Hans Verkuil6b1e5672007-12-02 06:56:00 -0300450 IVTV_DEBUG_HI_DMA("include DMA for %s\n", s_vbi->name);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300451 }
452
Hans Verkuilf4071b82007-07-28 12:07:12 -0300453 s->dma_xfer_cnt++;
Al Virob0510f82008-05-21 00:31:41 -0300454 memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size);
Hans Verkuil37093b12007-07-28 19:45:50 -0300455 s->sg_processing_size = s->sg_pending_size;
456 s->sg_pending_size = 0;
457 s->sg_processed = 0;
458 s->dma_offset = s->pending_offset;
459 s->dma_backup = s->pending_backup;
460 s->dma_pts = s->pending_pts;
Hans Verkuildd1e7292007-07-18 13:22:06 -0300461
Hans Verkuildc02d502007-05-19 14:07:16 -0300462 if (ivtv_use_pio(s)) {
Hans Verkuildc02d502007-05-19 14:07:16 -0300463 set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags);
464 set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
465 set_bit(IVTV_F_I_PIO, &itv->i_flags);
466 itv->cur_pio_stream = s->type;
467 }
468 else {
Hans Verkuil37093b12007-07-28 19:45:50 -0300469 itv->dma_retries = 0;
470 ivtv_dma_enc_start_xfer(s);
Hans Verkuildc02d502007-05-19 14:07:16 -0300471 set_bit(IVTV_F_I_DMA, &itv->i_flags);
472 itv->cur_dma_stream = s->type;
Hans Verkuildc02d502007-05-19 14:07:16 -0300473 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300474}
475
476static void ivtv_dma_dec_start(struct ivtv_stream *s)
477{
478 struct ivtv *itv = s->itv;
479
480 if (s->q_predma.bytesused)
481 ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
Hans Verkuil37093b12007-07-28 19:45:50 -0300482 s->dma_xfer_cnt++;
Al Virob0510f82008-05-21 00:31:41 -0300483 memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size);
Hans Verkuil37093b12007-07-28 19:45:50 -0300484 s->sg_processing_size = s->sg_pending_size;
485 s->sg_pending_size = 0;
486 s->sg_processed = 0;
487
Hans Verkuilbd58df62007-07-10 17:47:07 -0300488 IVTV_DEBUG_HI_DMA("start DMA for %s\n", s->name);
Hans Verkuil37093b12007-07-28 19:45:50 -0300489 itv->dma_retries = 0;
490 ivtv_dma_dec_start_xfer(s);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300491 set_bit(IVTV_F_I_DMA, &itv->i_flags);
492 itv->cur_dma_stream = s->type;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300493}
494
495static void ivtv_irq_dma_read(struct ivtv *itv)
496{
497 struct ivtv_stream *s = NULL;
498 struct ivtv_buffer *buf;
Hans Verkuil37093b12007-07-28 19:45:50 -0300499 int hw_stream_type = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300500
Hans Verkuilbd58df62007-07-10 17:47:07 -0300501 IVTV_DEBUG_HI_IRQ("DEC DMA READ\n");
Hans Verkuil9b2e5c62008-04-22 14:42:16 -0300502
503 del_timer(&itv->dma_timer);
504
505 if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream < 0)
Hans Verkuil37093b12007-07-28 19:45:50 -0300506 return;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300507
Hans Verkuil37093b12007-07-28 19:45:50 -0300508 if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
509 s = &itv->streams[itv->cur_dma_stream];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300510 ivtv_stream_sync_for_cpu(s);
511
Hans Verkuil37093b12007-07-28 19:45:50 -0300512 if (read_reg(IVTV_REG_DMASTATUS) & 0x14) {
513 IVTV_DEBUG_WARN("DEC DMA ERROR %x (xfer %d of %d, retry %d)\n",
514 read_reg(IVTV_REG_DMASTATUS),
515 s->sg_processed, s->sg_processing_size, itv->dma_retries);
516 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
517 if (itv->dma_retries == 3) {
Hans Verkuile17a06b2007-08-18 15:48:42 -0300518 /* Too many retries, give up on this frame */
Hans Verkuil37093b12007-07-28 19:45:50 -0300519 itv->dma_retries = 0;
Hans Verkuile17a06b2007-08-18 15:48:42 -0300520 s->sg_processed = s->sg_processing_size;
Hans Verkuil37093b12007-07-28 19:45:50 -0300521 }
522 else {
523 /* Retry, starting with the first xfer segment.
524 Just retrying the current segment is not sufficient. */
525 s->sg_processed = 0;
526 itv->dma_retries++;
527 }
528 }
529 if (s->sg_processed < s->sg_processing_size) {
530 /* DMA next buffer */
531 ivtv_dma_dec_start_xfer(s);
532 return;
533 }
534 if (s->type == IVTV_DEC_STREAM_TYPE_YUV)
535 hw_stream_type = 2;
536 IVTV_DEBUG_HI_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused);
537
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300538 /* For some reason must kick the firmware, like PIO mode,
539 I think this tells the firmware we are done and the size
540 of the xfer so it can calculate what we need next.
541 I think we can do this part ourselves but would have to
542 fully calculate xfer info ourselves and not use interrupts
543 */
544 ivtv_vapi(itv, CX2341X_DEC_SCHED_DMA_FROM_HOST, 3, 0, s->q_dma.bytesused,
545 hw_stream_type);
546
547 /* Free last DMA call */
548 while ((buf = ivtv_dequeue(s, &s->q_dma)) != NULL) {
549 ivtv_buf_sync_for_cpu(s, buf);
550 ivtv_enqueue(s, buf, &s->q_free);
551 }
552 wake_up(&s->waitq);
553 }
554 clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
555 clear_bit(IVTV_F_I_DMA, &itv->i_flags);
556 itv->cur_dma_stream = -1;
557 wake_up(&itv->dma_waitq);
558}
559
560static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
561{
562 u32 data[CX2341X_MBOX_MAX_DATA];
563 struct ivtv_stream *s;
564
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300565 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data);
Hans Verkuil37093b12007-07-28 19:45:50 -0300566 IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream);
Hans Verkuil9b2e5c62008-04-22 14:42:16 -0300567
568 del_timer(&itv->dma_timer);
569
570 if (itv->cur_dma_stream < 0)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300571 return;
Hans Verkuil9b2e5c62008-04-22 14:42:16 -0300572
Hans Verkuil37093b12007-07-28 19:45:50 -0300573 s = &itv->streams[itv->cur_dma_stream];
574 ivtv_stream_sync_for_cpu(s);
575
576 if (data[0] & 0x18) {
577 IVTV_DEBUG_WARN("ENC DMA ERROR %x (offset %08x, xfer %d of %d, retry %d)\n", data[0],
578 s->dma_offset, s->sg_processed, s->sg_processing_size, itv->dma_retries);
579 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
580 if (itv->dma_retries == 3) {
Hans Verkuile17a06b2007-08-18 15:48:42 -0300581 /* Too many retries, give up on this frame */
Hans Verkuil37093b12007-07-28 19:45:50 -0300582 itv->dma_retries = 0;
Hans Verkuile17a06b2007-08-18 15:48:42 -0300583 s->sg_processed = s->sg_processing_size;
Hans Verkuil37093b12007-07-28 19:45:50 -0300584 }
585 else {
586 /* Retry, starting with the first xfer segment.
587 Just retrying the current segment is not sufficient. */
588 s->sg_processed = 0;
589 itv->dma_retries++;
590 }
591 }
592 if (s->sg_processed < s->sg_processing_size) {
593 /* DMA next buffer */
594 ivtv_dma_enc_start_xfer(s);
595 return;
596 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300597 clear_bit(IVTV_F_I_DMA, &itv->i_flags);
598 itv->cur_dma_stream = -1;
599 dma_post(s);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300600 if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300601 s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300602 dma_post(s);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300603 }
Hans Verkuil37093b12007-07-28 19:45:50 -0300604 s->sg_processing_size = 0;
605 s->sg_processed = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300606 wake_up(&itv->dma_waitq);
607}
608
Hans Verkuildc02d502007-05-19 14:07:16 -0300609static void ivtv_irq_enc_pio_complete(struct ivtv *itv)
610{
611 struct ivtv_stream *s;
612
613 if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS) {
614 itv->cur_pio_stream = -1;
615 return;
616 }
617 s = &itv->streams[itv->cur_pio_stream];
Hans Verkuilbd58df62007-07-10 17:47:07 -0300618 IVTV_DEBUG_HI_IRQ("ENC PIO COMPLETE %s\n", s->name);
Hans Verkuildc02d502007-05-19 14:07:16 -0300619 clear_bit(IVTV_F_I_PIO, &itv->i_flags);
620 itv->cur_pio_stream = -1;
621 dma_post(s);
622 if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
623 ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 0);
624 else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
625 ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 1);
626 else if (s->type == IVTV_ENC_STREAM_TYPE_PCM)
627 ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2);
628 clear_bit(IVTV_F_I_PIO, &itv->i_flags);
629 if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
Hans Verkuildc02d502007-05-19 14:07:16 -0300630 s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
Hans Verkuildc02d502007-05-19 14:07:16 -0300631 dma_post(s);
Hans Verkuildc02d502007-05-19 14:07:16 -0300632 }
633 wake_up(&itv->dma_waitq);
634}
635
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300636static void ivtv_irq_dma_err(struct ivtv *itv)
637{
638 u32 data[CX2341X_MBOX_MAX_DATA];
639
640 del_timer(&itv->dma_timer);
641 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, data);
642 IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1],
Hans Verkuil37093b12007-07-28 19:45:50 -0300643 read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
644 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300645 if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) &&
646 itv->cur_dma_stream >= 0 && itv->cur_dma_stream < IVTV_MAX_STREAMS) {
647 struct ivtv_stream *s = &itv->streams[itv->cur_dma_stream];
648
649 /* retry */
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300650 if (s->type >= IVTV_DEC_STREAM_TYPE_MPG)
651 ivtv_dma_dec_start(s);
652 else
653 ivtv_dma_enc_start(s);
654 return;
655 }
Hans Verkuil37093b12007-07-28 19:45:50 -0300656 if (test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
657 ivtv_udma_start(itv);
658 return;
659 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300660 clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
661 clear_bit(IVTV_F_I_DMA, &itv->i_flags);
662 itv->cur_dma_stream = -1;
663 wake_up(&itv->dma_waitq);
664}
665
666static void ivtv_irq_enc_start_cap(struct ivtv *itv)
667{
668 u32 data[CX2341X_MBOX_MAX_DATA];
669 struct ivtv_stream *s;
670
671 /* Get DMA destination and size arguments from card */
672 ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, data);
Hans Verkuilbd58df62007-07-10 17:47:07 -0300673 IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300674
675 if (data[0] > 2 || data[1] == 0 || data[2] == 0) {
676 IVTV_DEBUG_WARN("Unknown input: %08x %08x %08x\n",
677 data[0], data[1], data[2]);
678 return;
679 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300680 s = &itv->streams[ivtv_stream_map[data[0]]];
681 if (!stream_enc_dma_append(s, data)) {
Hans Verkuildc02d502007-05-19 14:07:16 -0300682 set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300683 }
684}
685
686static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
687{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300688 u32 data[CX2341X_MBOX_MAX_DATA];
689 struct ivtv_stream *s;
690
Hans Verkuilbd58df62007-07-10 17:47:07 -0300691 IVTV_DEBUG_HI_IRQ("ENC START VBI CAP\n");
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300692 s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
693
Hans Verkuild526afe2008-09-03 16:47:14 -0300694 if (!stream_enc_dma_append(s, data))
Hans Verkuildc02d502007-05-19 14:07:16 -0300695 set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300696}
697
Hans Verkuildc02d502007-05-19 14:07:16 -0300698static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300699{
700 u32 data[CX2341X_MBOX_MAX_DATA];
701 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];
702
Hans Verkuilbd58df62007-07-10 17:47:07 -0300703 IVTV_DEBUG_HI_IRQ("DEC VBI REINSERT\n");
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300704 if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) &&
705 !stream_enc_dma_append(s, data)) {
Hans Verkuildc02d502007-05-19 14:07:16 -0300706 set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300707 }
708}
709
710static void ivtv_irq_dec_data_req(struct ivtv *itv)
711{
712 u32 data[CX2341X_MBOX_MAX_DATA];
713 struct ivtv_stream *s;
714
715 /* YUV or MPG */
716 ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, data);
717
718 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) {
Ian Armstrong77aded62007-11-05 14:27:09 -0300719 itv->dma_data_req_size =
720 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
721 itv->dma_data_req_offset = data[1];
722 if (atomic_read(&itv->yuv_info.next_dma_frame) >= 0)
723 ivtv_yuv_frame_complete(itv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300724 s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
725 }
726 else {
Richard Knutsson14d5deb2007-12-08 10:35:06 -0300727 itv->dma_data_req_size = min_t(u32, data[2], 0x10000);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300728 itv->dma_data_req_offset = data[1];
729 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
730 }
Hans Verkuilbd58df62007-07-10 17:47:07 -0300731 IVTV_DEBUG_HI_IRQ("DEC DATA REQ %s: %d %08x %u\n", s->name, s->q_full.bytesused,
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300732 itv->dma_data_req_offset, itv->dma_data_req_size);
733 if (itv->dma_data_req_size == 0 || s->q_full.bytesused < itv->dma_data_req_size) {
734 set_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
735 }
736 else {
Ian Armstrong77aded62007-11-05 14:27:09 -0300737 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
738 ivtv_yuv_setup_stream_frame(itv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300739 clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
740 ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, itv->dma_data_req_size);
741 ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + IVTV_DECODER_OFFSET, 0);
742 }
743}
744
745static void ivtv_irq_vsync(struct ivtv *itv)
746{
747 /* The vsync interrupt is unusual in that it won't clear until
748 * the end of the first line for the current field, at which
749 * point it clears itself. This can result in repeated vsync
750 * interrupts, or a missed vsync. Read some of the registers
751 * to determine the line being displayed and ensure we handle
752 * one vsync per frame.
753 */
754 unsigned int frame = read_reg(0x28c0) & 1;
Ian Armstronga3e5f5e2007-10-20 14:52:55 -0300755 struct yuv_playback_info *yi = &itv->yuv_info;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300756 int last_dma_frame = atomic_read(&itv->yuv_info.next_dma_frame);
Ian Armstrong3b5c1c82007-10-22 14:24:26 -0300757 struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300758
759 if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n");
760
Ian Armstrong3b5c1c82007-10-22 14:24:26 -0300761 if (((frame ^ f->sync_field) == 0 &&
762 ((itv->last_vsync_field & 1) ^ f->sync_field)) ||
763 (frame != (itv->last_vsync_field & 1) && !f->interlaced)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300764 int next_dma_frame = last_dma_frame;
765
Ian Armstrong3b5c1c82007-10-22 14:24:26 -0300766 if (!(f->interlaced && f->delay && yi->fields_lapsed < 1)) {
Ian Armstronga3e5f5e2007-10-20 14:52:55 -0300767 if (next_dma_frame >= 0 && next_dma_frame != atomic_read(&yi->next_fill_frame)) {
Ian Armstrongbfd7bea2007-08-03 10:01:39 -0300768 write_reg(yuv_offset[next_dma_frame] >> 4, 0x82c);
769 write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x830);
770 write_reg(yuv_offset[next_dma_frame] >> 4, 0x834);
771 write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x838);
Ian Armstronga3e5f5e2007-10-20 14:52:55 -0300772 next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS;
773 atomic_set(&yi->next_dma_frame, next_dma_frame);
774 yi->fields_lapsed = -1;
Ian Armstrongbfd7bea2007-08-03 10:01:39 -0300775 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300776 }
777 }
Hans Verkuila158f352007-08-23 11:31:57 -0300778 if (frame != (itv->last_vsync_field & 1)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300779 struct ivtv_stream *s = ivtv_get_output_stream(itv);
780
Hans Verkuila158f352007-08-23 11:31:57 -0300781 itv->last_vsync_field += 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300782 if (frame == 0) {
783 clear_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
784 clear_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags);
785 }
786 else {
787 set_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags);
788 }
789 if (test_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags)) {
790 set_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags);
791 wake_up(&itv->event_waitq);
792 }
793 wake_up(&itv->vsync_waitq);
794 if (s)
795 wake_up(&s->waitq);
796
797 /* Send VBI to saa7127 */
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300798 if (frame && (itv->output_mode == OUT_PASSTHROUGH ||
799 test_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags) ||
800 test_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags) ||
801 test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags))) {
Hans Verkuil1e13f9e2007-03-10 06:52:02 -0300802 set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags);
Hans Verkuildc02d502007-05-19 14:07:16 -0300803 set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
Hans Verkuil1e13f9e2007-03-10 06:52:02 -0300804 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300805
806 /* Check if we need to update the yuv registers */
Ian Armstrong3b5c1c82007-10-22 14:24:26 -0300807 if ((yi->yuv_forced_update || f->update) && last_dma_frame != -1) {
808 if (!f->update) {
Ian Armstrong166983c2007-10-21 08:09:10 -0300809 last_dma_frame = (u8)(last_dma_frame - 1) % IVTV_YUV_BUFFERS;
Ian Armstrong3b5c1c82007-10-22 14:24:26 -0300810 f = &yi->new_frame_info[last_dma_frame];
811 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300812
Ian Armstrong3b5c1c82007-10-22 14:24:26 -0300813 if (f->src_w) {
Ian Armstronga3e5f5e2007-10-20 14:52:55 -0300814 yi->update_frame = last_dma_frame;
Ian Armstrong3b5c1c82007-10-22 14:24:26 -0300815 f->update = 0;
Ian Armstronga3e5f5e2007-10-20 14:52:55 -0300816 yi->yuv_forced_update = 0;
Hans Verkuil1e13f9e2007-03-10 06:52:02 -0300817 set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags);
Hans Verkuildc02d502007-05-19 14:07:16 -0300818 set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300819 }
820 }
Ian Armstrongbfd7bea2007-08-03 10:01:39 -0300821
Ian Armstronga3e5f5e2007-10-20 14:52:55 -0300822 yi->fields_lapsed++;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300823 }
824}
825
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300826#define IVTV_IRQ_DMA (IVTV_IRQ_DMA_READ | IVTV_IRQ_ENC_DMA_COMPLETE | IVTV_IRQ_DMA_ERR | IVTV_IRQ_ENC_START_CAP | IVTV_IRQ_ENC_VBI_CAP | IVTV_IRQ_DEC_DATA_REQ | IVTV_IRQ_DEC_VBI_RE_INSERT)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300827
828irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
829{
830 struct ivtv *itv = (struct ivtv *)dev_id;
831 u32 combo;
832 u32 stat;
833 int i;
834 u8 vsync_force = 0;
835
836 spin_lock(&itv->dma_reg_lock);
837 /* get contents of irq status register */
838 stat = read_reg(IVTV_REG_IRQSTATUS);
839
840 combo = ~itv->irqmask & stat;
841
842 /* Clear out IRQ */
843 if (combo) write_reg(combo, IVTV_REG_IRQSTATUS);
844
845 if (0 == combo) {
846 /* The vsync interrupt is unusual and clears itself. If we
847 * took too long, we may have missed it. Do some checks
848 */
849 if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) {
850 /* vsync is enabled, see if we're in a new field */
Hans Verkuila158f352007-08-23 11:31:57 -0300851 if ((itv->last_vsync_field & 1) != (read_reg(0x28c0) & 1)) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300852 /* New field, looks like we missed it */
853 IVTV_DEBUG_YUV("VSync interrupt missed %d\n",read_reg(0x28c0)>>16);
854 vsync_force = 1;
855 }
856 }
857
858 if (!vsync_force) {
859 /* No Vsync expected, wasn't for us */
860 spin_unlock(&itv->dma_reg_lock);
861 return IRQ_NONE;
862 }
863 }
864
865 /* Exclude interrupts noted below from the output, otherwise the log is flooded with
866 these messages */
867 if (combo & ~0xff6d0400)
Hans Verkuilbd58df62007-07-10 17:47:07 -0300868 IVTV_DEBUG_HI_IRQ("======= valid IRQ bits: 0x%08x ======\n", combo);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300869
870 if (combo & IVTV_IRQ_DEC_DMA_COMPLETE) {
Hans Verkuilbd58df62007-07-10 17:47:07 -0300871 IVTV_DEBUG_HI_IRQ("DEC DMA COMPLETE\n");
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300872 }
873
874 if (combo & IVTV_IRQ_DMA_READ) {
875 ivtv_irq_dma_read(itv);
876 }
877
878 if (combo & IVTV_IRQ_ENC_DMA_COMPLETE) {
879 ivtv_irq_enc_dma_complete(itv);
880 }
881
Hans Verkuildc02d502007-05-19 14:07:16 -0300882 if (combo & IVTV_IRQ_ENC_PIO_COMPLETE) {
883 ivtv_irq_enc_pio_complete(itv);
884 }
885
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300886 if (combo & IVTV_IRQ_DMA_ERR) {
887 ivtv_irq_dma_err(itv);
888 }
889
890 if (combo & IVTV_IRQ_ENC_START_CAP) {
891 ivtv_irq_enc_start_cap(itv);
892 }
893
894 if (combo & IVTV_IRQ_ENC_VBI_CAP) {
895 ivtv_irq_enc_vbi_cap(itv);
896 }
897
898 if (combo & IVTV_IRQ_DEC_VBI_RE_INSERT) {
Hans Verkuildc02d502007-05-19 14:07:16 -0300899 ivtv_irq_dec_vbi_reinsert(itv);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300900 }
901
902 if (combo & IVTV_IRQ_ENC_EOS) {
903 IVTV_DEBUG_IRQ("ENC EOS\n");
904 set_bit(IVTV_F_I_EOS, &itv->i_flags);
Hans Verkuilfd8b2812007-08-23 10:13:15 -0300905 wake_up(&itv->eos_waitq);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300906 }
907
908 if (combo & IVTV_IRQ_DEC_DATA_REQ) {
909 ivtv_irq_dec_data_req(itv);
910 }
911
912 /* Decoder Vertical Sync - We can't rely on 'combo', so check if vsync enabled */
913 if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) {
914 ivtv_irq_vsync(itv);
915 }
916
917 if (combo & IVTV_IRQ_ENC_VIM_RST) {
918 IVTV_DEBUG_IRQ("VIM RST\n");
919 /*ivtv_vapi(itv, CX2341X_ENC_REFRESH_INPUT, 0); */
920 }
921
922 if (combo & IVTV_IRQ_DEC_AUD_MODE_CHG) {
923 IVTV_DEBUG_INFO("Stereo mode changed\n");
924 }
925
926 if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
Hans Verkuil33bc4de2007-08-18 11:36:09 -0300927 itv->irq_rr_idx++;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300928 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
Hans Verkuil33bc4de2007-08-18 11:36:09 -0300929 int idx = (i + itv->irq_rr_idx) % IVTV_MAX_STREAMS;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300930 struct ivtv_stream *s = &itv->streams[idx];
931
932 if (!test_and_clear_bit(IVTV_F_S_DMA_PENDING, &s->s_flags))
933 continue;
934 if (s->type >= IVTV_DEC_STREAM_TYPE_MPG)
935 ivtv_dma_dec_start(s);
936 else
937 ivtv_dma_enc_start(s);
938 break;
939 }
940 if (i == IVTV_MAX_STREAMS && test_and_clear_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags)) {
941 ivtv_udma_start(itv);
942 }
943 }
944
Hans Verkuildc02d502007-05-19 14:07:16 -0300945 if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) {
Hans Verkuil33bc4de2007-08-18 11:36:09 -0300946 itv->irq_rr_idx++;
Hans Verkuildc02d502007-05-19 14:07:16 -0300947 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
Hans Verkuil33bc4de2007-08-18 11:36:09 -0300948 int idx = (i + itv->irq_rr_idx) % IVTV_MAX_STREAMS;
Hans Verkuildc02d502007-05-19 14:07:16 -0300949 struct ivtv_stream *s = &itv->streams[idx];
950
951 if (!test_and_clear_bit(IVTV_F_S_PIO_PENDING, &s->s_flags))
952 continue;
953 if (s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type < IVTV_DEC_STREAM_TYPE_MPG)
954 ivtv_dma_enc_start(s);
955 break;
956 }
957 }
958
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300959 if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags)) {
Hans Verkuildc02d502007-05-19 14:07:16 -0300960 queue_work(itv->irq_work_queues, &itv->irq_work_queue);
Hans Verkuil2f3a9892007-08-25 14:11:23 -0300961 }
Hans Verkuildc02d502007-05-19 14:07:16 -0300962
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300963 spin_unlock(&itv->dma_reg_lock);
964
965 /* If we've just handled a 'forced' vsync, it's safest to say it
966 * wasn't ours. Another device may have triggered it at just
967 * the right time.
968 */
969 return vsync_force ? IRQ_NONE : IRQ_HANDLED;
970}
971
972void ivtv_unfinished_dma(unsigned long arg)
973{
974 struct ivtv *itv = (struct ivtv *)arg;
975
976 if (!test_bit(IVTV_F_I_DMA, &itv->i_flags))
977 return;
978 IVTV_ERR("DMA TIMEOUT %08x %d\n", read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);
979
980 write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
981 clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
982 clear_bit(IVTV_F_I_DMA, &itv->i_flags);
983 itv->cur_dma_stream = -1;
984 wake_up(&itv->dma_waitq);
985}