/* interrupt handling
    Copyright (C) 2003-2004  Kevin Thayer <nufan_wfk at yahoo.com>
    Copyright (C) 2004  Chris Kennedy <c@groovy.org>
    Copyright (C) 2005-2007  Hans Verkuil <hverkuil@xs4all.nl>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "ivtv-driver.h"
#include "ivtv-queue.h"
#include "ivtv-udma.h"
#include "ivtv-irq.h"
#include "ivtv-mailbox.h"
#include "ivtv-vbi.h"
#include "ivtv-yuv.h"
#include <media/v4l2-event.h>

#define DMA_MAGIC_COOKIE 0x000001fe

static void ivtv_dma_dec_start(struct ivtv_stream *s);

static const int ivtv_stream_map[] = {
	IVTV_ENC_STREAM_TYPE_MPG,
	IVTV_ENC_STREAM_TYPE_YUV,
	IVTV_ENC_STREAM_TYPE_PCM,
	IVTV_ENC_STREAM_TYPE_VBI,
};

static void ivtv_pcm_work_handler(struct ivtv *itv)
{
	struct ivtv_stream *s = &itv->streams[IVTV_ENC_STREAM_TYPE_PCM];
	struct ivtv_buffer *buf;

	/* Pass the PCM data to ivtv-alsa */

	while (1) {
		/*
		 * Users should not be using both the ALSA and V4L2 PCM audio
		 * capture interfaces at the same time.  If the user is doing
		 * this, there maybe a buffer in q_io to grab, use, and put
		 * back in rotation.
		 */
		buf = ivtv_dequeue(s, &s->q_io);
		if (buf == NULL)
			buf = ivtv_dequeue(s, &s->q_full);
		if (buf == NULL)
			break;

		if (buf->readpos < buf->bytesused)
			itv->pcm_announce_callback(itv->alsa,
				(u8 *)(buf->buf + buf->readpos),
				(size_t)(buf->bytesused - buf->readpos));

		ivtv_enqueue(s, buf, &s->q_free);
	}
}

static void ivtv_pio_work_handler(struct ivtv *itv)
{
	struct ivtv_stream *s = &itv->streams[itv->cur_pio_stream];
	struct ivtv_buffer *buf;
	int i = 0;

	IVTV_DEBUG_HI_DMA("ivtv_pio_work_handler\n");
	if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS ||
			s->vdev == NULL || !ivtv_use_pio(s)) {
		itv->cur_pio_stream = -1;
		/* trigger PIO complete user interrupt */
		write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
		return;
	}
	IVTV_DEBUG_HI_DMA("Process PIO %s\n", s->name);
	list_for_each_entry(buf, &s->q_dma.list, list) {
		u32 size = s->sg_processing[i].size & 0x3ffff;

		/* Copy the data from the card to the buffer */
		if (s->type == IVTV_DEC_STREAM_TYPE_VBI) {
			memcpy_fromio(buf->buf, itv->dec_mem + s->sg_processing[i].src - IVTV_DECODER_OFFSET, size);
		}
		else {
			memcpy_fromio(buf->buf, itv->enc_mem + s->sg_processing[i].src, size);
		}
		i++;
		if (i == s->sg_processing_size)
			break;
	}
	write_reg(IVTV_IRQ_ENC_PIO_COMPLETE, 0x44);
}

void ivtv_irq_work_handler(struct kthread_work *work)
{
	struct ivtv *itv = container_of(work, struct ivtv, irq_work);

	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags))
		ivtv_pio_work_handler(itv);

	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags))
		ivtv_vbi_work_handler(itv);

	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags))
		ivtv_yuv_work_handler(itv);

	if (test_and_clear_bit(IVTV_F_I_WORK_HANDLER_PCM, &itv->i_flags))
		ivtv_pcm_work_handler(itv);
}

/* Determine the required DMA size, setup enough buffers in the predma queue and
   actually copy the data from the card to the buffers in case a PIO transfer is
   required for this stream.
 */
static int stream_enc_dma_append(struct ivtv_stream *s, u32 data[CX2341X_MBOX_MAX_DATA])
{
	struct ivtv *itv = s->itv;
	struct ivtv_buffer *buf;
	u32 bytes_needed = 0;
	u32 offset, size;
	u32 UVoffset = 0, UVsize = 0;
	int skip_bufs = s->q_predma.buffers;
	int idx = s->sg_pending_size;
	int rc;

	/* sanity checks */
	if (s->vdev == NULL) {
		IVTV_DEBUG_WARN("Stream %s not started\n", s->name);
		return -1;
	}
	if (!test_bit(IVTV_F_S_CLAIMED, &s->s_flags)) {
		IVTV_DEBUG_WARN("Stream %s not open\n", s->name);
		return -1;
	}

	/* determine offset, size and PTS for the various streams */
	switch (s->type) {
		case IVTV_ENC_STREAM_TYPE_MPG:
			offset = data[1];
			size = data[2];
			s->pending_pts = 0;
			break;

		case IVTV_ENC_STREAM_TYPE_YUV:
			offset = data[1];
			size = data[2];
			UVoffset = data[3];
			UVsize = data[4];
			s->pending_pts = ((u64) data[5] << 32) | data[6];
			break;

		case IVTV_ENC_STREAM_TYPE_PCM:
			offset = data[1] + 12;
			size = data[2] - 12;
			s->pending_pts = read_dec(offset - 8) |
				((u64)(read_dec(offset - 12)) << 32);
			if (itv->has_cx23415)
				offset += IVTV_DECODER_OFFSET;
			break;

		case IVTV_ENC_STREAM_TYPE_VBI:
			size = itv->vbi.enc_size * itv->vbi.fpi;
			offset = read_enc(itv->vbi.enc_start - 4) + 12;
			if (offset == 12) {
				IVTV_DEBUG_INFO("VBI offset == 0\n");
				return -1;
			}
			s->pending_pts = read_enc(offset - 4) | ((u64)read_enc(offset - 8) << 32);
			break;

		case IVTV_DEC_STREAM_TYPE_VBI:
			size = read_dec(itv->vbi.dec_start + 4) + 8;
			offset = read_dec(itv->vbi.dec_start) + itv->vbi.dec_start;
			s->pending_pts = 0;
			offset += IVTV_DECODER_OFFSET;
			break;
		default:
			/* shouldn't happen */
			return -1;
	}

	/* if this is the start of the DMA then fill in the magic cookie */
	if (s->sg_pending_size == 0 && ivtv_use_dma(s)) {
		if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM ||
		    s->type == IVTV_DEC_STREAM_TYPE_VBI)) {
			s->pending_backup = read_dec(offset - IVTV_DECODER_OFFSET);
			write_dec_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset - IVTV_DECODER_OFFSET);
		}
		else {
			s->pending_backup = read_enc(offset);
			write_enc_sync(cpu_to_le32(DMA_MAGIC_COOKIE), offset);
		}
		s->pending_offset = offset;
	}

	bytes_needed = size;
	if (s->type == IVTV_ENC_STREAM_TYPE_YUV) {
		/* The size for the Y samples needs to be rounded upwards to a
		   multiple of the buf_size. The UV samples then start in the
		   next buffer. */
		bytes_needed = s->buf_size * ((bytes_needed + s->buf_size - 1) / s->buf_size);
		bytes_needed += UVsize;
	}

	IVTV_DEBUG_HI_DMA("%s %s: 0x%08x bytes at 0x%08x\n",
		ivtv_use_pio(s) ? "PIO" : "DMA", s->name, bytes_needed, offset);

	rc = ivtv_queue_move(s, &s->q_free, &s->q_full, &s->q_predma, bytes_needed);
	if (rc < 0) { /* Insufficient buffers */
		IVTV_DEBUG_WARN("Cannot obtain %d bytes for %s data transfer\n",
				bytes_needed, s->name);
		return -1;
	}
	if (rc && !s->buffers_stolen && test_bit(IVTV_F_S_APPL_IO, &s->s_flags)) {
		IVTV_WARN("All %s stream buffers are full. Dropping data.\n", s->name);
		IVTV_WARN("Cause: the application is not reading fast enough.\n");
	}
	s->buffers_stolen = rc;

	/* got the buffers, now fill in sg_pending */
	buf = list_entry(s->q_predma.list.next, struct ivtv_buffer, list);
	memset(buf->buf, 0, 128);
	list_for_each_entry(buf, &s->q_predma.list, list) {
		if (skip_bufs-- > 0)
			continue;
		s->sg_pending[idx].dst = buf->dma_handle;
		s->sg_pending[idx].src = offset;
		s->sg_pending[idx].size = s->buf_size;
		buf->bytesused = min(size, s->buf_size);
		buf->dma_xfer_cnt = s->dma_xfer_cnt;

		s->q_predma.bytesused += buf->bytesused;
		size -= buf->bytesused;
		offset += s->buf_size;

		/* Sync SG buffers */
		ivtv_buf_sync_for_device(s, buf);

		if (size == 0) {	/* YUV */
			/* process the UV section */
			offset = UVoffset;
			size = UVsize;
		}
		idx++;
	}
	s->sg_pending_size = idx;
	return 0;
}

static void dma_post(struct ivtv_stream *s)
{
	struct ivtv *itv = s->itv;
	struct ivtv_buffer *buf = NULL;
	struct list_head *p;
	u32 offset;
	__le32 *u32buf;
	int x = 0;

	IVTV_DEBUG_HI_DMA("%s %s completed (%x)\n", ivtv_use_pio(s) ? "PIO" : "DMA",
			s->name, s->dma_offset);
	list_for_each(p, &s->q_dma.list) {
		buf = list_entry(p, struct ivtv_buffer, list);
		u32buf = (__le32 *)buf->buf;

		/* Sync Buffer */
		ivtv_buf_sync_for_cpu(s, buf);

		if (x == 0 && ivtv_use_dma(s)) {
			offset = s->dma_last_offset;
			if (u32buf[offset / 4] != DMA_MAGIC_COOKIE)
			{
				for (offset = 0; offset < 64; offset++) {
					if (u32buf[offset] == DMA_MAGIC_COOKIE) {
						break;
					}
				}
				offset *= 4;
				if (offset == 256) {
					IVTV_DEBUG_WARN("%s: Couldn't find start of buffer within the first 256 bytes\n", s->name);
					offset = s->dma_last_offset;
				}
				if (s->dma_last_offset != offset)
					IVTV_DEBUG_WARN("%s: offset %d -> %d\n", s->name, s->dma_last_offset, offset);
				s->dma_last_offset = offset;
			}
			if (itv->has_cx23415 && (s->type == IVTV_ENC_STREAM_TYPE_PCM ||
						s->type == IVTV_DEC_STREAM_TYPE_VBI)) {
				write_dec_sync(0, s->dma_offset - IVTV_DECODER_OFFSET);
			}
			else {
				write_enc_sync(0, s->dma_offset);
			}
			if (offset) {
				buf->bytesused -= offset;
				memcpy(buf->buf, buf->buf + offset, buf->bytesused + offset);
			}
			*u32buf = cpu_to_le32(s->dma_backup);
		}
		x++;
		/* flag byteswap ABCD -> DCBA for MPG & VBI data outside irq */
		if (s->type == IVTV_ENC_STREAM_TYPE_MPG ||
		    s->type == IVTV_ENC_STREAM_TYPE_VBI)
			buf->b_flags |= IVTV_F_B_NEED_BUF_SWAP;
	}
	if (buf)
		buf->bytesused += s->dma_last_offset;
	if (buf && s->type == IVTV_DEC_STREAM_TYPE_VBI) {
		list_for_each_entry(buf, &s->q_dma.list, list) {
			/* Parse and Groom VBI Data */
			s->q_dma.bytesused -= buf->bytesused;
			ivtv_process_vbi_data(itv, buf, 0, s->type);
			s->q_dma.bytesused += buf->bytesused;
		}
		if (s->fh == NULL) {
			ivtv_queue_move(s, &s->q_dma, NULL, &s->q_free, 0);
			return;
		}
	}

	ivtv_queue_move(s, &s->q_dma, NULL, &s->q_full, s->q_dma.bytesused);

	if (s->type == IVTV_ENC_STREAM_TYPE_PCM &&
	    itv->pcm_announce_callback != NULL) {
		/*
		 * Set up the work handler to pass the data to ivtv-alsa.
		 *
		 * We just use q_full and let the work handler race with users
		 * making ivtv-fileops.c calls on the PCM device node.
		 *
		 * Users should not be using both the ALSA and V4L2 PCM audio
		 * capture interfaces at the same time.  If the user does this,
		 * fragments of data will just go out each interface as they
		 * race for PCM data.
		 */
		set_bit(IVTV_F_I_WORK_HANDLER_PCM, &itv->i_flags);
		set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
	}

	if (s->fh)
		wake_up(&s->waitq);
}

void ivtv_dma_stream_dec_prepare(struct ivtv_stream *s, u32 offset, int lock)
{
	struct ivtv *itv = s->itv;
	struct yuv_playback_info *yi = &itv->yuv_info;
	u8 frame = yi->draw_frame;
	struct yuv_frame_info *f = &yi->new_frame_info[frame];
	struct ivtv_buffer *buf;
	u32 y_size = 720 * ((f->src_h + 31) & ~31);
	u32 uv_offset = offset + IVTV_YUV_BUFFER_UV_OFFSET;
	int y_done = 0;
	int bytes_written = 0;
	unsigned long flags = 0;
	int idx = 0;

	IVTV_DEBUG_HI_DMA("DEC PREPARE DMA %s: %08x %08x\n", s->name, s->q_predma.bytesused, offset);

	/* Insert buffer block for YUV if needed */
	if (s->type == IVTV_DEC_STREAM_TYPE_YUV && f->offset_y) {
		if (yi->blanking_dmaptr) {
			s->sg_pending[idx].src = yi->blanking_dmaptr;
			s->sg_pending[idx].dst = offset;
			s->sg_pending[idx].size = 720 * 16;
		}
		offset += 720 * 16;
		idx++;
	}

	list_for_each_entry(buf, &s->q_predma.list, list) {
		/* YUV UV Offset from Y Buffer */
		if (s->type == IVTV_DEC_STREAM_TYPE_YUV && !y_done &&
				(bytes_written + buf->bytesused) >= y_size) {
			s->sg_pending[idx].src = buf->dma_handle;
			s->sg_pending[idx].dst = offset;
			s->sg_pending[idx].size = y_size - bytes_written;
			offset = uv_offset;
			if (s->sg_pending[idx].size != buf->bytesused) {
				idx++;
				s->sg_pending[idx].src =
				  buf->dma_handle + s->sg_pending[idx - 1].size;
				s->sg_pending[idx].dst = offset;
				s->sg_pending[idx].size =
				   buf->bytesused - s->sg_pending[idx - 1].size;
				offset += s->sg_pending[idx].size;
			}
			y_done = 1;
		} else {
			s->sg_pending[idx].src = buf->dma_handle;
			s->sg_pending[idx].dst = offset;
			s->sg_pending[idx].size = buf->bytesused;
			offset += buf->bytesused;
		}
		bytes_written += buf->bytesused;

		/* Sync SG buffers */
		ivtv_buf_sync_for_device(s, buf);
		idx++;
	}
	s->sg_pending_size = idx;

	/* Sync Hardware SG List of buffers */
	ivtv_stream_sync_for_device(s);
	if (lock)
		spin_lock_irqsave(&itv->dma_reg_lock, flags);
	if (!test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
		ivtv_dma_dec_start(s);
	}
	else {
		set_bit(IVTV_F_S_DMA_PENDING, &s->s_flags);
	}
	if (lock)
		spin_unlock_irqrestore(&itv->dma_reg_lock, flags);
}

static void ivtv_dma_enc_start_xfer(struct ivtv_stream *s)
{
	struct ivtv *itv = s->itv;

	s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src);
	s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst);
	s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000);
	s->sg_processed++;
	/* Sync Hardware SG List of buffers */
	ivtv_stream_sync_for_device(s);
	write_reg(s->sg_handle, IVTV_REG_ENCDMAADDR);
	write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x02, IVTV_REG_DMAXFER);
	itv->dma_timer.expires = jiffies + msecs_to_jiffies(300);
	add_timer(&itv->dma_timer);
}

static void ivtv_dma_dec_start_xfer(struct ivtv_stream *s)
{
	struct ivtv *itv = s->itv;

	s->sg_dma->src = cpu_to_le32(s->sg_processing[s->sg_processed].src);
	s->sg_dma->dst = cpu_to_le32(s->sg_processing[s->sg_processed].dst);
	s->sg_dma->size = cpu_to_le32(s->sg_processing[s->sg_processed].size | 0x80000000);
	s->sg_processed++;
	/* Sync Hardware SG List of buffers */
	ivtv_stream_sync_for_device(s);
	write_reg(s->sg_handle, IVTV_REG_DECDMAADDR);
	write_reg_sync(read_reg(IVTV_REG_DMAXFER) | 0x01, IVTV_REG_DMAXFER);
	itv->dma_timer.expires = jiffies + msecs_to_jiffies(300);
	add_timer(&itv->dma_timer);
}

/* start the encoder DMA */
static void ivtv_dma_enc_start(struct ivtv_stream *s)
{
	struct ivtv *itv = s->itv;
	struct ivtv_stream *s_vbi = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
	int i;

	IVTV_DEBUG_HI_DMA("start %s for %s\n", ivtv_use_dma(s) ? "DMA" : "PIO", s->name);

	if (s->q_predma.bytesused)
		ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);

	if (ivtv_use_dma(s))
		s->sg_pending[s->sg_pending_size - 1].size += 256;

	/* If this is an MPEG stream, and VBI data is also pending, then append the
	   VBI DMA to the MPEG DMA and transfer both sets of data at once.

	   VBI DMA is a second class citizen compared to MPEG and mixing them together
	   will confuse the firmware (the end of a VBI DMA is seen as the end of a
	   MPEG DMA, thus effectively dropping an MPEG frame). So instead we make
	   sure we only use the MPEG DMA to transfer the VBI DMA if both are in
	   use. This way no conflicts occur. */
	clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags);
	if (s->type == IVTV_ENC_STREAM_TYPE_MPG && s_vbi->sg_pending_size &&
			s->sg_pending_size + s_vbi->sg_pending_size <= s->buffers) {
		ivtv_queue_move(s_vbi, &s_vbi->q_predma, NULL, &s_vbi->q_dma, s_vbi->q_predma.bytesused);
		if (ivtv_use_dma(s_vbi))
			s_vbi->sg_pending[s_vbi->sg_pending_size - 1].size += 256;
		for (i = 0; i < s_vbi->sg_pending_size; i++) {
			s->sg_pending[s->sg_pending_size++] = s_vbi->sg_pending[i];
		}
		s_vbi->dma_offset = s_vbi->pending_offset;
		s_vbi->sg_pending_size = 0;
		s_vbi->dma_xfer_cnt++;
		set_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags);
		IVTV_DEBUG_HI_DMA("include DMA for %s\n", s_vbi->name);
	}

	s->dma_xfer_cnt++;
	memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size);
	s->sg_processing_size = s->sg_pending_size;
	s->sg_pending_size = 0;
	s->sg_processed = 0;
	s->dma_offset = s->pending_offset;
	s->dma_backup = s->pending_backup;
	s->dma_pts = s->pending_pts;

	if (ivtv_use_pio(s)) {
		set_bit(IVTV_F_I_WORK_HANDLER_PIO, &itv->i_flags);
		set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
		set_bit(IVTV_F_I_PIO, &itv->i_flags);
		itv->cur_pio_stream = s->type;
	}
	else {
		itv->dma_retries = 0;
		ivtv_dma_enc_start_xfer(s);
		set_bit(IVTV_F_I_DMA, &itv->i_flags);
		itv->cur_dma_stream = s->type;
	}
}

static void ivtv_dma_dec_start(struct ivtv_stream *s)
{
	struct ivtv *itv = s->itv;

	if (s->q_predma.bytesused)
		ivtv_queue_move(s, &s->q_predma, NULL, &s->q_dma, s->q_predma.bytesused);
	s->dma_xfer_cnt++;
	memcpy(s->sg_processing, s->sg_pending, sizeof(struct ivtv_sg_host_element) * s->sg_pending_size);
	s->sg_processing_size = s->sg_pending_size;
	s->sg_pending_size = 0;
	s->sg_processed = 0;

	IVTV_DEBUG_HI_DMA("start DMA for %s\n", s->name);
	itv->dma_retries = 0;
	ivtv_dma_dec_start_xfer(s);
	set_bit(IVTV_F_I_DMA, &itv->i_flags);
	itv->cur_dma_stream = s->type;
}

static void ivtv_irq_dma_read(struct ivtv *itv)
{
	struct ivtv_stream *s = NULL;
	struct ivtv_buffer *buf;
	int hw_stream_type = 0;

	IVTV_DEBUG_HI_IRQ("DEC DMA READ\n");

	del_timer(&itv->dma_timer);

	if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) && itv->cur_dma_stream < 0)
		return;

	if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
		s = &itv->streams[itv->cur_dma_stream];
		ivtv_stream_sync_for_cpu(s);

		if (read_reg(IVTV_REG_DMASTATUS) & 0x14) {
			IVTV_DEBUG_WARN("DEC DMA ERROR %x (xfer %d of %d, retry %d)\n",
					read_reg(IVTV_REG_DMASTATUS),
					s->sg_processed, s->sg_processing_size, itv->dma_retries);
			write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
			if (itv->dma_retries == 3) {
				/* Too many retries, give up on this frame */
				itv->dma_retries = 0;
				s->sg_processed = s->sg_processing_size;
			}
			else {
				/* Retry, starting with the first xfer segment.
				   Just retrying the current segment is not sufficient. */
				s->sg_processed = 0;
				itv->dma_retries++;
			}
		}
		if (s->sg_processed < s->sg_processing_size) {
			/* DMA next buffer */
			ivtv_dma_dec_start_xfer(s);
			return;
		}
		if (s->type == IVTV_DEC_STREAM_TYPE_YUV)
			hw_stream_type = 2;
		IVTV_DEBUG_HI_DMA("DEC DATA READ %s: %d\n", s->name, s->q_dma.bytesused);

		/* For some reason must kick the firmware, like PIO mode,
		   I think this tells the firmware we are done and the size
		   of the xfer so it can calculate what we need next.
		   I think we can do this part ourselves but would have to
		   fully calculate xfer info ourselves and not use interrupts
		 */
		ivtv_vapi(itv, CX2341X_DEC_SCHED_DMA_FROM_HOST, 3, 0, s->q_dma.bytesused,
				hw_stream_type);

		/* Free last DMA call */
		while ((buf = ivtv_dequeue(s, &s->q_dma)) != NULL) {
			ivtv_buf_sync_for_cpu(s, buf);
			ivtv_enqueue(s, buf, &s->q_free);
		}
		wake_up(&s->waitq);
	}
	clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
	clear_bit(IVTV_F_I_DMA, &itv->i_flags);
	itv->cur_dma_stream = -1;
	wake_up(&itv->dma_waitq);
}

static void ivtv_irq_enc_dma_complete(struct ivtv *itv)
{
	u32 data[CX2341X_MBOX_MAX_DATA];
	struct ivtv_stream *s;

	ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
	IVTV_DEBUG_HI_IRQ("ENC DMA COMPLETE %x %d (%d)\n", data[0], data[1], itv->cur_dma_stream);

	del_timer(&itv->dma_timer);

	if (itv->cur_dma_stream < 0)
		return;

	s = &itv->streams[itv->cur_dma_stream];
	ivtv_stream_sync_for_cpu(s);

	if (data[0] & 0x18) {
		IVTV_DEBUG_WARN("ENC DMA ERROR %x (offset %08x, xfer %d of %d, retry %d)\n", data[0],
			s->dma_offset, s->sg_processed, s->sg_processing_size, itv->dma_retries);
		write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
		if (itv->dma_retries == 3) {
			/* Too many retries, give up on this frame */
			itv->dma_retries = 0;
			s->sg_processed = s->sg_processing_size;
		}
		else {
			/* Retry, starting with the first xfer segment.
			   Just retrying the current segment is not sufficient. */
			s->sg_processed = 0;
			itv->dma_retries++;
		}
	}
	if (s->sg_processed < s->sg_processing_size) {
		/* DMA next buffer */
		ivtv_dma_enc_start_xfer(s);
		return;
	}
	clear_bit(IVTV_F_I_DMA, &itv->i_flags);
	itv->cur_dma_stream = -1;
	dma_post(s);
	if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
		s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
		dma_post(s);
	}
	s->sg_processing_size = 0;
	s->sg_processed = 0;
	wake_up(&itv->dma_waitq);
}

static void ivtv_irq_enc_pio_complete(struct ivtv *itv)
{
	struct ivtv_stream *s;

	if (itv->cur_pio_stream < 0 || itv->cur_pio_stream >= IVTV_MAX_STREAMS) {
		itv->cur_pio_stream = -1;
		return;
	}
	s = &itv->streams[itv->cur_pio_stream];
	IVTV_DEBUG_HI_IRQ("ENC PIO COMPLETE %s\n", s->name);
	clear_bit(IVTV_F_I_PIO, &itv->i_flags);
	itv->cur_pio_stream = -1;
	dma_post(s);
	if (s->type == IVTV_ENC_STREAM_TYPE_MPG)
		ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 0);
	else if (s->type == IVTV_ENC_STREAM_TYPE_YUV)
		ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 1);
	else if (s->type == IVTV_ENC_STREAM_TYPE_PCM)
		ivtv_vapi(itv, CX2341X_ENC_SCHED_DMA_TO_HOST, 3, 0, 0, 2);
	clear_bit(IVTV_F_I_PIO, &itv->i_flags);
	if (test_and_clear_bit(IVTV_F_S_DMA_HAS_VBI, &s->s_flags)) {
		s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];
		dma_post(s);
	}
	wake_up(&itv->dma_waitq);
}

static void ivtv_irq_dma_err(struct ivtv *itv)
{
	u32 data[CX2341X_MBOX_MAX_DATA];
	u32 status;

	del_timer(&itv->dma_timer);

	ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA_END, 2, data);
	status = read_reg(IVTV_REG_DMASTATUS);
	IVTV_DEBUG_WARN("DMA ERROR %08x %08x %08x %d\n", data[0], data[1],
				status, itv->cur_dma_stream);
	/*
	 * We do *not* write back to the IVTV_REG_DMASTATUS register to
	 * clear the error status, if either the encoder write (0x02) or
	 * decoder read (0x01) bus master DMA operation do not indicate
	 * completed.  We can race with the DMA engine, which may have
	 * transitioned to completed status *after* we read the register.
	 * Setting a IVTV_REG_DMASTATUS flag back to "busy" status, after the
	 * DMA engine has completed, will cause the DMA engine to stop working.
	 */
	status &= 0x3;
	if (status == 0x3)
		write_reg(status, IVTV_REG_DMASTATUS);

	if (!test_bit(IVTV_F_I_UDMA, &itv->i_flags) &&
	    itv->cur_dma_stream >= 0 && itv->cur_dma_stream < IVTV_MAX_STREAMS) {
		struct ivtv_stream *s = &itv->streams[itv->cur_dma_stream];

		if (s->type >= IVTV_DEC_STREAM_TYPE_MPG) {
			/* retry */
			/*
			 * FIXME - handle cases of DMA error similar to
			 * encoder below, except conditioned on status & 0x1
			 */
			ivtv_dma_dec_start(s);
			return;
		} else {
			if ((status & 0x2) == 0) {
				/*
				 * CX2341x Bus Master DMA write is ongoing.
				 * Reset the timer and let it complete.
				 */
				itv->dma_timer.expires =
						jiffies + msecs_to_jiffies(600);
				add_timer(&itv->dma_timer);
				return;
			}

			if (itv->dma_retries < 3) {
				/*
				 * CX2341x Bus Master DMA write has ended.
				 * Retry the write, starting with the first
				 * xfer segment. Just retrying the current
				 * segment is not sufficient.
				 */
				s->sg_processed = 0;
				itv->dma_retries++;
				ivtv_dma_enc_start_xfer(s);
				return;
			}
			/* Too many retries, give up on this one */
		}

	}
	if (test_bit(IVTV_F_I_UDMA, &itv->i_flags)) {
		ivtv_udma_start(itv);
		return;
	}
	clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
	clear_bit(IVTV_F_I_DMA, &itv->i_flags);
	itv->cur_dma_stream = -1;
	wake_up(&itv->dma_waitq);
}

static void ivtv_irq_enc_start_cap(struct ivtv *itv)
{
	u32 data[CX2341X_MBOX_MAX_DATA];
	struct ivtv_stream *s;

	/* Get DMA destination and size arguments from card */
	ivtv_api_get_data(&itv->enc_mbox, IVTV_MBOX_DMA, 7, data);
	IVTV_DEBUG_HI_IRQ("ENC START CAP %d: %08x %08x\n", data[0], data[1], data[2]);

	if (data[0] > 2 || data[1] == 0 || data[2] == 0) {
		IVTV_DEBUG_WARN("Unknown input: %08x %08x %08x\n",
				data[0], data[1], data[2]);
		return;
	}
	s = &itv->streams[ivtv_stream_map[data[0]]];
	if (!stream_enc_dma_append(s, data)) {
		set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
	}
}

static void ivtv_irq_enc_vbi_cap(struct ivtv *itv)
{
	u32 data[CX2341X_MBOX_MAX_DATA];
	struct ivtv_stream *s;

	IVTV_DEBUG_HI_IRQ("ENC START VBI CAP\n");
	s = &itv->streams[IVTV_ENC_STREAM_TYPE_VBI];

	if (!stream_enc_dma_append(s, data))
		set_bit(ivtv_use_pio(s) ? IVTV_F_S_PIO_PENDING : IVTV_F_S_DMA_PENDING, &s->s_flags);
}

static void ivtv_irq_dec_vbi_reinsert(struct ivtv *itv)
{
	u32 data[CX2341X_MBOX_MAX_DATA];
	struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_VBI];

	IVTV_DEBUG_HI_IRQ("DEC VBI REINSERT\n");
	if (test_bit(IVTV_F_S_CLAIMED, &s->s_flags) &&
			!stream_enc_dma_append(s, data)) {
		set_bit(IVTV_F_S_PIO_PENDING, &s->s_flags);
	}
}

static void ivtv_irq_dec_data_req(struct ivtv *itv)
{
	u32 data[CX2341X_MBOX_MAX_DATA];
	struct ivtv_stream *s;

	/* YUV or MPG */

	if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) {
		ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 2, data);
		itv->dma_data_req_size =
				 1080 * ((itv->yuv_info.v4l2_src_h + 31) & ~31);
		itv->dma_data_req_offset = data[1];
		if (atomic_read(&itv->yuv_info.next_dma_frame) >= 0)
			ivtv_yuv_frame_complete(itv);
		s = &itv->streams[IVTV_DEC_STREAM_TYPE_YUV];
	}
	else {
		ivtv_api_get_data(&itv->dec_mbox, IVTV_MBOX_DMA, 3, data);
		itv->dma_data_req_size = min_t(u32, data[2], 0x10000);
		itv->dma_data_req_offset = data[1];
		s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
	}
	IVTV_DEBUG_HI_IRQ("DEC DATA REQ %s: %d %08x %u\n", s->name, s->q_full.bytesused,
		       itv->dma_data_req_offset, itv->dma_data_req_size);
	if (itv->dma_data_req_size == 0 || s->q_full.bytesused < itv->dma_data_req_size) {
		set_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
	}
	else {
		if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
			ivtv_yuv_setup_stream_frame(itv);
		clear_bit(IVTV_F_S_NEEDS_DATA, &s->s_flags);
		ivtv_queue_move(s, &s->q_full, NULL, &s->q_predma, itv->dma_data_req_size);
		ivtv_dma_stream_dec_prepare(s, itv->dma_data_req_offset + IVTV_DECODER_OFFSET, 0);
	}
}

static void ivtv_irq_vsync(struct ivtv *itv)
{
	/* The vsync interrupt is unusual in that it won't clear until
	 * the end of the first line for the current field, at which
	 * point it clears itself. This can result in repeated vsync
	 * interrupts, or a missed vsync. Read some of the registers
	 * to determine the line being displayed and ensure we handle
	 * one vsync per frame.
	 */
	unsigned int frame = read_reg(IVTV_REG_DEC_LINE_FIELD) & 1;
	struct yuv_playback_info *yi = &itv->yuv_info;
	int last_dma_frame = atomic_read(&yi->next_dma_frame);
	struct yuv_frame_info *f = &yi->new_frame_info[last_dma_frame];

	if (0) IVTV_DEBUG_IRQ("DEC VSYNC\n");

	if (((frame ^ f->sync_field) == 0 &&
		((itv->last_vsync_field & 1) ^ f->sync_field)) ||
			(frame != (itv->last_vsync_field & 1) && !f->interlaced)) {
		int next_dma_frame = last_dma_frame;

		if (!(f->interlaced && f->delay && yi->fields_lapsed < 1)) {
			if (next_dma_frame >= 0 && next_dma_frame != atomic_read(&yi->next_fill_frame)) {
				write_reg(yuv_offset[next_dma_frame] >> 4, 0x82c);
				write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x830);
				write_reg(yuv_offset[next_dma_frame] >> 4, 0x834);
				write_reg((yuv_offset[next_dma_frame] + IVTV_YUV_BUFFER_UV_OFFSET) >> 4, 0x838);
				next_dma_frame = (next_dma_frame + 1) % IVTV_YUV_BUFFERS;
				atomic_set(&yi->next_dma_frame, next_dma_frame);
				yi->fields_lapsed = -1;
				yi->running = 1;
			}
		}
	}
	if (frame != (itv->last_vsync_field & 1)) {
		static const struct v4l2_event evtop = {
			.type = V4L2_EVENT_VSYNC,
			.u.vsync.field = V4L2_FIELD_TOP,
		};
		static const struct v4l2_event evbottom = {
			.type = V4L2_EVENT_VSYNC,
			.u.vsync.field = V4L2_FIELD_BOTTOM,
		};
		struct ivtv_stream *s = ivtv_get_output_stream(itv);

		itv->last_vsync_field += 1;
		if (frame == 0) {
			clear_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
			clear_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags);
		}
		else {
			set_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags);
		}
		if (test_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags)) {
			set_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags);
			wake_up(&itv->event_waitq);
			if (s)
				wake_up(&s->waitq);
		}
		if (s && s->vdev)
			v4l2_event_queue(s->vdev, frame ? &evtop : &evbottom);
		wake_up(&itv->vsync_waitq);

		/* Send VBI to saa7127 */
		if (frame && (itv->output_mode == OUT_PASSTHROUGH ||
			test_bit(IVTV_F_I_UPDATE_WSS, &itv->i_flags) ||
			test_bit(IVTV_F_I_UPDATE_VPS, &itv->i_flags) ||
			test_bit(IVTV_F_I_UPDATE_CC, &itv->i_flags))) {
			set_bit(IVTV_F_I_WORK_HANDLER_VBI, &itv->i_flags);
			set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
		}

		/* Check if we need to update the yuv registers */
		if (yi->running && (yi->yuv_forced_update || f->update)) {
			if (!f->update) {
				last_dma_frame =
					(u8)(atomic_read(&yi->next_dma_frame) -
						 1) % IVTV_YUV_BUFFERS;
				f = &yi->new_frame_info[last_dma_frame];
			}

			if (f->src_w) {
				yi->update_frame = last_dma_frame;
				f->update = 0;
				yi->yuv_forced_update = 0;
				set_bit(IVTV_F_I_WORK_HANDLER_YUV, &itv->i_flags);
				set_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags);
			}
		}

		yi->fields_lapsed++;
	}
}

#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)

irqreturn_t ivtv_irq_handler(int irq, void *dev_id)
{
	struct ivtv *itv = (struct ivtv *)dev_id;
	u32 combo;
	u32 stat;
	int i;
	u8 vsync_force = 0;

	spin_lock(&itv->dma_reg_lock);
	/* get contents of irq status register */
	stat = read_reg(IVTV_REG_IRQSTATUS);

	combo = ~itv->irqmask & stat;

	/* Clear out IRQ */
	if (combo) write_reg(combo, IVTV_REG_IRQSTATUS);

	if (0 == combo) {
		/* The vsync interrupt is unusual and clears itself. If we
		 * took too long, we may have missed it. Do some checks
		 */
		if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) {
			/* vsync is enabled, see if we're in a new field */
			if ((itv->last_vsync_field & 1) !=
			    (read_reg(IVTV_REG_DEC_LINE_FIELD) & 1)) {
				/* New field, looks like we missed it */
				IVTV_DEBUG_YUV("VSync interrupt missed %d\n",
				       read_reg(IVTV_REG_DEC_LINE_FIELD) >> 16);
				vsync_force = 1;
			}
		}

		if (!vsync_force) {
			/* No Vsync expected, wasn't for us */
			spin_unlock(&itv->dma_reg_lock);
			return IRQ_NONE;
		}
	}

	/* Exclude interrupts noted below from the output, otherwise the log is flooded with
	   these messages */
	if (combo & ~0xff6d0400)
		IVTV_DEBUG_HI_IRQ("======= valid IRQ bits: 0x%08x ======\n", combo);

	if (combo & IVTV_IRQ_DEC_DMA_COMPLETE) {
		IVTV_DEBUG_HI_IRQ("DEC DMA COMPLETE\n");
	}

	if (combo & IVTV_IRQ_DMA_READ) {
		ivtv_irq_dma_read(itv);
	}

	if (combo & IVTV_IRQ_ENC_DMA_COMPLETE) {
		ivtv_irq_enc_dma_complete(itv);
	}

	if (combo & IVTV_IRQ_ENC_PIO_COMPLETE) {
		ivtv_irq_enc_pio_complete(itv);
	}

	if (combo & IVTV_IRQ_DMA_ERR) {
		ivtv_irq_dma_err(itv);
	}

	if (combo & IVTV_IRQ_ENC_START_CAP) {
		ivtv_irq_enc_start_cap(itv);
	}

	if (combo & IVTV_IRQ_ENC_VBI_CAP) {
		ivtv_irq_enc_vbi_cap(itv);
	}

	if (combo & IVTV_IRQ_DEC_VBI_RE_INSERT) {
		ivtv_irq_dec_vbi_reinsert(itv);
	}

	if (combo & IVTV_IRQ_ENC_EOS) {
		IVTV_DEBUG_IRQ("ENC EOS\n");
		set_bit(IVTV_F_I_EOS, &itv->i_flags);
		wake_up(&itv->eos_waitq);
	}

	if (combo & IVTV_IRQ_DEC_DATA_REQ) {
		ivtv_irq_dec_data_req(itv);
	}

	/* Decoder Vertical Sync - We can't rely on 'combo', so check if vsync enabled */
	if (~itv->irqmask & IVTV_IRQ_DEC_VSYNC) {
		ivtv_irq_vsync(itv);
	}

	if (combo & IVTV_IRQ_ENC_VIM_RST) {
		IVTV_DEBUG_IRQ("VIM RST\n");
		/*ivtv_vapi(itv, CX2341X_ENC_REFRESH_INPUT, 0); */
	}

	if (combo & IVTV_IRQ_DEC_AUD_MODE_CHG) {
		IVTV_DEBUG_INFO("Stereo mode changed\n");
	}

	if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_DMA, &itv->i_flags)) {
		itv->irq_rr_idx++;
		for (i = 0; i < IVTV_MAX_STREAMS; i++) {
			int idx = (i + itv->irq_rr_idx) % IVTV_MAX_STREAMS;
			struct ivtv_stream *s = &itv->streams[idx];

			if (!test_and_clear_bit(IVTV_F_S_DMA_PENDING, &s->s_flags))
				continue;
			if (s->type >= IVTV_DEC_STREAM_TYPE_MPG)
				ivtv_dma_dec_start(s);
			else
				ivtv_dma_enc_start(s);
			break;
		}

		if (i == IVTV_MAX_STREAMS &&
		    test_bit(IVTV_F_I_UDMA_PENDING, &itv->i_flags))
			ivtv_udma_start(itv);
	}

	if ((combo & IVTV_IRQ_DMA) && !test_bit(IVTV_F_I_PIO, &itv->i_flags)) {
		itv->irq_rr_idx++;
		for (i = 0; i < IVTV_MAX_STREAMS; i++) {
			int idx = (i + itv->irq_rr_idx) % IVTV_MAX_STREAMS;
			struct ivtv_stream *s = &itv->streams[idx];

			if (!test_and_clear_bit(IVTV_F_S_PIO_PENDING, &s->s_flags))
				continue;
			if (s->type == IVTV_DEC_STREAM_TYPE_VBI || s->type < IVTV_DEC_STREAM_TYPE_MPG)
				ivtv_dma_enc_start(s);
			break;
		}
	}

	if (test_and_clear_bit(IVTV_F_I_HAVE_WORK, &itv->i_flags)) {
		queue_kthread_work(&itv->irq_worker, &itv->irq_work);
	}

	spin_unlock(&itv->dma_reg_lock);

	/* If we've just handled a 'forced' vsync, it's safest to say it
	 * wasn't ours. Another device may have triggered it at just
	 * the right time.
	 */
	return vsync_force ? IRQ_NONE : IRQ_HANDLED;
}

void ivtv_unfinished_dma(unsigned long arg)
{
	struct ivtv *itv = (struct ivtv *)arg;

	if (!test_bit(IVTV_F_I_DMA, &itv->i_flags))
		return;
	IVTV_ERR("DMA TIMEOUT %08x %d\n", read_reg(IVTV_REG_DMASTATUS), itv->cur_dma_stream);

	write_reg(read_reg(IVTV_REG_DMASTATUS) & 3, IVTV_REG_DMASTATUS);
	clear_bit(IVTV_F_I_UDMA, &itv->i_flags);
	clear_bit(IVTV_F_I_DMA, &itv->i_flags);
	itv->cur_dma_stream = -1;
	wake_up(&itv->dma_waitq);
}
