// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2013 NVIDIA Corporation
 */

#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/host1x.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>

#include <video/mipi_display.h>

#include <drm/drm_atomic_helper.h>
#include <drm/drm_debugfs.h>
#include <drm/drm_file.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_panel.h>
#include <drm/drm_simple_kms_helper.h>

#include "dc.h"
#include "drm.h"
#include "dsi.h"
#include "mipi-phy.h"
#include "trace.h"

struct tegra_dsi_state {
	struct drm_connector_state base;

	struct mipi_dphy_timing timing;
	unsigned long period;

	unsigned int vrefresh;
	unsigned int lanes;
	unsigned long pclk;
	unsigned long bclk;

	enum tegra_dsi_format format;
	unsigned int mul;
	unsigned int div;
};

static inline struct tegra_dsi_state *
to_dsi_state(struct drm_connector_state *state)
{
	return container_of(state, struct tegra_dsi_state, base);
}

struct tegra_dsi {
	struct host1x_client client;
	struct tegra_output output;
	struct device *dev;

	void __iomem *regs;

	struct reset_control *rst;
	struct clk *clk_parent;
	struct clk *clk_lp;
	struct clk *clk;

	struct drm_info_list *debugfs_files;

	unsigned long flags;
	enum mipi_dsi_pixel_format format;
	unsigned int lanes;

	struct tegra_mipi_device *mipi;
	struct mipi_dsi_host host;

	struct regulator *vdd;

	unsigned int video_fifo_depth;
	unsigned int host_fifo_depth;

	/* for ganged-mode support */
	struct tegra_dsi *master;
	struct tegra_dsi *slave;
};

static inline struct tegra_dsi *
host1x_client_to_dsi(struct host1x_client *client)
{
	return container_of(client, struct tegra_dsi, client);
}

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

static inline struct tegra_dsi *to_dsi(struct tegra_output *output)
{
	return container_of(output, struct tegra_dsi, output);
}

static struct tegra_dsi_state *tegra_dsi_get_state(struct tegra_dsi *dsi)
{
	return to_dsi_state(dsi->output.connector.state);
}

static inline u32 tegra_dsi_readl(struct tegra_dsi *dsi, unsigned int offset)
{
	u32 value = readl(dsi->regs + (offset << 2));

	trace_dsi_readl(dsi->dev, offset, value);

	return value;
}

static inline void tegra_dsi_writel(struct tegra_dsi *dsi, u32 value,
				    unsigned int offset)
{
	trace_dsi_writel(dsi->dev, offset, value);
	writel(value, dsi->regs + (offset << 2));
}

#define DEBUGFS_REG32(_name) { .name = #_name, .offset = _name }

static const struct debugfs_reg32 tegra_dsi_regs[] = {
	DEBUGFS_REG32(DSI_INCR_SYNCPT),
	DEBUGFS_REG32(DSI_INCR_SYNCPT_CONTROL),
	DEBUGFS_REG32(DSI_INCR_SYNCPT_ERROR),
	DEBUGFS_REG32(DSI_CTXSW),
	DEBUGFS_REG32(DSI_RD_DATA),
	DEBUGFS_REG32(DSI_WR_DATA),
	DEBUGFS_REG32(DSI_POWER_CONTROL),
	DEBUGFS_REG32(DSI_INT_ENABLE),
	DEBUGFS_REG32(DSI_INT_STATUS),
	DEBUGFS_REG32(DSI_INT_MASK),
	DEBUGFS_REG32(DSI_HOST_CONTROL),
	DEBUGFS_REG32(DSI_CONTROL),
	DEBUGFS_REG32(DSI_SOL_DELAY),
	DEBUGFS_REG32(DSI_MAX_THRESHOLD),
	DEBUGFS_REG32(DSI_TRIGGER),
	DEBUGFS_REG32(DSI_TX_CRC),
	DEBUGFS_REG32(DSI_STATUS),
	DEBUGFS_REG32(DSI_INIT_SEQ_CONTROL),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_0),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_1),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_2),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_3),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_4),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_5),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_6),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_7),
	DEBUGFS_REG32(DSI_PKT_SEQ_0_LO),
	DEBUGFS_REG32(DSI_PKT_SEQ_0_HI),
	DEBUGFS_REG32(DSI_PKT_SEQ_1_LO),
	DEBUGFS_REG32(DSI_PKT_SEQ_1_HI),
	DEBUGFS_REG32(DSI_PKT_SEQ_2_LO),
	DEBUGFS_REG32(DSI_PKT_SEQ_2_HI),
	DEBUGFS_REG32(DSI_PKT_SEQ_3_LO),
	DEBUGFS_REG32(DSI_PKT_SEQ_3_HI),
	DEBUGFS_REG32(DSI_PKT_SEQ_4_LO),
	DEBUGFS_REG32(DSI_PKT_SEQ_4_HI),
	DEBUGFS_REG32(DSI_PKT_SEQ_5_LO),
	DEBUGFS_REG32(DSI_PKT_SEQ_5_HI),
	DEBUGFS_REG32(DSI_DCS_CMDS),
	DEBUGFS_REG32(DSI_PKT_LEN_0_1),
	DEBUGFS_REG32(DSI_PKT_LEN_2_3),
	DEBUGFS_REG32(DSI_PKT_LEN_4_5),
	DEBUGFS_REG32(DSI_PKT_LEN_6_7),
	DEBUGFS_REG32(DSI_PHY_TIMING_0),
	DEBUGFS_REG32(DSI_PHY_TIMING_1),
	DEBUGFS_REG32(DSI_PHY_TIMING_2),
	DEBUGFS_REG32(DSI_BTA_TIMING),
	DEBUGFS_REG32(DSI_TIMEOUT_0),
	DEBUGFS_REG32(DSI_TIMEOUT_1),
	DEBUGFS_REG32(DSI_TO_TALLY),
	DEBUGFS_REG32(DSI_PAD_CONTROL_0),
	DEBUGFS_REG32(DSI_PAD_CONTROL_CD),
	DEBUGFS_REG32(DSI_PAD_CD_STATUS),
	DEBUGFS_REG32(DSI_VIDEO_MODE_CONTROL),
	DEBUGFS_REG32(DSI_PAD_CONTROL_1),
	DEBUGFS_REG32(DSI_PAD_CONTROL_2),
	DEBUGFS_REG32(DSI_PAD_CONTROL_3),
	DEBUGFS_REG32(DSI_PAD_CONTROL_4),
	DEBUGFS_REG32(DSI_GANGED_MODE_CONTROL),
	DEBUGFS_REG32(DSI_GANGED_MODE_START),
	DEBUGFS_REG32(DSI_GANGED_MODE_SIZE),
	DEBUGFS_REG32(DSI_RAW_DATA_BYTE_COUNT),
	DEBUGFS_REG32(DSI_ULTRA_LOW_POWER_CONTROL),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_8),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_9),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_10),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_11),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_12),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_13),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_14),
	DEBUGFS_REG32(DSI_INIT_SEQ_DATA_15),
};

static int tegra_dsi_show_regs(struct seq_file *s, void *data)
{
	struct drm_info_node *node = s->private;
	struct tegra_dsi *dsi = node->info_ent->data;
	struct drm_crtc *crtc = dsi->output.encoder.crtc;
	struct drm_device *drm = node->minor->dev;
	unsigned int i;
	int err = 0;

	drm_modeset_lock_all(drm);

	if (!crtc || !crtc->state->active) {
		err = -EBUSY;
		goto unlock;
	}

	for (i = 0; i < ARRAY_SIZE(tegra_dsi_regs); i++) {
		unsigned int offset = tegra_dsi_regs[i].offset;

		seq_printf(s, "%-32s %#05x %08x\n", tegra_dsi_regs[i].name,
			   offset, tegra_dsi_readl(dsi, offset));
	}

unlock:
	drm_modeset_unlock_all(drm);
	return err;
}

static struct drm_info_list debugfs_files[] = {
	{ "regs", tegra_dsi_show_regs, 0, NULL },
};

static int tegra_dsi_late_register(struct drm_connector *connector)
{
	struct tegra_output *output = connector_to_output(connector);
	unsigned int i, count = ARRAY_SIZE(debugfs_files);
	struct drm_minor *minor = connector->dev->primary;
	struct dentry *root = connector->debugfs_entry;
	struct tegra_dsi *dsi = to_dsi(output);

	dsi->debugfs_files = kmemdup(debugfs_files, sizeof(debugfs_files),
				     GFP_KERNEL);
	if (!dsi->debugfs_files)
		return -ENOMEM;

	for (i = 0; i < count; i++)
		dsi->debugfs_files[i].data = dsi;

	drm_debugfs_create_files(dsi->debugfs_files, count, root, minor);

	return 0;
}

static void tegra_dsi_early_unregister(struct drm_connector *connector)
{
	struct tegra_output *output = connector_to_output(connector);
	unsigned int count = ARRAY_SIZE(debugfs_files);
	struct tegra_dsi *dsi = to_dsi(output);

	drm_debugfs_remove_files(dsi->debugfs_files, count,
				 connector->dev->primary);
	kfree(dsi->debugfs_files);
	dsi->debugfs_files = NULL;
}

#define PKT_ID0(id)	((((id) & 0x3f) <<  3) | (1 <<  9))
#define PKT_LEN0(len)	(((len) & 0x07) <<  0)
#define PKT_ID1(id)	((((id) & 0x3f) << 13) | (1 << 19))
#define PKT_LEN1(len)	(((len) & 0x07) << 10)
#define PKT_ID2(id)	((((id) & 0x3f) << 23) | (1 << 29))
#define PKT_LEN2(len)	(((len) & 0x07) << 20)

#define PKT_LP		(1 << 30)
#define NUM_PKT_SEQ	12

/*
 * 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 void tegra_dsi_set_phy_timing(struct tegra_dsi *dsi,
				     unsigned long period,
				     const struct mipi_dphy_timing *timing)
{
	u32 value;

	value = DSI_TIMING_FIELD(timing->hsexit, period, 1) << 24 |
		DSI_TIMING_FIELD(timing->hstrail, period, 0) << 16 |
		DSI_TIMING_FIELD(timing->hszero, period, 3) << 8 |
		DSI_TIMING_FIELD(timing->hsprepare, period, 1);
	tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_0);

	value = DSI_TIMING_FIELD(timing->clktrail, period, 1) << 24 |
		DSI_TIMING_FIELD(timing->clkpost, period, 1) << 16 |
		DSI_TIMING_FIELD(timing->clkzero, period, 1) << 8 |
		DSI_TIMING_FIELD(timing->lpx, period, 1);
	tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_1);

	value = DSI_TIMING_FIELD(timing->clkprepare, period, 1) << 16 |
		DSI_TIMING_FIELD(timing->clkpre, period, 1) << 8 |
		DSI_TIMING_FIELD(0xff * period, period, 0) << 0;
	tegra_dsi_writel(dsi, value, DSI_PHY_TIMING_2);

	value = DSI_TIMING_FIELD(timing->taget, period, 1) << 16 |
		DSI_TIMING_FIELD(timing->tasure, period, 1) << 8 |
		DSI_TIMING_FIELD(timing->tago, period, 1);
	tegra_dsi_writel(dsi, value, DSI_BTA_TIMING);

	if (dsi->slave)
		tegra_dsi_set_phy_timing(dsi->slave, period, timing);
}

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 unsigned int tegra_dsi_get_lanes(struct tegra_dsi *dsi)
{
	if (dsi->master)
		return dsi->master->lanes + dsi->lanes;

	if (dsi->slave)
		return dsi->lanes + dsi->slave->lanes;

	return dsi->lanes;
}

static void tegra_dsi_configure(struct tegra_dsi *dsi, unsigned int pipe,
				const struct drm_display_mode *mode)
{
	unsigned int hact, hsw, hbp, hfp, i, mul, div;
	struct tegra_dsi_state *state;
	const u32 *pkt_seq;
	u32 value;

	/* XXX: pass in state into this function? */
	if (dsi->master)
		state = tegra_dsi_get_state(dsi->master);
	else
		state = tegra_dsi_get_state(dsi);

	mul = state->mul;
	div = state->div;

	if (dsi->flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) {
		DRM_DEBUG_KMS("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) {
		DRM_DEBUG_KMS("Non-burst video mode with sync events\n");
		pkt_seq = pkt_seq_video_non_burst_sync_events;
	} else {
		DRM_DEBUG_KMS("Command mode\n");
		pkt_seq = pkt_seq_command_mode;
	}

	value = DSI_CONTROL_CHANNEL(0) |
		DSI_CONTROL_FORMAT(state->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->hdisplay * mul / div;

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

		/* horizontal back porch */
		hbp = (mode->htotal - mode->hsync_end) * mul / div;

		if ((dsi->flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE) == 0)
			hbp += hsw;

		/* horizontal front porch */
		hfp = (mode->hsync_start - mode->hdisplay) * 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->master || dsi->slave) {
			/*
			 * For ganged mode, assume symmetric left-right mode.
			 */
			bytes = 1 + (mode->hdisplay / 2) * mul / div;
		} else {
			/* 1 byte (DCS command) + pixel data */
			bytes = 1 + mode->hdisplay * mul / div;
		}

		tegra_dsi_writel(dsi, 0, DSI_PKT_LEN_0_1);
		tegra_dsi_writel(dsi, bytes << 16, DSI_PKT_LEN_2_3);
		tegra_dsi_writel(dsi, 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->master || dsi->slave) {
			unsigned long delay, bclk, bclk_ganged;
			unsigned int lanes = state->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(mode->htotal * 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) {
		tegra_dsi_configure(dsi->slave, pipe, mode);

		/*
		 * TODO: Support modes other than symmetrical left-right
		 * split.
		 */
		tegra_dsi_ganged_enable(dsi, 0, mode->hdisplay / 2);
		tegra_dsi_ganged_enable(dsi->slave, mode->hdisplay / 2,
					mode->hdisplay / 2);
	}
}

static int tegra_dsi_wait_idle(struct tegra_dsi *dsi, unsigned long timeout)
{
	u32 value;

	timeout = jiffies + msecs_to_jiffies(timeout);

	while (time_before(jiffies, timeout)) {
		value = tegra_dsi_readl(dsi, DSI_STATUS);
		if (value & DSI_STATUS_IDLE)
			return 0;

		usleep_range(1000, 2000);
	}

	return -ETIMEDOUT;
}

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

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

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

static void tegra_dsi_ganged_disable(struct tegra_dsi *dsi)
{
	tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_START);
	tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_SIZE);
	tegra_dsi_writel(dsi, 0, DSI_GANGED_MODE_CONTROL);
}

static int tegra_dsi_pad_enable(struct tegra_dsi *dsi)
{
	u32 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;
	int err;

	/*
	 * XXX Is this still needed? The module reset is deasserted right
	 * before this function is called.
	 */
	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);

	err = tegra_mipi_calibrate(dsi->mipi);
	if (err < 0)
		return err;

	return tegra_mipi_wait(dsi->mipi);
}

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 void tegra_dsi_disable(struct tegra_dsi *dsi)
{
	u32 value;

	if (dsi->slave) {
		tegra_dsi_ganged_disable(dsi->slave);
		tegra_dsi_ganged_disable(dsi);
	}

	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_disable(dsi->slave);

	usleep_range(5000, 10000);
}

static void tegra_dsi_soft_reset(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);

	usleep_range(300, 1000);

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

	usleep_range(300, 1000);

	value = tegra_dsi_readl(dsi, DSI_TRIGGER);
	if (value)
		tegra_dsi_writel(dsi, 0, DSI_TRIGGER);

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

static void tegra_dsi_connector_reset(struct drm_connector *connector)
{
	struct tegra_dsi_state *state = kzalloc(sizeof(*state), GFP_KERNEL);

	if (!state)
		return;

	if (connector->state) {
		__drm_atomic_helper_connector_destroy_state(connector->state);
		kfree(connector->state);
	}

	__drm_atomic_helper_connector_reset(connector, &state->base);
}

static struct drm_connector_state *
tegra_dsi_connector_duplicate_state(struct drm_connector *connector)
{
	struct tegra_dsi_state *state = to_dsi_state(connector->state);
	struct tegra_dsi_state *copy;

	copy = kmemdup(state, sizeof(*state), GFP_KERNEL);
	if (!copy)
		return NULL;

	__drm_atomic_helper_connector_duplicate_state(connector,
						      &copy->base);

	return &copy->base;
}

static const struct drm_connector_funcs tegra_dsi_connector_funcs = {
	.reset = tegra_dsi_connector_reset,
	.detect = tegra_output_connector_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = tegra_output_connector_destroy,
	.atomic_duplicate_state = tegra_dsi_connector_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
	.late_register = tegra_dsi_late_register,
	.early_unregister = tegra_dsi_early_unregister,
};

static enum drm_mode_status
tegra_dsi_connector_mode_valid(struct drm_connector *connector,
			       struct drm_display_mode *mode)
{
	return MODE_OK;
}

static const struct drm_connector_helper_funcs tegra_dsi_connector_helper_funcs = {
	.get_modes = tegra_output_connector_get_modes,
	.mode_valid = tegra_dsi_connector_mode_valid,
};

static void tegra_dsi_unprepare(struct tegra_dsi *dsi)
{
	int err;

	if (dsi->slave)
		tegra_dsi_unprepare(dsi->slave);

	err = tegra_mipi_disable(dsi->mipi);
	if (err < 0)
		dev_err(dsi->dev, "failed to disable MIPI calibration: %d\n",
			err);

	err = host1x_client_suspend(&dsi->client);
	if (err < 0)
		dev_err(dsi->dev, "failed to suspend: %d\n", err);
}

static void tegra_dsi_encoder_disable(struct drm_encoder *encoder)
{
	struct tegra_output *output = encoder_to_output(encoder);
	struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
	struct tegra_dsi *dsi = to_dsi(output);
	u32 value;
	int err;

	if (output->panel)
		drm_panel_disable(output->panel);

	tegra_dsi_video_disable(dsi);

	/*
	 * The following accesses registers of the display controller, so make
	 * sure it's only executed when the output is attached to one.
	 */
	if (dc) {
		value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
		value &= ~DSI_ENABLE;
		tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);

		tegra_dc_commit(dc);
	}

	err = tegra_dsi_wait_idle(dsi, 100);
	if (err < 0)
		dev_dbg(dsi->dev, "failed to idle DSI: %d\n", err);

	tegra_dsi_soft_reset(dsi);

	if (output->panel)
		drm_panel_unprepare(output->panel);

	tegra_dsi_disable(dsi);

	tegra_dsi_unprepare(dsi);
}

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

	err = host1x_client_resume(&dsi->client);
	if (err < 0) {
		dev_err(dsi->dev, "failed to resume: %d\n", err);
		return err;
	}

	err = tegra_mipi_enable(dsi->mipi);
	if (err < 0)
		dev_err(dsi->dev, "failed to enable MIPI calibration: %d\n",
			err);

	err = tegra_dsi_pad_calibrate(dsi);
	if (err < 0)
		dev_err(dsi->dev, "MIPI calibration failed: %d\n", err);

	if (dsi->slave)
		tegra_dsi_prepare(dsi->slave);

	return 0;
}

static void tegra_dsi_encoder_enable(struct drm_encoder *encoder)
{
	struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode;
	struct tegra_output *output = encoder_to_output(encoder);
	struct tegra_dc *dc = to_tegra_dc(encoder->crtc);
	struct tegra_dsi *dsi = to_dsi(output);
	struct tegra_dsi_state *state;
	u32 value;
	int err;

	err = tegra_dsi_prepare(dsi);
	if (err < 0) {
		dev_err(dsi->dev, "failed to prepare: %d\n", err);
		return;
	}

	state = tegra_dsi_get_state(dsi);

	tegra_dsi_set_timeout(dsi, state->bclk, state->vrefresh);

	/*
	 * The D-PHY timing fields are expressed in byte-clock cycles, so
	 * multiply the period by 8.
	 */
	tegra_dsi_set_phy_timing(dsi, state->period * 8, &state->timing);

	if (output->panel)
		drm_panel_prepare(output->panel);

	tegra_dsi_configure(dsi, dc->pipe, mode);

	/* enable display controller */
	value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
	value |= DSI_ENABLE;
	tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);

	tegra_dc_commit(dc);

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

	if (output->panel)
		drm_panel_enable(output->panel);
}

static int
tegra_dsi_encoder_atomic_check(struct drm_encoder *encoder,
			       struct drm_crtc_state *crtc_state,
			       struct drm_connector_state *conn_state)
{
	struct tegra_output *output = encoder_to_output(encoder);
	struct tegra_dsi_state *state = to_dsi_state(conn_state);
	struct tegra_dc *dc = to_tegra_dc(conn_state->crtc);
	struct tegra_dsi *dsi = to_dsi(output);
	unsigned int scdiv;
	unsigned long plld;
	int err;

	state->pclk = crtc_state->mode.clock * 1000;

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

	state->lanes = tegra_dsi_get_lanes(dsi);

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

	state->vrefresh = drm_mode_vrefresh(&crtc_state->mode);

	/* compute byte clock */
	state->bclk = (state->pclk * state->mul) / (state->div * state->lanes);

	DRM_DEBUG_KMS("mul: %u, div: %u, lanes: %u\n", state->mul, state->div,
		      state->lanes);
	DRM_DEBUG_KMS("format: %u, vrefresh: %u\n", state->format,
		      state->vrefresh);
	DRM_DEBUG_KMS("bclk: %lu\n", state->bclk);

	/*
	 * Compute bit clock and round up to the next MHz.
	 */
	plld = DIV_ROUND_UP(state->bclk * 8, USEC_PER_SEC) * USEC_PER_SEC;
	state->period = DIV_ROUND_CLOSEST(NSEC_PER_SEC, plld);

	err = mipi_dphy_timing_get_default(&state->timing, state->period);
	if (err < 0)
		return err;

	err = mipi_dphy_timing_validate(&state->timing, state->period);
	if (err < 0) {
		dev_err(dsi->dev, "failed to validate D-PHY timing: %d\n", err);
		return err;
	}

	/*
	 * We divide the frequency by two here, but we make up for that by
	 * setting the shift clock divider (further below) to half of the
	 * correct value.
	 */
	plld /= 2;

	/*
	 * 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.
	 *
	 * It's not clear exactly why this is necessary, but the display is
	 * not working properly otherwise. Perhaps the PLLs cannot generate
	 * frequencies sufficiently high.
	 */
	scdiv = ((8 * state->mul) / (state->div * state->lanes)) - 2;

	err = tegra_dc_state_setup_clock(dc, crtc_state, dsi->clk_parent,
					 plld, scdiv);
	if (err < 0) {
		dev_err(output->dev, "failed to setup CRTC state: %d\n", err);
		return err;
	}

	return err;
}

static const struct drm_encoder_helper_funcs tegra_dsi_encoder_helper_funcs = {
	.disable = tegra_dsi_encoder_disable,
	.enable = tegra_dsi_encoder_enable,
	.atomic_check = tegra_dsi_encoder_atomic_check,
};

static int tegra_dsi_init(struct host1x_client *client)
{
	struct drm_device *drm = dev_get_drvdata(client->host);
	struct tegra_dsi *dsi = host1x_client_to_dsi(client);
	int err;

	/* Gangsters must not register their own outputs. */
	if (!dsi->master) {
		dsi->output.dev = client->dev;

		drm_connector_init(drm, &dsi->output.connector,
				   &tegra_dsi_connector_funcs,
				   DRM_MODE_CONNECTOR_DSI);
		drm_connector_helper_add(&dsi->output.connector,
					 &tegra_dsi_connector_helper_funcs);
		dsi->output.connector.dpms = DRM_MODE_DPMS_OFF;

		drm_simple_encoder_init(drm, &dsi->output.encoder,
					DRM_MODE_ENCODER_DSI);
		drm_encoder_helper_add(&dsi->output.encoder,
				       &tegra_dsi_encoder_helper_funcs);

		drm_connector_attach_encoder(&dsi->output.connector,
						  &dsi->output.encoder);
		drm_connector_register(&dsi->output.connector);

		err = tegra_output_init(drm, &dsi->output);
		if (err < 0)
			dev_err(dsi->dev, "failed to initialize output: %d\n",
				err);

		dsi->output.encoder.possible_crtcs = 0x3;
	}

	return 0;
}

static int tegra_dsi_exit(struct host1x_client *client)
{
	struct tegra_dsi *dsi = host1x_client_to_dsi(client);

	tegra_output_exit(&dsi->output);

	return 0;
}

static int tegra_dsi_runtime_suspend(struct host1x_client *client)
{
	struct tegra_dsi *dsi = host1x_client_to_dsi(client);
	struct device *dev = client->dev;
	int err;

	if (dsi->rst) {
		err = reset_control_assert(dsi->rst);
		if (err < 0) {
			dev_err(dev, "failed to assert reset: %d\n", err);
			return err;
		}
	}

	usleep_range(1000, 2000);

	clk_disable_unprepare(dsi->clk_lp);
	clk_disable_unprepare(dsi->clk);

	regulator_disable(dsi->vdd);
	pm_runtime_put_sync(dev);

	return 0;
}

static int tegra_dsi_runtime_resume(struct host1x_client *client)
{
	struct tegra_dsi *dsi = host1x_client_to_dsi(client);
	struct device *dev = client->dev;
	int err;

	err = pm_runtime_get_sync(dev);
	if (err < 0) {
		dev_err(dev, "failed to get runtime PM: %d\n", err);
		return err;
	}

	err = regulator_enable(dsi->vdd);
	if (err < 0) {
		dev_err(dev, "failed to enable VDD supply: %d\n", err);
		goto put_rpm;
	}

	err = clk_prepare_enable(dsi->clk);
	if (err < 0) {
		dev_err(dev, "cannot enable DSI clock: %d\n", err);
		goto disable_vdd;
	}

	err = clk_prepare_enable(dsi->clk_lp);
	if (err < 0) {
		dev_err(dev, "cannot enable low-power clock: %d\n", err);
		goto disable_clk;
	}

	usleep_range(1000, 2000);

	if (dsi->rst) {
		err = reset_control_deassert(dsi->rst);
		if (err < 0) {
			dev_err(dev, "cannot assert reset: %d\n", err);
			goto disable_clk_lp;
		}
	}

	return 0;

disable_clk_lp:
	clk_disable_unprepare(dsi->clk_lp);
disable_clk:
	clk_disable_unprepare(dsi->clk);
disable_vdd:
	regulator_disable(dsi->vdd);
put_rpm:
	pm_runtime_put_sync(dev);
	return err;
}

static const struct host1x_client_ops dsi_client_ops = {
	.init = tegra_dsi_init,
	.exit = tegra_dsi_exit,
	.suspend = tegra_dsi_runtime_suspend,
	.resume = tegra_dsi_runtime_resume,
};

static int tegra_dsi_setup_clocks(struct tegra_dsi *dsi)
{
	struct clk *parent;
	int err;

	parent = clk_get_parent(dsi->clk);
	if (!parent)
		return -EINVAL;

	err = clk_set_parent(parent, dsi->clk_parent);
	if (err < 0)
		return err;

	return 0;
}

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 ssize_t tegra_dsi_read_response(struct tegra_dsi *dsi,
				       const struct mipi_dsi_msg *msg,
				       size_t 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;
		dev_dbg(dsi->dev, "Acknowledge and error report: %04x\n",
			errors);
		for (i = 0; i < ARRAY_SIZE(error_report); i++)
			if (errors & BIT(i))
				dev_dbg(dsi->dev, "  %2u: %s\n", i,
					error_report[i]);
		break;

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

	case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
		rx[0] = (value >>  8) & 0xff;
		rx[1] = (value >> 16) & 0xff;
		size = 2;
		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:
		dev_err(dsi->dev, "unhandled response type: %02x\n",
			value & 0x3f);
		return -EPROTO;
	}

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

	if (msg->rx_buf && size > 0) {
		for (i = 0, j = 0; i < count - 1; i++, j += 4) {
			u8 *rx = msg->rx_buf + j;

			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 size;
}

static int tegra_dsi_transmit(struct tegra_dsi *dsi, unsigned long timeout)
{
	tegra_dsi_writel(dsi, DSI_TRIGGER_HOST, DSI_TRIGGER);

	timeout = jiffies + msecs_to_jiffies(timeout);

	while (time_before(jiffies, timeout)) {
		u32 value = tegra_dsi_readl(dsi, DSI_TRIGGER);
		if ((value & DSI_TRIGGER_HOST) == 0)
			return 0;

		usleep_range(1000, 2000);
	}

	DRM_DEBUG_KMS("timeout waiting for transmission to complete\n");
	return -ETIMEDOUT;
}

static int tegra_dsi_wait_for_response(struct tegra_dsi *dsi,
				       unsigned long timeout)
{
	timeout = jiffies + msecs_to_jiffies(250);

	while (time_before(jiffies, timeout)) {
		u32 value = tegra_dsi_readl(dsi, DSI_STATUS);
		u8 count = value & 0x1f;

		if (count > 0)
			return count;

		usleep_range(1000, 2000);
	}

	DRM_DEBUG_KMS("peripheral returned no data\n");
	return -ETIMEDOUT;
}

static void tegra_dsi_writesl(struct tegra_dsi *dsi, unsigned long offset,
			      const void *buffer, size_t size)
{
	const u8 *buf = buffer;
	size_t i, j;
	u32 value;

	for (j = 0; j < size; j += 4) {
		value = 0;

		for (i = 0; i < 4 && j + i < size; i++)
			value |= buf[j + i] << (i << 3);

		tegra_dsi_writel(dsi, value, DSI_WR_DATA);
	}
}

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);
	struct mipi_dsi_packet packet;
	const u8 *header;
	size_t count;
	ssize_t err;
	u32 value;

	err = mipi_dsi_create_packet(&packet, msg);
	if (err < 0)
		return err;

	header = packet.header;

	/* maximum FIFO depth is 1920 words */
	if (packet.size > 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);
		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);

	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 (packet.size > 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, ECC is generated by hardware */
	value = header[2] << 16 | header[1] << 8 | header[0];
	tegra_dsi_writel(dsi, value, DSI_WR_DATA);

	/* write payload (if any) */
	if (packet.payload_length > 0)
		tegra_dsi_writesl(dsi, DSI_WR_DATA, packet.payload,
				  packet.payload_length);

	err = tegra_dsi_transmit(dsi, 250);
	if (err < 0)
		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)
			return err;

		count = err;

		value = tegra_dsi_readl(dsi, DSI_RD_DATA);
		switch (value) {
		case 0x84:
			/*
			dev_dbg(dsi->dev, "ACK\n");
			*/
			break;

		case 0x87:
			/*
			dev_dbg(dsi->dev, "ESCAPE\n");
			*/
			break;

		default:
			dev_err(dsi->dev, "unknown status: %08x\n", value);
			break;
		}

		if (count > 1) {
			err = tegra_dsi_read_response(dsi, msg, count);
			if (err < 0)
				dev_err(dsi->dev,
					"failed to parse response: %zd\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 + packet.payload_length;
	}

	return count;
}

static int tegra_dsi_ganged_setup(struct tegra_dsi *dsi)
{
	struct clk *parent;
	int err;

	/* make sure both DSI controllers share the same PLL */
	parent = clk_get_parent(dsi->slave->clk);
	if (!parent)
		return -EINVAL;

	err = clk_set_parent(parent, dsi->clk_parent);
	if (err < 0)
		return err;

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

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

	if (dsi->slave) {
		int err;

		dev_dbg(dsi->dev, "attaching dual-channel device %s\n",
			dev_name(&device->dev));

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

	/*
	 * Slaves don't have a panel associated with them, so they provide
	 * merely the second channel.
	 */
	if (!dsi->master) {
		struct tegra_output *output = &dsi->output;

		output->panel = of_drm_find_panel(device->dev.of_node);
		if (IS_ERR(output->panel))
			output->panel = NULL;

		if (output->panel && output->connector.dev) {
			drm_panel_attach(output->panel, &output->connector);
			drm_helper_hpd_irq_event(output->connector.dev);
		}
	}

	return 0;
}

static int tegra_dsi_host_detach(struct mipi_dsi_host *host,
				 struct mipi_dsi_device *device)
{
	struct tegra_dsi *dsi = host_to_tegra(host);
	struct tegra_output *output = &dsi->output;

	if (output->panel && &device->dev == output->panel->dev) {
		output->panel = NULL;

		if (output->connector.dev)
			drm_helper_hpd_irq_event(output->connector.dev);
	}

	return 0;
}

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

static int tegra_dsi_ganged_probe(struct tegra_dsi *dsi)
{
	struct device_node *np;

	np = of_parse_phandle(dsi->dev->of_node, "nvidia,ganged-mode", 0);
	if (np) {
		struct platform_device *gangster = of_find_device_by_node(np);

		dsi->slave = platform_get_drvdata(gangster);
		of_node_put(np);

		if (!dsi->slave)
			return -EPROBE_DEFER;

		dsi->slave->master = dsi;
	}

	return 0;
}

static int tegra_dsi_probe(struct platform_device *pdev)
{
	struct tegra_dsi *dsi;
	struct resource *regs;
	int err;

	dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
	if (!dsi)
		return -ENOMEM;

	dsi->output.dev = dsi->dev = &pdev->dev;
	dsi->video_fifo_depth = 1920;
	dsi->host_fifo_depth = 64;

	err = tegra_dsi_ganged_probe(dsi);
	if (err < 0)
		return err;

	err = tegra_output_probe(&dsi->output);
	if (err < 0)
		return err;

	dsi->output.connector.polled = DRM_CONNECTOR_POLL_HPD;

	/*
	 * Assume these values by default. When a DSI peripheral driver
	 * attaches to the DSI host, the parameters will be taken from
	 * the attached device.
	 */
	dsi->flags = MIPI_DSI_MODE_VIDEO;
	dsi->format = MIPI_DSI_FMT_RGB888;
	dsi->lanes = 4;

	if (!pdev->dev.pm_domain) {
		dsi->rst = devm_reset_control_get(&pdev->dev, "dsi");
		if (IS_ERR(dsi->rst))
			return PTR_ERR(dsi->rst);
	}

	dsi->clk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(dsi->clk)) {
		dev_err(&pdev->dev, "cannot get DSI clock\n");
		return PTR_ERR(dsi->clk);
	}

	dsi->clk_lp = devm_clk_get(&pdev->dev, "lp");
	if (IS_ERR(dsi->clk_lp)) {
		dev_err(&pdev->dev, "cannot get low-power clock\n");
		return PTR_ERR(dsi->clk_lp);
	}

	dsi->clk_parent = devm_clk_get(&pdev->dev, "parent");
	if (IS_ERR(dsi->clk_parent)) {
		dev_err(&pdev->dev, "cannot get parent clock\n");
		return PTR_ERR(dsi->clk_parent);
	}

	dsi->vdd = devm_regulator_get(&pdev->dev, "avdd-dsi-csi");
	if (IS_ERR(dsi->vdd)) {
		dev_err(&pdev->dev, "cannot get VDD supply\n");
		return PTR_ERR(dsi->vdd);
	}

	err = tegra_dsi_setup_clocks(dsi);
	if (err < 0) {
		dev_err(&pdev->dev, "cannot setup clocks\n");
		return err;
	}

	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	dsi->regs = devm_ioremap_resource(&pdev->dev, regs);
	if (IS_ERR(dsi->regs))
		return PTR_ERR(dsi->regs);

	dsi->mipi = tegra_mipi_request(&pdev->dev, pdev->dev.of_node);
	if (IS_ERR(dsi->mipi))
		return PTR_ERR(dsi->mipi);

	dsi->host.ops = &tegra_dsi_host_ops;
	dsi->host.dev = &pdev->dev;

	err = mipi_dsi_host_register(&dsi->host);
	if (err < 0) {
		dev_err(&pdev->dev, "failed to register DSI host: %d\n", err);
		goto mipi_free;
	}

	platform_set_drvdata(pdev, dsi);
	pm_runtime_enable(&pdev->dev);

	INIT_LIST_HEAD(&dsi->client.list);
	dsi->client.ops = &dsi_client_ops;
	dsi->client.dev = &pdev->dev;

	err = host1x_client_register(&dsi->client);
	if (err < 0) {
		dev_err(&pdev->dev, "failed to register host1x client: %d\n",
			err);
		goto unregister;
	}

	return 0;

unregister:
	mipi_dsi_host_unregister(&dsi->host);
mipi_free:
	tegra_mipi_free(dsi->mipi);
	return err;
}

static int tegra_dsi_remove(struct platform_device *pdev)
{
	struct tegra_dsi *dsi = platform_get_drvdata(pdev);
	int err;

	pm_runtime_disable(&pdev->dev);

	err = host1x_client_unregister(&dsi->client);
	if (err < 0) {
		dev_err(&pdev->dev, "failed to unregister host1x client: %d\n",
			err);
		return err;
	}

	tegra_output_remove(&dsi->output);

	mipi_dsi_host_unregister(&dsi->host);
	tegra_mipi_free(dsi->mipi);

	return 0;
}

static const struct of_device_id tegra_dsi_of_match[] = {
	{ .compatible = "nvidia,tegra210-dsi", },
	{ .compatible = "nvidia,tegra132-dsi", },
	{ .compatible = "nvidia,tegra124-dsi", },
	{ .compatible = "nvidia,tegra114-dsi", },
	{ },
};
MODULE_DEVICE_TABLE(of, tegra_dsi_of_match);

struct platform_driver tegra_dsi_driver = {
	.driver = {
		.name = "tegra-dsi",
		.of_match_table = tegra_dsi_of_match,
	},
	.probe = tegra_dsi_probe,
	.remove = tegra_dsi_remove,
};
