/* SPDX-License-Identifier: GPL-2.0-only */

#include <commonlib/helpers.h>
#include <console/console.h>
#include <device/mmio.h>
#include <delay.h>
#include <timer.h>
#include <soc/addressmap.h>
#include <soc/clock.h>
#include <device/device.h>
#include <edid.h>
#include <soc/nvidia/tegra/types.h>
#include <soc/nvidia/tegra/dc.h>
#include <soc/display.h>
#include <soc/mipi_dsi.h>
#include <soc/mipi_display.h>
#include <soc/tegra_dsi.h>
#include <soc/mipi-phy.h>
#include <types.h>

#include "chip.h"
#include "jdi_25x18_display/panel-jdi-lpm102a188a.h"

struct tegra_mipi_device mipi_device_data[NUM_DSI];

struct tegra_dsi dsi_data[NUM_DSI] = {
	{
		.regs = (void *)TEGRA_DSIA_BASE,
		.channel = 0,
		.slave = &dsi_data[DSI_B],
		.master = NULL,
		.video_fifo_depth = MAX_DSI_VIDEO_FIFO_DEPTH,
		.host_fifo_depth = MAX_DSI_HOST_FIFO_DEPTH,
	},
	{
		.regs = (void *)TEGRA_DSIB_BASE,
		.channel = 0,
		.slave = NULL,
		.master = &dsi_data[DSI_A],
		.video_fifo_depth = MAX_DSI_VIDEO_FIFO_DEPTH,
		.host_fifo_depth = MAX_DSI_HOST_FIFO_DEPTH,
	},
};

static const u32 init_reg[] = {
	DSI_INT_ENABLE,
	DSI_INT_STATUS,
	DSI_INT_MASK,
	DSI_INIT_SEQ_DATA_0,
	DSI_INIT_SEQ_DATA_1,
	DSI_INIT_SEQ_DATA_2,
	DSI_INIT_SEQ_DATA_3,
	DSI_INIT_SEQ_DATA_4,
	DSI_INIT_SEQ_DATA_5,
	DSI_INIT_SEQ_DATA_6,
	DSI_INIT_SEQ_DATA_7,
	DSI_INIT_SEQ_DATA_15,
	DSI_DCS_CMDS,
	DSI_PKT_SEQ_0_LO,
	DSI_PKT_SEQ_1_LO,
	DSI_PKT_SEQ_2_LO,
	DSI_PKT_SEQ_3_LO,
	DSI_PKT_SEQ_4_LO,
	DSI_PKT_SEQ_5_LO,
	DSI_PKT_SEQ_0_HI,
	DSI_PKT_SEQ_1_HI,
	DSI_PKT_SEQ_2_HI,
	DSI_PKT_SEQ_3_HI,
	DSI_PKT_SEQ_4_HI,
	DSI_PKT_SEQ_5_HI,
	DSI_CONTROL,
	DSI_HOST_CONTROL,
	DSI_PAD_CONTROL_0,
	DSI_PAD_CONTROL_CD,
	DSI_SOL_DELAY,
	DSI_MAX_THRESHOLD,
	DSI_TRIGGER,
	DSI_TX_CRC,
	DSI_INIT_SEQ_CONTROL,
	DSI_PKT_LEN_0_1,
	DSI_PKT_LEN_2_3,
	DSI_PKT_LEN_4_5,
	DSI_PKT_LEN_6_7,
};

static inline struct tegra_dsi *host_to_tegra(struct mipi_dsi_host *host)
{
	return container_of(host, struct tegra_dsi, host);
}

/*
 * non-burst mode with sync pulses
 */
static const u32 pkt_seq_video_non_burst_sync_pulses[NUM_PKT_SEQ] = {
	[ 0] = PKT_ID0(MIPI_DSI_V_SYNC_START) | PKT_LEN0(0) |
	       PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
	       PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0) |
	       PKT_LP,
	[ 1] = 0,
	[ 2] = PKT_ID0(MIPI_DSI_V_SYNC_END) | PKT_LEN0(0) |
	       PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
	       PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0) |
	       PKT_LP,
	[ 3] = 0,
	[ 4] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
	       PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
	       PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0) |
	       PKT_LP,
	[ 5] = 0,
	[ 6] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
	       PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
	       PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0),
	[ 7] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(2) |
	       PKT_ID1(MIPI_DSI_PACKED_PIXEL_STREAM_24) | PKT_LEN1(3) |
	       PKT_ID2(MIPI_DSI_BLANKING_PACKET) | PKT_LEN2(4),
	[ 8] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
	       PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
	       PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0) |
	       PKT_LP,
	[ 9] = 0,
	[10] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
	       PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(1) |
	       PKT_ID2(MIPI_DSI_H_SYNC_END) | PKT_LEN2(0),
	[11] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(2) |
	       PKT_ID1(MIPI_DSI_PACKED_PIXEL_STREAM_24) | PKT_LEN1(3) |
	       PKT_ID2(MIPI_DSI_BLANKING_PACKET) | PKT_LEN2(4),
};

/*
 * non-burst mode with sync events
 */
static const u32 pkt_seq_video_non_burst_sync_events[NUM_PKT_SEQ] = {
	[ 0] = PKT_ID0(MIPI_DSI_V_SYNC_START) | PKT_LEN0(0) |
	       PKT_ID1(MIPI_DSI_END_OF_TRANSMISSION) | PKT_LEN1(7) |
	       PKT_LP,
	[ 1] = 0,
	[ 2] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
	       PKT_ID1(MIPI_DSI_END_OF_TRANSMISSION) | PKT_LEN1(7) |
	       PKT_LP,
	[ 3] = 0,
	[ 4] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
	       PKT_ID1(MIPI_DSI_END_OF_TRANSMISSION) | PKT_LEN1(7) |
	       PKT_LP,
	[ 5] = 0,

	[ 6] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
	       PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(2) |
	       PKT_ID2(MIPI_DSI_PACKED_PIXEL_STREAM_24) | PKT_LEN2(3),

	[ 7] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(4),
	[ 8] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
	       PKT_ID1(MIPI_DSI_END_OF_TRANSMISSION) | PKT_LEN1(7) |
	       PKT_LP,
	[ 9] = 0,

	[10] = PKT_ID0(MIPI_DSI_H_SYNC_START) | PKT_LEN0(0) |
	       PKT_ID1(MIPI_DSI_BLANKING_PACKET) | PKT_LEN1(2) |
	       PKT_ID2(MIPI_DSI_PACKED_PIXEL_STREAM_24) | PKT_LEN2(3),

	[11] = PKT_ID0(MIPI_DSI_BLANKING_PACKET) | PKT_LEN0(4),
};

static const u32 pkt_seq_command_mode[NUM_PKT_SEQ] = {
	[ 0] = 0,
	[ 1] = 0,
	[ 2] = 0,
	[ 3] = 0,
	[ 4] = 0,
	[ 5] = 0,
	[ 6] = PKT_ID0(MIPI_DSI_DCS_LONG_WRITE) | PKT_LEN0(3) | PKT_LP,
	[ 7] = 0,
	[ 8] = 0,
	[ 9] = 0,
	[10] = PKT_ID0(MIPI_DSI_DCS_LONG_WRITE) | PKT_LEN0(5) | PKT_LP,
	[11] = 0,
};

static int tegra_dsi_set_phy_timing(struct tegra_dsi *dsi)
{
	int err;

	err = mipi_dphy_set_timing(dsi);
	if (err < 0) {
		printk(BIOS_ERR, "failed to set D-PHY timing: %d\n", err);
		return err;
	}

	if (dsi->slave)
		tegra_dsi_set_phy_timing(dsi->slave);
	return 0;
}

static int tegra_dsi_get_muldiv(enum mipi_dsi_pixel_format format,
				unsigned int *mulp, unsigned int *divp)
{
	switch (format) {
	case MIPI_DSI_FMT_RGB666_PACKED:
	case MIPI_DSI_FMT_RGB888:
		*mulp = 3;
		*divp = 1;
		break;

	case MIPI_DSI_FMT_RGB565:
		*mulp = 2;
		*divp = 1;
		break;

	case MIPI_DSI_FMT_RGB666:
		*mulp = 9;
		*divp = 4;
		break;

	default:
		return -EINVAL;
	}
	return 0;
}

static int tegra_dsi_get_format(enum mipi_dsi_pixel_format format,
				enum tegra_dsi_format *fmt)
{
	switch (format) {
	case MIPI_DSI_FMT_RGB888:
		*fmt = TEGRA_DSI_FORMAT_24P;
		break;

	case MIPI_DSI_FMT_RGB666:
		*fmt = TEGRA_DSI_FORMAT_18NP;
		break;

	case MIPI_DSI_FMT_RGB666_PACKED:
		*fmt = TEGRA_DSI_FORMAT_18P;
		break;

	case MIPI_DSI_FMT_RGB565:
		*fmt = TEGRA_DSI_FORMAT_16P;
		break;

	default:
		return -EINVAL;
	}
	return 0;
}

static void tegra_dsi_ganged_enable(struct tegra_dsi *dsi, unsigned int start,
				    unsigned int size)
{
	u32 value;

	tegra_dsi_writel(dsi, start, DSI_GANGED_MODE_START);
	tegra_dsi_writel(dsi, size << 16 | size, DSI_GANGED_MODE_SIZE);

	value = DSI_GANGED_MODE_CONTROL_ENABLE;
	tegra_dsi_writel(dsi, value, DSI_GANGED_MODE_CONTROL);
}

static void tegra_dsi_enable(struct tegra_dsi *dsi)
{
	u32 value;

	value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL);
	value |= DSI_POWER_CONTROL_ENABLE;
	tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL);

	if (dsi->slave)
		tegra_dsi_enable(dsi->slave);
}

static int tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe,
			const struct soc_nvidia_tegra210_config *mode)
{
	unsigned int hact, hsw, hbp, hfp, i, mul, div;
	enum tegra_dsi_format format;
	const u32 *pkt_seq;
	u32 value;
	int err;

	if (dsi->flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) {
		printk(BIOS_SPEW, "Non-burst video mode with sync pulses\n");
		pkt_seq = pkt_seq_video_non_burst_sync_pulses;
	} else if (dsi->flags & MIPI_DSI_MODE_VIDEO) {
		printk(BIOS_SPEW, "Non-burst video mode with sync events\n");
		pkt_seq = pkt_seq_video_non_burst_sync_events;
	} else {
		printk(BIOS_SPEW, "Command mode\n");
		pkt_seq = pkt_seq_command_mode;
	}

	err = tegra_dsi_get_muldiv(dsi->format, &mul, &div);
	if (err < 0)
		return err;

	err = tegra_dsi_get_format(dsi->format, &format);
	if (err < 0)
		return err;

	value = DSI_CONTROL_CHANNEL(0) | DSI_CONTROL_FORMAT(format) |
		DSI_CONTROL_LANES(dsi->lanes - 1) |
		DSI_CONTROL_SOURCE(pipe);
	tegra_dsi_writel(dsi, value, DSI_CONTROL);

	tegra_dsi_writel(dsi, dsi->video_fifo_depth, DSI_MAX_THRESHOLD);

	value = DSI_HOST_CONTROL_HS;
	tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL);

	value = tegra_dsi_readl(dsi, DSI_CONTROL);

	if (dsi->flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
		value |= DSI_CONTROL_HS_CLK_CTRL;

	value &= ~DSI_CONTROL_TX_TRIG(3);

	/* enable DCS commands for command mode */
	if (dsi->flags & MIPI_DSI_MODE_VIDEO)
		value &= ~DSI_CONTROL_DCS_ENABLE;
	else
		value |= DSI_CONTROL_DCS_ENABLE;

	value |= DSI_CONTROL_VIDEO_ENABLE;
	value &= ~DSI_CONTROL_HOST_ENABLE;
	tegra_dsi_writel(dsi, value, DSI_CONTROL);

	for (i = 0; i < NUM_PKT_SEQ; i++)
		tegra_dsi_writel(dsi, pkt_seq[i], DSI_PKT_SEQ_0_LO + i);

	if (dsi->flags & MIPI_DSI_MODE_VIDEO) {
		/* horizontal active pixels */
		hact = mode->xres * mul / div;

		/* horizontal sync width */
		hsw = (hsync_end(mode) - hsync_start(mode)) * mul / div;

		/* horizontal back porch */
		hbp = (htotal(mode) - hsync_end(mode)) * mul / div;
		if ((dsi->flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) == 0)
			hbp += hsw;

		/* horizontal front porch */
		hfp = (hsync_start(mode) - mode->xres) * mul / div;

		/* subtract packet overhead */
		hsw -= 10;
		hbp -= 14;
		hfp -= 8;

		tegra_dsi_writel(dsi, hsw << 16 | 0, DSI_PKT_LEN_0_1);
		tegra_dsi_writel(dsi, hact << 16 | hbp, DSI_PKT_LEN_2_3);
		tegra_dsi_writel(dsi, hfp, DSI_PKT_LEN_4_5);
		tegra_dsi_writel(dsi, 0x0f0f << 16, DSI_PKT_LEN_6_7);

		/* set SOL delay (for non-burst mode only) */
		tegra_dsi_writel(dsi, 8 * mul / div, DSI_SOL_DELAY);

		/* TODO: implement ganged mode */
	} else {
		u16 bytes;
		if (dsi->ganged_mode) {
			/*
			 * For ganged mode, assume symmetric left-right mode.
			 */
			bytes = 1 + (mode->xres / 2) * mul / div;
		} else {
			/* 1 byte (DCS command) + pixel data */
			bytes = 1 + mode->xres * mul / div;
		}

		tegra_dsi_writel(dsi, 0, DSI_PKT_LEN_0_1);
		tegra_dsi_writel(dsi, (u32)bytes << 16, DSI_PKT_LEN_2_3);
		tegra_dsi_writel(dsi, (u32)bytes << 16, DSI_PKT_LEN_4_5);
		tegra_dsi_writel(dsi, 0, DSI_PKT_LEN_6_7);

		value = MIPI_DCS_WRITE_MEMORY_START << 8 |
			MIPI_DCS_WRITE_MEMORY_CONTINUE;
		tegra_dsi_writel(dsi, value, DSI_DCS_CMDS);

		/* set SOL delay */
		if (dsi->ganged_mode) {
			unsigned long delay, bclk, bclk_ganged;
			unsigned int lanes = dsi->ganged_lanes;

			/* SOL to valid, valid to FIFO and FIFO write delay */
			delay = 4 + 4 + 2;
			delay = DIV_ROUND_UP(delay * mul, div * lanes);
			/* FIFO read delay */
			delay = delay + 6;

			bclk = DIV_ROUND_UP(htotal(mode) * mul, div * lanes);
			bclk_ganged = DIV_ROUND_UP(bclk * lanes / 2, lanes);
			value = bclk - bclk_ganged + delay + 20;
		} else {
			/* TODO: revisit for non-ganged mode */
			value = 8 * mul / div;
		}

		tegra_dsi_writel(dsi, value, DSI_SOL_DELAY);
	}

	if (dsi->slave) {
		err = tegra_dsi_configure(dsi->slave, pipe, mode);
		if (err < 0)
			return err;

		/*
		 * enable ganged mode
		 */
		if (dsi->ganged_mode) {
			tegra_dsi_ganged_enable(dsi, mode->xres / 2,
					mode->xres / 2);
			tegra_dsi_ganged_enable(dsi->slave, 0, mode->xres / 2);
		}
	}
	return 0;
}

static int tegra_output_dsi_enable(struct tegra_dsi *dsi,
			const struct soc_nvidia_tegra210_config *config)
{
	int err;

	if (dsi->enabled)
		return 0;

	err = tegra_dsi_configure(dsi, 0, config);
	if (err < 0) {
		printk(BIOS_ERR, "DSI configuration failed\n");
		return err;
	}

	/* enable DSI controller */
	tegra_dsi_enable(dsi);

	dsi->enabled = true;
	return 0;
}

static void tegra_dsi_set_timeout(struct tegra_dsi *dsi, unsigned long bclk,
				  unsigned int vrefresh)
{
	unsigned int timeout;
	u32 value;

	/* one frame high-speed transmission timeout */
	timeout = (bclk / vrefresh) / 512;
	value = DSI_TIMEOUT_LRX(0x2000) | DSI_TIMEOUT_HTX(timeout);
	tegra_dsi_writel(dsi, value, DSI_TIMEOUT_0);

	/* 2 ms peripheral timeout for panel */
	timeout = 2 * bclk / 512 * 1000;
	value = DSI_TIMEOUT_PR(timeout) | DSI_TIMEOUT_TA(0x2000);
	tegra_dsi_writel(dsi, value, DSI_TIMEOUT_1);

	value = DSI_TALLY_TA(0) | DSI_TALLY_LRX(0) | DSI_TALLY_HTX(0);
	tegra_dsi_writel(dsi, value, DSI_TO_TALLY);

	if (dsi->slave)
		tegra_dsi_set_timeout(dsi->slave, bclk, vrefresh);
}

static int tegra_output_dsi_setup_clock(struct tegra_dsi *dsi,
			const struct soc_nvidia_tegra210_config *config)
{
	unsigned int mul, div, num_lanes;
	unsigned long bclk;
	unsigned long pclk = config->pixel_clock;
	int plld;
	int err;
	struct display_controller *disp_ctrl =
			(void *)config->display_controller;
	unsigned int shift_clk_div;

	err = tegra_dsi_get_muldiv(dsi->format, &mul, &div);
	if (err < 0)
		return err;

	/*
	 * In ganged mode, account for the total number of lanes across both
	 * DSI channels so that the bit clock is properly computed.
	 */
	if (dsi->ganged_mode)
		num_lanes = dsi->ganged_lanes;
	else
		num_lanes = dsi->lanes;

	/* compute byte clock */
	bclk = (pclk * mul) / (div * num_lanes);

	/*
	 * Compute bit clock and round up to the next MHz.
	 */
	plld = DIV_ROUND_UP(bclk * 8, USECS_PER_SEC) * USECS_PER_SEC;

	/*
	 * the actual rate on PLLD_OUT0 is 1/2 plld
	 */
	dsi->clk_rate = plld / 2;
	if (dsi->slave)
		dsi->slave->clk_rate = dsi->clk_rate;

	/* set up plld */
	plld = clock_configure_plld(plld);
	if (plld == 0) {
		printk(BIOS_ERR, "%s: clock init failed\n", __func__);
		return -1;
	} else
		printk(BIOS_INFO, "%s:  plld is configured to: %u\n",
			 __func__, plld);

	/*
	 * Derive pixel clock from bit clock using the shift clock divider.
	 * Note that this is only half of what we would expect, but we need
	 * that to make up for the fact that we divided the bit clock by a
	 * factor of two above.
	 */
	shift_clk_div = ((8 * mul) / (div * num_lanes)) - 2;
	update_display_shift_clock_divider(disp_ctrl, shift_clk_div);

	tegra_dsi_set_timeout(dsi, bclk, config->refresh);
	return plld/1000000;
}

static int tegra_dsi_pad_enable(struct tegra_dsi *dsi)
{
	unsigned long value;

	value = DSI_PAD_CONTROL_VS1_PULLDN(0) | DSI_PAD_CONTROL_VS1_PDIO(0);
	tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_0);
	return 0;
}

static int tegra_dsi_pad_calibrate(struct tegra_dsi *dsi)
{
	u32 value;

	tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_0);
	tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_1);
	tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_2);
	tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_3);
	tegra_dsi_writel(dsi, 0, DSI_PAD_CONTROL_4);

	/* start calibration */
	tegra_dsi_pad_enable(dsi);

	value = DSI_PAD_SLEW_UP(0x7) | DSI_PAD_SLEW_DN(0x7) |
		DSI_PAD_LP_UP(0x1) | DSI_PAD_LP_DN(0x1) |
		DSI_PAD_OUT_CLK(0x0);
	tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_2);

	value = DSI_PAD_PREEMP_PD_CLK(0x3) | DSI_PAD_PREEMP_PU_CLK(0x3) |
		DSI_PAD_PREEMP_PD(0x03) | DSI_PAD_PREEMP_PU(0x3);
	tegra_dsi_writel(dsi, value, DSI_PAD_CONTROL_3);

	return tegra_mipi_calibrate(dsi->mipi);
}

static const char *const error_report[16] = {
	"SoT Error",
	"SoT Sync Error",
	"EoT Sync Error",
	"Escape Mode Entry Command Error",
	"Low-Power Transmit Sync Error",
	"Peripheral Timeout Error",
	"False Control Error",
	"Contention Detected",
	"ECC Error, single-bit",
	"ECC Error, multi-bit",
	"Checksum Error",
	"DSI Data Type Not Recognized",
	"DSI VC ID Invalid",
	"Invalid Transmission Length",
	"Reserved",
	"DSI Protocol Violation",
};

static int tegra_dsi_read_response(struct tegra_dsi *dsi,
				   const struct mipi_dsi_msg *msg,
				   unsigned int count)
{
	u8 *rx = msg->rx_buf;
	unsigned int i, j, k;
	size_t size = 0;
	u16 errors;
	u32 value;

	/* read and parse packet header */
	value = tegra_dsi_readl(dsi, DSI_RD_DATA);

	switch (value & 0x3f) {
	case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
		errors = (value >> 8) & 0xffff;
		printk(BIOS_ERR, "Acknowledge and error report: %04x\n",
			errors);
		for (i = 0; i < ARRAY_SIZE(error_report); i++)
			if (errors & BIT(i))
				printk(BIOS_INFO, "  %2u: %s\n", i,
					error_report[i]);
		break;

	case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
		rx[0] = (value >> 8) & 0xff;
		break;

	case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
		rx[0] = (value >>  8) & 0xff;
		rx[1] = (value >> 16) & 0xff;
		break;

	case MIPI_DSI_RX_DCS_LONG_READ_RESPONSE:
		size = ((value >> 8) & 0xff00) | ((value >> 8) & 0xff);
		break;

	case MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE:
		size = ((value >> 8) & 0xff00) | ((value >> 8) & 0xff);
		break;

	default:
		printk(BIOS_ERR, "unhandled response type: %02x\n",
			value & 0x3f);
		break;
	}

	size = MIN(size, msg->rx_len);

	if (msg->rx_buf && size > 0) {
		for (i = 0, j = 0; i < count - 1; i++, j += 4) {
			value = tegra_dsi_readl(dsi, DSI_RD_DATA);

			for (k = 0; k < 4 && (j + k) < msg->rx_len; k++)
				rx[j + k] = (value >> (k << 3)) & 0xff;
		}
	}
	return 0;
}

static int tegra_dsi_transmit(struct tegra_dsi *dsi, unsigned long timeout_ms)
{
	u32 poll_interval_us = 2000;
	u32 timeout_us = timeout_ms * 1000;

	tegra_dsi_writel(dsi, DSI_TRIGGER_HOST, DSI_TRIGGER);
	udelay(poll_interval_us);

	do {
		u32 value = tegra_dsi_readl(dsi, DSI_TRIGGER);
		if ((value & DSI_TRIGGER_HOST) == 0)
			return 0;

		//usleep_range(1000, 2000);
		if (timeout_us > poll_interval_us)
			timeout_us -= poll_interval_us;
		else
			break;

		udelay(poll_interval_us);
	} while (1);

	printk(BIOS_ERR, "%s: ERROR: timeout waiting for transmission"
			" to complete\n", __func__);
	return -ETIMEDOUT;
}

static int tegra_dsi_wait_for_response(struct tegra_dsi *dsi,
				       unsigned long timeout_ms)
{
	u32 poll_interval_us = 2000;
	u32 timeout_us = timeout_ms * 1000;

	do {
		u32 value = tegra_dsi_readl(dsi, DSI_STATUS);
		u8 count = value & 0x1f;

		if (count > 0)
			return count;

		if (timeout_us > poll_interval_us)
			timeout_us -= poll_interval_us;
		else
			break;

		udelay(poll_interval_us);
	} while (1);

	printk(BIOS_ERR, "%s: ERROR: timeout\n", __func__);

	return -ETIMEDOUT;
}

static ssize_t tegra_dsi_host_transfer(struct mipi_dsi_host *host,
				const struct mipi_dsi_msg *msg)
{
	struct tegra_dsi *dsi = host_to_tegra(host);
	const u8 *tx = msg->tx_buf;
	unsigned int count, i, j;
	u32 value;
	int err;

	if (msg->tx_len > dsi->video_fifo_depth * 4)
		return -ENOSPC;

	/* reset underflow/overflow flags */
	value = tegra_dsi_readl(dsi, DSI_STATUS);
	if (value & (DSI_STATUS_UNDERFLOW | DSI_STATUS_OVERFLOW)) {
		value = DSI_HOST_CONTROL_FIFO_RESET;
		tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL);
		udelay(20);	// usleep_range(10, 20);
	}

	value = tegra_dsi_readl(dsi, DSI_POWER_CONTROL);
	value |= DSI_POWER_CONTROL_ENABLE;
	tegra_dsi_writel(dsi, value, DSI_POWER_CONTROL);

	udelay(7000);	//usleep_range(5000, 10000);

	value = DSI_HOST_CONTROL_CRC_RESET | DSI_HOST_CONTROL_TX_TRIG_HOST |
		DSI_HOST_CONTROL_CS | DSI_HOST_CONTROL_ECC;

	if ((msg->flags & MIPI_DSI_MSG_USE_LPM) == 0)
		value |= DSI_HOST_CONTROL_HS;

	/*
	 * The host FIFO has a maximum of 64 words, so larger transmissions
	 * need to use the video FIFO.
	 */
	if (msg->tx_len > dsi->host_fifo_depth * 4)
		value |= DSI_HOST_CONTROL_FIFO_SEL;

	tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL);

	/*
	 * For reads and messages with explicitly requested ACK, generate a
	 * BTA sequence after the transmission of the packet.
	 */
	if ((msg->flags & MIPI_DSI_MSG_REQ_ACK) ||
	    (msg->rx_buf && msg->rx_len > 0)) {
		value = tegra_dsi_readl(dsi, DSI_HOST_CONTROL);
		value |= DSI_HOST_CONTROL_PKT_BTA;
		tegra_dsi_writel(dsi, value, DSI_HOST_CONTROL);
	}

	value = DSI_CONTROL_LANES(0) | DSI_CONTROL_HOST_ENABLE;
	tegra_dsi_writel(dsi, value, DSI_CONTROL);

	/* write packet header */
	value = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f);

	if (tx && msg->tx_len > 0)
		value |= tx[0] <<  8;

	if (tx && msg->tx_len > 1)
		value |= tx[1] << 16;

	tegra_dsi_writel(dsi, value, DSI_WR_DATA);

	/* write payload (if any) */
	if (tx && msg->tx_len > 2) {
		for (j = 2; j < msg->tx_len; j += 4) {
			value = 0;

			for (i = 0; i < 4 && j + i < msg->tx_len; i++)
				value |= tx[j + i] << (i << 3);

			tegra_dsi_writel(dsi, value, DSI_WR_DATA);
		}
	}

	err = tegra_dsi_transmit(dsi, 250);
	if (err < 0) {
		printk(BIOS_INFO, "Failed to transmit. %d\n", err);
		return err;
	}

	if ((msg->flags & MIPI_DSI_MSG_REQ_ACK) ||
	    (msg->rx_buf && msg->rx_len > 0)) {
		err = tegra_dsi_wait_for_response(dsi, 250);
		if (err < 0) {
			printk(BIOS_INFO, "Failed to read response. %d\n", err);
			return err;
		}
		count = err;

		value = tegra_dsi_readl(dsi, DSI_RD_DATA);
		switch (value) {
		case 0x84:
			printk(BIOS_INFO, "ACK\n");
			break;

		case 0x87:
			printk(BIOS_INFO, "ESCAPE\n");
			break;

		default:
			printk(BIOS_INFO, "unknown status: %08x\n", value);
			break;
		}

		if (count > 1) {
			err = tegra_dsi_read_response(dsi, msg, count);
			if (err < 0)
				printk(BIOS_INFO,
					"failed to parse response: %d\n",
					err);
			else {
				/*
				 * For read commands, return the number of
				 * bytes returned by the peripheral.
				 */
				count = err;
			}
		}
	} else {
		/*
		 * For write commands, we have transmitted the 4-byte header
		 * plus the variable-length payload.
		 */
		count = 4 + msg->tx_len;
	}

	return count;
}

static int tegra_dsi_ganged_setup(struct tegra_dsi *dsi,
			  struct tegra_dsi *slave)
{
	/*
	 * The number of ganged lanes is the sum of lanes of all peripherals
	 * in the gang.
	 */
	dsi->slave->ganged_lanes = dsi->lanes + dsi->slave->lanes;
	dsi->slave->ganged_mode = 1;

	dsi->ganged_lanes = dsi->lanes + dsi->slave->lanes;
	dsi->ganged_mode = 1;
	return 0;
}

static int tegra_dsi_host_attach(struct mipi_dsi_host *host,
				struct mipi_dsi_device *device)
{
	struct tegra_dsi *dsi = host_to_tegra(host);
	int err;

	dsi->flags = device->mode_flags;
	dsi->format = device->format;
	dsi->lanes = device->lanes;

	if (dsi->master) {
		err = tegra_dsi_ganged_setup(dsi->master, dsi);
		if (err < 0) {
			printk(BIOS_ERR, "failed to set up ganged mode: %d\n",
				err);
			return err;
		}
	}
	return 0;
}

static const struct mipi_dsi_host_ops tegra_dsi_host_ops = {
	.attach = tegra_dsi_host_attach,
	.transfer = tegra_dsi_host_transfer,
};

static int dsi_probe_if(int dsi_index,
			struct soc_nvidia_tegra210_config *config)
{
	struct tegra_dsi *dsi = &dsi_data[dsi_index];
	int err;

	tegra_dsi_writel(dsi, 0, DSI_INIT_SEQ_CONTROL);

	/*
	 * Set default value. Will be taken from attached device once detected
	 */
	dsi->flags = 0;
	dsi->format = MIPI_DSI_FMT_RGB888;
	dsi->lanes = 4;

	/* get tegra_mipi_device */
	dsi->mipi = tegra_mipi_request(&mipi_device_data[dsi_index], dsi_index);

	/* calibrate */
	err = tegra_dsi_pad_calibrate(dsi);
	if (err < 0) {
		printk(BIOS_ERR, "MIPI calibration failed: %d\n", err);
		return err;
	}

	dsi->host.ops = &tegra_dsi_host_ops;
	err = mipi_dsi_host_register(&dsi->host);
	if (err < 0) {
		printk(BIOS_ERR, "failed to register DSI host: %d\n", err);
		return err;
	}

	/* get panel */
	dsi->panel = panel_jdi_dsi_probe((struct mipi_dsi_device *)dsi->host.dev);
	if (IS_ERR_PTR(dsi->panel)) {
		printk(BIOS_ERR, "failed to get dsi panel\n");
		return -EPTR;
	}
	dsi->panel->mode = config;
	return 0;
}

static int dsi_probe(struct soc_nvidia_tegra210_config *config)
{
	dsi_probe_if(DSI_A, config);
	dsi_probe_if(DSI_B, config);
	return 0;
}

static void tegra_dsi_init_regs(struct tegra_dsi *dsi)
{
	int i;
	for (i = 0; i < ARRAY_SIZE(init_reg); i++)
		tegra_dsi_writel(dsi, 0, init_reg[i]);

	if (dsi->slave)
		tegra_dsi_init_regs(dsi->slave);
}

static int dsi_enable(struct soc_nvidia_tegra210_config *config)
{
	struct tegra_dsi *dsi_a = &dsi_data[DSI_A];

	dsi_probe(config);

	/* set up clock and TimeOutRegisters */
	tegra_output_dsi_setup_clock(dsi_a, config);

	/* configure APB_MISC_GP_MIPI_PAD_CTRL_0 */
	write32((unsigned int *)APB_MISC_GP_MIPI_PAD_CTRL_0, DSIB_MODE_DSI);

	/* configure phy interface timing registers */
	tegra_dsi_set_phy_timing(dsi_a);

	/* Initialize DSI registers */
	tegra_dsi_init_regs(dsi_a);

	/* prepare panel */
	panel_jdi_prepare(dsi_a->panel);

	/* enable dsi */
	if (tegra_output_dsi_enable(dsi_a, config)) {
		printk(BIOS_ERR,"%s: Error: failed to enable dsi output.\n",
			__func__);
		return -1;
	}

	return 0;
}

void dsi_display_startup(struct device *dev)
{
	struct soc_nvidia_tegra210_config *config = dev->chip_info;
	struct display_controller *disp_ctrl =
			(void *)config->display_controller;
	u32 plld_rate;

	u32 framebuffer_size_mb = config->framebuffer_size / MiB;
	u32 framebuffer_base_mb= config->framebuffer_base / MiB;

	printk(BIOS_INFO, "%s: entry: disp_ctrl: %p.\n",
		 __func__, disp_ctrl);

	if (disp_ctrl == NULL) {
		printk(BIOS_ERR, "No dc is assigned by dt.\n");
		return;
	}

	if (framebuffer_size_mb == 0){
		framebuffer_size_mb = ALIGN_UP(config->display_xres *
			config->display_yres *
			(config->framebuffer_bits_per_pixel / 8), MiB)/MiB;
	}

	config->framebuffer_size = framebuffer_size_mb * MiB;
	config->framebuffer_base = framebuffer_base_mb * MiB;

	/*
	 * The plld is programmed with the assumption of the SHIFT_CLK_DIVIDER
	 * and PIXEL_CLK_DIVIDER are zero (divide by 1). See the
	 * update_display_mode() for detail.
	 */
	/* set default plld */
	plld_rate = clock_configure_plld(config->pixel_clock * 2);
	if (plld_rate == 0) {
		printk(BIOS_ERR, "dc: clock init failed\n");
		return;
	}

	/* set disp1's clock source to PLLD_OUT0 */
	clock_configure_source(disp1, PLLD_OUT0, (plld_rate/KHz));

	/* Init dc */
	if (tegra_dc_init(disp_ctrl)) {
		printk(BIOS_ERR, "dc: init failed\n");
		return;
	}

	/* Configure dc mode */
	if (update_display_mode(disp_ctrl, config)) {
		printk(BIOS_ERR, "dc: failed to configure display mode.\n");
		return;
	}

	/* Configure and enable dsi controller and panel */
	if (dsi_enable(config)) {
		printk(BIOS_ERR, "%s: failed to enable dsi controllers.\n",
			__func__);
		return;
	}

	/* Set up window */
	update_window(config);
	printk(BIOS_INFO, "%s: display init done.\n", __func__);

	/* Save panel information to cb tables */
	pass_mode_info_to_payload(config);

	/*
	 * After this point, it is payload's responsibility to allocate
	 * framebuffer and sets the base address to dc's
	 * WINBUF_START_ADDR register and enables window by setting dc's
	 * DISP_DISP_WIN_OPTIONS register.
	 */
}
