/*
 * NWL DSI drm driver - Northwest Logic MIPI DSI bridge
 *
 * Copyright (C) 2017 NXP
 *
 * 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.
 */

#include <asm/unaligned.h>
#include <drm/bridge/nwl_dsi.h>
#include <drm/drmP.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc_helper.h>
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <linux/clk-provider.h>
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/phy/phy.h>
#include <linux/spinlock.h>
#include <video/mipi_display.h>
#include <video/videomode.h>

#define MIPI_FIFO_TIMEOUT msecs_to_jiffies(500)

/* DSI HOST registers */
#define CFG_NUM_LANES			0x0
#define CFG_NONCONTINUOUS_CLK		0x4
#define CFG_T_PRE			0x8
#define CFG_T_POST			0xc
#define CFG_TX_GAP			0x10
#define CFG_AUTOINSERT_EOTP		0x14
#define CFG_EXTRA_CMDS_AFTER_EOTP	0x18
#define CFG_HTX_TO_COUNT		0x1c
#define CFG_LRX_H_TO_COUNT		0x20
#define CFG_BTA_H_TO_COUNT		0x24
#define CFG_TWAKEUP			0x28
#define CFG_STATUS_OUT			0x2c
#define RX_ERROR_STATUS			0x30

/* DSI DPI registers */
#define PIXEL_PAYLOAD_SIZE		0x200
#define PIXEL_FIFO_SEND_LEVEL		0x204
#define INTERFACE_COLOR_CODING		0x208
#define PIXEL_FORMAT			0x20c
#define VSYNC_POLARITY			0x210
#define HSYNC_POLARITY			0x214
#define VIDEO_MODE			0x218
#define HFP				0x21c
#define HBP				0x220
#define HSA				0x224
#define ENABLE_MULT_PKTS		0x228
#define VBP				0x22c
#define VFP				0x230
#define BLLP_MODE			0x234
#define USE_NULL_PKT_BLLP		0x238
#define VACTIVE				0x23c
#define VC				0x240

/* DSI APB PKT control */
#define TX_PAYLOAD			0x280
#define PKT_CONTROL			0x284
#define SEND_PACKET			0x288
#define PKT_STATUS			0x28c
#define PKT_FIFO_WR_LEVEL		0x290
#define PKT_FIFO_RD_LEVEL		0x294
#define RX_PAYLOAD			0x298
#define RX_PKT_HEADER			0x29c

/* PKT reg bit manipulation */
#define REG_MASK(e, s) (((1 << ((e) - (s) + 1)) - 1) << (s))
#define REG_PUT(x, e, s) (((x) << (s)) & REG_MASK(e, s))
#define REG_GET(x, e, s) (((x) & REG_MASK(e, s)) >> (s))

/*
 * PKT_CONTROL format:
 * [15: 0] - word count
 * [17:16] - virtual channel
 * [23:18] - data type
 * [24]    - LP or HS select (0 - LP, 1 - HS)
 * [25]    - perform BTA after packet is sent
 * [26]    - perform BTA only, no packet tx
 */
#define WC(x)		REG_PUT((x), 15,  0)
#define TX_VC(x)	REG_PUT((x), 17, 16)
#define TX_DT(x)	REG_PUT((x), 23, 18)
#define HS_SEL(x)	REG_PUT((x), 24, 24)
#define BTA_TX(x)	REG_PUT((x), 25, 25)
#define BTA_NO_TX(x)	REG_PUT((x), 26, 26)

/*
 * RX_PKT_HEADER format:
 * [15: 0] - word count
 * [21:16] - data type
 * [23:22] - virtual channel
 */
#define RX_DT(x)	REG_GET((x), 21, 16)
#define RX_VC(x)	REG_GET((x), 23, 22)

/* DSI IRQ handling */
#define IRQ_STATUS			0x2a0
#define SM_NOT_IDLE			BIT(0)
#define TX_PKT_DONE			BIT(1)
#define DPHY_DIRECTION			BIT(2)
#define TX_FIFO_OVFLW			BIT(3)
#define TX_FIFO_UDFLW			BIT(4)
#define RX_FIFO_OVFLW			BIT(5)
#define RX_FIFO_UDFLW			BIT(6)
#define RX_PKT_HDR_RCVD			BIT(7)
#define RX_PKT_PAYLOAD_DATA_RCVD	BIT(8)
#define BTA_TIMEOUT			BIT(29)
#define LP_RX_TIMEOUT			BIT(30)
#define HS_TX_TIMEOUT			BIT(31)

#define IRQ_STATUS2			0x2a4
#define SINGLE_BIT_ECC_ERR		BIT(0)
#define MULTI_BIT_ECC_ERR		BIT(1)
#define CRC_ERR				BIT(2)

#define IRQ_MASK			0x2a8
#define SM_NOT_IDLE_MASK		BIT(0)
#define TX_PKT_DONE_MASK		BIT(1)
#define DPHY_DIRECTION_MASK		BIT(2)
#define TX_FIFO_OVFLW_MASK		BIT(3)
#define TX_FIFO_UDFLW_MASK		BIT(4)
#define RX_FIFO_OVFLW_MASK		BIT(5)
#define RX_FIFO_UDFLW_MASK		BIT(6)
#define RX_PKT_HDR_RCVD_MASK		BIT(7)
#define RX_PKT_PAYLOAD_DATA_RCVD_MASK	BIT(8)
#define BTA_TIMEOUT_MASK		BIT(29)
#define LP_RX_TIMEOUT_MASK		BIT(30)
#define HS_TX_TIMEOUT_MASK		BIT(31)

#define IRQ_MASK2			0x2ac
#define SINGLE_BIT_ECC_ERR_MASK		BIT(0)
#define MULTI_BIT_ECC_ERR_MASK		BIT(1)
#define CRC_ERR_MASK			BIT(2)

static const char IRQ_NAME[] = "nwl-dsi";

enum {
	CLK_PHY_REF	= BIT(1),
	CLK_RX_ESC	= BIT(2),
	CLK_TX_ESC	= BIT(3)
};

enum transfer_direction {
	DSI_PACKET_SEND,
	DSI_PACKET_RECEIVE
};

struct mipi_dsi_transfer {
	const struct mipi_dsi_msg *msg;
	struct mipi_dsi_packet packet;
	struct completion completed;

	int status;    /* status of transmission */
	enum transfer_direction direction;
	bool need_bta;
	u8 cmd;
	u16 rx_word_count;
	size_t tx_len; /* bytes sent */
	size_t rx_len; /* bytes received */
};

struct clk_config {
	struct clk *clk;
	unsigned long rate;
	bool enabled;
};

struct nwl_mipi_dsi {
	struct device			*dev;
	struct drm_panel		*panel;
	struct drm_bridge		*next_bridge;
	struct drm_bridge		bridge;
	struct drm_connector		connector;
	struct mipi_dsi_host		host;

	struct phy			*phy;

	/* Mandatory clocks */
	struct clk_config		phy_ref;
	struct clk_config		rx_esc;
	struct clk_config		tx_esc;

	void __iomem			*base;
	int				irq;
	enum mipi_dsi_pixel_format	format;
	struct videomode		vm;

	struct mipi_dsi_transfer	*xfer;

	u32				lanes;
	u32				vc;
	unsigned long			dsi_mode_flags;
	bool				enabled;
};

static inline void nwl_dsi_write(struct nwl_mipi_dsi *dsi, u32 reg, u32 val)
{
	writel(val, dsi->base + reg);
}

static inline u32 nwl_dsi_read(struct nwl_mipi_dsi *dsi, u32 reg)
{
	return readl(dsi->base + reg);
}

static u32 nwl_dsi_get_dpi_pixel_format(enum mipi_dsi_pixel_format format)
{

	switch (format) {
	case MIPI_DSI_FMT_RGB565:
		return 0x00;
	case MIPI_DSI_FMT_RGB666:
		return 0x01;
	case MIPI_DSI_FMT_RGB666_PACKED:
		return 0x02;
	case MIPI_DSI_FMT_RGB888:
		return 0x03;
	default:
		return DPI_24_BIT;
	}
}

/* Adds a bridge to encoder bridge chain */
bool nwl_dsi_add_bridge(struct drm_encoder *encoder,
			struct drm_bridge *next_bridge)
{
	struct drm_bridge *bridge = encoder->bridge;

	if (!next_bridge)
		return false;

	next_bridge->encoder = encoder;
	if (!bridge) {
		encoder->bridge = bridge;
		return true;
	}

	while (bridge != next_bridge && bridge->next)
		bridge = bridge->next;

	/* Avoid adding an existing bridge to the chain */
	if (bridge == next_bridge) {
		next_bridge->encoder = NULL;
		return false;
	}

	bridge->next = next_bridge;
	return true;
}
EXPORT_SYMBOL_GPL(nwl_dsi_add_bridge);

/* Removes last bridge from encoder bridge chain */
bool nwl_dsi_del_bridge(struct drm_encoder *encoder,
			struct drm_bridge *bridge)
{
	struct drm_bridge *b = encoder->bridge;
	struct drm_bridge *prev = NULL;

	if (!b || !bridge)
		return false;

	while (b->next) {
		prev = b;
		b = b->next;
	}

	bridge->encoder = NULL;
	if (prev)
		prev->next = NULL;
	else
		encoder->bridge = NULL;

	return true;
}
EXPORT_SYMBOL_GPL(nwl_dsi_del_bridge);

unsigned long nwl_dsi_get_bit_clock(struct drm_bridge *bridge,
	unsigned long pixclock)
{
	struct nwl_mipi_dsi *dsi;
	int bpp;

	/* Make sure the bridge is correctly initialized */
	if (!bridge || !bridge->driver_private)
		return 0;

	dsi = bridge->driver_private;

	if (dsi->lanes < 1 || dsi->lanes > 4)
		return 0;

	bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);

	return (pixclock / dsi->lanes) * bpp;
}
EXPORT_SYMBOL_GPL(nwl_dsi_get_bit_clock);

static void nwl_dsi_config_host(struct nwl_mipi_dsi *dsi)
{
	if (dsi->lanes < 1 || dsi->lanes > 4)
		return;

	nwl_dsi_write(dsi, CFG_NUM_LANES, dsi->lanes - 1);

	if (dsi->dsi_mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS) {
		nwl_dsi_write(dsi, CFG_NONCONTINUOUS_CLK, 0x01);
		nwl_dsi_write(dsi, CFG_AUTOINSERT_EOTP, 0x01);
	} else {
		nwl_dsi_write(dsi, CFG_NONCONTINUOUS_CLK, 0x00);
		nwl_dsi_write(dsi, CFG_AUTOINSERT_EOTP, 0x00);
	}

	nwl_dsi_write(dsi, CFG_T_PRE, 0x01);
	nwl_dsi_write(dsi, CFG_T_POST, 0x34);
	nwl_dsi_write(dsi, CFG_TX_GAP, 0x0D);
	nwl_dsi_write(dsi, CFG_EXTRA_CMDS_AFTER_EOTP, 0x00);
	nwl_dsi_write(dsi, CFG_HTX_TO_COUNT, 0x00);
	nwl_dsi_write(dsi, CFG_LRX_H_TO_COUNT, 0x00);
	nwl_dsi_write(dsi, CFG_BTA_H_TO_COUNT, 0x00);
	nwl_dsi_write(dsi, CFG_TWAKEUP, 0x3a98);
}

static void nwl_dsi_config_dpi(struct nwl_mipi_dsi *dsi)
{
	struct videomode *vm = &dsi->vm;
	u32 color_format = nwl_dsi_get_dpi_pixel_format(dsi->format);
	bool burst_mode;

	nwl_dsi_write(dsi, INTERFACE_COLOR_CODING, DPI_24_BIT);
	nwl_dsi_write(dsi, PIXEL_FORMAT, color_format);
	/*TODO: need to make polarity configurable */
	nwl_dsi_write(dsi, VSYNC_POLARITY, 0x00);
	nwl_dsi_write(dsi, HSYNC_POLARITY, 0x00);

	burst_mode = (dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_BURST) &&
		!(dsi->dsi_mode_flags & MIPI_DSI_MODE_VIDEO_SYNC_PULSE);

	if (burst_mode) {
		nwl_dsi_write(dsi, VIDEO_MODE, 0x2);
		nwl_dsi_write(dsi, PIXEL_FIFO_SEND_LEVEL, 256);
	} else {
		nwl_dsi_write(dsi, VIDEO_MODE, 0x0);
		nwl_dsi_write(dsi, PIXEL_FIFO_SEND_LEVEL, vm->hactive);
	}

	nwl_dsi_write(dsi, HFP, vm->hfront_porch);
	nwl_dsi_write(dsi, HBP, vm->hback_porch);
	nwl_dsi_write(dsi, HSA, vm->hsync_len);

	nwl_dsi_write(dsi, ENABLE_MULT_PKTS, 0x0);
	nwl_dsi_write(dsi, BLLP_MODE, 0x1);
	nwl_dsi_write(dsi, ENABLE_MULT_PKTS, 0x0);
	nwl_dsi_write(dsi, USE_NULL_PKT_BLLP, 0x0);
	nwl_dsi_write(dsi, VC, 0x0);

	nwl_dsi_write(dsi, PIXEL_PAYLOAD_SIZE, vm->hactive);
	nwl_dsi_write(dsi, VACTIVE, vm->vactive - 1);
	nwl_dsi_write(dsi, VBP, vm->vback_porch);
	nwl_dsi_write(dsi, VFP, vm->vfront_porch);
}

static void nwl_dsi_enable_clocks(struct nwl_mipi_dsi *dsi, u32 clks)
{
	struct device *dev = dsi->dev;
	unsigned long rate;

	if (clks & CLK_PHY_REF && !dsi->phy_ref.enabled) {
		clk_prepare_enable(dsi->phy_ref.clk);
		dsi->phy_ref.enabled = true;
		rate = clk_get_rate(dsi->phy_ref.clk);
		DRM_DEV_DEBUG_DRIVER(dev,
				"Enabled phy_ref clk (rate=%lu)\n", rate);
	}

	if (clks & CLK_RX_ESC && !dsi->rx_esc.enabled) {
		clk_set_rate(dsi->rx_esc.clk, dsi->rx_esc.rate);
		clk_prepare_enable(dsi->rx_esc.clk);
		dsi->rx_esc.enabled = true;
		rate = clk_get_rate(dsi->rx_esc.clk);
	}

	if (clks & CLK_TX_ESC && !dsi->tx_esc.enabled) {
		clk_set_rate(dsi->tx_esc.clk, dsi->tx_esc.rate);
		clk_prepare_enable(dsi->tx_esc.clk);
		dsi->tx_esc.enabled = true;
		rate = clk_get_rate(dsi->tx_esc.clk);
		DRM_DEV_DEBUG_DRIVER(dev,
				"Enabled tx_esc clk (rate=%lu)\n", rate);
	}
}

static void nwl_dsi_disable_clocks(struct nwl_mipi_dsi *dsi, u32 clks)
{
	struct device *dev = dsi->dev;

	if (clks & CLK_PHY_REF && dsi->phy_ref.enabled) {
		clk_disable_unprepare(dsi->phy_ref.clk);
		dsi->phy_ref.enabled = false;
		DRM_DEV_DEBUG_DRIVER(dev, "Disabled phy_ref clk\n");
	}

	if (clks & CLK_RX_ESC && dsi->rx_esc.enabled) {
		clk_disable_unprepare(dsi->rx_esc.clk);
		dsi->rx_esc.enabled = false;
	}

	if (clks & CLK_TX_ESC && dsi->tx_esc.enabled) {
		clk_disable_unprepare(dsi->tx_esc.clk);
		dsi->tx_esc.enabled = false;
		DRM_DEV_DEBUG_DRIVER(dev, "Disabled tx_esc clk\n");
	}

}

static void nwl_dsi_init_interrupts(struct nwl_mipi_dsi *dsi)
{
	u32 irq_enable;

	nwl_dsi_write(dsi, IRQ_MASK, 0xffffffff);
	nwl_dsi_write(dsi, IRQ_MASK2, 0x7);

	irq_enable = ~(u32)(TX_PKT_DONE_MASK |
			RX_PKT_HDR_RCVD_MASK);

	nwl_dsi_write(dsi, IRQ_MASK, irq_enable);
}

static bool nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
			   const struct drm_display_mode *mode,
			   struct drm_display_mode *adjusted_mode)
{
	struct nwl_mipi_dsi *dsi = bridge->driver_private;
	int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format);
	unsigned long pixclock = adjusted_mode->clock * 1000;
	unsigned long data_rate;

	if (dsi->lanes < 1 || dsi->lanes > 4)
		return false;

	/* Data rate is in bit clock for each lane */
	data_rate = (pixclock / dsi->lanes) * bpp;

	/* Max data rate for this controller is 1.5Gbps */
	if (data_rate > 1500000000)
		return false;

	return true;
}

static void nwl_dsi_bridge_mode_set(struct drm_bridge *bridge,
				     struct drm_display_mode *mode,
				     struct drm_display_mode *adjusted)
{
	struct nwl_mipi_dsi *dsi = bridge->driver_private;

	drm_display_mode_to_videomode(adjusted, &dsi->vm);

	DRM_DEV_DEBUG_DRIVER(dsi->dev, "\n");
	drm_mode_debug_printmodeline(adjusted);
}

static int nwl_dsi_host_attach(struct mipi_dsi_host *host,
			       struct mipi_dsi_device *device)
{
	struct nwl_mipi_dsi *dsi = container_of(host,
						struct nwl_mipi_dsi,
						host);
	struct device *dev = dsi->dev;

	DRM_DEV_INFO(dev, "lanes=%u, format=0x%x flags=0x%lx\n",
		     device->lanes, device->format, device->mode_flags);

	if (device->lanes < 1 || device->lanes > 4)
		return -EINVAL;

	/*
	 * Someone has attached to us; it could be a panel or another bridge.
	 * Check to is if this is a panel or not.
	 */
	if (!dsi->next_bridge ||
	    device->dev.of_node != dsi->next_bridge->of_node)
		dsi->panel = of_drm_find_panel(device->dev.of_node);

	/*
	 * Bridge has priority in front of panel.
	 * Since the panel driver cannot tell if there is a physical
	 * panel connected, we'll asume that there is no physical panel if there
	 * is a bridge registered.
	 */
	if (dsi->next_bridge &&
	    device->dev.of_node != NULL &&
	    device->dev.of_node != dsi->next_bridge->of_node) {
		dsi->panel = NULL;
		return -EPERM;
	}

	if (dsi->panel)
		DRM_DEV_DEBUG_DRIVER(dsi->dev, "Panel attached\n");
	else
		DRM_DEV_DEBUG_DRIVER(dsi->dev, "Bridge attached\n");

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

	if (dsi->connector.dev)
		drm_helper_hpd_irq_event(dsi->connector.dev);

	return 0;
}

static int nwl_dsi_host_detach(struct mipi_dsi_host *host,
			       struct mipi_dsi_device *device)
{
	struct nwl_mipi_dsi *dsi = container_of(host,
						struct nwl_mipi_dsi,
						host);
	if (dsi->panel)
		dsi->panel = NULL;

	if (dsi->connector.dev)
		drm_helper_hpd_irq_event(dsi->connector.dev);

	return 0;
}

static void nwl_dsi_print_error(struct device *dev, u16 error)
{
	DRM_DEV_DEBUG_DRIVER(dev, "DSI Error Register (detailed report):\n");
	if (error & BIT(0))
		DRM_DEV_DEBUG_DRIVER(dev,
			"SoT Error\n");
	if (error & BIT(1))
		DRM_DEV_DEBUG_DRIVER(dev,
			"SoT Sync Error\n");
	if (error & BIT(2))
		DRM_DEV_DEBUG_DRIVER(dev,
			"EoT Sync Error\n");
	if (error & BIT(3))
		DRM_DEV_DEBUG_DRIVER(dev,
			"Escape Mode Entry Command Error\n");
	if (error & BIT(4))
		DRM_DEV_DEBUG_DRIVER(dev,
			"Low-Power Transmit Sync Error\n");
	if (error & BIT(5))
		DRM_DEV_DEBUG_DRIVER(dev,
			"Peripheral Timeout Error\n");
	if (error & BIT(6))
		DRM_DEV_DEBUG_DRIVER(dev,
			"False Control Error\n");
	if (error & BIT(7))
		DRM_DEV_DEBUG_DRIVER(dev,
			"Contention Detected\n");
	if (error & BIT(8))
		DRM_DEV_DEBUG_DRIVER(dev,
			"ECC Error, single-bit (detected and corrected)\n");
	if (error & BIT(9))
		DRM_DEV_DEBUG_DRIVER(dev,
			"ECC Error, multi-bit (detected, not corrected)\n");
	if (error & BIT(10))
		DRM_DEV_DEBUG_DRIVER(dev,
			"Checksum Error (long packet only)\n");
	if (error & BIT(11))
		DRM_DEV_DEBUG_DRIVER(dev,
			"DSI Data Type Not Recognized\n");
	if (error & BIT(12))
		DRM_DEV_DEBUG_DRIVER(dev,
			"DSI VC ID Invalid\n");
	if (error & BIT(13))
		DRM_DEV_DEBUG_DRIVER(dev,
			"Invalid Transmission Length\n");
	/* BIT(14) is reserved */
	if (error & BIT(15))
		DRM_DEV_DEBUG_DRIVER(dev,
			"DSI Protocol Violation\n");
}

static bool nwl_dsi_read_packet(struct nwl_mipi_dsi *dsi, u32 status)
{
	struct device *dev = dsi->dev;
	struct mipi_dsi_transfer *xfer = dsi->xfer;
	u8 *payload = xfer->msg->rx_buf;
	u32 val;
	u16 word_count;
	u8 channel;
	u8 data_type;

	xfer->status = 0;

	if (xfer->rx_word_count == 0) {
		if (!(status & RX_PKT_HDR_RCVD))
			return false;
		/* Get the RX header and parse it */
		val = nwl_dsi_read(dsi, RX_PKT_HEADER);
		word_count = WC(val);
		channel	= RX_VC(val);
		data_type = RX_DT(val);

		if (channel != xfer->msg->channel) {
			DRM_DEV_ERROR(dev,
				"[%02X] Channel missmatch (%u != %u)\n",
				 xfer->cmd, channel, xfer->msg->channel);
			return true;
		}

		switch (data_type) {
		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE:
			/* Fall through */
		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE:
			if (xfer->msg->rx_len > 1) {
				/* read second byte */
				payload[1] = word_count >> 8;
				++xfer->rx_len;
			}
			/* Fall through */
		case MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE:
			/* Fall through */
		case MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE:
			if (xfer->msg->rx_len > 0) {
				/* read first byte */
				payload[0] = word_count & 0xff;
				++xfer->rx_len;
			}
			xfer->status = xfer->rx_len;
			return true;
		case MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT:
			word_count &= 0xff;
			DRM_DEV_ERROR(dev,
				"[%02X] DSI error report: 0x%02x\n",
				xfer->cmd, word_count);
			nwl_dsi_print_error(dev, word_count);
			xfer->status = -EPROTO;
			return true;

		}

		if (word_count > xfer->msg->rx_len) {
			DRM_DEV_ERROR(dev,
				"[%02X] Receive buffer too small: %lu (< %u)\n",
				 xfer->cmd,
				 xfer->msg->rx_len,
				 word_count);
			return true;
		}

		xfer->rx_word_count = word_count;
	} else {
		/* Set word_count from previous header read */
		word_count = xfer->rx_word_count;
	}

	/* If RX payload is not yet received, wait for it */
	if (!(status & RX_PKT_PAYLOAD_DATA_RCVD))
		return false;

	/* Read the RX payload */
	while (word_count >= 4) {
		val = nwl_dsi_read(dsi, RX_PAYLOAD);
		payload[0] = (val >>  0) & 0xff;
		payload[1] = (val >>  8) & 0xff;
		payload[2] = (val >> 16) & 0xff;
		payload[3] = (val >> 24) & 0xff;
		payload += 4;
		xfer->rx_len += 4;
		word_count -= 4;
	}

	if (word_count > 0) {
		val = nwl_dsi_read(dsi, RX_PAYLOAD);
		switch (word_count) {
		case 3:
			payload[2] = (val >> 16) & 0xff;
			++xfer->rx_len;
			/* Fall through */
		case 2:
			payload[1] = (val >>  8) & 0xff;
			++xfer->rx_len;
			/* Fall through */
		case 0:
			payload[0] = (val >>  0) & 0xff;
			++xfer->rx_len;
			break;
		}
	}

	xfer->status = xfer->rx_len;

	return true;
}

static void nwl_dsi_finish_transmission(struct nwl_mipi_dsi *dsi, u32 status)
{
	struct mipi_dsi_transfer *xfer = dsi->xfer;
	bool end_packet = false;

	if (!xfer)
		return;

	if (xfer->direction == DSI_PACKET_SEND && status & TX_PKT_DONE) {
		xfer->status = xfer->tx_len;
		end_packet = true;
	} else if (status & DPHY_DIRECTION && status & RX_PKT_HDR_RCVD)
		end_packet = nwl_dsi_read_packet(dsi, status);

	if (end_packet)
		complete(&xfer->completed);
}

static void nwl_dsi_begin_transmission(struct nwl_mipi_dsi *dsi)
{
	struct mipi_dsi_transfer *xfer = dsi->xfer;
	struct mipi_dsi_packet *pkt = &xfer->packet;
	const u8 *payload;
	size_t length;
	u16 word_count;
	u8 lp_mode;
	u32 val;

	/* Send the payload, if any */
	/* TODO: Need to check the TX FIFO overflow */
	length = pkt->payload_length;
	payload = pkt->payload;

	while (length >= 4) {
		val = get_unaligned_le32(payload);
		nwl_dsi_write(dsi, TX_PAYLOAD, val);
		payload += 4;
		length -= 4;
	}
	/* Send the rest of the payload */
	val = 0;
	switch (length) {
	case 3:
		val |= payload[2] << 16;
		/* Fall through */
	case 2:
		val |= payload[1] << 8;
		/* Fall through */
	case 1:
		val |= payload[0];
		nwl_dsi_write(dsi, TX_PAYLOAD, val);
		break;
	}
	xfer->tx_len = length;

	/*
	 * Now, send the header
	 * header structure is:
	 * header[0] = Virtual Channel + Data Type
	 * header[1] = Word Count LSB
	 * header[2] = Word Count MSB
	 */
	word_count = pkt->header[1] | (pkt->header[2] << 8);
	lp_mode = (xfer->msg->flags & MIPI_DSI_MSG_USE_LPM)?0:1;
	val = WC(word_count) |
		TX_VC(xfer->msg->channel) |
		TX_DT(xfer->msg->type) |
		HS_SEL(lp_mode) |
		BTA_TX(xfer->need_bta);
	nwl_dsi_write(dsi, PKT_CONTROL, val);

	/* Send packet command */
	nwl_dsi_write(dsi, SEND_PACKET, 0x1);
}

static ssize_t nwl_dsi_host_transfer(struct mipi_dsi_host *host,
				     const struct mipi_dsi_msg *msg)
{
	struct nwl_mipi_dsi *dsi = container_of(host,
						struct nwl_mipi_dsi,
						host);
	struct mipi_dsi_transfer xfer;
	ssize_t ret = 0;

	/* Create packet to be sent */
	dsi->xfer = &xfer;
	ret = mipi_dsi_create_packet(&xfer.packet, msg);
	if (ret < 0) {
		dsi->xfer = NULL;
		return ret;
	}

	if ((msg->type & MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM ||
	    msg->type & MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM ||
	    msg->type & MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM ||
	    msg->type & MIPI_DSI_DCS_READ) &&
	    msg->rx_len > 0 &&
	    msg->rx_buf != NULL)
		xfer.direction = DSI_PACKET_RECEIVE;
	else
		xfer.direction = DSI_PACKET_SEND;

	xfer.need_bta = (xfer.direction == DSI_PACKET_RECEIVE);
	xfer.need_bta |= (msg->flags & MIPI_DSI_MSG_REQ_ACK)?1:0;
	xfer.msg = msg;
	xfer.status = -ETIMEDOUT;
	xfer.rx_word_count = 0;
	xfer.rx_len = 0;
	xfer.cmd = 0x00;
	if (msg->tx_len > 0)
		xfer.cmd = ((u8 *)(msg->tx_buf))[0];
	init_completion(&xfer.completed);

	nwl_dsi_enable_clocks(dsi, CLK_RX_ESC);

	/* Initiate the DSI packet transmision */
	nwl_dsi_begin_transmission(dsi);

	wait_for_completion_timeout(&xfer.completed, MIPI_FIFO_TIMEOUT);

	ret = xfer.status;
	if (xfer.status == -ETIMEDOUT)
		DRM_DEV_ERROR(host->dev, "[%02X] DSI transfer timed out\n",
			xfer.cmd);

	nwl_dsi_disable_clocks(dsi, CLK_RX_ESC);

	return ret;
}

static const struct mipi_dsi_host_ops nwl_dsi_host_ops = {
	.attach = nwl_dsi_host_attach,
	.detach = nwl_dsi_host_detach,
	.transfer = nwl_dsi_host_transfer,
};

static irqreturn_t nwl_dsi_irq_handler(int irq, void *data)
{
	u32 irq_status;
	struct nwl_mipi_dsi *dsi = data;

	irq_status = nwl_dsi_read(dsi, IRQ_STATUS);

	if (irq_status & TX_PKT_DONE ||
	    irq_status & RX_PKT_HDR_RCVD ||
	    irq_status & RX_PKT_PAYLOAD_DATA_RCVD)
		nwl_dsi_finish_transmission(dsi, irq_status);

	return IRQ_HANDLED;
}

static enum drm_connector_status nwl_dsi_connector_detect(
	struct drm_connector *connector, bool force)
{
	struct nwl_mipi_dsi *dsi = container_of(connector,
						struct nwl_mipi_dsi,
						connector);

	if (dsi->panel)
		return connector_status_connected;

	return connector_status_unknown;
}

static int nwl_dsi_connector_get_modes(struct drm_connector *connector)
{
	struct nwl_mipi_dsi *dsi = container_of(connector,
						struct nwl_mipi_dsi,
						connector);

	if (dsi->panel)
		return drm_panel_get_modes(dsi->panel);

	return 0;
}

static const struct drm_connector_funcs nwl_dsi_connector_funcs = {
	.dpms = drm_atomic_helper_connector_dpms,
	.detect = nwl_dsi_connector_detect,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = drm_connector_cleanup,
	.reset = drm_atomic_helper_connector_reset,
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};

static const struct drm_connector_helper_funcs
	nwl_dsi_connector_helper_funcs = {
	.get_modes = nwl_dsi_connector_get_modes,
};

static int nwl_dsi_create_connector(struct drm_device *drm,
				    struct nwl_mipi_dsi *dsi)
{
	struct device *dev = dsi->dev;
	int ret;

	ret = drm_connector_init(drm, &dsi->connector,
				 &nwl_dsi_connector_funcs,
				 DRM_MODE_CONNECTOR_DSI);
	if (ret) {
		DRM_DEV_ERROR(dev, "Failed to init drm connector: %d\n", ret);
		return ret;
	}

	drm_connector_helper_add(&dsi->connector,
				 &nwl_dsi_connector_helper_funcs);

	dsi->connector.dpms = DRM_MODE_DPMS_OFF;
	drm_mode_connector_attach_encoder(&dsi->connector, dsi->bridge.encoder);

	ret = drm_panel_attach(dsi->panel, &dsi->connector);
	if (ret) {
		DRM_DEV_ERROR(dev, "Failed to attach panel: %d\n", ret);
		drm_connector_cleanup(&dsi->connector);
		return ret;
	}

	return 0;
}

static int nwl_dsi_attach_next_bridge(struct drm_encoder *encoder,
				      struct drm_bridge *bridge)
{
	int ret = 0;

	/* Attach the next bridge in chain */
	if (!nwl_dsi_add_bridge(encoder, bridge))
		return -EEXIST;
	ret = drm_bridge_attach(encoder->dev, bridge);
	if (ret)
		nwl_dsi_del_bridge(encoder, bridge);

	return ret;
}

static int nwl_dsi_bridge_attach(struct drm_bridge *bridge)
{
	struct nwl_mipi_dsi *dsi = bridge->driver_private;
	struct device *dev = dsi->dev;
	struct drm_encoder *encoder = bridge->encoder;
	struct device_node *np = dev->of_node;
	struct device_node *remote_node, *endpoint;

	int ret = 0;

	DRM_DEV_DEBUG_DRIVER(dsi->dev, "\n");
	if (!encoder) {
		DRM_DEV_ERROR(dev, "Parent encoder object not found\n");
		return -ENODEV;
	}

	dsi->host.ops = &nwl_dsi_host_ops;
	dsi->host.dev = dev;
	ret = mipi_dsi_host_register(&dsi->host);
	if (ret < 0) {
		dev_err(dev, "failed to register DSI host (%d)\n", ret);
		return ret;
	}

	endpoint = of_graph_get_next_endpoint(np, NULL);
	while (endpoint && !dsi->next_bridge) {
		remote_node = of_graph_get_remote_port_parent(endpoint);
		if (!remote_node) {
			DRM_DEV_ERROR(dev, "No endpoint found!\n");
			return -ENODEV;
		}

		dsi->next_bridge = of_drm_find_bridge(remote_node);
		ret = nwl_dsi_attach_next_bridge(encoder, dsi->next_bridge);
		if (ret)
			dsi->next_bridge = NULL;
		of_node_put(remote_node);
		endpoint = of_graph_get_next_endpoint(np, endpoint);
	};

	/*
	 * Create the connector. If we have a bridge, attach it and let the
	 * bridge create the connector.
	 */
	if (dsi->panel)
		ret = nwl_dsi_create_connector(encoder->dev, dsi);
	else if (!dsi->next_bridge)
		ret = -ENODEV;

	return ret;
}

static void nwl_dsi_bridge_detach(struct drm_bridge *bridge)
{
	struct nwl_mipi_dsi *dsi = bridge->driver_private;

	DRM_DEV_DEBUG_DRIVER(dsi->dev, "\n");
	if (dsi->panel) {
		drm_panel_detach(dsi->panel);
		drm_connector_cleanup(&dsi->connector);
		dsi->panel = NULL;
	} else if (dsi->next_bridge) {
		drm_bridge_detach(dsi->next_bridge);
		nwl_dsi_del_bridge(dsi->next_bridge->encoder, dsi->next_bridge);
		dsi->next_bridge = NULL;
	}
	if (dsi->host.dev)
		mipi_dsi_host_unregister(&dsi->host);
}

static void nwl_dsi_bridge_enable(struct drm_bridge *bridge)
{
	struct nwl_mipi_dsi *dsi = bridge->driver_private;
	struct device *dev = dsi->dev;
	int ret;

	if (dsi->enabled || (!dsi->panel && !dsi->next_bridge))
		return;

	if (!dsi->lanes) {
		DRM_DEV_ERROR(dev, "Bridge not set up properly!\n");
		return;
	}

	ret = devm_request_irq(dev, dsi->irq,
			       nwl_dsi_irq_handler, 0, IRQ_NAME, dsi);
	if (ret < 0) {
		DRM_DEV_ERROR(dev, "Failed to request IRQ: %d (%d)\n",
			      dsi->irq, ret);
		return;
	}

	nwl_dsi_enable_clocks(dsi, CLK_PHY_REF | CLK_TX_ESC);

	nwl_dsi_config_host(dsi);
	nwl_dsi_config_dpi(dsi);

	phy_init(dsi->phy);

	ret = phy_power_on(dsi->phy);
	if (ret < 0) {
		DRM_DEV_ERROR(dev, "Failed to power on DPHY (%d)\n", ret);
		return;
	}

	nwl_dsi_init_interrupts(dsi);

	if (dsi->panel && drm_panel_prepare(dsi->panel)) {
		DRM_DEV_ERROR(dev, "Failed to setup panel\n");
		return;
	}

	if (dsi->dsi_mode_flags & MIPI_DSI_CLOCK_NON_CONTINUOUS)
		nwl_dsi_write(dsi, CFG_NONCONTINUOUS_CLK, 0x00);

	if (dsi->panel && drm_panel_enable(dsi->panel)) {
		DRM_DEV_ERROR(dev, "Failed to enable panel\n");
		drm_panel_unprepare(dsi->panel);
		return;
	}

	dsi->enabled = true;
}

static void nwl_dsi_bridge_disable(struct drm_bridge *bridge)
{
	struct nwl_mipi_dsi *dsi = bridge->driver_private;
	struct device *dev = dsi->dev;

	if (!dsi->enabled)
		return;

	if (dsi->panel) {
		if (drm_panel_disable(dsi->panel)) {
			DRM_DEV_ERROR(dev, "failed to disable panel\n");
			return;
		}
		drm_panel_unprepare(dsi->panel);
	}

	nwl_dsi_disable_clocks(dsi, CLK_PHY_REF | CLK_TX_ESC);
	devm_free_irq(dev, dsi->irq, dsi);

	phy_power_off(dsi->phy);
	phy_exit(dsi->phy);

	dsi->enabled = false;
}

static const struct drm_bridge_funcs nwl_dsi_bridge_funcs = {
	.enable = nwl_dsi_bridge_enable,
	.disable = nwl_dsi_bridge_disable,
	.mode_fixup = nwl_dsi_bridge_mode_fixup,
	.mode_set = nwl_dsi_bridge_mode_set,
	.attach = nwl_dsi_bridge_attach,
	.detach = nwl_dsi_bridge_detach,
};

static int nwl_dsi_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct nwl_mipi_dsi *dsi;
	struct clk *clk;
	struct resource *res;
	int ret;

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

	dsi->phy = devm_phy_get(dev, "dphy");
	if (IS_ERR(dsi->phy)) {
		ret = PTR_ERR(dsi->phy);
		dev_err(dev, "Could not get PHY (%d)\n", ret);
		return ret;
	}

	clk = devm_clk_get(dev, "phy_ref");
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		dev_err(dev, "Failed to get phy_ref clock: %d\n", ret);
		return ret;
	}
	dsi->phy_ref.clk = clk;
	dsi->phy_ref.rate = clk_get_rate(clk);
	dsi->phy_ref.enabled = false;

	clk = devm_clk_get(dev, "rx_esc");
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		dev_err(dev, "Failed to get rx_esc clock: %d\n", ret);
		return ret;
	}
	dsi->rx_esc.clk = clk;
	dsi->rx_esc.rate = clk_get_rate(clk);
	dsi->rx_esc.enabled = false;

	clk = devm_clk_get(dev, "tx_esc");
	if (IS_ERR(clk)) {
		ret = PTR_ERR(clk);
		dev_err(dev, "Failed to get tx_esc clock: %d\n", ret);
		return ret;
	}
	dsi->tx_esc.clk = clk;
	dsi->tx_esc.rate = clk_get_rate(clk);
	dsi->tx_esc.enabled = false;
	/* TX clk rate must be RX clk rate divided by 4 */
	if (dsi->tx_esc.rate != (dsi->rx_esc.rate / 4))
		dsi->tx_esc.rate = dsi->rx_esc.rate / 4;

	dsi->enabled = false;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res)
		return -EBUSY;

	dsi->base = devm_ioremap_resource(dev, res);
	if (IS_ERR(dsi->base))
		return PTR_ERR(dsi->base);

	dsi->irq = platform_get_irq(pdev, 0);
	if (dsi->irq < 0) {
		DRM_DEV_ERROR(dev, "Failed to get device IRQ!\n");
		return -EINVAL;
	}

	dsi->dev = dev;
	platform_set_drvdata(pdev, dsi);

	dsi->bridge.driver_private = dsi;
	dsi->bridge.funcs = &nwl_dsi_bridge_funcs;
	dsi->bridge.of_node = dev->of_node;

	ret = drm_bridge_add(&dsi->bridge);
	if (ret < 0)
		dev_err(dev, "Failed to add nwl-dsi bridge (%d)\n", ret);

	return ret;
}

static int nwl_dsi_remove(struct platform_device *pdev)
{
	struct nwl_mipi_dsi *dsi = platform_get_drvdata(pdev);

	drm_bridge_remove(&dsi->bridge);

	return 0;
}

static const struct of_device_id nwl_dsi_dt_ids[] = {
	{ .compatible = "nwl,mipi-dsi" },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, nwl_dsi_dt_ids);

static struct platform_driver imx_nwl_dsi_driver = {
	.probe		= nwl_dsi_probe,
	.remove		= nwl_dsi_remove,
	.driver		= {
		.of_match_table = nwl_dsi_dt_ids,
		.name	= "nwl-mipi-dsi",
	},
};

module_platform_driver(imx_nwl_dsi_driver);

MODULE_AUTHOR("NXP Semiconductor");
MODULE_DESCRIPTION("NWL MIPI-DSI transmitter driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:nwl-dsi");
