/*
 * Copyright (C) 2015 Freescale Semiconductor, Inc. All Rights Reserved.
 * Copyright 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.

 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <linux/types.h>
#include <linux/init.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <linux/console.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/bitops.h>
#include <linux/mipi_dsi_samsung.h>
#include <linux/module.h>
#include <linux/mxcfb.h>
#include <linux/pm_runtime.h>
#include <linux/busfreq-imx.h>
#include <linux/backlight.h>
#include <linux/of_device.h>
#include <linux/of_address.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
#include <linux/spinlock.h>
#include <linux/delay.h>
#include <video/mipi_display.h>
#include <linux/mfd/syscon.h>

#include "mipi_dsi.h"

#define DISPDRV_MIPI			"mipi_dsi_samsung"
#define ROUND_UP(x)			((x)+1)
#define NS2PS_RATIO			(1000)
#define	MIPI_LCD_SLEEP_MODE_DELAY	(120)
#define MIPI_FIFO_TIMEOUT		msecs_to_jiffies(250)

static struct mipi_dsi_match_lcd mipi_dsi_lcd_db[] = {
#ifdef CONFIG_FB_MXC_TRULY_WVGA_SYNC_PANEL
	{
	 "TRULY-WVGA",
	 {mipid_hx8369_get_lcd_videomode, mipid_hx8369_lcd_setup}
	},
#endif
#ifdef CONFIG_FB_MXC_TRULY_PANEL_TFT3P5079E
	{
	 "TRULY-WVGA-TFT3P5079E",
	 {mipid_otm8018b_get_lcd_videomode, mipid_otm8018b_lcd_setup}
	},
#endif
#ifdef CONFIG_FB_MXC_TRULY_PANEL_TFT3P5581E
	{
	 "TRULY-WVGA-TFT3P5581E",
	 {mipid_hx8363_get_lcd_videomode, mipid_hx8363_lcd_setup}
	},
#endif
	{
	"", {NULL, NULL}
	}
};

enum mipi_dsi_mode {
	DSI_COMMAND_MODE,
	DSI_VIDEO_MODE
};

enum mipi_dsi_trans_mode {
	DSI_LP_MODE,
	DSI_HS_MODE
};

static struct regulator *mipi_phy_reg;
static DECLARE_COMPLETION(dsi_rx_done);
static DECLARE_COMPLETION(dsi_tx_done);

static void mipi_dsi_dphy_power_down(void);
static void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi,
			      enum mipi_dsi_trans_mode mode);

static int mipi_dsi_lcd_init(struct mipi_dsi_info *mipi_dsi,
			     struct mxc_dispdrv_setting *setting)
{
	int i, size, err;
	struct fb_videomode *mipi_lcd_modedb;
	struct fb_videomode mode;
	struct device *dev = &mipi_dsi->pdev->dev;

	for (i = 0; i < ARRAY_SIZE(mipi_dsi_lcd_db); i++) {
		if (!strcmp(mipi_dsi->lcd_panel,
			mipi_dsi_lcd_db[i].lcd_panel)) {
			mipi_dsi->lcd_callback =
				&mipi_dsi_lcd_db[i].lcd_callback;
			break;
		}
	}
	if (i == ARRAY_SIZE(mipi_dsi_lcd_db)) {
		dev_err(dev, "failed to find supported lcd panel.\n");
		return -EINVAL;
	}

	/* set default bpp to 32 if not set*/
	if (!setting->default_bpp)
		setting->default_bpp = 32;

	mipi_dsi->lcd_callback->get_mipi_lcd_videomode(&mipi_lcd_modedb, &size,
					&mipi_dsi->lcd_config);

	err = fb_find_mode(&setting->fbi->var, setting->fbi,
				setting->dft_mode_str,
				mipi_lcd_modedb, size, NULL,
				setting->default_bpp);
	if (err != 1)
		fb_videomode_to_var(&setting->fbi->var, mipi_lcd_modedb);

	INIT_LIST_HEAD(&setting->fbi->modelist);
	for (i = 0; i < size; i++) {
		fb_var_to_videomode(&mode, &setting->fbi->var);
		if (fb_mode_is_equal(&mode, mipi_lcd_modedb + i)) {
			err = fb_add_videomode(mipi_lcd_modedb + i,
					&setting->fbi->modelist);
			mipi_dsi->mode = mipi_lcd_modedb + i;
			break;
		}
	}

	if ((err < 0) || (size == i)) {
		dev_err(dev, "failed to add videomode.\n");
		return err;
	}

	return 0;
}

static void mipi_dsi_wr_tx_header(struct mipi_dsi_info *mipi_dsi,
			u8 di, u8 data0, u8 data1)
{
	unsigned int reg;

	reg = (data1 << 16) | (data0 << 8) | ((di & 0x3f) << 0);

	writel(reg, mipi_dsi->mmio_base + MIPI_DSI_PKTHDR);
}

static void mipi_dsi_wr_tx_data(struct mipi_dsi_info *mipi_dsi,
				unsigned int tx_data)
{
	writel(tx_data, mipi_dsi->mmio_base + MIPI_DSI_PAYLOAD);
}

static void mipi_dsi_long_data_wr(struct mipi_dsi_info *mipi_dsi,
			const unsigned char *data0, unsigned int data_size)
{
	unsigned int data_cnt = 0, payload = 0;

        /* in case that data count is more then 4 */
        for (data_cnt = 0; data_cnt < data_size; data_cnt += 4) {
                /*
                 * after sending 4bytes per one time,
                 * send remainder data less then 4.
                 */
                if ((data_size - data_cnt) < 4) {
                        if ((data_size - data_cnt) == 3) {
                                payload = data0[data_cnt] |
                                    data0[data_cnt + 1] << 8 |
                                        data0[data_cnt + 2] << 16;
                        dev_dbg(&mipi_dsi->pdev->dev, "count = 3 payload = %x, %x %x %x\n",
                                payload, data0[data_cnt],
                                data0[data_cnt + 1],
                                data0[data_cnt + 2]);
                        } else if ((data_size - data_cnt) == 2) {
                                payload = data0[data_cnt] |
                                        data0[data_cnt + 1] << 8;
                        dev_dbg(&mipi_dsi->pdev->dev,
                                "count = 2 payload = %x, %x %x\n", payload,
                                data0[data_cnt],
                                data0[data_cnt + 1]);
                        } else if ((data_size - data_cnt) == 1) {
                                payload = data0[data_cnt];
                        }

                        mipi_dsi_wr_tx_data(mipi_dsi, payload);
                /* send 4bytes per one time. */
                } else {
                        payload = data0[data_cnt] |
                                data0[data_cnt + 1] << 8 |
                                data0[data_cnt + 2] << 16 |
                                data0[data_cnt + 3] << 24;

                        dev_dbg(&mipi_dsi->pdev->dev,
                                "count = 4 payload = %x, %x %x %x %x\n",
                                payload, *(u8 *)(data0 + data_cnt),
                                data0[data_cnt + 1],
                                data0[data_cnt + 2],
                                data0[data_cnt + 3]);

			mipi_dsi_wr_tx_data(mipi_dsi, payload);
                }
        }
}

static int mipi_dsi_pkt_write(struct mipi_dsi_info *mipi_dsi,
		       u8 data_type, const u32 *buf, int len)
{
	int ret = 0;
	struct platform_device *pdev = mipi_dsi->pdev;
	const unsigned char *data = (const unsigned char*)buf;

	if (len == 0)
		/* handle generic short write command */
		mipi_dsi_wr_tx_header(mipi_dsi, data_type, data[0], data[1]);
	else {
		reinit_completion(&dsi_tx_done);

		/* handle generic long write command */
		mipi_dsi_long_data_wr(mipi_dsi, data, len);
		mipi_dsi_wr_tx_header(mipi_dsi, data_type, len & 0xff, (len & 0xff00) >> 8);

		ret = wait_for_completion_timeout(&dsi_tx_done, MIPI_FIFO_TIMEOUT);
		if (!ret) {
			dev_err(&pdev->dev, "wait tx done timeout!\n");
			return -ETIMEDOUT;
		}
	}
	mdelay(10);

	return 0;
}

static void mipi_dsi_rd_tx_header(struct mipi_dsi_info *mipi_dsi,
				  u8 data_type, u8 data0)
{
	unsigned int reg = (data_type << 0) | (data0 << 8);

	writel(reg, mipi_dsi->mmio_base + MIPI_DSI_PKTHDR);
}

static unsigned int mipi_dsi_rd_rx_fifo(struct mipi_dsi_info *mipi_dsi)
{
	return readl(mipi_dsi->mmio_base + MIPI_DSI_RXFIFO);
}

static int mipi_dsi_pkt_read(struct mipi_dsi_info *mipi_dsi,
				u8 data_type, u32 *buf, int len)
{
	int ret;
	struct platform_device *pdev = mipi_dsi->pdev;

	if (len <= 4) {
		reinit_completion(&dsi_rx_done);

		mipi_dsi_rd_tx_header(mipi_dsi, data_type, buf[0]);

		ret = wait_for_completion_timeout(&dsi_rx_done, MIPI_FIFO_TIMEOUT);
		if (!ret) {
			dev_err(&pdev->dev, "wait rx done timeout!\n");
			return -ETIMEDOUT;
		}

		buf[0] = mipi_dsi_rd_rx_fifo(mipi_dsi);
		buf[0] = buf[0] >> 8;
	}
	else {
		/* TODO: add support later */
	}

	return 0;
}

int mipi_dsi_dcs_cmd(struct mipi_dsi_info *mipi_dsi,
				u8 cmd, const u32 *param, int num)
{
	int err = 0;
	u32 buf[DSI_CMD_BUF_MAXSIZE];

	switch (cmd) {
	case MIPI_DCS_EXIT_SLEEP_MODE:
	case MIPI_DCS_ENTER_SLEEP_MODE:
	case MIPI_DCS_SET_DISPLAY_ON:
	case MIPI_DCS_SET_DISPLAY_OFF:
		buf[0] = cmd;
		err = mipi_dsi_pkt_write(mipi_dsi,
				MIPI_DSI_DCS_SHORT_WRITE, buf, 0);
		break;

	default:
		dev_err(&mipi_dsi->pdev->dev,
			"MIPI DSI DCS Command:0x%x Not supported!\n", cmd);
		break;
	}

	return err;
}

static void mipi_dsi_set_main_standby(struct mipi_dsi_info *mipi_dsi,
                               unsigned int enable)
{
        unsigned int reg;

        reg = readl(mipi_dsi->mmio_base + MIPI_DSI_MDRESOL);

        reg &= ~MIPI_DSI_MAIN_STANDBY(1);

        if (enable)
                reg |= MIPI_DSI_MAIN_STANDBY(1);

        writel(reg, mipi_dsi->mmio_base + MIPI_DSI_MDRESOL);
}

static void mipi_dsi_power_off(struct mxc_dispdrv_handle *disp)
{
	int err;
	struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);

	err = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_ENTER_SLEEP_MODE,
			NULL, 0);
	if (err) {
		dev_err(&mipi_dsi->pdev->dev,
			"MIPI DSI DCS Command display on error!\n");
	}
	msleep(MIPI_LCD_SLEEP_MODE_DELAY);

	mipi_dsi_set_main_standby(mipi_dsi, 0);

	clk_disable_unprepare(mipi_dsi->dphy_clk);
	clk_disable_unprepare(mipi_dsi->cfg_clk);
}

static void mipi_dsi_dphy_power_on(struct platform_device *pdev)
{
	int ret;

	regulator_set_voltage(mipi_phy_reg, 1000000, 1000000);

	ret = regulator_enable(mipi_phy_reg);
	if (ret){
		dev_err(&pdev->dev, "failed to enable mipi phy regulatore\n");
		BUG_ON(1);
	}
}

static void mipi_dsi_dphy_power_down(void)
{
	regulator_disable(mipi_phy_reg);
}

static int mipi_dsi_lane_stop_state(struct mipi_dsi_info *mipi_dsi)
{
	unsigned int reg;

	reg = readl(mipi_dsi->mmio_base + MIPI_DSI_STATUS);

	if (((reg & MIPI_DSI_STOP_STATE_DAT(0x3)) == 0x3) &&
	    ((reg & MIPI_DSI_STOP_STATE_CLK(0x1)) ||
	     (reg & MIPI_DSI_TX_READY_HS_CLK(0x1))))
		return 1;

	return 0;
}

static void mipi_dsi_init_interrupt(struct mipi_dsi_info *mipi_dsi)
{
	unsigned int intsrc, intmsk;

	intsrc = (INTSRC_SFR_PL_FIFO_EMPTY | INTSRC_RX_DATA_DONE);
	writel(intsrc, mipi_dsi->mmio_base + MIPI_DSI_INTSRC);

	intmsk = ~(INTMSK_SFR_PL_FIFO_EMPTY | INTMSK_RX_DATA_DONE);
	writel(intmsk, mipi_dsi->mmio_base + MIPI_DSI_INTMSK);
}

static int mipi_dsi_master_init(struct mipi_dsi_info *mipi_dsi,
				bool init)
{
	unsigned int time_out = 100;
	unsigned int reg, byte_clk, esc_div;
	struct fb_videomode *mode = mipi_dsi->mode;
	struct device *dev = &mipi_dsi->pdev->dev;

	/* configure DPHY PLL clock */
	writel(MIPI_DSI_TX_REQUEST_HSCLK(0) |
	       MIPI_DSI_DPHY_SEL(0) |
	       MIPI_DSI_PLL_BYPASS(0) |
	       MIPI_DSI_BYTE_CLK_SRC(0),
	       mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL);
	if (!strcmp(mipi_dsi->lcd_panel, "TRULY-WVGA-TFT3P5581E"))
		writel(MIPI_DSI_PLL_EN(1) | MIPI_DSI_PMS(0x3141),
		       mipi_dsi->mmio_base + MIPI_DSI_PLLCTRL);
	else
		writel(MIPI_DSI_PLL_EN(1) | MIPI_DSI_PMS(0x4190),
		       mipi_dsi->mmio_base + MIPI_DSI_PLLCTRL);

	/* set PLLTMR: stable time */
	writel(33024, mipi_dsi->mmio_base + MIPI_DSI_PLLTMR);
	udelay(300);

	/* configure byte clock */
	reg = readl(mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL);
	reg |= MIPI_DSI_BYTE_CLK_EN(1);
	byte_clk = 1500000000 / 8;
	esc_div  = DIV_ROUND_UP(byte_clk, 20 * 1000000);
	reg |= (esc_div & 0xffff);
	/* enable escape clock for clock lane and data lane0 and lane1 */
	reg |= MIPI_DSI_LANE_ESC_CLK_EN(0x7);
	reg |= MIPI_DSI_ESC_CLK_EN(1);
	writel(reg, mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL);

	/* set main display resolution */
	writel(MIPI_DSI_MAIN_HRESOL(mode->xres) |
	       MIPI_DSI_MAIN_VRESOL(mode->yres) |
	       MIPI_DSI_MAIN_STANDBY(0),
	       mipi_dsi->mmio_base + MIPI_DSI_MDRESOL);

	/* set config register */
	writel(MIPI_DSI_MFLUSH_VS(1) |
	       MIPI_DSI_SYNC_IN_FORM(0) |
	       MIPI_DSI_BURST_MODE(1) |
	       MIPI_DSI_VIDEO_MODE(1) |
	       MIPI_DSI_AUTO_MODE(0)  |
	       MIPI_DSI_HSE_DISABLE_MODE(0) |
	       MIPI_DSI_HFP_DISABLE_MODE(0) |
	       MIPI_DSI_HBP_DISABLE_MODE(0) |
	       MIPI_DSI_HSA_DISABLE_MODE(0) |
	       MIPI_DSI_MAIN_VC(0) |
	       MIPI_DSI_SUB_VC(1)  |
	       MIPI_DSI_MAIN_PIX_FORMAT(0x7) |
	       MIPI_DSI_SUB_PIX_FORMAT(0x7) |
	       MIPI_DSI_NUM_OF_DATALANE(0x1) |
	       MIPI_DSI_LANE_EN(0x7), /* enable data lane 0 and 1 */
	       mipi_dsi->mmio_base + MIPI_DSI_CONFIG);

	/* set main display vporch */
	writel(MIPI_DSI_CMDALLOW(0xf) |
	       MIPI_DSI_STABLE_VFP(mode->lower_margin) |
	       MIPI_DSI_MAIN_VBP(mode->upper_margin),
	       mipi_dsi->mmio_base + MIPI_DSI_MVPORCH);
	/* set main display hporch */
	writel(MIPI_DSI_MAIN_HFP(mode->right_margin) |
	       MIPI_DSI_MAIN_HBP(mode->left_margin),
	       mipi_dsi->mmio_base + MIPI_DSI_MHPORCH);
	/* set main display sync */
	writel(MIPI_DSI_MAIN_VSA(mode->vsync_len) |
	       MIPI_DSI_MAIN_HSA(mode->hsync_len),
	       mipi_dsi->mmio_base + MIPI_DSI_MSYNC);

	/* configure d-phy timings */
	if (!strcmp(mipi_dsi->lcd_panel, "TRULY-WVGA-TFT3P5581E")) {
		writel(MIPI_DSI_M_TLPXCTL(2) | MIPI_DSI_M_THSEXITCTL(4),
			mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING);
		writel(MIPI_DSI_M_TCLKPRPRCTL(5) |
			MIPI_DSI_M_TCLKZEROCTL(14) |
			MIPI_DSI_M_TCLKPOSTCTL(8) |
			MIPI_DSI_M_TCLKTRAILCTL(3),
			mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING1);
		writel(MIPI_DSI_M_THSPRPRCTL(3) |
			MIPI_DSI_M_THSZEROCTL(3) |
			MIPI_DSI_M_THSTRAILCTL(3),
			mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING2);
	} else {
		writel(MIPI_DSI_M_TLPXCTL(11) | MIPI_DSI_M_THSEXITCTL(18),
			mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING);
		writel(MIPI_DSI_M_TCLKPRPRCTL(13) |
			MIPI_DSI_M_TCLKZEROCTL(65) |
			MIPI_DSI_M_TCLKPOSTCTL(17) |
			MIPI_DSI_M_TCLKTRAILCTL(13),
			mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING1);
		writel(MIPI_DSI_M_THSPRPRCTL(16) |
			MIPI_DSI_M_THSZEROCTL(24) |
			MIPI_DSI_M_THSTRAILCTL(16),
			mipi_dsi->mmio_base + MIPI_DSI_PHYTIMING2);
	}

	writel(0xf000f, mipi_dsi->mmio_base + MIPI_DSI_TIMEOUT);

	/* Init FIFO */
	writel(0x0, mipi_dsi->mmio_base + MIPI_DSI_FIFOCTRL);
	udelay(300);
	writel(0x1f, mipi_dsi->mmio_base + MIPI_DSI_FIFOCTRL);

	/* check clock and data lanes are in stop state
	 * which means dphy is in low power mode
	 */
	while (!mipi_dsi_lane_stop_state(mipi_dsi)) {
		time_out--;
		if (time_out == 0) {
			dev_err(dev, "MIPI DSI is not stop state.\n");
			return -EINVAL;
		}
	}

	/* transfer commands always in lp mode */
	writel(MIPI_DSI_CMD_LPDT, mipi_dsi->mmio_base + MIPI_DSI_ESCMODE);

	mipi_dsi_init_interrupt(mipi_dsi);

	return 0;
}

static int mipi_dsi_disp_init(struct mxc_dispdrv_handle *disp,
	struct mxc_dispdrv_setting *setting)
{
	struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
	struct device *dev = &mipi_dsi->pdev->dev;
	struct device_node *np = dev->of_node;
	struct reset_control *reset = NULL;
	int ret = 0;

	reset = of_reset_control_get(np, NULL);
	if (IS_ERR(reset))
		return PTR_ERR(reset);

	ret = mipi_dsi_lcd_init(mipi_dsi, setting);
	if (ret) {
		dev_err(dev, "failed to init mipi dsi lcd\n");
		goto out;
	}

	dev_info(dev, "MIPI DSI dispdrv inited!\n");

out:
	reset_control_put(reset);
	return ret;
}

static void mipi_dsi_disp_deinit(struct mxc_dispdrv_handle *disp)
{
	struct mipi_dsi_info *mipi_dsi;

	mipi_dsi = mxc_dispdrv_getdata(disp);

	mipi_dsi_power_off(mipi_dsi->disp_mipi);
	if (mipi_dsi->bl)
		backlight_device_unregister(mipi_dsi->bl);
}

static void mipi_dsi_set_mode(struct mipi_dsi_info *mipi_dsi,
			      enum mipi_dsi_trans_mode mode)
{
	unsigned int dsi_clkctrl;

	dsi_clkctrl = readl(mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL);

	switch (mode) {
	case DSI_LP_MODE:
		dsi_clkctrl &= ~MIPI_DSI_TX_REQUEST_HSCLK(1);
		break;
	case DSI_HS_MODE:
		dsi_clkctrl |= MIPI_DSI_TX_REQUEST_HSCLK(1);
		break;
	default:
		dev_err(&mipi_dsi->pdev->dev,
			"invalid dsi mode\n");
		return;
	}

	writel(dsi_clkctrl, mipi_dsi->mmio_base + MIPI_DSI_CLKCTRL);
	mdelay(1);
}

static int mipi_dsi_enable(struct mxc_dispdrv_handle *disp,
			   struct fb_info *fbi)
{
	int ret;
	struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);

	if (fbi->state == FBINFO_STATE_SUSPENDED) {
		if (mipi_dsi->disp_power_on) {
			ret = regulator_enable(mipi_dsi->disp_power_on);
			if (ret) {
				dev_err(&mipi_dsi->pdev->dev, "failed to enable display "
						"power regulator, err = %d\n", ret);
				return ret;
			}
		}
	}

	if (!mipi_dsi->dsi_power_on)
		pm_runtime_get_sync(&mipi_dsi->pdev->dev);

	ret = clk_prepare_enable(mipi_dsi->dphy_clk);
	ret |= clk_prepare_enable(mipi_dsi->cfg_clk);
	if (ret) {
		dev_err(&mipi_dsi->pdev->dev,
				"clk enable error:%d!\n", ret);
		return -EINVAL;
	}

	if (!mipi_dsi->lcd_inited) {
		ret = mipi_dsi_master_init(mipi_dsi, true);
		if (ret)
			return -EINVAL;

		msleep(20);
		ret = device_reset(&mipi_dsi->pdev->dev);
		if (ret) {
			dev_err(&mipi_dsi->pdev->dev, "failed to reset device: %d\n", ret);
			return -EINVAL;
		}
		msleep(120);

		/* the panel should be config under LP mode */
		ret = mipi_dsi->lcd_callback->mipi_lcd_setup(mipi_dsi);
		if (ret < 0) {
			dev_err(&mipi_dsi->pdev->dev,
					"failed to init mipi lcd.\n");
			return ret ;
		}
		mipi_dsi->lcd_inited = 1;

		/* change to HS mode for panel display */
		mipi_dsi_set_mode(mipi_dsi, DSI_HS_MODE);
	} else {
		ret = mipi_dsi_dcs_cmd(mipi_dsi, MIPI_DCS_EXIT_SLEEP_MODE,
			NULL, 0);
		if (ret) {
			dev_err(&mipi_dsi->pdev->dev,
				"MIPI DSI DCS Command sleep-in error!\n");
		}
		msleep(MIPI_LCD_SLEEP_MODE_DELAY);
	}

	mipi_dsi_set_main_standby(mipi_dsi, 1);

	return 0;
}

static void mipi_dsi_disable(struct mxc_dispdrv_handle *disp,
			     struct fb_info *fbi)
{
	struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);

	mipi_dsi_power_off(mipi_dsi->disp_mipi);

	if (fbi->state == FBINFO_STATE_SUSPENDED) {
		if (mipi_dsi->dsi_power_on) {
			pm_runtime_put_noidle(&mipi_dsi->pdev->dev);
			pm_runtime_put_sync_suspend(&mipi_dsi->pdev->dev);
			pm_runtime_get_noresume(&mipi_dsi->pdev->dev);
		}

		if (mipi_dsi->disp_power_on)
			regulator_disable(mipi_dsi->disp_power_on);

		mipi_dsi->lcd_inited = 0;
	}
}

static int mipi_dsi_setup(struct mxc_dispdrv_handle *disp,
			  struct fb_info *fbi)
{
	struct mipi_dsi_info *mipi_dsi = mxc_dispdrv_getdata(disp);
	int xres_virtual = fbi->var.xres_virtual;
	int yres_virtual = fbi->var.yres_virtual;
	int xoffset = fbi->var.xoffset;
	int yoffset = fbi->var.yoffset;
	int pixclock = fbi->var.pixclock;

	if (!mipi_dsi->mode)
		return 0;

	/* set the mode back to var in case userspace changes it */
	fb_videomode_to_var(&fbi->var, mipi_dsi->mode);

	/* restore some var entries cached */
	fbi->var.xres_virtual = xres_virtual;
	fbi->var.yres_virtual = yres_virtual;
	fbi->var.xoffset = xoffset;
	fbi->var.yoffset = yoffset;
	fbi->var.pixclock = pixclock;

	return 0;
}

static struct mxc_dispdrv_driver mipi_dsi_drv = {
	.name = DISPDRV_MIPI,
	.init = mipi_dsi_disp_init,
	.deinit = mipi_dsi_disp_deinit,
	.enable = mipi_dsi_enable,
	.disable = mipi_dsi_disable,
	.setup = mipi_dsi_setup,
};

static const struct of_device_id imx_mipi_dsi_dt_ids[] = {
	{ .compatible = "fsl,imx7d-mipi-dsi", .data = NULL, },
	{ }
};
MODULE_DEVICE_TABLE(of, imx_mipi_dsi_dt_ids);

static irqreturn_t mipi_dsi_irq_handler(int irq, void *data)
{
	unsigned int intsrc, intclr;
	struct mipi_dsi_info *mipi_dsi = data;
	struct platform_device *pdev = mipi_dsi->pdev;

	intclr = 0;
	intsrc = readl(mipi_dsi->mmio_base + MIPI_DSI_INTSRC);

	dev_dbg(&pdev->dev, "intsrc = 0x%x\n", intsrc);

	if (intsrc & INTSRC_SFR_PL_FIFO_EMPTY) {
		dev_dbg(&pdev->dev, "playload tx finished\n");
		intclr |= INTSRC_SFR_PL_FIFO_EMPTY;
		complete(&dsi_tx_done);
	}

	if(intsrc & INTSRC_RX_DATA_DONE) {
		dev_dbg(&pdev->dev, "rx data finished\n");
		intclr |= INTSRC_RX_DATA_DONE;
		complete(&dsi_rx_done);
	}

	/* clear the interrupts */
	if (intclr)
		writel(intclr, mipi_dsi->mmio_base + MIPI_DSI_INTSRC);

	return IRQ_HANDLED;
}

/**
 * This function is called by the driver framework to initialize the MIPI DSI
 * device.
 *
 * @param	pdev	The device structure for the MIPI DSI passed in by the
 *			driver framework.
 *
 * @return      Returns 0 on success or negative error code on error
 */
static int mipi_dsi_probe(struct platform_device *pdev)
{
	struct device_node *np = pdev->dev.of_node;
	struct mipi_dsi_info *mipi_dsi;
	struct resource *res;
	const char *lcd_panel;
	int ret = 0;

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

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	if (!res) {
		dev_err(&pdev->dev, "failed to get platform resource mem\n");
		return -ENODEV;
	}

	if (!devm_request_mem_region(&pdev->dev, res->start,
				resource_size(res), pdev->name))
		return -EBUSY;

	mipi_dsi->mmio_base = devm_ioremap(&pdev->dev, res->start,
					resource_size(res));
	if (!mipi_dsi->mmio_base)
		return -ENOMEM;

	mipi_dsi->irq = platform_get_irq(pdev, 0);
	if (mipi_dsi->irq < 0) {
		dev_err(&pdev->dev, "failed to get device irq\n");
		return -EINVAL;
	}

	ret = devm_request_irq(&pdev->dev, mipi_dsi->irq,
				mipi_dsi_irq_handler,
				0, "mipi_dsi_samsung", mipi_dsi);
	if (ret) {
		dev_err(&pdev->dev, "failed to request mipi dsi irq\n");
		return ret;
	}

	mipi_dsi->dphy_clk = devm_clk_get(&pdev->dev, "mipi_pllref_clk");
	if (IS_ERR(mipi_dsi->dphy_clk)) {
		dev_err(&pdev->dev, "failed to get dphy pll_ref_clk\n");
		return PTR_ERR(mipi_dsi->dphy_clk);
	}

	mipi_dsi->cfg_clk = devm_clk_get(&pdev->dev, "mipi_cfg_clk");
	if (IS_ERR(mipi_dsi->cfg_clk)) {
		dev_err(&pdev->dev, "failed to get cfg_clk\n");
		return PTR_ERR(mipi_dsi->cfg_clk);
	}

	ret = of_property_read_string(np, "lcd_panel", &lcd_panel);
	if (ret) {
		dev_err(&pdev->dev, "failed to read lcd_panel property\n");
		return ret;
	}

	mipi_phy_reg = devm_regulator_get(&pdev->dev, "mipi-phy");
	if (IS_ERR(mipi_phy_reg)) {
		dev_err(&pdev->dev, "mipi phy power supply not found\n");
		return ret;
	}

	mipi_dsi->disp_power_on = devm_regulator_get(&pdev->dev,
						"disp-power-on");
	if (!IS_ERR(mipi_dsi->disp_power_on)) {
		ret = regulator_enable(mipi_dsi->disp_power_on);
		if (ret) {
			dev_err(&pdev->dev, "failed to enable display "
				"power regulator, err = %d\n", ret);
			return ret;
		}
	}

	mipi_dsi->lcd_panel = kstrdup(lcd_panel, GFP_KERNEL);
	if (!mipi_dsi->lcd_panel) {
		dev_err(&pdev->dev, "failed to allocate lcd panel name\n");
		ret = -ENOMEM;
		goto kstrdup_fail;
	}

	mipi_dsi->disp_mipi = mxc_dispdrv_register(&mipi_dsi_drv);
	if (IS_ERR(mipi_dsi->disp_mipi)) {
		dev_err(&pdev->dev, "mxc_dispdrv_register error\n");
		ret = PTR_ERR(mipi_dsi->disp_mipi);
		goto dispdrv_reg_fail;
	}

        mipi_dsi->mipi_dsi_pkt_read  = mipi_dsi_pkt_read;
        mipi_dsi->mipi_dsi_pkt_write = mipi_dsi_pkt_write;
        mipi_dsi->mipi_dsi_dcs_cmd   = mipi_dsi_dcs_cmd;

	pm_runtime_enable(&pdev->dev);

	mxc_dispdrv_setdata(mipi_dsi->disp_mipi, mipi_dsi);
	dev_set_drvdata(&pdev->dev, mipi_dsi);

	dev_info(&pdev->dev, "i.MX MIPI DSI driver probed\n");
	return ret;

dispdrv_reg_fail:
	kfree(mipi_dsi->lcd_panel);
kstrdup_fail:
	if (mipi_dsi->disp_power_on)
		regulator_disable(mipi_dsi->disp_power_on);

	return ret;
}

static void mipi_dsi_shutdown(struct platform_device *pdev)
{
	struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);

	mipi_dsi_power_off(mipi_dsi->disp_mipi);
	mipi_dsi_dphy_power_down();
}

static int mipi_dsi_remove(struct platform_device *pdev)
{
	struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);

	mxc_dispdrv_puthandle(mipi_dsi->disp_mipi);
	mxc_dispdrv_unregister(mipi_dsi->disp_mipi);

	if (mipi_dsi->disp_power_on)
		regulator_disable(mipi_dsi->disp_power_on);

	kfree(mipi_dsi->lcd_panel);
	dev_set_drvdata(&pdev->dev, NULL);

	return 0;
}

static int mipi_dsi_runtime_suspend(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);

	if (mipi_dsi->dsi_power_on) {
		release_bus_freq(BUS_FREQ_HIGH);
		dev_dbg(dev, "mipi dsi busfreq high release.\n");

		mipi_dsi_dphy_power_down();
		mipi_dsi->dsi_power_on = 0;
	}

	return 0;
}

static int mipi_dsi_runtime_resume(struct device *dev)
{
	struct platform_device *pdev = to_platform_device(dev);
	struct mipi_dsi_info *mipi_dsi = dev_get_drvdata(&pdev->dev);

	if (!mipi_dsi->dsi_power_on) {
		request_bus_freq(BUS_FREQ_HIGH);
		dev_dbg(dev, "mipi dsi busfreq high request.\n");

		mipi_dsi_dphy_power_on(pdev);
		mipi_dsi->dsi_power_on = 1;
	}

	return 0;
}

static const struct dev_pm_ops mipi_dsi_pm_ops = {
	.runtime_suspend = mipi_dsi_runtime_suspend,
	.runtime_resume  = mipi_dsi_runtime_resume,
	.runtime_idle	 = NULL,
};

static struct platform_driver mipi_dsi_driver = {
	.driver = {
		   .of_match_table = imx_mipi_dsi_dt_ids,
		   .name = "mxc_mipi_dsi_samsung",
		   .pm = &mipi_dsi_pm_ops,
	},
	.probe  = mipi_dsi_probe,
	.remove = mipi_dsi_remove,
	.shutdown = mipi_dsi_shutdown,
};

static int __init mipi_dsi_init(void)
{
	int err;

	err = platform_driver_register(&mipi_dsi_driver);
	if (err) {
		pr_err("mipi_dsi_driver register failed\n");
		return err;
	}

	pr_debug("MIPI DSI driver module loaded: %s\n", mipi_dsi_driver.driver.name);

	return 0;
}

static void __exit mipi_dsi_cleanup(void)
{
	platform_driver_unregister(&mipi_dsi_driver);
}

module_init(mipi_dsi_init);
module_exit(mipi_dsi_cleanup);

MODULE_AUTHOR("Freescale Semiconductor, Inc.");
MODULE_DESCRIPTION("i.MX MIPI DSI driver");
MODULE_LICENSE("GPL");
