/*
 * Copyright 2022, NXP
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#define DT_DRV_COMPAT nxp_imx_mipi_dsi

#include <zephyr/drivers/mipi_dsi.h>
#include <fsl_mipi_dsi.h>
#include <fsl_clock.h>
#include <zephyr/logging/log.h>

LOG_MODULE_REGISTER(dsi_mcux, CONFIG_MIPI_DSI_LOG_LEVEL);

#define MIPI_DPHY_REF_CLK DT_INST_PROP(0, dphy_ref_frequency)

/*
 * The DPHY bit clock must be fast enough to send out the pixels, it should be
 * larger than:
 *
 *         (Pixel clock * bit per output pixel) / number of MIPI data lane
 *
 * Here the desired DPHY bit clock multiplied by ( 9 / 8 = 1.125) to ensure
 * it is fast enough.
 */
#define MIPI_DPHY_BIT_CLK_ENLARGE(origin) (((origin) / 8) * 9)

struct display_mcux_mipi_dsi_config {
	MIPI_DSI_Type base;
	dsi_dpi_config_t dpi_config;
	bool auto_insert_eotp;
};

struct display_mcux_mipi_dsi_data {
	const struct device *dev;
};

static int dsi_mcux_attach(const struct device *dev,
			   uint8_t channel,
			   const struct mipi_dsi_device *mdev)
{
	const struct display_mcux_mipi_dsi_config *config = dev->config;
	dsi_dphy_config_t dphy_config;
	dsi_config_t dsi_config;
	uint32_t mipi_dsi_esc_clk_hz;
	uint32_t mipi_dsi_tx_esc_clk_hz;
	uint32_t mipi_dsi_dphy_ref_clk_hz = MIPI_DPHY_REF_CLK;

	DSI_GetDefaultConfig(&dsi_config);
	dsi_config.numLanes = mdev->data_lanes;
	dsi_config.autoInsertEoTp = config->auto_insert_eotp;

	/* Init the DSI module. */
	DSI_Init((MIPI_DSI_Type *)&config->base, &dsi_config);

	/* Init DPHY.
	 *
	 * The DPHY bit clock must be fast enough to send out the pixels, it should be
	 * larger than:
	 *
	 *         (Pixel clock * bit per output pixel) / number of MIPI data lane
	 *
	 * Here the desired DPHY bit clock multiplied by ( 9 / 8 = 1.125) to ensure
	 * it is fast enough.
	 *
	 * Note that the DSI output pixel is 24bit per pixel.
	 */
	uint32_t mipi_dsi_dpi_clk_hz = CLOCK_GetRootClockFreq(kCLOCK_Root_Lcdif);
	uint32_t mipi_dsi_dphy_bit_clk_hz = mipi_dsi_dpi_clk_hz * (24 / mdev->data_lanes);

	mipi_dsi_dphy_bit_clk_hz = MIPI_DPHY_BIT_CLK_ENLARGE(mipi_dsi_dphy_bit_clk_hz);

	mipi_dsi_esc_clk_hz = CLOCK_GetRootClockFreq(kCLOCK_Root_Mipi_Esc);
	mipi_dsi_tx_esc_clk_hz = mipi_dsi_esc_clk_hz / 3;

	DSI_GetDphyDefaultConfig(&dphy_config, mipi_dsi_dphy_bit_clk_hz, mipi_dsi_tx_esc_clk_hz);

	mipi_dsi_dphy_bit_clk_hz = DSI_InitDphy((MIPI_DSI_Type *)&config->base,
						&dphy_config, mipi_dsi_dphy_ref_clk_hz);

	/* Init DPI interface. */
	DSI_SetDpiConfig((MIPI_DSI_Type *)&config->base, &config->dpi_config, mdev->data_lanes,
					mipi_dsi_dpi_clk_hz, mipi_dsi_dphy_bit_clk_hz);

	imxrt_post_init_display_interface();

	return 0;
}

static ssize_t dsi_mcux_transfer(const struct device *dev, uint8_t channel,
				 struct mipi_dsi_msg *msg)
{
	const struct display_mcux_mipi_dsi_config *config = dev->config;
	dsi_transfer_t dsi_xfer = {0};
	status_t status;

	dsi_xfer.virtualChannel = channel;
	dsi_xfer.txDataSize = msg->tx_len;
	dsi_xfer.txData = msg->tx_buf;
	dsi_xfer.rxDataSize = msg->rx_len;
	dsi_xfer.rxData = msg->rx_buf;

	switch (msg->type) {

	case MIPI_DSI_DCS_READ:
		LOG_ERR("DCS Read not yet implemented or used");
		return -ENOTSUP;
	case MIPI_DSI_DCS_SHORT_WRITE:
		dsi_xfer.sendDscCmd = true;
		dsi_xfer.dscCmd = msg->cmd;
		dsi_xfer.txDataType = kDSI_TxDataDcsShortWrNoParam;
		break;
	case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
		__fallthrough;
	case MIPI_DSI_DCS_LONG_WRITE:
		dsi_xfer.sendDscCmd = true;
		dsi_xfer.dscCmd = msg->cmd;
		dsi_xfer.txDataType = kDSI_TxDataDcsShortWrOneParam;
		break;
	case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
		dsi_xfer.txDataType = kDSI_TxDataGenShortWrNoParam;
		break;
	case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
		dsi_xfer.txDataType = kDSI_TxDataGenShortWrOneParam;
		break;
	case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
		dsi_xfer.txDataType = kDSI_TxDataGenShortWrTwoParam;
		break;
	case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
		__fallthrough;
	case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
		__fallthrough;
	case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
		LOG_ERR("Generic Read not yet implemented or used");
		return -ENOTSUP;
	default:
		LOG_ERR("Unsupported message type (%d)", msg->type);
		return -ENOTSUP;
	}

	status = DSI_TransferBlocking(&config->base, &dsi_xfer);

	if (status != kStatus_Success) {
		LOG_ERR("Transmission failed");
		return -EIO;
	}

	if (msg->rx_len != 0) {
		/* Return rx_len on a read */
		return msg->rx_len;
	}

	/* Return tx_len on a write */
	return msg->tx_len;

}

static struct mipi_dsi_driver_api dsi_mcux_api = {
	.attach = dsi_mcux_attach,
	.transfer = dsi_mcux_transfer,
};

static int display_mcux_mipi_dsi_init(const struct device *dev)
{
	imxrt_pre_init_display_interface();

	return 0;
}

#define MCUX_MIPI_DSI_DEVICE(id)								\
	static const struct display_mcux_mipi_dsi_config display_mcux_mipi_dsi_config_##id = {	\
		.base = {									\
			.host = (DSI_HOST_Type *)DT_INST_REG_ADDR_BY_IDX(id, 0),		\
			.dpi = (DSI_HOST_DPI_INTFC_Type *)DT_INST_REG_ADDR_BY_IDX(id, 1),	\
			.apb = (DSI_HOST_APB_PKT_IF_Type *)DT_INST_REG_ADDR_BY_IDX(id, 2),	\
			.dphy = (DSI_HOST_NXP_FDSOI28_DPHY_INTFC_Type *)			\
				DT_INST_REG_ADDR_BY_IDX(id, 3),					\
		},										\
		.dpi_config = {									\
			.dpiColorCoding = DT_INST_ENUM_IDX(id, dpi_color_coding),		\
			.pixelPacket = DT_INST_ENUM_IDX(id, dpi_pixel_packet),			\
			.videoMode = DT_INST_ENUM_IDX(id, dpi_video_mode),			\
			.bllpMode = DT_INST_ENUM_IDX(id, dpi_bllp_mode),			\
			.pixelPayloadSize = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, width),	\
			.panelHeight = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, height),		\
			.polarityFlags = DT_INST_PROP_BY_PHANDLE_IDX(				\
					id, nxp_lcdif, id, polarity) >> 2,			\
			.hfp = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, hfp),			\
			.hbp = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, hbp),			\
			.hsw = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, hsync),			\
			.vfp = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, vfp),			\
			.vbp = DT_INST_PROP_BY_PHANDLE(id, nxp_lcdif, vbp),			\
		},										\
		.auto_insert_eotp = DT_INST_PROP(id, autoinsert_eotp),				\
	};											\
	static struct display_mcux_mipi_dsi_data display_mcux_mipi_dsi_data_##id;		\
	DEVICE_DT_INST_DEFINE(id,								\
			    &display_mcux_mipi_dsi_init,					\
			    NULL,								\
			    &display_mcux_mipi_dsi_data_##id,					\
			    &display_mcux_mipi_dsi_config_##id,					\
			    POST_KERNEL,							\
			    CONFIG_MIPI_DSI_INIT_PRIORITY,					\
			    &dsi_mcux_api);

DT_INST_FOREACH_STATUS_OKAY(MCUX_MIPI_DSI_DEVICE)
