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

 /* Based on dsi_mcux.c, which is (c) 2022 NXP */

#define DT_DRV_COMPAT nxp_mipi_dsi_2l

#include <zephyr/kernel.h>
#include <zephyr/drivers/clock_control.h>
#include <zephyr/drivers/mipi_dsi.h>
#include <zephyr/drivers/mipi_dsi/mipi_dsi_mcux_2l.h>
#include <zephyr/drivers/dma.h>
#include <zephyr/drivers/dma/dma_mcux_smartdma.h>
#include <zephyr/logging/log.h>

#include <fsl_inputmux.h>
#include <fsl_mipi_dsi.h>
#include <fsl_clock.h>

#include <soc.h>

LOG_MODULE_REGISTER(dsi_mcux_host, CONFIG_MIPI_DSI_LOG_LEVEL);

struct mcux_mipi_dsi_config {
	MIPI_DSI_HOST_Type *base;
	dsi_dpi_config_t dpi_config;
	bool auto_insert_eotp;
	const struct device *bit_clk_dev;
	clock_control_subsys_t bit_clk_subsys;
	const struct device *esc_clk_dev;
	clock_control_subsys_t esc_clk_subsys;
	const struct device *pixel_clk_dev;
	clock_control_subsys_t pixel_clk_subsys;
	uint32_t dphy_ref_freq;
#ifdef CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA
	const struct device *smart_dma;
#else
	void (*irq_config_func)(const struct device *dev);
#endif
};

struct mcux_mipi_dsi_data {
	dsi_handle_t mipi_handle;
	struct k_sem transfer_sem;
};


/* MAX DSI TX payload */
#define DSI_TX_MAX_PAYLOAD_BYTE (64U * 4U)


#ifdef CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA

/* Callback for DSI DMA transfer completion, called in ISR context */
static void dsi_mcux_dma_cb(const struct device *dma_dev,
				void *user_data, uint32_t channel, int status)
{
	const struct device *dev = user_data;
	const struct mcux_mipi_dsi_config *config = dev->config;
	struct mcux_mipi_dsi_data *data = dev->data;
	uint32_t int_flags1, int_flags2;

	if (status != 0) {
		LOG_ERR("SMARTDMA transfer failed");
	} else {
		/* Disable DSI interrupts at transfer completion */
		DSI_DisableInterrupts(config->base, kDSI_InterruptGroup1ApbTxDone |
						kDSI_InterruptGroup1HtxTo, 0U);
		DSI_GetAndClearInterruptStatus(config->base, &int_flags1, &int_flags2);
		k_sem_give(&data->transfer_sem);
	}
}

/* Helper function to transfer DSI color (DMA based implementation) */
static int dsi_mcux_tx_color(const struct device *dev, uint8_t channel,
			     struct mipi_dsi_msg *msg)
{
	/*
	 * Color streams are a special case for this DSI peripheral, because
	 * the SMARTDMA peripheral (if enabled) can be used to accelerate
	 * the transfer of data to the DSI. The SMARTDMA has the additional
	 * advantage over traditional DMA of being able to to automatically
	 * byte swap color data. This is advantageous, as most graphical
	 * frameworks store RGB data in little endian format, but many
	 * MIPI displays expect color data in big endian format.
	 */
	const struct mcux_mipi_dsi_config *config = dev->config;
	struct mcux_mipi_dsi_data *data = dev->data;
	struct dma_config dma_cfg = {0};
	struct dma_block_config block = {0};
	int ret;

	if (channel != 0) {
		return -ENOTSUP; /* DMA can only transfer on virtual channel 0 */
	}

	/* Configure smartDMA device, and run transfer */
	block.source_address = (uint32_t)msg->tx_buf;
	block.block_size = msg->tx_len;

	dma_cfg.dma_callback = dsi_mcux_dma_cb;
	dma_cfg.user_data = (struct device *)dev;
	dma_cfg.head_block = &block;
	dma_cfg.block_count = 1;
	if (IS_ENABLED(CONFIG_MIPI_DSI_MCUX_2L_SWAP16)) {
		dma_cfg.dma_slot = DMA_SMARTDMA_MIPI_RGB565_DMA_SWAP;
	} else {
		dma_cfg.dma_slot = DMA_SMARTDMA_MIPI_RGB565_DMA;
	}
	dma_cfg.channel_direction = MEMORY_TO_PERIPHERAL;
	ret = dma_config(config->smart_dma, 0, &dma_cfg);
	if (ret < 0) {
		LOG_ERR("Could not configure SMARTDMA");
		return ret;
	}
	/*
	 * SMARTDMA uses DSI interrupt line as input for the DMA
	 * transfer trigger. Therefore, we need to enable DSI TX
	 * interrupts in order to trigger the DMA engine.
	 * Note that if the MIPI IRQ is enabled in
	 * the NVIC, it will fire on every SMARTDMA transfer
	 */
	DSI_EnableInterrupts(config->base, kDSI_InterruptGroup1ApbTxDone |
					kDSI_InterruptGroup1HtxTo, 0U);
	/* Trigger DMA engine */
	ret = dma_start(config->smart_dma, 0);
	if (ret < 0) {
		LOG_ERR("Could not start SMARTDMA");
		return ret;
	}
	/* Wait for TX completion */
	k_sem_take(&data->transfer_sem, K_FOREVER);
	return msg->tx_len;
}

#else /* CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA is not set */

/* Callback for DSI transfer completion, called in ISR context */
static void dsi_transfer_complete(MIPI_DSI_HOST_Type *base,
	dsi_handle_t *handle, status_t status, void *userData)
{
	struct mcux_mipi_dsi_data *data = userData;

	k_sem_give(&data->transfer_sem);
}


/* Helper function to transfer DSI color (Interrupt based implementation) */
static int dsi_mcux_tx_color(const struct device *dev, uint8_t channel,
			     struct mipi_dsi_msg *msg)
{
	const struct mcux_mipi_dsi_config *config = dev->config;
	struct mcux_mipi_dsi_data *data = dev->data;
	status_t status;
	dsi_transfer_t xfer = {
		.virtualChannel = channel,
		.txData = msg->tx_buf,
		.rxDataSize = (uint16_t)msg->rx_len,
		.rxData = msg->rx_buf,
		.sendDscCmd = true,
		.dscCmd = msg->cmd,
		.txDataType = kDSI_TxDataDcsLongWr,
		.flags = kDSI_TransferUseHighSpeed,
	};

	/*
	 * Cap transfer size. Note that we subtract six bytes here,
	 * one for the DSC command and five to insure that
	 * transfers are still aligned on a pixel boundary
	 * (two or three byte pixel sizes are supported).
	 */
	xfer.txDataSize = MIN(msg->tx_len, (DSI_TX_MAX_PAYLOAD_BYTE - 6));

	if (IS_ENABLED(CONFIG_MIPI_DSI_MCUX_2L_SWAP16)) {
		/* Manually swap the 16 byte color data in software */
		uint8_t *src = (uint8_t *)xfer.txData;
		uint8_t tmp;

		for (uint32_t i = 0; i < xfer.txDataSize; i += 2) {
			tmp = src[i];
			src[i] = src[i + 1];
			src[i + 1] = tmp;
		}
	}
	/* Send TX data using non-blocking DSI API */
	status = DSI_TransferNonBlocking(config->base,
					&data->mipi_handle, &xfer);
	/* Wait for transfer completion */
	k_sem_take(&data->transfer_sem, K_FOREVER);
	if (status != kStatus_Success) {
		LOG_ERR("Transmission failed");
		return -EIO;
	}
	return xfer.txDataSize;
}

/* ISR is used for DSI interrupt based implementation, unnecessary if DMA is used */
static int mipi_dsi_isr(const struct device *dev)
{
	const struct mcux_mipi_dsi_config *config = dev->config;
	struct mcux_mipi_dsi_data *data = dev->data;

	DSI_TransferHandleIRQ(config->base, &data->mipi_handle);
	return 0;
}

#endif

static int dsi_mcux_attach(const struct device *dev,
			   uint8_t channel,
			   const struct mipi_dsi_device *mdev)
{
	const struct mcux_mipi_dsi_config *config = dev->config;
	dsi_dphy_config_t dphy_config;
	dsi_config_t dsi_config;
	uint32_t dphy_bit_clk_freq;
	uint32_t dphy_esc_clk_freq;
	uint32_t dsi_pixel_clk_freq;
	uint32_t bit_width;

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

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

#ifdef CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA
	/* Connect DSI IRQ line to SMARTDMA trigger via
	 * INPUTMUX.
	 */
	/* Attach INPUTMUX from MIPI to SMARTDMA */
	INPUTMUX_Init(INPUTMUX);
	INPUTMUX_AttachSignal(INPUTMUX, 0, kINPUTMUX_MipiIrqToSmartDmaInput);
	/* Gate inputmux clock to save power */
	INPUTMUX_Deinit(INPUTMUX);

	if (!device_is_ready(config->smart_dma)) {
		return -ENODEV;
	}
#else
	struct mcux_mipi_dsi_data *data = dev->data;

	/* Create transfer handle */
	if (DSI_TransferCreateHandle(config->base, &data->mipi_handle,
				dsi_transfer_complete, data) != kStatus_Success) {
		return -ENODEV;
	}
#endif

	/* Get the DPHY bit clock frequency */
	if (clock_control_get_rate(config->bit_clk_dev,
				config->bit_clk_subsys,
				&dphy_bit_clk_freq)) {
		return -EINVAL;
	};
	/* Get the DPHY ESC clock frequency */
	if (clock_control_get_rate(config->esc_clk_dev,
				config->esc_clk_subsys,
				&dphy_esc_clk_freq)) {
		return -EINVAL;
	}
	/* Get the Pixel clock frequency */
	if (clock_control_get_rate(config->pixel_clk_dev,
				config->pixel_clk_subsys,
				&dsi_pixel_clk_freq)) {
		return -EINVAL;
	}

	switch (config->dpi_config.pixelPacket) {
	case kDSI_PixelPacket16Bit:
		bit_width = 16;
		break;
	case kDSI_PixelPacket18Bit:
		__fallthrough;
	case kDSI_PixelPacket18BitLoosely:
		bit_width = 18;
		break;
	case kDSI_PixelPacket24Bit:
		bit_width = 24;
		break;
	default:
		return -EINVAL; /* Invalid bit width enum value? */
	}
	/* 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
	 */
	if (((dsi_pixel_clk_freq * bit_width) / mdev->data_lanes) > dphy_bit_clk_freq) {
		return -EINVAL;
	}

	DSI_GetDphyDefaultConfig(&dphy_config, dphy_bit_clk_freq, dphy_esc_clk_freq);

	if (config->dphy_ref_freq != 0) {
		dphy_bit_clk_freq = DSI_InitDphy(config->base,
					&dphy_config, config->dphy_ref_freq);
	} else {
		/* DPHY PLL is not present, ref clock is unused */
		DSI_InitDphy(config->base, &dphy_config, 0);
	}

	/*
	 * If nxp,lcdif node is present, then the MIPI DSI driver will
	 * accept input on the DPI port from the LCDIF, and convert the output
	 * to DSI data. This is useful for video mode, where the LCDIF can
	 * constantly refresh the MIPI panel.
	 */
	if (mdev->mode_flags & MIPI_DSI_MODE_VIDEO) {
		/* Init DPI interface. */
		DSI_SetDpiConfig(config->base, &config->dpi_config, mdev->data_lanes,
						dsi_pixel_clk_freq, dphy_bit_clk_freq);
	}

	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 mcux_mipi_dsi_config *config = dev->config;
	dsi_transfer_t dsi_xfer = {0};
	status_t status;
	int ret;

	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:
		dsi_xfer.sendDscCmd = true;
		dsi_xfer.dscCmd = msg->cmd;
		dsi_xfer.txDataType = kDSI_TxDataDcsShortWrOneParam;
		break;
	case MIPI_DSI_DCS_LONG_WRITE:
		dsi_xfer.sendDscCmd = true;
		dsi_xfer.dscCmd = msg->cmd;
		dsi_xfer.txDataType = kDSI_TxDataDcsLongWr;
		dsi_xfer.flags = kDSI_TransferUseHighSpeed;
		if (msg->flags & MCUX_DSI_2L_FB_DATA) {
			/*
			 * Special case- transfer framebuffer data using
			 * SMARTDMA or non blocking DSI API. The framebuffer
			 * will also be color swapped, if enabled.
			 */
			ret = dsi_mcux_tx_color(dev, channel, msg);
			if (ret < 0) {
				LOG_ERR("Transmission failed");
				return -EIO;
			}
			return ret;
		}
		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_LONG_WRITE:
		dsi_xfer.txDataType = kDSI_TxDataGenLongWr;
		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 mcux_mipi_dsi_init(const struct device *dev)
{
	const struct mcux_mipi_dsi_config *config = dev->config;
	struct mcux_mipi_dsi_data *data = dev->data;

#ifndef CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA
	/* Enable IRQ */
	config->irq_config_func(dev);
#endif

	k_sem_init(&data->transfer_sem, 0, 1);

	imxrt_pre_init_display_interface();

	if (!device_is_ready(config->bit_clk_dev) ||
			!device_is_ready(config->esc_clk_dev) ||
			!device_is_ready(config->pixel_clk_dev)) {
		return -ENODEV;
	}
	return 0;
}

#define MCUX_DSI_DPI_CONFIG(id)									\
	IF_ENABLED(DT_NODE_HAS_PROP(DT_DRV_INST(id), nxp_lcdif),				\
	(.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_PROP(DT_CHILD(DT_INST_PHANDLE(id, nxp_lcdif),		\
					display_timings),  vsync_active) ?			\
					kDSI_DpiVsyncActiveHigh :				\
					kDSI_DpiVsyncActiveLow) |				\
				(DT_PROP(DT_CHILD(DT_INST_PHANDLE(id, nxp_lcdif),		\
					display_timings),  hsync_active) ?			\
					kDSI_DpiHsyncActiveHigh :				\
					kDSI_DpiHsyncActiveLow),				\
		.hfp = DT_PROP(DT_CHILD(DT_INST_PHANDLE(id, nxp_lcdif),				\
					display_timings),  hfront_porch),			\
		.hbp = DT_PROP(DT_CHILD(DT_INST_PHANDLE(id, nxp_lcdif),				\
					display_timings),  hback_porch),			\
		.hsw = DT_PROP(DT_CHILD(DT_INST_PHANDLE(id, nxp_lcdif),				\
					display_timings),  hsync_len),				\
		.vfp = DT_PROP(DT_CHILD(DT_INST_PHANDLE(id, nxp_lcdif),				\
					display_timings),  vfront_porch),			\
		.vbp = DT_PROP(DT_CHILD(DT_INST_PHANDLE(id, nxp_lcdif),				\
					display_timings),  vback_porch),			\
	},))

#define MCUX_MIPI_DSI_DEVICE(id)								\
	COND_CODE_1(CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA,						\
	(), (static void mipi_dsi_##n##_irq_config_func(const struct device *dev)		\
	{											\
		IRQ_CONNECT(DT_INST_IRQN(id), DT_INST_IRQ(id, priority),			\
			mipi_dsi_isr, DEVICE_DT_INST_GET(id), 0);				\
			irq_enable(DT_INST_IRQN(id));						\
	}))											\
												\
	static const struct mcux_mipi_dsi_config mipi_dsi_config_##id = {			\
		MCUX_DSI_DPI_CONFIG(id)								\
		COND_CODE_1(CONFIG_MIPI_DSI_MCUX_2L_SMARTDMA,					\
		(.smart_dma = DEVICE_DT_GET(DT_INST_DMAS_CTLR_BY_NAME(id, smartdma)),),		\
		(.irq_config_func = mipi_dsi_##n##_irq_config_func,))				\
		.base = (MIPI_DSI_HOST_Type *)DT_INST_REG_ADDR(id),				\
		.auto_insert_eotp = DT_INST_PROP(id, autoinsert_eotp),				\
		.dphy_ref_freq = DT_INST_PROP_OR(id, dphy_ref_frequency, 0),			\
		.bit_clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_NAME(id, dphy)),		\
		.bit_clk_subsys =								\
			(clock_control_subsys_t)DT_INST_CLOCKS_CELL_BY_NAME(id, dphy, name),	\
		.esc_clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_NAME(id, esc)),		\
		.esc_clk_subsys =								\
			(clock_control_subsys_t)DT_INST_CLOCKS_CELL_BY_NAME(id, esc, name),	\
		.pixel_clk_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR_BY_NAME(id, pixel)),		\
		.pixel_clk_subsys =								\
			(clock_control_subsys_t)DT_INST_CLOCKS_CELL_BY_NAME(id, pixel, name),	\
	};											\
												\
	static struct mcux_mipi_dsi_data mipi_dsi_data_##id;					\
	DEVICE_DT_INST_DEFINE(id,								\
			    &mcux_mipi_dsi_init,						\
			    NULL,								\
			    &mipi_dsi_data_##id,						\
			    &mipi_dsi_config_##id,						\
			    POST_KERNEL,							\
			    CONFIG_MIPI_DSI_INIT_PRIORITY,					\
			    &dsi_mcux_api);

DT_INST_FOREACH_STATUS_OKAY(MCUX_MIPI_DSI_DEVICE)
