// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (c) 2021 MediaTek Inc.
 */

#include <linux/clk.h>
#include <linux/component.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/of_irq.h>
#include <linux/platform_device.h>
#include <linux/soc/mediatek/mtk-cmdq.h>

#include "mtk_disp_drv.h"
#include "mtk_drm_crtc.h"
#include "mtk_drm_ddp_comp.h"

#define DISP_CCORR_EN				0x0000
#define CCORR_EN					BIT(0)
#define DISP_CCORR_CFG				0x0020
#define CCORR_RELAY_MODE				BIT(0)
#define CCORR_ENGINE_EN					BIT(1)
#define CCORR_GAMMA_OFF					BIT(2)
#define CCORR_WGAMUT_SRC_CLIP				BIT(3)
#define DISP_CCORR_SIZE				0x0030
#define DISP_CCORR_COEF_0			0x0080
#define DISP_CCORR_COEF_1			0x0084
#define DISP_CCORR_COEF_2			0x0088
#define DISP_CCORR_COEF_3			0x008C
#define DISP_CCORR_COEF_4			0x0090

struct mtk_disp_ccorr_data {
	u32 matrix_bits;
};

/**
 * struct mtk_disp_ccorr - DISP_CCORR driver structure
 * @ddp_comp - structure containing type enum and hardware resources
 * @crtc - associated crtc to report irq events to
 */
struct mtk_disp_ccorr {
	struct clk *clk;
	void __iomem *regs;
	struct cmdq_client_reg cmdq_reg;
	const struct mtk_disp_ccorr_data	*data;
};

int mtk_ccorr_clk_enable(struct device *dev)
{
	struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);

	return clk_prepare_enable(ccorr->clk);
}

void mtk_ccorr_clk_disable(struct device *dev)
{
	struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);

	clk_disable_unprepare(ccorr->clk);
}

void mtk_ccorr_config(struct device *dev, unsigned int w,
			     unsigned int h, unsigned int vrefresh,
			     unsigned int bpc, struct cmdq_pkt *cmdq_pkt)
{
	struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);

	mtk_ddp_write(cmdq_pkt, w << 16 | h, &ccorr->cmdq_reg, ccorr->regs,
		      DISP_CCORR_SIZE);
	mtk_ddp_write(cmdq_pkt, CCORR_ENGINE_EN, &ccorr->cmdq_reg, ccorr->regs,
		      DISP_CCORR_CFG);
}

void mtk_ccorr_start(struct device *dev)
{
	struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);

	writel(CCORR_EN, ccorr->regs + DISP_CCORR_EN);
}

void mtk_ccorr_stop(struct device *dev)
{
	struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);

	writel_relaxed(0x0, ccorr->regs + DISP_CCORR_EN);
}

/* Converts a DRM S31.32 value to the HW S1.n format. */
static u16 mtk_ctm_s31_32_to_s1_n(u64 in, u32 n)
{
	u16 r;

	/* Sign bit. */
	r = in & BIT_ULL(63) ? BIT(n + 1) : 0;

	if ((in & GENMASK_ULL(62, 33)) > 0) {
		/* identity value 0x100000000 -> 0x400(mt8183), */
		/* identity value 0x100000000 -> 0x800(mt8192), */
		/* if bigger this, set it to max 0x7ff. */
		r |= GENMASK(n, 0);
	} else {
		/* take the n+1 most important bits. */
		r |= (in >> (32 - n)) & GENMASK(n, 0);
	}

	return r;
}

void mtk_ccorr_ctm_set(struct device *dev, struct drm_crtc_state *state)
{
	struct mtk_disp_ccorr *ccorr = dev_get_drvdata(dev);
	struct drm_property_blob *blob = state->ctm;
	struct drm_color_ctm *ctm;
	const u64 *input;
	uint16_t coeffs[9] = { 0 };
	int i;
	struct cmdq_pkt *cmdq_pkt = NULL;
	u32 matrix_bits = ccorr->data->matrix_bits;

	if (!blob)
		return;

	ctm = (struct drm_color_ctm *)blob->data;
	input = ctm->matrix;

	for (i = 0; i < ARRAY_SIZE(coeffs); i++)
		coeffs[i] = mtk_ctm_s31_32_to_s1_n(input[i], matrix_bits);

	mtk_ddp_write(cmdq_pkt, coeffs[0] << 16 | coeffs[1],
		      &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_0);
	mtk_ddp_write(cmdq_pkt, coeffs[2] << 16 | coeffs[3],
		      &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_1);
	mtk_ddp_write(cmdq_pkt, coeffs[4] << 16 | coeffs[5],
		      &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_2);
	mtk_ddp_write(cmdq_pkt, coeffs[6] << 16 | coeffs[7],
		      &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_3);
	mtk_ddp_write(cmdq_pkt, coeffs[8] << 16,
		      &ccorr->cmdq_reg, ccorr->regs, DISP_CCORR_COEF_4);
}

static int mtk_disp_ccorr_bind(struct device *dev, struct device *master,
			       void *data)
{
	return 0;
}

static void mtk_disp_ccorr_unbind(struct device *dev, struct device *master,
				  void *data)
{
}

static const struct component_ops mtk_disp_ccorr_component_ops = {
	.bind	= mtk_disp_ccorr_bind,
	.unbind	= mtk_disp_ccorr_unbind,
};

static int mtk_disp_ccorr_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct mtk_disp_ccorr *priv;
	struct resource *res;
	int ret;

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

	priv->clk = devm_clk_get(dev, NULL);
	if (IS_ERR(priv->clk)) {
		dev_err(dev, "failed to get ccorr clk\n");
		return PTR_ERR(priv->clk);
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	priv->regs = devm_ioremap_resource(dev, res);
	if (IS_ERR(priv->regs)) {
		dev_err(dev, "failed to ioremap ccorr\n");
		return PTR_ERR(priv->regs);
	}

#if IS_REACHABLE(CONFIG_MTK_CMDQ)
	ret = cmdq_dev_get_client_reg(dev, &priv->cmdq_reg, 0);
	if (ret)
		dev_dbg(dev, "get mediatek,gce-client-reg fail!\n");
#endif

	priv->data = of_device_get_match_data(dev);
	platform_set_drvdata(pdev, priv);

	ret = component_add(dev, &mtk_disp_ccorr_component_ops);
	if (ret)
		dev_err(dev, "Failed to add component: %d\n", ret);

	return ret;
}

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

	return 0;
}

static const struct mtk_disp_ccorr_data mt8183_ccorr_driver_data = {
	.matrix_bits = 10,
};

static const struct of_device_id mtk_disp_ccorr_driver_dt_match[] = {
	{ .compatible = "mediatek,mt8183-disp-ccorr",
	  .data = &mt8183_ccorr_driver_data},
	{},
};
MODULE_DEVICE_TABLE(of, mtk_disp_ccorr_driver_dt_match);

struct platform_driver mtk_disp_ccorr_driver = {
	.probe		= mtk_disp_ccorr_probe,
	.remove		= mtk_disp_ccorr_remove,
	.driver		= {
		.name	= "mediatek-disp-ccorr",
		.owner	= THIS_MODULE,
		.of_match_table = mtk_disp_ccorr_driver_dt_match,
	},
};
