/*
 * Copyright © 2010 Intel Corporation
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 *
 * Authors:
 * Jackie Li<yaodong.li@intel.com>
 */

#include <linux/freezer.h>

#include "mdfld_dsi_output.h"
#include "mdfld_dsi_pkg_sender.h"
#include "mdfld_dsi_dpi.h"

#define MDFLD_DSI_READ_MAX_COUNT		5000

enum data_type {
	DSI_DT_GENERIC_SHORT_WRITE_0	= 0x03,
	DSI_DT_GENERIC_SHORT_WRITE_1	= 0x13,
	DSI_DT_GENERIC_SHORT_WRITE_2	= 0x23,
	DSI_DT_GENERIC_READ_0		= 0x04,
	DSI_DT_GENERIC_READ_1		= 0x14,
	DSI_DT_GENERIC_READ_2		= 0x24,
	DSI_DT_GENERIC_LONG_WRITE	= 0x29,
	DSI_DT_DCS_SHORT_WRITE_0	= 0x05,
	DSI_DT_DCS_SHORT_WRITE_1	= 0x15,
	DSI_DT_DCS_READ			= 0x06,
	DSI_DT_DCS_LONG_WRITE		= 0x39,
};

enum {
	MDFLD_DSI_PANEL_MODE_SLEEP = 0x1,
};

enum {
	MDFLD_DSI_PKG_SENDER_FREE = 0x0,
	MDFLD_DSI_PKG_SENDER_BUSY = 0x1,
};

static const char *const dsi_errors[] = {
	"RX SOT Error",
	"RX SOT Sync Error",
	"RX EOT Sync Error",
	"RX Escape Mode Entry Error",
	"RX LP TX Sync Error",
	"RX HS Receive Timeout Error",
	"RX False Control Error",
	"RX ECC Single Bit Error",
	"RX ECC Multibit Error",
	"RX Checksum Error",
	"RX DSI Data Type Not Recognised",
	"RX DSI VC ID Invalid",
	"TX False Control Error",
	"TX ECC Single Bit Error",
	"TX ECC Multibit Error",
	"TX Checksum Error",
	"TX DSI Data Type Not Recognised",
	"TX DSI VC ID invalid",
	"High Contention",
	"Low contention",
	"DPI FIFO Under run",
	"HS TX Timeout",
	"LP RX Timeout",
	"Turn Around ACK Timeout",
	"ACK With No Error",
	"RX Invalid TX Length",
	"RX Prot Violation",
	"HS Generic Write FIFO Full",
	"LP Generic Write FIFO Full",
	"Generic Read Data Avail",
	"Special Packet Sent",
	"Tearing Effect",
};

static inline int wait_for_gen_fifo_empty(struct mdfld_dsi_pkg_sender *sender,
						u32 mask)
{
	struct drm_device *dev = sender->dev;
	u32 gen_fifo_stat_reg = sender->mipi_gen_fifo_stat_reg;
	int retry = 0xffff;

	while (retry--) {
		if ((mask & REG_READ(gen_fifo_stat_reg)) == mask)
			return 0;
		udelay(100);
	}
	DRM_ERROR("fifo is NOT empty 0x%08x\n", REG_READ(gen_fifo_stat_reg));
	return -EIO;
}

static int wait_for_all_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
{
	return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(10) | BIT(18) |
						BIT(26) | BIT(27) | BIT(28)));
}

static int wait_for_lp_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
{
	return wait_for_gen_fifo_empty(sender, (BIT(10) | BIT(26)));
}

static int wait_for_hs_fifos_empty(struct mdfld_dsi_pkg_sender *sender)
{
	return wait_for_gen_fifo_empty(sender, (BIT(2) | BIT(18)));
}

static int handle_dsi_error(struct mdfld_dsi_pkg_sender *sender, u32 mask)
{
	u32 intr_stat_reg = sender->mipi_intr_stat_reg;
	struct drm_device *dev = sender->dev;

	dev_dbg(sender->dev->dev, "Handling error 0x%08x\n", mask);

	switch (mask) {
	case BIT(0):
	case BIT(1):
	case BIT(2):
	case BIT(3):
	case BIT(4):
	case BIT(5):
	case BIT(6):
	case BIT(7):
	case BIT(8):
	case BIT(9):
	case BIT(10):
	case BIT(11):
	case BIT(12):
	case BIT(13):
		dev_dbg(sender->dev->dev, "No Action required\n");
		break;
	case BIT(14):
		/*wait for all fifo empty*/
		/*wait_for_all_fifos_empty(sender)*/;
		break;
	case BIT(15):
		dev_dbg(sender->dev->dev, "No Action required\n");
		break;
	case BIT(16):
		break;
	case BIT(17):
		break;
	case BIT(18):
	case BIT(19):
		dev_dbg(sender->dev->dev, "High/Low contention detected\n");
		/*wait for contention recovery time*/
		/*mdelay(10);*/
		/*wait for all fifo empty*/
		if (0)
			wait_for_all_fifos_empty(sender);
		break;
	case BIT(20):
		dev_dbg(sender->dev->dev, "No Action required\n");
		break;
	case BIT(21):
		/*wait for all fifo empty*/
		/*wait_for_all_fifos_empty(sender);*/
		break;
	case BIT(22):
		break;
	case BIT(23):
	case BIT(24):
	case BIT(25):
	case BIT(26):
	case BIT(27):
		dev_dbg(sender->dev->dev, "HS Gen fifo full\n");
		REG_WRITE(intr_stat_reg, mask);
		wait_for_hs_fifos_empty(sender);
		break;
	case BIT(28):
		dev_dbg(sender->dev->dev, "LP Gen fifo full\n");
		REG_WRITE(intr_stat_reg, mask);
		wait_for_lp_fifos_empty(sender);
		break;
	case BIT(29):
	case BIT(30):
	case BIT(31):
		dev_dbg(sender->dev->dev, "No Action required\n");
		break;
	}

	if (mask & REG_READ(intr_stat_reg))
		dev_dbg(sender->dev->dev,
				"Cannot clean interrupt 0x%08x\n", mask);
	return 0;
}

static int dsi_error_handler(struct mdfld_dsi_pkg_sender *sender)
{
	struct drm_device *dev = sender->dev;
	u32 intr_stat_reg = sender->mipi_intr_stat_reg;
	u32 mask;
	u32 intr_stat;
	int i;
	int err = 0;

	intr_stat = REG_READ(intr_stat_reg);

	for (i = 0; i < 32; i++) {
		mask = (0x00000001UL) << i;
		if (intr_stat & mask) {
			dev_dbg(sender->dev->dev, "[DSI]: %s\n", dsi_errors[i]);
			err = handle_dsi_error(sender, mask);
			if (err)
				DRM_ERROR("Cannot handle error\n");
		}
	}
	return err;
}

static int send_short_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
			u8 cmd, u8 param, bool hs)
{
	struct drm_device *dev = sender->dev;
	u32 ctrl_reg;
	u32 val;
	u8 virtual_channel = 0;

	if (hs) {
		ctrl_reg = sender->mipi_hs_gen_ctrl_reg;

		/* FIXME: wait_for_hs_fifos_empty(sender); */
	} else {
		ctrl_reg = sender->mipi_lp_gen_ctrl_reg;

		/* FIXME: wait_for_lp_fifos_empty(sender); */
	}

	val = FLD_VAL(param, 23, 16) | FLD_VAL(cmd, 15, 8) |
		FLD_VAL(virtual_channel, 7, 6) | FLD_VAL(data_type, 5, 0);

	REG_WRITE(ctrl_reg, val);

	return 0;
}

static int send_long_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
			u8 *data, int len, bool hs)
{
	struct drm_device *dev = sender->dev;
	u32 ctrl_reg;
	u32 data_reg;
	u32 val;
	u8 *p;
	u8 b1, b2, b3, b4;
	u8 virtual_channel = 0;
	int i;

	if (hs) {
		ctrl_reg = sender->mipi_hs_gen_ctrl_reg;
		data_reg = sender->mipi_hs_gen_data_reg;

		/* FIXME: wait_for_hs_fifos_empty(sender); */
	} else {
		ctrl_reg = sender->mipi_lp_gen_ctrl_reg;
		data_reg = sender->mipi_lp_gen_data_reg;

		/* FIXME: wait_for_lp_fifos_empty(sender); */
	}

	p = data;
	for (i = 0; i < len / 4; i++) {
		b1 = *p++;
		b2 = *p++;
		b3 = *p++;
		b4 = *p++;

		REG_WRITE(data_reg, b4 << 24 | b3 << 16 | b2 << 8 | b1);
	}

	i = len % 4;
	if (i) {
		b1 = 0; b2 = 0; b3 = 0;

		switch (i) {
		case 3:
			b1 = *p++;
			b2 = *p++;
			b3 = *p++;
			break;
		case 2:
			b1 = *p++;
			b2 = *p++;
			break;
		case 1:
			b1 = *p++;
			break;
		}

		REG_WRITE(data_reg, b3 << 16 | b2 << 8 | b1);
	}

	val = FLD_VAL(len, 23, 8) | FLD_VAL(virtual_channel, 7, 6) |
		FLD_VAL(data_type, 5, 0);

	REG_WRITE(ctrl_reg, val);

	return 0;
}

static int send_pkg_prepare(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
			u8 *data, u16 len)
{
	u8 cmd;

	switch (data_type) {
	case DSI_DT_DCS_SHORT_WRITE_0:
	case DSI_DT_DCS_SHORT_WRITE_1:
	case DSI_DT_DCS_LONG_WRITE:
		cmd = *data;
		break;
	default:
		return 0;
	}

	/*this prevents other package sending while doing msleep*/
	sender->status = MDFLD_DSI_PKG_SENDER_BUSY;

	/*wait for 120 milliseconds in case exit_sleep_mode just be sent*/
	if (unlikely(cmd == DCS_ENTER_SLEEP_MODE)) {
		/*TODO: replace it with msleep later*/
		mdelay(120);
	}

	if (unlikely(cmd == DCS_EXIT_SLEEP_MODE)) {
		/*TODO: replace it with msleep later*/
		mdelay(120);
	}
	return 0;
}

static int send_pkg_done(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
			u8 *data, u16 len)
{
	u8 cmd;

	switch (data_type) {
	case DSI_DT_DCS_SHORT_WRITE_0:
	case DSI_DT_DCS_SHORT_WRITE_1:
	case DSI_DT_DCS_LONG_WRITE:
		cmd = *data;
		break;
	default:
		return 0;
	}

	/*update panel status*/
	if (unlikely(cmd == DCS_ENTER_SLEEP_MODE)) {
		sender->panel_mode |= MDFLD_DSI_PANEL_MODE_SLEEP;
		/*TODO: replace it with msleep later*/
		mdelay(120);
	} else if (unlikely(cmd == DCS_EXIT_SLEEP_MODE)) {
		sender->panel_mode &= ~MDFLD_DSI_PANEL_MODE_SLEEP;
		/*TODO: replace it with msleep later*/
		mdelay(120);
	} else if (unlikely(cmd == DCS_SOFT_RESET)) {
		/*TODO: replace it with msleep later*/
		mdelay(5);
	}

	sender->status = MDFLD_DSI_PKG_SENDER_FREE;

	return 0;
}

static int send_pkg(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
		u8 *data, u16 len, bool hs)
{
	int ret;

	/*handle DSI error*/
	ret = dsi_error_handler(sender);
	if (ret) {
		DRM_ERROR("Error handling failed\n");
		return -EAGAIN;
	}

	/* send pkg */
	if (sender->status == MDFLD_DSI_PKG_SENDER_BUSY) {
		DRM_ERROR("sender is busy\n");
		return -EAGAIN;
	}

	ret = send_pkg_prepare(sender, data_type, data, len);
	if (ret) {
		DRM_ERROR("send_pkg_prepare error\n");
		return ret;
	}

	switch (data_type) {
	case DSI_DT_GENERIC_SHORT_WRITE_0:
	case DSI_DT_GENERIC_SHORT_WRITE_1:
	case DSI_DT_GENERIC_SHORT_WRITE_2:
	case DSI_DT_GENERIC_READ_0:
	case DSI_DT_GENERIC_READ_1:
	case DSI_DT_GENERIC_READ_2:
	case DSI_DT_DCS_SHORT_WRITE_0:
	case DSI_DT_DCS_SHORT_WRITE_1:
	case DSI_DT_DCS_READ:
		ret = send_short_pkg(sender, data_type, data[0], data[1], hs);
		break;
	case DSI_DT_GENERIC_LONG_WRITE:
	case DSI_DT_DCS_LONG_WRITE:
		ret = send_long_pkg(sender, data_type, data, len, hs);
		break;
	}

	send_pkg_done(sender, data_type, data, len);

	/*FIXME: should I query complete and fifo empty here?*/

	return ret;
}

int mdfld_dsi_send_mcs_long(struct mdfld_dsi_pkg_sender *sender, u8 *data,
			u32 len, bool hs)
{
	unsigned long flags;

	if (!sender || !data || !len) {
		DRM_ERROR("Invalid parameters\n");
		return -EINVAL;
	}

	spin_lock_irqsave(&sender->lock, flags);
	send_pkg(sender, DSI_DT_DCS_LONG_WRITE, data, len, hs);
	spin_unlock_irqrestore(&sender->lock, flags);

	return 0;
}

int mdfld_dsi_send_mcs_short(struct mdfld_dsi_pkg_sender *sender, u8 cmd,
			u8 param, u8 param_num, bool hs)
{
	u8 data[2];
	unsigned long flags;
	u8 data_type;

	if (!sender) {
		DRM_ERROR("Invalid parameter\n");
		return -EINVAL;
	}

	data[0] = cmd;

	if (param_num) {
		data_type = DSI_DT_DCS_SHORT_WRITE_1;
		data[1] = param;
	} else {
		data_type = DSI_DT_DCS_SHORT_WRITE_0;
		data[1] = 0;
	}

	spin_lock_irqsave(&sender->lock, flags);
	send_pkg(sender, data_type, data, sizeof(data), hs);
	spin_unlock_irqrestore(&sender->lock, flags);

	return 0;
}

int mdfld_dsi_send_gen_short(struct mdfld_dsi_pkg_sender *sender, u8 param0,
			u8 param1, u8 param_num, bool hs)
{
	u8 data[2];
	unsigned long flags;
	u8 data_type;

	if (!sender || param_num > 2) {
		DRM_ERROR("Invalid parameter\n");
		return -EINVAL;
	}

	switch (param_num) {
	case 0:
		data_type = DSI_DT_GENERIC_SHORT_WRITE_0;
		data[0] = 0;
		data[1] = 0;
		break;
	case 1:
		data_type = DSI_DT_GENERIC_SHORT_WRITE_1;
		data[0] = param0;
		data[1] = 0;
		break;
	case 2:
		data_type = DSI_DT_GENERIC_SHORT_WRITE_2;
		data[0] = param0;
		data[1] = param1;
		break;
	}

	spin_lock_irqsave(&sender->lock, flags);
	send_pkg(sender, data_type, data, sizeof(data), hs);
	spin_unlock_irqrestore(&sender->lock, flags);

	return 0;
}

int mdfld_dsi_send_gen_long(struct mdfld_dsi_pkg_sender *sender, u8 *data,
			u32 len, bool hs)
{
	unsigned long flags;

	if (!sender || !data || !len) {
		DRM_ERROR("Invalid parameters\n");
		return -EINVAL;
	}

	spin_lock_irqsave(&sender->lock, flags);
	send_pkg(sender, DSI_DT_GENERIC_LONG_WRITE, data, len, hs);
	spin_unlock_irqrestore(&sender->lock, flags);

	return 0;
}

static int __read_panel_data(struct mdfld_dsi_pkg_sender *sender, u8 data_type,
			u8 *data, u16 len, u32 *data_out, u16 len_out, bool hs)
{
	unsigned long flags;
	struct drm_device *dev = sender->dev;
	int i;
	u32 gen_data_reg;
	int retry = MDFLD_DSI_READ_MAX_COUNT;

	if (!sender || !data_out || !len_out) {
		DRM_ERROR("Invalid parameters\n");
		return -EINVAL;
	}

	/**
	 * do reading.
	 * 0) send out generic read request
	 * 1) polling read data avail interrupt
	 * 2) read data
	 */
	spin_lock_irqsave(&sender->lock, flags);

	REG_WRITE(sender->mipi_intr_stat_reg, BIT(29));

	if ((REG_READ(sender->mipi_intr_stat_reg) & BIT(29)))
		DRM_ERROR("Can NOT clean read data valid interrupt\n");

	/*send out read request*/
	send_pkg(sender, data_type, data, len, hs);

	/*polling read data avail interrupt*/
	while (retry && !(REG_READ(sender->mipi_intr_stat_reg) & BIT(29))) {
		udelay(100);
		retry--;
	}

	if (!retry) {
		spin_unlock_irqrestore(&sender->lock, flags);
		return -ETIMEDOUT;
	}

	REG_WRITE(sender->mipi_intr_stat_reg, BIT(29));

	/*read data*/
	if (hs)
		gen_data_reg = sender->mipi_hs_gen_data_reg;
	else
		gen_data_reg = sender->mipi_lp_gen_data_reg;

	for (i = 0; i < len_out; i++)
		*(data_out + i) = REG_READ(gen_data_reg);

	spin_unlock_irqrestore(&sender->lock, flags);

	return 0;
}

int mdfld_dsi_read_mcs(struct mdfld_dsi_pkg_sender *sender, u8 cmd,
		u32 *data, u16 len, bool hs)
{
	if (!sender || !data || !len) {
		DRM_ERROR("Invalid parameters\n");
		return -EINVAL;
	}

	return __read_panel_data(sender, DSI_DT_DCS_READ, &cmd, 1,
				data, len, hs);
}

int mdfld_dsi_pkg_sender_init(struct mdfld_dsi_connector *dsi_connector,
								int pipe)
{
	struct mdfld_dsi_pkg_sender *pkg_sender;
	struct mdfld_dsi_config *dsi_config =
				mdfld_dsi_get_config(dsi_connector);
	struct drm_device *dev = dsi_config->dev;
	struct drm_psb_private *dev_priv = dev->dev_private;
	const struct psb_offset *map = &dev_priv->regmap[pipe];
	u32 mipi_val = 0;

	if (!dsi_connector) {
		DRM_ERROR("Invalid parameter\n");
		return -EINVAL;
	}

	pkg_sender = dsi_connector->pkg_sender;

	if (!pkg_sender || IS_ERR(pkg_sender)) {
		pkg_sender = kzalloc(sizeof(struct mdfld_dsi_pkg_sender),
								GFP_KERNEL);
		if (!pkg_sender) {
			DRM_ERROR("Create DSI pkg sender failed\n");
			return -ENOMEM;
		}
		dsi_connector->pkg_sender = (void *)pkg_sender;
	}

	pkg_sender->dev = dev;
	pkg_sender->dsi_connector = dsi_connector;
	pkg_sender->pipe = pipe;
	pkg_sender->pkg_num = 0;
	pkg_sender->panel_mode = 0;
	pkg_sender->status = MDFLD_DSI_PKG_SENDER_FREE;

	/*init regs*/
	/* FIXME: should just copy the regmap ptr ? */
	pkg_sender->dpll_reg = map->dpll;
	pkg_sender->dspcntr_reg = map->cntr;
	pkg_sender->pipeconf_reg = map->conf;
	pkg_sender->dsplinoff_reg = map->linoff;
	pkg_sender->dspsurf_reg = map->surf;
	pkg_sender->pipestat_reg = map->status;

	pkg_sender->mipi_intr_stat_reg = MIPI_INTR_STAT_REG(pipe);
	pkg_sender->mipi_lp_gen_data_reg = MIPI_LP_GEN_DATA_REG(pipe);
	pkg_sender->mipi_hs_gen_data_reg = MIPI_HS_GEN_DATA_REG(pipe);
	pkg_sender->mipi_lp_gen_ctrl_reg = MIPI_LP_GEN_CTRL_REG(pipe);
	pkg_sender->mipi_hs_gen_ctrl_reg = MIPI_HS_GEN_CTRL_REG(pipe);
	pkg_sender->mipi_gen_fifo_stat_reg = MIPI_GEN_FIFO_STAT_REG(pipe);
	pkg_sender->mipi_data_addr_reg = MIPI_DATA_ADD_REG(pipe);
	pkg_sender->mipi_data_len_reg = MIPI_DATA_LEN_REG(pipe);
	pkg_sender->mipi_cmd_addr_reg = MIPI_CMD_ADD_REG(pipe);
	pkg_sender->mipi_cmd_len_reg = MIPI_CMD_LEN_REG(pipe);

	/*init lock*/
	spin_lock_init(&pkg_sender->lock);

	if (mdfld_get_panel_type(dev, pipe) != TC35876X) {
		/**
		 * For video mode, don't enable DPI timing output here,
		 * will init the DPI timing output during mode setting.
		 */
		mipi_val = PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;

		if (pipe == 0)
			mipi_val |= 0x2;

		REG_WRITE(MIPI_PORT_CONTROL(pipe), mipi_val);
		REG_READ(MIPI_PORT_CONTROL(pipe));

		/* do dsi controller init */
		mdfld_dsi_controller_init(dsi_config, pipe);
	}

	return 0;
}

void mdfld_dsi_pkg_sender_destroy(struct mdfld_dsi_pkg_sender *sender)
{
	if (!sender || IS_ERR(sender))
		return;

	/*free*/
	kfree(sender);
}


