/*
 * i.MX drm driver - Northwest Logic MIPI DSI display driver
 *
 * 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 <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 <linux/busfreq-imx.h>
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/mfd/syscon.h>
#include <linux/mfd/syscon/imx8mq-iomuxc-gpr.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/of_platform.h>
#include <linux/phy/phy.h>
#include <linux/regmap.h>
#include <soc/imx8/sc/sci.h>
#include <video/videomode.h>

#include "imx-drm.h"

#define DRIVER_NAME "nwl_dsi-imx"

/* 8MQ SRC specific registers */
#define SRC_MIPIPHY_RCR				0x28
#define RESET_BYTE_N				BIT(1)
#define RESET_N					BIT(2)
#define DPI_RESET_N				BIT(3)
#define ESC_RESET_N				BIT(4)
#define PCLK_RESET_N				BIT(5)

#define DC_ID(x)	SC_R_DC_ ## x
#define MIPI_ID(x)	SC_R_MIPI_ ## x
#define SYNC_CTRL(x)	SC_C_SYNC_CTRL ## x
#define PXL_VLD(x)	SC_C_PXL_LINK_MST ## x ## _VLD
#define PXL_ADDR(x)	SC_C_PXL_LINK_MST ## x ## _ADDR

/* Possible clocks */
#define CLK_PIXEL	"pixel"
#define CLK_CORE	"core"
#define CLK_BYPASS	"bypass"
#define CLK_PHYREF	"phy_ref"

struct imx_mipi_dsi {
	struct drm_encoder		encoder;
	struct drm_bridge		bridge;
	struct drm_bridge		*next_bridge;
	struct device			*dev;
	struct phy			*phy;

	/* Optional external regs */
	struct regmap			*csr;
	struct regmap			*reset;
	struct regmap			*mux_sel;

	/* Optional clocks */
	struct clk_config		*clk_config;
	size_t				clk_num;

	u32 tx_ulps_reg;
	u32 pxl2dpi_reg;

	u32				instance;
	u32				sync_pol;
	u32				power_on_delay;
	bool				no_clk_reset;
	bool				enabled;
	bool				suspended;
};

struct clk_config {
	const char *id;
	struct clk *clk;
	bool present;
	bool enabled;
	u32 rate;
};

enum imx_ext_regs {
	IMX_REG_CSR = BIT(1),
	IMX_REG_SRC = BIT(2),
	IMX_REG_GPR = BIT(3),
};

struct devtype {
	int (*poweron)(struct imx_mipi_dsi *);
	void (*poweroff)(struct imx_mipi_dsi *);
	u32 ext_regs; /* required external registers */
	u32 tx_ulps_reg;
	u32 pxl2dpi_reg;
	u8 max_instances;
	struct clk_config clk_config[4];
};

static int imx8qm_dsi_poweron(struct imx_mipi_dsi *dsi);
static void imx8qm_dsi_poweroff(struct imx_mipi_dsi *dsi);
static struct devtype imx8qm_dev = {
	.poweron = &imx8qm_dsi_poweron,
	.poweroff = &imx8qm_dsi_poweroff,
	.clk_config = {
		{ .id = CLK_CORE,   .present = false },
		{ .id = CLK_PHYREF, .present = true },
		{ .id = CLK_BYPASS, .present = true },
		{ .id = CLK_PIXEL,  .present = true },
	},
	.ext_regs = IMX_REG_CSR,
	.tx_ulps_reg   = 0x00,
	.pxl2dpi_reg   = 0x04,
	.max_instances =    2,
};

static int imx8qxp_dsi_poweron(struct imx_mipi_dsi *dsi);
static void imx8qxp_dsi_poweroff(struct imx_mipi_dsi *dsi);
static struct devtype imx8qxp_dev = {
	.poweron = &imx8qxp_dsi_poweron,
	.poweroff = &imx8qxp_dsi_poweroff,
	.clk_config = {
		{ .id = CLK_CORE,   .present = false },
		{ .id = CLK_PHYREF, .present = true },
		{ .id = CLK_BYPASS, .present = true },
		{ .id = CLK_PIXEL,  .present = true },
	},
	.ext_regs = IMX_REG_CSR,
	.tx_ulps_reg   = 0x30,
	.pxl2dpi_reg   = 0x40,
	.max_instances =    2,
};

static int imx8mq_dsi_poweron(struct imx_mipi_dsi *dsi);
static void imx8mq_dsi_poweroff(struct imx_mipi_dsi *dsi);
static struct devtype imx8mq_dev = {
	.poweron = &imx8mq_dsi_poweron,
	.poweroff = &imx8mq_dsi_poweroff,
	.clk_config = {
		{ .id = CLK_CORE,   .present = true },
		{ .id = CLK_PIXEL,  .present = false },
		{ .id = CLK_BYPASS, .present = false },
		{ .id = CLK_PHYREF, .present = true },
	},
	.ext_regs = IMX_REG_SRC | IMX_REG_GPR,
	.max_instances = 1,
};

static const struct of_device_id imx_nwl_dsi_dt_ids[] = {
	{ .compatible = "fsl,imx8qm-mipi-dsi", .data = &imx8qm_dev, },
	{ .compatible = "fsl,imx8qxp-mipi-dsi", .data = &imx8qxp_dev, },
	{ .compatible = "fsl,imx8mq-mipi-dsi_drm", .data = &imx8mq_dev, },
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_nwl_dsi_dt_ids);

static inline struct imx_mipi_dsi *encoder_to_dsi(struct drm_encoder *encoder)
{
	return container_of(encoder, struct imx_mipi_dsi, encoder);
}

static void imx_nwl_dsi_set_clocks(struct imx_mipi_dsi *dsi, bool enable)
{
	struct device *dev = dsi->dev;
	const char *id;
	struct clk *clk;
	unsigned long new_rate, cur_rate;
	bool enabled;
	size_t i;

	for (i = 0; i < dsi->clk_num; i++) {
		if (!dsi->clk_config[i].present)
			continue;
		id = dsi->clk_config[i].id;
		clk = dsi->clk_config[i].clk;
		new_rate = dsi->clk_config[i].rate;
		cur_rate = clk_get_rate(clk);
		enabled = dsi->clk_config[i].enabled;

		if (enable) {
			if (enabled && new_rate != cur_rate)
				clk_disable_unprepare(clk);
			else if (enabled && new_rate == cur_rate)
				continue;
			if (new_rate > 0)
				clk_set_rate(clk, new_rate);
			clk_prepare_enable(clk);
			dsi->clk_config[i].enabled = true;
			cur_rate = clk_get_rate(clk);
			DRM_DEV_DEBUG_DRIVER(dev,
				"Enabled %s clk (rate: req=%lu act=%lu)\n",
				id, new_rate, cur_rate);
		} else if (enabled) {
			clk_disable_unprepare(clk);
			dsi->clk_config[i].enabled = false;
			DRM_DEV_DEBUG_DRIVER(dev, "Disabled %s clk\n", id);
		}
	}
}

/*
 * v2 is true for QXP
 * On QM, we have 2 DPUs, each one with a MIPI-DSI link
 * On QXP, we have 1 DPU with two MIPI-DSI links
 * Because of this, we will have different initialization
 * paths for MIPI0 and MIPI1 on QM vs QXP
 */
static int imx8q_dsi_poweron(struct imx_mipi_dsi *dsi, bool v2)
{
	struct device *dev = dsi->dev;
	int ret = 0;
	sc_err_t sci_err = 0;
	sc_ipc_t ipc_handle = 0;
	u32 inst = dsi->instance;
	u32 mu_id;
	sc_rsrc_t mipi_id, dc_id;
	sc_ctrl_t mipi_ctrl;

	sci_err = sc_ipc_getMuID(&mu_id);
	if (sci_err != SC_ERR_NONE) {
		DRM_DEV_ERROR(dev, "Failed to get MU ID (%d)\n", sci_err);
		return -ENODEV;
	}
	sci_err = sc_ipc_open(&ipc_handle, mu_id);
	if (sci_err != SC_ERR_NONE) {
		DRM_DEV_ERROR(dev, "Failed to open IPC (%d)\n", sci_err);
		return -ENODEV;
	}

	mipi_id = inst?MIPI_ID(1):MIPI_ID(0);
	dc_id = (!v2 && inst)?DC_ID(1):DC_ID(0);
	DRM_DEV_DEBUG_DRIVER(dev, "MIPI ID: %d DC ID: %d\n",
			     mipi_id,
			     dc_id);

	/* Assert DPI and MIPI bits */
	sci_err = sc_misc_set_control(ipc_handle,
				      mipi_id,
				      SC_C_DPI_RESET,
				      0);
	if (sci_err != SC_ERR_NONE) {
		DRM_DEV_ERROR(dev,
			      "Failed to assert DPI reset (%d)\n",
			      sci_err);
		ret = -ENODEV;
		goto err_ipc;
	}

	sci_err = sc_misc_set_control(ipc_handle,
				      mipi_id,
				      SC_C_MIPI_RESET,
				      0);
	if (sci_err != SC_ERR_NONE) {
		DRM_DEV_ERROR(dev,
			      "Failed to assert MIPI reset (%d)\n",
			      sci_err);
		ret = -ENODEV;
		goto err_ipc;
	}

	if (v2) {
		sci_err = sc_misc_set_control(ipc_handle,
				mipi_id, SC_C_MODE, 0);
		if (sci_err != SC_ERR_NONE)
			DRM_DEV_ERROR(dev,
				      "Failed to set SC_C_MODE (%d)\n",
				      sci_err);
		sci_err = sc_misc_set_control(ipc_handle,
				mipi_id, SC_C_DUAL_MODE, 0);
		if (sci_err != SC_ERR_NONE)
			DRM_DEV_ERROR(dev,
				      "Failed to set SC_C_DUAL_MODE (%d)\n",
				      sci_err);
		sci_err = sc_misc_set_control(ipc_handle,
				mipi_id, SC_C_PXL_LINK_SEL, 0);
		if (sci_err != SC_ERR_NONE)
			DRM_DEV_ERROR(dev,
				     "Failed to set SC_C_PXL_LINK_SEL (%d)\n",
				     sci_err);
	}

	/* Initialize Pixel Link */
	mipi_ctrl = (v2 && inst)?PXL_ADDR(2):PXL_ADDR(1);
	sci_err = sc_misc_set_control(ipc_handle,
				      dc_id,
				      mipi_ctrl,
				      0);
	if (sci_err != SC_ERR_NONE) {
		DRM_DEV_ERROR(dev,
			"Failed to set SC_C_PXL_LINK_MST%d_ADDR (%d)\n",
			inst,
			sci_err);
		ret = -ENODEV;
		goto err_ipc;
	}

	mipi_ctrl = (v2 && inst)?PXL_VLD(2):PXL_VLD(1);
	sci_err = sc_misc_set_control(ipc_handle,
				      dc_id,
				      mipi_ctrl,
				      1);
	if (sci_err != SC_ERR_NONE) {
		DRM_DEV_ERROR(dev,
			"Failed to set SC_C_PXL_LINK_MST%d_VLD (%d)\n",
			inst + 1,
			sci_err);
		ret = -ENODEV;
		goto err_ipc;
	}

	mipi_ctrl = (v2 && inst)?SYNC_CTRL(1):SYNC_CTRL(0);
	sci_err = sc_misc_set_control(ipc_handle,
				      dc_id,
				      mipi_ctrl,
				      1);
	if (sci_err != SC_ERR_NONE) {
		DRM_DEV_ERROR(dev,
			"Failed to set SC_C_SYNC_CTRL%d (%d)\n",
			inst,
			sci_err);
		ret = -ENODEV;
		goto err_ipc;
	}

	/* De-Assert DPI and MIPI bits */
	sci_err = sc_misc_set_control(ipc_handle,
				      mipi_id,
				      SC_C_DPI_RESET,
				      1);
	if (sci_err != SC_ERR_NONE) {
		DRM_DEV_ERROR(dev,
			"Failed to deassert DPI reset (%d)\n",
			sci_err);
		ret = -ENODEV;
		goto err_ipc;
	}

	sci_err = sc_misc_set_control(ipc_handle,
				      mipi_id,
				      SC_C_MIPI_RESET,
				      1);
	if (sci_err != SC_ERR_NONE) {
		DRM_DEV_ERROR(dev,
			"Failed to deassert MIPI reset (%d)\n",
			sci_err);
		ret = -ENODEV;
		goto err_ipc;
	}

	regmap_write(dsi->csr,
		     dsi->tx_ulps_reg,
		     0);
	regmap_write(dsi->csr,
		     dsi->pxl2dpi_reg,
		     DPI_24_BIT);

	sc_ipc_close(ipc_handle);
	return ret;

err_ipc:
	sc_ipc_close(ipc_handle);
	return ret;
}

static void imx8q_dsi_poweroff(struct imx_mipi_dsi *dsi, bool v2)
{
	struct device *dev = dsi->dev;
	sc_err_t sci_err = 0;
	sc_ipc_t ipc_handle = 0;
	u32 mu_id;
	u32 inst = dsi->instance;
	sc_rsrc_t mipi_id, dc_id;
	sc_ctrl_t mipi_ctrl;

	mipi_id = inst?MIPI_ID(1):MIPI_ID(0);
	dc_id = (!v2 && inst)?DC_ID(1):DC_ID(0);

	/* Deassert DPI and MIPI bits */
	if (sc_ipc_getMuID(&mu_id) != SC_ERR_NONE ||
	    sc_ipc_open(&ipc_handle, mu_id) != SC_ERR_NONE)
		return;

	sci_err = sc_misc_set_control(ipc_handle,
			mipi_id, SC_C_DPI_RESET, 0);
	if (sci_err != SC_ERR_NONE)
		DRM_DEV_ERROR(dev,
			"Failed to deassert DPI reset (%d)\n",
			sci_err);

	sci_err = sc_misc_set_control(ipc_handle,
			mipi_id, SC_C_MIPI_RESET, 0);
	if (sci_err != SC_ERR_NONE)
		DRM_DEV_ERROR(dev,
			"Failed to deassert MIPI reset (%d)\n",
			sci_err);

	mipi_ctrl = (v2 && inst)?SYNC_CTRL(1):SYNC_CTRL(0);
	sci_err = sc_misc_set_control(ipc_handle,
			dc_id, mipi_ctrl, 0);
	if (sci_err != SC_ERR_NONE)
		DRM_DEV_ERROR(dev,
			"Failed to reset SC_C_SYNC_CTRL0 (%d)\n",
			sci_err);

	mipi_ctrl = (v2 && inst)?PXL_VLD(2):PXL_VLD(1);
	sci_err = sc_misc_set_control(ipc_handle,
			dc_id, mipi_ctrl, 0);
	if (sci_err != SC_ERR_NONE)
		DRM_DEV_ERROR(dev,
			"Failed to reset SC_C_SYNC_CTRL0 (%d)\n",
			sci_err);

	sc_ipc_close(ipc_handle);
}

static int imx8qm_dsi_poweron(struct imx_mipi_dsi *dsi)
{
	return imx8q_dsi_poweron(dsi, false);
}

static void imx8qm_dsi_poweroff(struct imx_mipi_dsi *dsi)
{
	return imx8q_dsi_poweroff(dsi, false);
}

static int imx8qxp_dsi_poweron(struct imx_mipi_dsi *dsi)
{
	return imx8q_dsi_poweron(dsi, true);
}

static void imx8qxp_dsi_poweroff(struct imx_mipi_dsi *dsi)
{
	return imx8q_dsi_poweroff(dsi, true);
}

static int imx8mq_dsi_poweron(struct imx_mipi_dsi *dsi)
{
	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
			   PCLK_RESET_N, PCLK_RESET_N);
	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
			   ESC_RESET_N, ESC_RESET_N);
	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
			   RESET_BYTE_N, RESET_BYTE_N);
	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
			   DPI_RESET_N, DPI_RESET_N);

	return 0;
}

static void imx8mq_dsi_poweroff(struct imx_mipi_dsi *dsi)
{
	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
			   PCLK_RESET_N, 0);
	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
			   ESC_RESET_N, 0);
	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
			   RESET_BYTE_N, 0);
	regmap_update_bits(dsi->reset, SRC_MIPIPHY_RCR,
			   DPI_RESET_N, 0);
}

static void imx_nwl_dsi_enable(struct imx_mipi_dsi *dsi)
{
	struct device *dev = dsi->dev;
	const struct of_device_id *of_id = of_match_device(imx_nwl_dsi_dt_ids,
							   dev);
	const struct devtype *devtype = of_id->data;
	unsigned long min_sleep, max_sleep;
	int ret;

	if (dsi->enabled)
		return;

	DRM_DEV_DEBUG_DRIVER(dev, "id = %s\n", (dsi->instance)?"DSI1":"DSI0");

	/*
	 * On some systems we need to wait some time before enabling the
	 * phy_ref clock, in order to allow the parent PLL to become stable
	 */
	if (dsi->power_on_delay > 20) {
		msleep(dsi->power_on_delay);
	} else if (dsi->power_on_delay > 0) {
		max_sleep = dsi->power_on_delay * 1000;
		min_sleep = 1000;
		if (max_sleep > 6000)
			min_sleep = max_sleep - 5000;
		usleep_range(min_sleep, max_sleep);
	}

	request_bus_freq(BUS_FREQ_HIGH);

	imx_nwl_dsi_set_clocks(dsi, true);

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

	dsi->enabled = true;
}

static void imx_nwl_dsi_disable(struct imx_mipi_dsi *dsi)
{
	struct device *dev = dsi->dev;
	const struct of_device_id *of_id = of_match_device(imx_nwl_dsi_dt_ids,
							   dev);
	const struct devtype *devtype = of_id->data;

	if (!dsi->enabled)
		return;

	DRM_DEV_DEBUG_DRIVER(dev, "id = %s\n", (dsi->instance)?"DSI1":"DSI0");

	if (!dsi->no_clk_reset)
		devtype->poweroff(dsi);

	imx_nwl_dsi_set_clocks(dsi, false);

	release_bus_freq(BUS_FREQ_HIGH);

	dsi->enabled = false;
}

static void imx_nwl_dsi_encoder_enable(struct drm_encoder *encoder)
{
	struct imx_mipi_dsi *dsi = encoder_to_dsi(encoder);

	pm_runtime_get_sync(dsi->dev);
	imx_nwl_dsi_enable(dsi);
}

static void imx_nwl_dsi_encoder_disable(struct drm_encoder *encoder)
{
	struct imx_mipi_dsi *dsi = encoder_to_dsi(encoder);

	imx_nwl_dsi_disable(dsi);
	pm_runtime_put_sync(dsi->dev);
}

static bool imx_nwl_dsi_mode_fixup(struct imx_mipi_dsi *dsi,
				 struct drm_display_mode *mode)
{
	unsigned int *flags = &mode->flags;

	DRM_DEV_DEBUG_DRIVER(dsi->dev, "Fixup mode:\n");
	drm_mode_debug_printmodeline(mode);

	/* Make sure all flags are set-up accordingly */
	if (dsi->sync_pol) {
		*flags |= DRM_MODE_FLAG_PHSYNC;
		*flags |= DRM_MODE_FLAG_PVSYNC;
		*flags &= ~DRM_MODE_FLAG_NHSYNC;
		*flags &= ~DRM_MODE_FLAG_NVSYNC;
	} else {
		*flags &= ~DRM_MODE_FLAG_PHSYNC;
		*flags &= ~DRM_MODE_FLAG_PVSYNC;
		*flags |= DRM_MODE_FLAG_NHSYNC;
		*flags |= DRM_MODE_FLAG_NVSYNC;
	}

	return true;
}

static void imx_nwl_dsi_mode_set(struct imx_mipi_dsi *dsi,
				 struct drm_display_mode *mode)
{	const char *id;
	struct clk *clk;
	size_t i;

	for (i = 0; i < dsi->clk_num; i++) {
		if (!dsi->clk_config[i].present)
			continue;
		id = dsi->clk_config[i].id;
		clk = dsi->clk_config[i].clk;

		/* Set bypass and pixel clocks to mode clock rate */
		if (!strcmp(id, CLK_BYPASS) || !strcmp(id, CLK_PIXEL))
			dsi->clk_config[i].rate = mode->crtc_clock * 1000;
	}

}

static int imx_nwl_dsi_encoder_atomic_check(struct drm_encoder *encoder,
					struct drm_crtc_state *crtc_state,
					struct drm_connector_state *conn_state)
{
	struct imx_mipi_dsi *dsi = encoder_to_dsi(encoder);
	struct imx_crtc_state *imx_crtc_state = to_imx_crtc_state(crtc_state);

	imx_crtc_state->bus_format = MEDIA_BUS_FMT_RGB101010_1X30;

	return !imx_nwl_dsi_mode_fixup(dsi, &crtc_state->adjusted_mode);
}

static void imx_nwl_dsi_encoder_mode_set(struct drm_encoder *encoder,
			 struct drm_display_mode *mode,
			 struct drm_display_mode *adjusted_mode)
{
	struct imx_mipi_dsi *dsi = encoder_to_dsi(encoder);

	imx_nwl_dsi_mode_set(dsi, adjusted_mode);
}

static const struct drm_encoder_helper_funcs
imx_nwl_dsi_encoder_helper_funcs = {
	.enable = imx_nwl_dsi_encoder_enable,
	.disable = imx_nwl_dsi_encoder_disable,
	.atomic_check = imx_nwl_dsi_encoder_atomic_check,
	.mode_set = imx_nwl_dsi_encoder_mode_set,
};

static void imx_nwl_dsi_encoder_destroy(struct drm_encoder *encoder)
{
	drm_encoder_cleanup(encoder);
}

static const struct drm_encoder_funcs imx_nwl_dsi_encoder_funcs = {
	.destroy = imx_nwl_dsi_encoder_destroy,
};


static void imx_nwl_dsi_bridge_enable(struct drm_bridge *bridge)
{
	struct imx_mipi_dsi *dsi = bridge->driver_private;

	imx_nwl_dsi_enable(dsi);
	pm_runtime_get_sync(dsi->dev);
}

static void imx_nwl_dsi_bridge_disable(struct drm_bridge *bridge)
{
	struct imx_mipi_dsi *dsi = bridge->driver_private;

	imx_nwl_dsi_disable(dsi);
	pm_runtime_put_sync(dsi->dev);
}

static bool imx_nwl_dsi_bridge_mode_fixup(struct drm_bridge *bridge,
			   const struct drm_display_mode *mode,
			   struct drm_display_mode *adjusted)
{
	struct imx_mipi_dsi *dsi = bridge->driver_private;

	return imx_nwl_dsi_mode_fixup(dsi, adjusted);
}

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

	imx_nwl_dsi_mode_set(dsi, adjusted);
}

static int imx_nwl_dsi_bridge_attach(struct drm_bridge *bridge)
{
	struct imx_mipi_dsi *dsi = bridge->driver_private;
	struct drm_encoder *encoder = bridge->encoder;
	int ret = 0;

	DRM_DEV_DEBUG_DRIVER(dsi->dev, "id = %s\n",
			     (dsi->instance)?"DSI1":"DSI0");
	if (!encoder) {
		DRM_DEV_ERROR(dsi->dev, "Parent encoder object not found\n");
		return -ENODEV;
	}

	/* Attach the next bridge in chain */
	ret = drm_bridge_attach(encoder, dsi->next_bridge, bridge);
	if (ret)
		DRM_DEV_ERROR(dsi->dev, "Failed to attach bridge! (%d)\n",
			      ret);

	return ret;
}

static void imx_nwl_dsi_bridge_detach(struct drm_bridge *bridge)
{
	struct imx_mipi_dsi *dsi = bridge->driver_private;

	DRM_DEV_DEBUG_DRIVER(dsi->dev, "id = %s\n",
			     (dsi->instance)?"DSI1":"DSI0");
	/*
	 * The next bridge in chain will be automatically detached, there is
	 * no need for us to detach it.
	 */
}

static const struct drm_bridge_funcs imx_nwl_dsi_bridge_funcs = {
	.enable = imx_nwl_dsi_bridge_enable,
	.disable = imx_nwl_dsi_bridge_disable,
	.mode_fixup = imx_nwl_dsi_bridge_mode_fixup,
	.mode_set = imx_nwl_dsi_bridge_mode_set,
	.attach = imx_nwl_dsi_bridge_attach,
	.detach = imx_nwl_dsi_bridge_detach,
};

static int imx_nwl_dsi_parse_of(struct device *dev, bool as_bridge)
{
	struct device_node *np = dev->of_node;
	const struct of_device_id *of_id = of_match_device(imx_nwl_dsi_dt_ids,
							   dev);
	const struct devtype *devtype = of_id->data;
	struct imx_mipi_dsi *dsi = dev_get_drvdata(dev);
	struct clk *clk;
	const char *clk_id;
	size_t i, clk_config_sz;
	int id;
	u32 mux_val;
	int ret = 0;

	id = of_alias_get_id(np, "mipi_dsi");
	if (id < 0) {
		dev_err(dev, "No mipi_dsi alias found!");
		return id;
	}
	if (id > devtype->max_instances - 1) {
		dev_err(dev, "Too many instances! (cur: %d, max: %d)\n",
			id, devtype->max_instances);
		return -ENODEV;
	}
	dsi->instance = id;

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

	/* Look for optional clocks */
	dsi->clk_num = ARRAY_SIZE(devtype->clk_config);
	dsi->clk_config = devm_kcalloc(dev,
				dsi->clk_num,
				sizeof(struct clk_config),
				GFP_KERNEL);
	clk_config_sz = dsi->clk_num * sizeof(struct clk_config);
	memcpy(dsi->clk_config, devtype->clk_config, clk_config_sz);

	for (i = 0; i < dsi->clk_num; i++) {
		if (!dsi->clk_config[i].present)
			continue;

		clk_id = dsi->clk_config[i].id;
		clk = devm_clk_get(dev, clk_id);
		if (IS_ERR(clk)) {
			ret = PTR_ERR(clk);
			dev_err(dev, "Failed to get %s clock (%d)\n",
				clk_id, ret);
			return ret;
		}
		dev_dbg(dev, "Setup clk %s (rate: %lu)\n",
			clk_id, clk_get_rate(clk));
		dsi->clk_config[i].clk = clk;
	}

	dsi->tx_ulps_reg = devtype->tx_ulps_reg;
	dsi->pxl2dpi_reg = devtype->pxl2dpi_reg;

	of_property_read_u32(np, "sync-pol", &dsi->sync_pol);
	of_property_read_u32(np, "pwr-delay", &dsi->power_on_delay);

	/* Look for optional regmaps */
	dsi->csr = syscon_regmap_lookup_by_phandle(np, "csr");
	if (IS_ERR(dsi->csr) && (devtype->ext_regs & IMX_REG_CSR)) {
		ret = PTR_ERR(dsi->csr);
		dev_err(dev, "Failed to get CSR regmap (%d)\n", ret);
		return ret;
	}
	dsi->reset = syscon_regmap_lookup_by_phandle(np, "src");
	if (IS_ERR(dsi->reset) && (devtype->ext_regs & IMX_REG_SRC)) {
		ret = PTR_ERR(dsi->reset);
		dev_err(dev, "Failed to get SRC regmap (%d)\n", ret);
		return ret;
	}
	dsi->mux_sel = syscon_regmap_lookup_by_phandle(np, "mux-sel");
	if (IS_ERR(dsi->mux_sel) && (devtype->ext_regs & IMX_REG_GPR)) {
		ret = PTR_ERR(dsi->mux_sel);
		dev_err(dev, "Failed to get GPR regmap (%d)\n", ret);
		return ret;
	}
	if (IS_ERR(dsi->mux_sel))
		return 0;

	mux_val = IMX8MQ_GPR13_MIPI_MUX_SEL;
	if (as_bridge)
		mux_val = 0;
	dev_info(dev, "Using %s as input source\n",
		(mux_val)?"DCSS":"LCDIF");
	regmap_update_bits(dsi->mux_sel,
		   IOMUXC_GPR13,
		   IMX8MQ_GPR13_MIPI_MUX_SEL,
		   mux_val);

	dsi->no_clk_reset = of_property_read_bool(np, "no_clk_reset");

	return 0;
}

static int imx_nwl_dsi_bind(struct device *dev,
			struct device *master,
			void *data)
{
	struct drm_device *drm = data;
	struct drm_bridge *next_bridge = NULL;
	struct imx_mipi_dsi *dsi = dev_get_drvdata(dev);
	int ret = 0;

	ret = imx_nwl_dsi_parse_of(dev, false);
	if (ret)
		return ret;

	DRM_DEV_DEBUG_DRIVER(dev, "id = %s\n", (dsi->instance)?"DSI1":"DSI0");

	/* Re-validate the bridge */
	if (dsi->next_bridge)
		next_bridge = of_drm_find_bridge(dsi->next_bridge->of_node);
	dsi->next_bridge = next_bridge;

	if (!dsi->next_bridge) {
		dev_warn(dev, "No bridge found, skipping encoder creation\n");
		return ret;
	}

	ret = imx_drm_encoder_parse_of(drm, &dsi->encoder, dev->of_node);
	if (ret)
		return ret;

	drm_encoder_helper_add(&dsi->encoder,
			       &imx_nwl_dsi_encoder_helper_funcs);
	ret = drm_encoder_init(drm,
			       &dsi->encoder,
			       &imx_nwl_dsi_encoder_funcs,
			       DRM_MODE_ENCODER_DSI,
			       NULL);
	if (ret) {
		DRM_DEV_ERROR(dev, "failed to init DSI encoder (%d)\n", ret);
		return ret;
	}

	dsi->next_bridge->encoder = &dsi->encoder;
	dsi->encoder.bridge = dsi->next_bridge;
	ret = drm_bridge_attach(&dsi->encoder, dsi->next_bridge, NULL);
	if (ret)
		drm_encoder_cleanup(&dsi->encoder);

	return ret;
}

static void imx_nwl_dsi_unbind(struct device *dev,
			   struct device *master,
			   void *data)
{
	struct imx_mipi_dsi *dsi = dev_get_drvdata(dev);
	struct drm_bridge *next_bridge = NULL;

	DRM_DEV_DEBUG_DRIVER(dev, "id = %s\n", (dsi->instance)?"DSI1":"DSI0");

	/*
	 * At this point, our next bridge in chain might be already removed,
	 * so update it's status.
	 */
	if (dsi->next_bridge)
		next_bridge = of_drm_find_bridge(dsi->next_bridge->of_node);
	dsi->next_bridge = next_bridge;

	if (dsi->enabled)
		imx_nwl_dsi_encoder_disable(&dsi->encoder);

	if (dsi->encoder.dev)
		drm_encoder_cleanup(&dsi->encoder);

	pm_runtime_disable(dev);
}

static const struct component_ops imx_nwl_dsi_component_ops = {
	.bind	= imx_nwl_dsi_bind,
	.unbind	= imx_nwl_dsi_unbind,
};

static int imx_nwl_dsi_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct device_node *remote_node, *endpoint;
	int remote_ports = 0;
	struct imx_mipi_dsi *dsi;
	int ret = 0;

	if (!np)
		return -ENODEV;

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

	/* Search for next bridge (usually the DSI HOST bridge) */
	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) {
			dev_err(dev, "No endpoint found!\n");
			return -ENODEV;
		}

		dsi->next_bridge = of_drm_find_bridge(remote_node);
		of_node_put(remote_node);
		endpoint = of_graph_get_next_endpoint(np, endpoint);
		if (!of_device_is_available(remote_node))
			continue;
		remote_ports++;
	};

	/*
	 * Normally, we should have two remote ports: one is our input source,
	 * while the second is the NWL host bridge. This bridge can be disabled
	 * if the connector fails to find a physical device. In this case, we
	 * should continue and do nothing, so that DRM master can bind all the
	 * components.
	 */
	if (!dsi->next_bridge && remote_ports == 2) {
		dev_warn(dev, "Waiting for DSI host bridge\n");
		return -EPROBE_DEFER;
	}

	dsi->dev = dev;
	dev_set_drvdata(dev, dsi);

	pm_runtime_enable(dev);

	if (of_property_read_bool(dev->of_node, "as_bridge")) {
		ret = imx_nwl_dsi_parse_of(dev, true);
		if (ret)
			return ret;
		/* Create our bridge */
		dsi->bridge.driver_private = dsi;
		dsi->bridge.funcs = &imx_nwl_dsi_bridge_funcs;
		dsi->bridge.of_node = np;

		ret = drm_bridge_add(&dsi->bridge);
		if (ret) {
			dev_err(dev, "Failed to add imx-nwl-dsi bridge (%d)\n",
				ret);
			return ret;
		}
		dev_info(dev, "Added drm bridge!");
		return 0;
	}

	return component_add(&pdev->dev, &imx_nwl_dsi_component_ops);
}

static int imx_nwl_dsi_remove(struct platform_device *pdev)
{
	component_del(&pdev->dev, &imx_nwl_dsi_component_ops);

	return 0;
}

#ifdef CONFIG_PM
static int imx_nwl_suspend(struct device *dev)
{
	struct imx_mipi_dsi *dsi = dev_get_drvdata(dev);

	if (!dsi->enabled)
		return 0;

	if (dsi->next_bridge)
		drm_bridge_disable(dsi->next_bridge);
	imx_nwl_dsi_disable(dsi);
	dsi->suspended = true;

	return 0;
}

static int imx_nwl_resume(struct device *dev)
{
	struct imx_mipi_dsi *dsi = dev_get_drvdata(dev);

	if (!dsi->suspended)
		return 0;

	imx_nwl_dsi_enable(dsi);
	if (dsi->next_bridge)
		drm_bridge_enable(dsi->next_bridge);
	dsi->suspended = false;

	return 0;
}

#endif

static const struct dev_pm_ops imx_nwl_pm_ops = {
	SET_RUNTIME_PM_OPS(imx_nwl_suspend, imx_nwl_resume, NULL)
	SET_SYSTEM_SLEEP_PM_OPS(imx_nwl_suspend, imx_nwl_resume)
};

static struct platform_driver imx_nwl_dsi_driver = {
	.probe		= imx_nwl_dsi_probe,
	.remove		= imx_nwl_dsi_remove,
	.driver		= {
		.of_match_table = imx_nwl_dsi_dt_ids,
		.name	= DRIVER_NAME,
		.pm	= &imx_nwl_pm_ops,
	},
};

module_platform_driver(imx_nwl_dsi_driver);

MODULE_AUTHOR("NXP Semiconductor");
MODULE_DESCRIPTION("i.MX Northwest Logic MIPI-DSI driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:" DRIVER_NAME);
