/*
    mailbox functions
    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 <stdarg.h>

#include "ivtv-driver.h"
#include "ivtv-mailbox.h"

/* Firmware mailbox flags*/
#define IVTV_MBOX_FIRMWARE_DONE 0x00000004
#define IVTV_MBOX_DRIVER_DONE   0x00000002
#define IVTV_MBOX_DRIVER_BUSY   0x00000001
#define IVTV_MBOX_FREE 		0x00000000

/* Firmware mailbox standard timeout */
#define IVTV_API_STD_TIMEOUT 	0x02000000

#define API_CACHE 	 (1 << 0) 	/* Allow the command to be stored in the cache */
#define API_RESULT	 (1 << 1) 	/* Allow 1 second for this cmd to end */
#define API_FAST_RESULT	 (3 << 1)	/* Allow 0.1 second for this cmd to end */
#define API_DMA 	 (1 << 3)	/* DMA mailbox, has special handling */
#define API_NO_WAIT_MB 	 (1 << 4)	/* Command may not wait for a free mailbox */
#define API_NO_WAIT_RES	 (1 << 5)	/* Command may not wait for the result */

struct ivtv_api_info {
	int flags;		/* Flags, see above */
	const char *name; 	/* The name of the command */
};

#define API_ENTRY(x, f) [x] = { (f), #x }

static const struct ivtv_api_info api_info[256] = {
	/* MPEG encoder API */
	API_ENTRY(CX2341X_ENC_PING_FW, 			API_FAST_RESULT),
	API_ENTRY(CX2341X_ENC_START_CAPTURE, 		API_RESULT),
	API_ENTRY(CX2341X_ENC_STOP_CAPTURE, 		API_RESULT),
	API_ENTRY(CX2341X_ENC_SET_AUDIO_ID, 		API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_VIDEO_ID, 		API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_PCR_ID, 		API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_FRAME_RATE, 		API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_FRAME_SIZE, 		API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_BIT_RATE, 		API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_GOP_PROPERTIES, 	API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_ASPECT_RATIO, 	API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_MODE, 	API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_DNR_FILTER_PROPS, 	API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_CORING_LEVELS, 	API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_SPATIAL_FILTER_TYPE, 	API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_VBI_LINE, 		API_RESULT),
	API_ENTRY(CX2341X_ENC_SET_STREAM_TYPE, 		API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_OUTPUT_PORT, 		API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_AUDIO_PROPERTIES, 	API_CACHE),
	API_ENTRY(CX2341X_ENC_HALT_FW, 			API_FAST_RESULT),
	API_ENTRY(CX2341X_ENC_GET_VERSION, 		API_FAST_RESULT),
	API_ENTRY(CX2341X_ENC_SET_GOP_CLOSURE, 		API_CACHE),
	API_ENTRY(CX2341X_ENC_GET_SEQ_END, 		API_RESULT),
	API_ENTRY(CX2341X_ENC_SET_PGM_INDEX_INFO, 	API_FAST_RESULT),
	API_ENTRY(CX2341X_ENC_SET_VBI_CONFIG, 		API_RESULT),
	API_ENTRY(CX2341X_ENC_SET_DMA_BLOCK_SIZE, 	API_CACHE),
	API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_10, 	API_FAST_RESULT),
	API_ENTRY(CX2341X_ENC_GET_PREV_DMA_INFO_MB_9, 	API_FAST_RESULT),
	API_ENTRY(CX2341X_ENC_SCHED_DMA_TO_HOST, 	API_DMA),
	API_ENTRY(CX2341X_ENC_INITIALIZE_INPUT, 	API_RESULT),
	API_ENTRY(CX2341X_ENC_SET_FRAME_DROP_RATE, 	API_CACHE),
	API_ENTRY(CX2341X_ENC_PAUSE_ENCODER, 		API_RESULT),
	API_ENTRY(CX2341X_ENC_REFRESH_INPUT, 		API_NO_WAIT_MB),
	API_ENTRY(CX2341X_ENC_SET_COPYRIGHT, 		API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_EVENT_NOTIFICATION, 	API_RESULT),
	API_ENTRY(CX2341X_ENC_SET_NUM_VSYNC_LINES, 	API_CACHE),
	API_ENTRY(CX2341X_ENC_SET_PLACEHOLDER, 		API_CACHE),
	API_ENTRY(CX2341X_ENC_MUTE_VIDEO, 		API_RESULT),
	API_ENTRY(CX2341X_ENC_MUTE_AUDIO, 		API_RESULT),
	API_ENTRY(CX2341X_ENC_SET_VERT_CROP_LINE,	API_FAST_RESULT),
	API_ENTRY(CX2341X_ENC_MISC, 			API_FAST_RESULT),
	/* Obsolete PULLDOWN API command */
	API_ENTRY(0xb1, 				API_CACHE),

	/* MPEG decoder API */
	API_ENTRY(CX2341X_DEC_PING_FW, 			API_FAST_RESULT),
	API_ENTRY(CX2341X_DEC_START_PLAYBACK, 		API_RESULT),
	API_ENTRY(CX2341X_DEC_STOP_PLAYBACK, 		API_RESULT),
	API_ENTRY(CX2341X_DEC_SET_PLAYBACK_SPEED, 	API_RESULT),
	API_ENTRY(CX2341X_DEC_STEP_VIDEO, 		API_RESULT),
	API_ENTRY(CX2341X_DEC_SET_DMA_BLOCK_SIZE, 	API_CACHE),
	API_ENTRY(CX2341X_DEC_GET_XFER_INFO, 		API_FAST_RESULT),
	API_ENTRY(CX2341X_DEC_GET_DMA_STATUS, 		API_FAST_RESULT),
	API_ENTRY(CX2341X_DEC_SCHED_DMA_FROM_HOST, 	API_DMA),
	API_ENTRY(CX2341X_DEC_PAUSE_PLAYBACK, 		API_RESULT),
	API_ENTRY(CX2341X_DEC_HALT_FW, 			API_FAST_RESULT),
	API_ENTRY(CX2341X_DEC_SET_STANDARD, 		API_CACHE),
	API_ENTRY(CX2341X_DEC_GET_VERSION, 		API_FAST_RESULT),
	API_ENTRY(CX2341X_DEC_SET_STREAM_INPUT, 	API_CACHE),
	API_ENTRY(CX2341X_DEC_GET_TIMING_INFO, 		API_RESULT /*| API_NO_WAIT_RES*/),
	API_ENTRY(CX2341X_DEC_SET_AUDIO_MODE, 		API_CACHE),
	API_ENTRY(CX2341X_DEC_SET_EVENT_NOTIFICATION, 	API_RESULT),
	API_ENTRY(CX2341X_DEC_SET_DISPLAY_BUFFERS, 	API_CACHE),
	API_ENTRY(CX2341X_DEC_EXTRACT_VBI, 		API_RESULT),
	API_ENTRY(CX2341X_DEC_SET_DECODER_SOURCE, 	API_FAST_RESULT),
	API_ENTRY(CX2341X_DEC_SET_PREBUFFERING, 	API_CACHE),

	/* OSD API */
	API_ENTRY(CX2341X_OSD_GET_FRAMEBUFFER, 		API_FAST_RESULT),
	API_ENTRY(CX2341X_OSD_GET_PIXEL_FORMAT, 	API_FAST_RESULT),
	API_ENTRY(CX2341X_OSD_SET_PIXEL_FORMAT, 	API_CACHE),
	API_ENTRY(CX2341X_OSD_GET_STATE, 		API_FAST_RESULT),
	API_ENTRY(CX2341X_OSD_SET_STATE, 		API_CACHE),
	API_ENTRY(CX2341X_OSD_GET_OSD_COORDS, 		API_FAST_RESULT),
	API_ENTRY(CX2341X_OSD_SET_OSD_COORDS, 		API_CACHE),
	API_ENTRY(CX2341X_OSD_GET_SCREEN_COORDS, 	API_FAST_RESULT),
	API_ENTRY(CX2341X_OSD_SET_SCREEN_COORDS, 	API_CACHE),
	API_ENTRY(CX2341X_OSD_GET_GLOBAL_ALPHA, 	API_FAST_RESULT),
	API_ENTRY(CX2341X_OSD_SET_GLOBAL_ALPHA, 	API_CACHE),
	API_ENTRY(CX2341X_OSD_SET_BLEND_COORDS, 	API_CACHE),
	API_ENTRY(CX2341X_OSD_GET_FLICKER_STATE, 	API_FAST_RESULT),
	API_ENTRY(CX2341X_OSD_SET_FLICKER_STATE, 	API_CACHE),
	API_ENTRY(CX2341X_OSD_BLT_COPY, 		API_RESULT),
	API_ENTRY(CX2341X_OSD_BLT_FILL, 		API_RESULT),
	API_ENTRY(CX2341X_OSD_BLT_TEXT, 		API_RESULT),
	API_ENTRY(CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 	API_CACHE),
	API_ENTRY(CX2341X_OSD_SET_CHROMA_KEY, 		API_CACHE),
	API_ENTRY(CX2341X_OSD_GET_ALPHA_CONTENT_INDEX, 	API_FAST_RESULT),
	API_ENTRY(CX2341X_OSD_SET_ALPHA_CONTENT_INDEX, 	API_CACHE)
};

static int try_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int mb)
{
	u32 flags = readl(&mbdata->mbox[mb].flags);
	int is_free = flags == IVTV_MBOX_FREE || (flags & IVTV_MBOX_FIRMWARE_DONE);

	/* if the mailbox is free, then try to claim it */
	if (is_free && !test_and_set_bit(mb, &mbdata->busy)) {
		write_sync(IVTV_MBOX_DRIVER_BUSY, &mbdata->mbox[mb].flags);
		return 1;
	}
	return 0;
}

/* Try to find a free mailbox. Note mailbox 0 is reserved for DMA and so is not
   attempted here. */
static int get_mailbox(struct ivtv *itv, struct ivtv_mailbox_data *mbdata, int flags)
{
	unsigned long then = jiffies;
	int i, mb;
	int max_mbox = mbdata->max_mbox;
	int retries = 100;

	/* All slow commands use the same mailbox, serializing them and also
	   leaving the other mailbox free for simple fast commands. */
	if ((flags & API_FAST_RESULT) == API_RESULT)
		max_mbox = 1;

	/* find free non-DMA mailbox */
	for (i = 0; i < retries; i++) {
		for (mb = 1; mb <= max_mbox; mb++)
			if (try_mailbox(itv, mbdata, mb))
				return mb;

		/* Sleep before a retry, if not atomic */
		if (!(flags & API_NO_WAIT_MB)) {
			if (jiffies - then > retries * HZ / 100)
			       break;
			ivtv_sleep_timeout(HZ / 100, 0);
		}
	}
	return -ENODEV;
}

static void write_mailbox(volatile struct ivtv_mailbox __iomem *mbox, int cmd, int args, u32 data[])
{
	int i;

	write_sync(cmd, &mbox->cmd);
	write_sync(IVTV_API_STD_TIMEOUT, &mbox->timeout);

	for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++)
		write_sync(data[i], &mbox->data[i]);

	write_sync(IVTV_MBOX_DRIVER_DONE | IVTV_MBOX_DRIVER_BUSY, &mbox->flags);
}

static void clear_all_mailboxes(struct ivtv *itv, struct ivtv_mailbox_data *mbdata)
{
	int i;

	for (i = 0; i <= mbdata->max_mbox; i++) {
		IVTV_DEBUG_WARN("Clearing mailbox %d: cmd 0x%08x flags 0x%08x\n",
			i, readl(&mbdata->mbox[i].cmd), readl(&mbdata->mbox[i].flags));
		write_sync(0, &mbdata->mbox[i].flags);
		clear_bit(i, &mbdata->busy);
	}
}

static int ivtv_api_call(struct ivtv *itv, int cmd, int args, u32 data[])
{
	struct ivtv_mailbox_data *mbdata = (cmd >= 128) ? &itv->enc_mbox : &itv->dec_mbox;
	volatile struct ivtv_mailbox __iomem *mbox;
	int api_timeout = HZ;
	int flags, mb, i;
	unsigned long then;

	/* sanity checks */
	if (NULL == mbdata) {
		IVTV_ERR("No mailbox allocated\n");
		return -ENODEV;
	}
	if (args < 0 || args > CX2341X_MBOX_MAX_DATA ||
	    cmd < 0 || cmd > 255 || api_info[cmd].name == NULL) {
		IVTV_ERR("Invalid API call: cmd = 0x%02x, args = %d\n", cmd, args);
		return -EINVAL;
	}

	IVTV_DEBUG_API("API Call: %s\n", api_info[cmd].name);

	/* clear possibly uninitialized part of data array */
	for (i = args; i < CX2341X_MBOX_MAX_DATA; i++)
		data[i] = 0;

	/* If this command was issued within the last 30 minutes and with identical
	   data, then just return 0 as there is no need to issue this command again.
	   Just an optimization to prevent unnecessary use of mailboxes. */
	if (itv->api_cache[cmd].last_jiffies &&
	    jiffies - itv->api_cache[cmd].last_jiffies < HZ * 1800 &&
	    !memcmp(data, itv->api_cache[cmd].data, sizeof(itv->api_cache[cmd].data))) {
		itv->api_cache[cmd].last_jiffies = jiffies;
		return 0;
	}

	flags = api_info[cmd].flags;

	if (flags & API_DMA) {
		for (i = 0; i < 100; i++) {
			mb = i % (mbdata->max_mbox + 1);
			if (try_mailbox(itv, mbdata, mb)) {
				write_mailbox(&mbdata->mbox[mb], cmd, args, data);
				clear_bit(mb, &mbdata->busy);
				return 0;
			}
			IVTV_DEBUG_WARN("%s: mailbox %d not free %08x\n",
					api_info[cmd].name, mb, readl(&mbdata->mbox[mb].flags));
		}
		IVTV_WARN("Could not find free DMA mailbox for %s\n", api_info[cmd].name);
		clear_all_mailboxes(itv, mbdata);
		return -EBUSY;
	}

	if ((flags & API_FAST_RESULT) == API_FAST_RESULT)
		api_timeout = HZ / 10;

	mb = get_mailbox(itv, mbdata, flags);
	if (mb < 0) {
		IVTV_DEBUG_WARN("No free mailbox found (%s)\n", api_info[cmd].name);
		clear_all_mailboxes(itv, mbdata);
		return -EBUSY;
	}
	mbox = &mbdata->mbox[mb];
	write_mailbox(mbox, cmd, args, data);
	if (flags & API_CACHE) {
		memcpy(itv->api_cache[cmd].data, data, sizeof(itv->api_cache[cmd].data));
		itv->api_cache[cmd].last_jiffies = jiffies;
	}
	if ((flags & API_RESULT) == 0) {
		clear_bit(mb, &mbdata->busy);
		return 0;
	}

	/* Get results */
	then = jiffies;

	while (!(readl(&mbox->flags) & IVTV_MBOX_FIRMWARE_DONE)) {
		if (jiffies - then > api_timeout) {
			IVTV_DEBUG_WARN("Could not get result (%s)\n", api_info[cmd].name);
			/* reset the mailbox, but it is likely too late already */
			write_sync(0, &mbox->flags);
			clear_bit(mb, &mbdata->busy);
			return -EIO;
		}
		if (flags & API_NO_WAIT_RES)
			mdelay(1);
		else
			ivtv_sleep_timeout(HZ / 100, 0);
	}
	if (jiffies - then > HZ / 10)
		IVTV_DEBUG_WARN("%s took %lu jiffies (%d per HZ)\n",
				api_info[cmd].name, jiffies - then, HZ);

	for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++)
		data[i] = readl(&mbox->data[i]);
	write_sync(0, &mbox->flags);
	clear_bit(mb, &mbdata->busy);
	return 0;
}

int ivtv_api(struct ivtv *itv, int cmd, int args, u32 data[])
{
	int res = ivtv_api_call(itv, cmd, args, data);

	/* Allow a single retry, probably already too late though.
	   If there is no free mailbox then that is usually an indication
	   of a more serious problem. */
	return (res == -EBUSY) ? ivtv_api_call(itv, cmd, args, data) : res;
}

int ivtv_api_func(void *priv, int cmd, int in, int out, u32 data[CX2341X_MBOX_MAX_DATA])
{
	return ivtv_api(priv, cmd, in, data);
}

int ivtv_vapi_result(struct ivtv *itv, u32 data[CX2341X_MBOX_MAX_DATA], int cmd, int args, ...)
{
	va_list ap;
	int i;

	va_start(ap, args);
	for (i = 0; i < args; i++) {
		data[i] = va_arg(ap, u32);
	}
	va_end(ap);
	return ivtv_api(itv, cmd, args, data);
}

int ivtv_vapi(struct ivtv *itv, int cmd, int args, ...)
{
	u32 data[CX2341X_MBOX_MAX_DATA];
	va_list ap;
	int i;

	va_start(ap, args);
	for (i = 0; i < args; i++) {
		data[i] = va_arg(ap, u32);
	}
	va_end(ap);
	return ivtv_api(itv, cmd, args, data);
}

/* This one is for stuff that can't sleep.. irq handlers, etc.. */
void ivtv_api_get_data(struct ivtv_mailbox_data *mbdata, int mb, u32 data[])
{
	int i;

	for (i = 0; i < CX2341X_MBOX_MAX_DATA; i++)
		data[i] = readl(&mbdata->mbox[mb].data[i]);
}
