// SPDX-License-Identifier: GPL-2.0+
/*
 * Driver for Cadence MIPI-CSI2 TX Controller
 *
 * Copyright (C) 2017-2018 Cadence Design Systems Inc.
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/platform_device.h>
#include <linux/slab.h>

#include <media/v4l2-ctrls.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>
#include <media/v4l2-subdev.h>

#define CSI2TX_DEVICE_CONFIG_REG	0x00
#define CSI2TX_DEVICE_CONFIG_STREAMS_MASK	GENMASK(6, 4)
#define CSI2TX_DEVICE_CONFIG_HAS_DPHY		BIT(3)
#define CSI2TX_DEVICE_CONFIG_LANES_MASK		GENMASK(2, 0)

#define CSI2TX_CONFIG_REG		0x20
#define CSI2TX_CONFIG_CFG_REQ			BIT(2)
#define CSI2TX_CONFIG_SRST_REQ			BIT(1)

#define CSI2TX_DPHY_CFG_REG		0x28
#define CSI2TX_DPHY_CFG_CLK_RESET		BIT(16)
#define CSI2TX_DPHY_CFG_LANE_RESET(n)		BIT((n) + 12)
#define CSI2TX_DPHY_CFG_MODE_MASK		GENMASK(9, 8)
#define CSI2TX_DPHY_CFG_MODE_LPDT		(2 << 8)
#define CSI2TX_DPHY_CFG_MODE_HS			(1 << 8)
#define CSI2TX_DPHY_CFG_MODE_ULPS		(0 << 8)
#define CSI2TX_DPHY_CFG_CLK_ENABLE		BIT(4)
#define CSI2TX_DPHY_CFG_LANE_ENABLE(n)		BIT(n)

#define CSI2TX_DPHY_CLK_WAKEUP_REG	0x2c
#define CSI2TX_DPHY_CLK_WAKEUP_ULPS_CYCLES(n)	((n) & 0xffff)

#define CSI2TX_DT_CFG_REG(n)		(0x80 + (n) * 8)
#define CSI2TX_DT_CFG_DT(n)			(((n) & 0x3f) << 2)

#define CSI2TX_DT_FORMAT_REG(n)		(0x84 + (n) * 8)
#define CSI2TX_DT_FORMAT_BYTES_PER_LINE(n)	(((n) & 0xffff) << 16)
#define CSI2TX_DT_FORMAT_MAX_LINE_NUM(n)	((n) & 0xffff)

#define CSI2TX_STREAM_IF_CFG_REG(n)	(0x100 + (n) * 4)
#define CSI2TX_STREAM_IF_CFG_FILL_LEVEL(n)	((n) & 0x1f)

#define CSI2TX_LANES_MAX	4
#define CSI2TX_STREAMS_MAX	4

enum csi2tx_pads {
	CSI2TX_PAD_SOURCE,
	CSI2TX_PAD_SINK_STREAM0,
	CSI2TX_PAD_SINK_STREAM1,
	CSI2TX_PAD_SINK_STREAM2,
	CSI2TX_PAD_SINK_STREAM3,
	CSI2TX_PAD_MAX,
};

struct csi2tx_fmt {
	u32	mbus;
	u32	dt;
	u32	bpp;
};

struct csi2tx_priv {
	struct device			*dev;
	unsigned int			count;

	/*
	 * Used to prevent race conditions between multiple,
	 * concurrent calls to start and stop.
	 */
	struct mutex			lock;

	void __iomem			*base;

	struct clk			*esc_clk;
	struct clk			*p_clk;
	struct clk			*pixel_clk[CSI2TX_STREAMS_MAX];

	struct v4l2_subdev		subdev;
	struct media_pad		pads[CSI2TX_PAD_MAX];
	struct v4l2_mbus_framefmt	pad_fmts[CSI2TX_PAD_MAX];

	bool				has_internal_dphy;
	u8				lanes[CSI2TX_LANES_MAX];
	unsigned int			num_lanes;
	unsigned int			max_lanes;
	unsigned int			max_streams;
};

static const struct csi2tx_fmt csi2tx_formats[] = {
	{
		.mbus	= MEDIA_BUS_FMT_UYVY8_1X16,
		.bpp	= 2,
		.dt	= 0x1e,
	},
	{
		.mbus	= MEDIA_BUS_FMT_RGB888_1X24,
		.bpp	= 3,
		.dt	= 0x24,
	},
};

static const struct v4l2_mbus_framefmt fmt_default = {
	.width		= 1280,
	.height		= 720,
	.code		= MEDIA_BUS_FMT_RGB888_1X24,
	.field		= V4L2_FIELD_NONE,
	.colorspace	= V4L2_COLORSPACE_DEFAULT,
};

static inline
struct csi2tx_priv *v4l2_subdev_to_csi2tx(struct v4l2_subdev *subdev)
{
	return container_of(subdev, struct csi2tx_priv, subdev);
}

static const struct csi2tx_fmt *csi2tx_get_fmt_from_mbus(u32 mbus)
{
	unsigned int i;

	for (i = 0; i < ARRAY_SIZE(csi2tx_formats); i++)
		if (csi2tx_formats[i].mbus == mbus)
			return &csi2tx_formats[i];

	return NULL;
}

static int csi2tx_enum_mbus_code(struct v4l2_subdev *subdev,
				 struct v4l2_subdev_pad_config *cfg,
				 struct v4l2_subdev_mbus_code_enum *code)
{
	if (code->pad || code->index >= ARRAY_SIZE(csi2tx_formats))
		return -EINVAL;

	code->code = csi2tx_formats[code->index].mbus;

	return 0;
}

static struct v4l2_mbus_framefmt *
__csi2tx_get_pad_format(struct v4l2_subdev *subdev,
			struct v4l2_subdev_pad_config *cfg,
			struct v4l2_subdev_format *fmt)
{
	struct csi2tx_priv *csi2tx = v4l2_subdev_to_csi2tx(subdev);

	if (fmt->which == V4L2_SUBDEV_FORMAT_TRY)
		return v4l2_subdev_get_try_format(subdev, cfg,
						  fmt->pad);

	return &csi2tx->pad_fmts[fmt->pad];
}

static int csi2tx_get_pad_format(struct v4l2_subdev *subdev,
				 struct v4l2_subdev_pad_config *cfg,
				 struct v4l2_subdev_format *fmt)
{
	const struct v4l2_mbus_framefmt *format;

	/* Multiplexed pad? */
	if (fmt->pad == CSI2TX_PAD_SOURCE)
		return -EINVAL;

	format = __csi2tx_get_pad_format(subdev, cfg, fmt);
	if (!format)
		return -EINVAL;

	fmt->format = *format;

	return 0;
}

static int csi2tx_set_pad_format(struct v4l2_subdev *subdev,
				 struct v4l2_subdev_pad_config *cfg,
				 struct v4l2_subdev_format *fmt)
{
	const struct v4l2_mbus_framefmt *src_format = &fmt->format;
	struct v4l2_mbus_framefmt *dst_format;

	/* Multiplexed pad? */
	if (fmt->pad == CSI2TX_PAD_SOURCE)
		return -EINVAL;

	if (!csi2tx_get_fmt_from_mbus(fmt->format.code))
		src_format = &fmt_default;

	dst_format = __csi2tx_get_pad_format(subdev, cfg, fmt);
	if (!dst_format)
		return -EINVAL;

	*dst_format = *src_format;

	return 0;
}

static const struct v4l2_subdev_pad_ops csi2tx_pad_ops = {
	.enum_mbus_code	= csi2tx_enum_mbus_code,
	.get_fmt	= csi2tx_get_pad_format,
	.set_fmt	= csi2tx_set_pad_format,
};

static void csi2tx_reset(struct csi2tx_priv *csi2tx)
{
	writel(CSI2TX_CONFIG_SRST_REQ, csi2tx->base + CSI2TX_CONFIG_REG);

	udelay(10);
}

static int csi2tx_start(struct csi2tx_priv *csi2tx)
{
	struct media_entity *entity = &csi2tx->subdev.entity;
	struct media_link *link;
	unsigned int i;
	u32 reg;

	csi2tx_reset(csi2tx);

	writel(CSI2TX_CONFIG_CFG_REQ, csi2tx->base + CSI2TX_CONFIG_REG);

	udelay(10);

	/* Configure our PPI interface with the D-PHY */
	writel(CSI2TX_DPHY_CLK_WAKEUP_ULPS_CYCLES(32),
	       csi2tx->base + CSI2TX_DPHY_CLK_WAKEUP_REG);

	/* Put our lanes (clock and data) out of reset */
	reg = CSI2TX_DPHY_CFG_CLK_RESET | CSI2TX_DPHY_CFG_MODE_LPDT;
	for (i = 0; i < csi2tx->num_lanes; i++)
		reg |= CSI2TX_DPHY_CFG_LANE_RESET(csi2tx->lanes[i]);
	writel(reg, csi2tx->base + CSI2TX_DPHY_CFG_REG);

	udelay(10);

	/* Enable our (clock and data) lanes */
	reg |= CSI2TX_DPHY_CFG_CLK_ENABLE;
	for (i = 0; i < csi2tx->num_lanes; i++)
		reg |= CSI2TX_DPHY_CFG_LANE_ENABLE(csi2tx->lanes[i]);
	writel(reg, csi2tx->base + CSI2TX_DPHY_CFG_REG);

	udelay(10);

	/* Switch to HS mode */
	reg &= ~CSI2TX_DPHY_CFG_MODE_MASK;
	writel(reg | CSI2TX_DPHY_CFG_MODE_HS,
	       csi2tx->base + CSI2TX_DPHY_CFG_REG);

	udelay(10);

	/*
	 * Create a static mapping between the CSI virtual channels
	 * and the input streams.
	 *
	 * This should be enhanced, but v4l2 lacks the support for
	 * changing that mapping dynamically at the moment.
	 *
	 * We're protected from the userspace setting up links at the
	 * same time by the upper layer having called
	 * media_pipeline_start().
	 */
	list_for_each_entry(link, &entity->links, list) {
		struct v4l2_mbus_framefmt *mfmt;
		const struct csi2tx_fmt *fmt;
		unsigned int stream;
		int pad_idx = -1;

		/* Only consider our enabled input pads */
		for (i = CSI2TX_PAD_SINK_STREAM0; i < CSI2TX_PAD_MAX; i++) {
			struct media_pad *pad = &csi2tx->pads[i];

			if ((pad == link->sink) &&
			    (link->flags & MEDIA_LNK_FL_ENABLED)) {
				pad_idx = i;
				break;
			}
		}

		if (pad_idx < 0)
			continue;

		mfmt = &csi2tx->pad_fmts[pad_idx];
		fmt = csi2tx_get_fmt_from_mbus(mfmt->code);
		if (!fmt)
			continue;

		stream = pad_idx - CSI2TX_PAD_SINK_STREAM0;

		/*
		 * We use the stream ID there, but it's wrong.
		 *
		 * A stream could very well send a data type that is
		 * not equal to its stream ID. We need to find a
		 * proper way to address it.
		 */
		writel(CSI2TX_DT_CFG_DT(fmt->dt),
		       csi2tx->base + CSI2TX_DT_CFG_REG(stream));

		writel(CSI2TX_DT_FORMAT_BYTES_PER_LINE(mfmt->width * fmt->bpp) |
		       CSI2TX_DT_FORMAT_MAX_LINE_NUM(mfmt->height + 1),
		       csi2tx->base + CSI2TX_DT_FORMAT_REG(stream));

		/*
		 * TODO: This needs to be calculated based on the
		 * output CSI2 clock rate.
		 */
		writel(CSI2TX_STREAM_IF_CFG_FILL_LEVEL(4),
		       csi2tx->base + CSI2TX_STREAM_IF_CFG_REG(stream));
	}

	/* Disable the configuration mode */
	writel(0, csi2tx->base + CSI2TX_CONFIG_REG);

	return 0;
}

static void csi2tx_stop(struct csi2tx_priv *csi2tx)
{
	writel(CSI2TX_CONFIG_CFG_REQ | CSI2TX_CONFIG_SRST_REQ,
	       csi2tx->base + CSI2TX_CONFIG_REG);
}

static int csi2tx_s_stream(struct v4l2_subdev *subdev, int enable)
{
	struct csi2tx_priv *csi2tx = v4l2_subdev_to_csi2tx(subdev);
	int ret = 0;

	mutex_lock(&csi2tx->lock);

	if (enable) {
		/*
		 * If we're not the first users, there's no need to
		 * enable the whole controller.
		 */
		if (!csi2tx->count) {
			ret = csi2tx_start(csi2tx);
			if (ret)
				goto out;
		}

		csi2tx->count++;
	} else {
		csi2tx->count--;

		/*
		 * Let the last user turn off the lights.
		 */
		if (!csi2tx->count)
			csi2tx_stop(csi2tx);
	}

out:
	mutex_unlock(&csi2tx->lock);
	return ret;
}

static const struct v4l2_subdev_video_ops csi2tx_video_ops = {
	.s_stream	= csi2tx_s_stream,
};

static const struct v4l2_subdev_ops csi2tx_subdev_ops = {
	.pad		= &csi2tx_pad_ops,
	.video		= &csi2tx_video_ops,
};

static int csi2tx_get_resources(struct csi2tx_priv *csi2tx,
				struct platform_device *pdev)
{
	struct resource *res;
	unsigned int i;
	u32 dev_cfg;

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	csi2tx->base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(csi2tx->base))
		return PTR_ERR(csi2tx->base);

	csi2tx->p_clk = devm_clk_get(&pdev->dev, "p_clk");
	if (IS_ERR(csi2tx->p_clk)) {
		dev_err(&pdev->dev, "Couldn't get p_clk\n");
		return PTR_ERR(csi2tx->p_clk);
	}

	csi2tx->esc_clk = devm_clk_get(&pdev->dev, "esc_clk");
	if (IS_ERR(csi2tx->esc_clk)) {
		dev_err(&pdev->dev, "Couldn't get the esc_clk\n");
		return PTR_ERR(csi2tx->esc_clk);
	}

	clk_prepare_enable(csi2tx->p_clk);
	dev_cfg = readl(csi2tx->base + CSI2TX_DEVICE_CONFIG_REG);
	clk_disable_unprepare(csi2tx->p_clk);

	csi2tx->max_lanes = dev_cfg & CSI2TX_DEVICE_CONFIG_LANES_MASK;
	if (csi2tx->max_lanes > CSI2TX_LANES_MAX) {
		dev_err(&pdev->dev, "Invalid number of lanes: %u\n",
			csi2tx->max_lanes);
		return -EINVAL;
	}

	csi2tx->max_streams = (dev_cfg & CSI2TX_DEVICE_CONFIG_STREAMS_MASK) >> 4;
	if (csi2tx->max_streams > CSI2TX_STREAMS_MAX) {
		dev_err(&pdev->dev, "Invalid number of streams: %u\n",
			csi2tx->max_streams);
		return -EINVAL;
	}

	csi2tx->has_internal_dphy = !!(dev_cfg & CSI2TX_DEVICE_CONFIG_HAS_DPHY);

	for (i = 0; i < csi2tx->max_streams; i++) {
		char clk_name[16];

		snprintf(clk_name, sizeof(clk_name), "pixel_if%u_clk", i);
		csi2tx->pixel_clk[i] = devm_clk_get(&pdev->dev, clk_name);
		if (IS_ERR(csi2tx->pixel_clk[i])) {
			dev_err(&pdev->dev, "Couldn't get clock %s\n",
				clk_name);
			return PTR_ERR(csi2tx->pixel_clk[i]);
		}
	}

	return 0;
}

static int csi2tx_check_lanes(struct csi2tx_priv *csi2tx)
{
	struct v4l2_fwnode_endpoint v4l2_ep;
	struct device_node *ep;
	int ret;

	ep = of_graph_get_endpoint_by_regs(csi2tx->dev->of_node, 0, 0);
	if (!ep)
		return -EINVAL;

	ret = v4l2_fwnode_endpoint_parse(of_fwnode_handle(ep), &v4l2_ep);
	if (ret) {
		dev_err(csi2tx->dev, "Could not parse v4l2 endpoint\n");
		goto out;
	}

	if (v4l2_ep.bus_type != V4L2_MBUS_CSI2) {
		dev_err(csi2tx->dev, "Unsupported media bus type: 0x%x\n",
			v4l2_ep.bus_type);
		ret = -EINVAL;
		goto out;
	}

	csi2tx->num_lanes = v4l2_ep.bus.mipi_csi2.num_data_lanes;
	if (csi2tx->num_lanes > csi2tx->max_lanes) {
		dev_err(csi2tx->dev,
			"Current configuration uses more lanes than supported\n");
		ret = -EINVAL;
		goto out;
	}

	memcpy(csi2tx->lanes, v4l2_ep.bus.mipi_csi2.data_lanes,
	       sizeof(csi2tx->lanes));

out:
	of_node_put(ep);
	return ret;
}

static int csi2tx_probe(struct platform_device *pdev)
{
	struct csi2tx_priv *csi2tx;
	unsigned int i;
	int ret;

	csi2tx = kzalloc(sizeof(*csi2tx), GFP_KERNEL);
	if (!csi2tx)
		return -ENOMEM;
	platform_set_drvdata(pdev, csi2tx);
	mutex_init(&csi2tx->lock);
	csi2tx->dev = &pdev->dev;

	ret = csi2tx_get_resources(csi2tx, pdev);
	if (ret)
		goto err_free_priv;

	v4l2_subdev_init(&csi2tx->subdev, &csi2tx_subdev_ops);
	csi2tx->subdev.owner = THIS_MODULE;
	csi2tx->subdev.dev = &pdev->dev;
	csi2tx->subdev.flags |= V4L2_SUBDEV_FL_HAS_DEVNODE;
	snprintf(csi2tx->subdev.name, V4L2_SUBDEV_NAME_SIZE, "%s.%s",
		 KBUILD_MODNAME, dev_name(&pdev->dev));

	ret = csi2tx_check_lanes(csi2tx);
	if (ret)
		goto err_free_priv;

	/* Create our media pads */
	csi2tx->subdev.entity.function = MEDIA_ENT_F_VID_IF_BRIDGE;
	csi2tx->pads[CSI2TX_PAD_SOURCE].flags = MEDIA_PAD_FL_SOURCE;
	for (i = CSI2TX_PAD_SINK_STREAM0; i < CSI2TX_PAD_MAX; i++)
		csi2tx->pads[i].flags = MEDIA_PAD_FL_SINK;

	/*
	 * Only the input pads are considered to have a format at the
	 * moment. The CSI link can multiplex various streams with
	 * different formats, and we can't expose this in v4l2 right
	 * now.
	 */
	for (i = CSI2TX_PAD_SINK_STREAM0; i < CSI2TX_PAD_MAX; i++)
		csi2tx->pad_fmts[i] = fmt_default;

	ret = media_entity_pads_init(&csi2tx->subdev.entity, CSI2TX_PAD_MAX,
				     csi2tx->pads);
	if (ret)
		goto err_free_priv;

	ret = v4l2_async_register_subdev(&csi2tx->subdev);
	if (ret < 0)
		goto err_free_priv;

	dev_info(&pdev->dev,
		 "Probed CSI2TX with %u/%u lanes, %u streams, %s D-PHY\n",
		 csi2tx->num_lanes, csi2tx->max_lanes, csi2tx->max_streams,
		 csi2tx->has_internal_dphy ? "internal" : "no");

	return 0;

err_free_priv:
	kfree(csi2tx);
	return ret;
}

static int csi2tx_remove(struct platform_device *pdev)
{
	struct csi2tx_priv *csi2tx = platform_get_drvdata(pdev);

	v4l2_async_unregister_subdev(&csi2tx->subdev);
	kfree(csi2tx);

	return 0;
}

static const struct of_device_id csi2tx_of_table[] = {
	{ .compatible = "cdns,csi2tx" },
	{ },
};
MODULE_DEVICE_TABLE(of, csi2tx_of_table);

static struct platform_driver csi2tx_driver = {
	.probe	= csi2tx_probe,
	.remove	= csi2tx_remove,

	.driver	= {
		.name		= "cdns-csi2tx",
		.of_match_table	= csi2tx_of_table,
	},
};
module_platform_driver(csi2tx_driver);
MODULE_AUTHOR("Maxime Ripard <maxime.ripard@bootlin.com>");
MODULE_DESCRIPTION("Cadence CSI2-TX controller");
MODULE_LICENSE("GPL");
