// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for STM32 Digital Camera Memory Interface Pixel Processor
 *
 * Copyright (C) STMicroelectronics SA 2023
 * Authors: Hugues Fruchet <hugues.fruchet@foss.st.com>
 *          Alain Volmat <alain.volmat@foss.st.com>
 *          for STMicroelectronics.
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/pinctrl/consumer.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
#include <linux/reset.h>
#include <media/media-device.h>
#include <media/v4l2-device.h>
#include <media/v4l2-fwnode.h>

#include "dcmipp-common.h"

#define DCMIPP_MDEV_MODEL_NAME "DCMIPP MDEV"

#define DCMIPP_ENT_LINK(src, srcpad, sink, sinkpad, link_flags) {	\
	.src_ent = src,						\
	.src_pad = srcpad,					\
	.sink_ent = sink,					\
	.sink_pad = sinkpad,					\
	.flags = link_flags,					\
}

struct dcmipp_device {
	/* The platform device */
	struct platform_device		pdev;
	struct device			*dev;

	/* Hardware resources */
	void __iomem			*regs;
	struct clk			*kclk;

	/* The pipeline configuration */
	const struct dcmipp_pipeline_config	*pipe_cfg;

	/* The Associated media_device parent */
	struct media_device		mdev;

	/* Internal v4l2 parent device*/
	struct v4l2_device		v4l2_dev;

	/* Entities */
	struct dcmipp_ent_device	**entity;

	struct v4l2_async_notifier	notifier;
};

static inline struct dcmipp_device *
notifier_to_dcmipp(struct v4l2_async_notifier *n)
{
	return container_of(n, struct dcmipp_device, notifier);
}

/* Structure which describes individual configuration for each entity */
struct dcmipp_ent_config {
	const char *name;
	struct dcmipp_ent_device *(*init)
		(struct device *dev, const char *entity_name,
		 struct v4l2_device *v4l2_dev, void __iomem *regs);
	void (*release)(struct dcmipp_ent_device *ved);
};

/* Structure which describes links between entities */
struct dcmipp_ent_link {
	unsigned int src_ent;
	u16 src_pad;
	unsigned int sink_ent;
	u16 sink_pad;
	u32 flags;
};

/* Structure which describes the whole topology */
struct dcmipp_pipeline_config {
	const struct dcmipp_ent_config *ents;
	size_t num_ents;
	const struct dcmipp_ent_link *links;
	size_t num_links;
};

/* --------------------------------------------------------------------------
 * Topology Configuration
 */

static const struct dcmipp_ent_config stm32mp13_ent_config[] = {
	{
		.name = "dcmipp_parallel",
		.init = dcmipp_par_ent_init,
		.release = dcmipp_par_ent_release,
	},
	{
		.name = "dcmipp_dump_postproc",
		.init = dcmipp_byteproc_ent_init,
		.release = dcmipp_byteproc_ent_release,
	},
	{
		.name = "dcmipp_dump_capture",
		.init = dcmipp_bytecap_ent_init,
		.release = dcmipp_bytecap_ent_release,
	},
};

#define ID_PARALLEL 0
#define ID_DUMP_BYTEPROC 1
#define ID_DUMP_CAPTURE 2

static const struct dcmipp_ent_link stm32mp13_ent_links[] = {
	DCMIPP_ENT_LINK(ID_PARALLEL,      1, ID_DUMP_BYTEPROC, 0,
			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
	DCMIPP_ENT_LINK(ID_DUMP_BYTEPROC, 1, ID_DUMP_CAPTURE,  0,
			MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE),
};

static const struct dcmipp_pipeline_config stm32mp13_pipe_cfg = {
	.ents		= stm32mp13_ent_config,
	.num_ents	= ARRAY_SIZE(stm32mp13_ent_config),
	.links		= stm32mp13_ent_links,
	.num_links	= ARRAY_SIZE(stm32mp13_ent_links)
};

#define LINK_FLAG_TO_STR(f) ((f) == 0 ? "" :\
			     (f) == MEDIA_LNK_FL_ENABLED ? "ENABLED" :\
			     (f) == MEDIA_LNK_FL_IMMUTABLE ? "IMMUTABLE" :\
			     (f) == (MEDIA_LNK_FL_ENABLED |\
				     MEDIA_LNK_FL_IMMUTABLE) ?\
					"ENABLED, IMMUTABLE" :\
			     "UNKNOWN")

static int dcmipp_create_links(struct dcmipp_device *dcmipp)
{
	unsigned int i;
	int ret;

	/* Initialize the links between entities */
	for (i = 0; i < dcmipp->pipe_cfg->num_links; i++) {
		const struct dcmipp_ent_link *link =
			&dcmipp->pipe_cfg->links[i];
		struct dcmipp_ent_device *ved_src =
			dcmipp->entity[link->src_ent];
		struct dcmipp_ent_device *ved_sink =
			dcmipp->entity[link->sink_ent];

		dev_dbg(dcmipp->dev, "Create link \"%s\":%d -> %d:\"%s\" [%s]\n",
			dcmipp->pipe_cfg->ents[link->src_ent].name,
			link->src_pad, link->sink_pad,
			dcmipp->pipe_cfg->ents[link->sink_ent].name,
			LINK_FLAG_TO_STR(link->flags));

		ret = media_create_pad_link(ved_src->ent, link->src_pad,
					    ved_sink->ent, link->sink_pad,
					    link->flags);
		if (ret)
			return ret;
	}

	return 0;
}

static int dcmipp_graph_init(struct dcmipp_device *dcmipp);

static int dcmipp_create_subdevs(struct dcmipp_device *dcmipp)
{
	int ret, i;

	/* Call all subdev inits */
	for (i = 0; i < dcmipp->pipe_cfg->num_ents; i++) {
		const char *name = dcmipp->pipe_cfg->ents[i].name;

		dev_dbg(dcmipp->dev, "add subdev %s\n", name);
		dcmipp->entity[i] =
			dcmipp->pipe_cfg->ents[i].init(dcmipp->dev, name,
						       &dcmipp->v4l2_dev,
						       dcmipp->regs);
		if (IS_ERR(dcmipp->entity[i])) {
			dev_err(dcmipp->dev, "failed to init subdev %s\n",
				name);
			ret = PTR_ERR(dcmipp->entity[i]);
			goto err_init_entity;
		}
	}

	/* Initialize links */
	ret = dcmipp_create_links(dcmipp);
	if (ret)
		goto err_init_entity;

	ret = dcmipp_graph_init(dcmipp);
	if (ret < 0)
		goto err_init_entity;

	return 0;

err_init_entity:
	while (i > 0)
		dcmipp->pipe_cfg->ents[i - 1].release(dcmipp->entity[i - 1]);
	return ret;
}

static const struct of_device_id dcmipp_of_match[] = {
	{ .compatible = "st,stm32mp13-dcmipp", .data = &stm32mp13_pipe_cfg },
	{ /* end node */ },
};
MODULE_DEVICE_TABLE(of, dcmipp_of_match);

static irqreturn_t dcmipp_irq_thread(int irq, void *arg)
{
	struct dcmipp_device *dcmipp = arg;
	struct dcmipp_ent_device *ved;
	unsigned int i;

	/* Call irq thread of each entities of pipeline */
	for (i = 0; i < dcmipp->pipe_cfg->num_ents; i++) {
		ved = dcmipp->entity[i];
		if (ved->thread_fn && ved->handler_ret == IRQ_WAKE_THREAD)
			ved->thread_fn(irq, ved);
	}

	return IRQ_HANDLED;
}

static irqreturn_t dcmipp_irq_callback(int irq, void *arg)
{
	struct dcmipp_device *dcmipp = arg;
	struct dcmipp_ent_device *ved;
	irqreturn_t ret = IRQ_HANDLED;
	unsigned int i;

	/* Call irq handler of each entities of pipeline */
	for (i = 0; i < dcmipp->pipe_cfg->num_ents; i++) {
		ved = dcmipp->entity[i];
		if (ved->handler)
			ved->handler_ret = ved->handler(irq, ved);
		else if (ved->thread_fn)
			ved->handler_ret = IRQ_WAKE_THREAD;
		else
			ved->handler_ret = IRQ_HANDLED;
		if (ved->handler_ret != IRQ_HANDLED)
			ret = ved->handler_ret;
	}

	return ret;
}

static int dcmipp_graph_notify_bound(struct v4l2_async_notifier *notifier,
				     struct v4l2_subdev *subdev,
				     struct v4l2_async_connection *asd)
{
	struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier);
	unsigned int ret;
	int src_pad;
	struct dcmipp_ent_device *sink;
	struct v4l2_fwnode_endpoint vep = { .bus_type = V4L2_MBUS_PARALLEL };
	struct fwnode_handle *ep;

	dev_dbg(dcmipp->dev, "Subdev \"%s\" bound\n", subdev->name);

	/*
	 * Link this sub-device to DCMIPP, it could be
	 * a parallel camera sensor or a CSI-2 to parallel bridge
	 */
	src_pad = media_entity_get_fwnode_pad(&subdev->entity,
					      subdev->fwnode,
					      MEDIA_PAD_FL_SOURCE);

	/* Get bus characteristics from devicetree */
	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dcmipp->dev), 0, 0,
					     FWNODE_GRAPH_ENDPOINT_NEXT);
	if (!ep) {
		dev_err(dcmipp->dev, "Could not find the endpoint\n");
		return -ENODEV;
	}

	/* Check for parallel bus-type first, then bt656 */
	ret = v4l2_fwnode_endpoint_parse(ep, &vep);
	if (ret) {
		vep.bus_type = V4L2_MBUS_BT656;
		ret = v4l2_fwnode_endpoint_parse(ep, &vep);
		if (ret) {
			dev_err(dcmipp->dev, "Could not parse the endpoint\n");
			fwnode_handle_put(ep);
			return ret;
		}
	}

	fwnode_handle_put(ep);

	if (vep.bus.parallel.bus_width == 0) {
		dev_err(dcmipp->dev, "Invalid parallel interface bus-width\n");
		return -ENODEV;
	}

	/* Only 8 bits bus width supported with BT656 bus */
	if (vep.bus_type == V4L2_MBUS_BT656 &&
	    vep.bus.parallel.bus_width != 8) {
		dev_err(dcmipp->dev, "BT656 bus conflicts with %u bits bus width (8 bits required)\n",
			vep.bus.parallel.bus_width);
		return -ENODEV;
	}

	/* Parallel input device detected, connect it to parallel subdev */
	sink = dcmipp->entity[ID_PARALLEL];
	sink->bus.flags = vep.bus.parallel.flags;
	sink->bus.bus_width = vep.bus.parallel.bus_width;
	sink->bus.data_shift = vep.bus.parallel.data_shift;
	sink->bus_type = vep.bus_type;
	ret = media_create_pad_link(&subdev->entity, src_pad, sink->ent, 0,
				    MEDIA_LNK_FL_IMMUTABLE |
				    MEDIA_LNK_FL_ENABLED);
	if (ret) {
		dev_err(dcmipp->dev, "Failed to create media pad link with subdev \"%s\"\n",
			subdev->name);
		return ret;
	}

	dev_dbg(dcmipp->dev, "DCMIPP is now linked to \"%s\"\n", subdev->name);

	return 0;
}

static void dcmipp_graph_notify_unbind(struct v4l2_async_notifier *notifier,
				       struct v4l2_subdev *sd,
				       struct v4l2_async_connection *asd)
{
	struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier);

	dev_dbg(dcmipp->dev, "Removing %s\n", sd->name);
}

static int dcmipp_graph_notify_complete(struct v4l2_async_notifier *notifier)
{
	struct dcmipp_device *dcmipp = notifier_to_dcmipp(notifier);
	int ret;

	/* Register the media device */
	ret = media_device_register(&dcmipp->mdev);
	if (ret) {
		dev_err(dcmipp->mdev.dev,
			"media device register failed (err=%d)\n", ret);
		return ret;
	}

	/* Expose all subdev's nodes*/
	ret = v4l2_device_register_subdev_nodes(&dcmipp->v4l2_dev);
	if (ret) {
		dev_err(dcmipp->mdev.dev,
			"dcmipp subdev nodes registration failed (err=%d)\n",
			ret);
		media_device_unregister(&dcmipp->mdev);
		return ret;
	}

	dev_dbg(dcmipp->dev, "Notify complete !\n");

	return 0;
}

static const struct v4l2_async_notifier_operations dcmipp_graph_notify_ops = {
	.bound = dcmipp_graph_notify_bound,
	.unbind = dcmipp_graph_notify_unbind,
	.complete = dcmipp_graph_notify_complete,
};

static int dcmipp_graph_init(struct dcmipp_device *dcmipp)
{
	struct v4l2_async_connection *asd;
	struct fwnode_handle *ep;
	int ret;

	ep = fwnode_graph_get_endpoint_by_id(dev_fwnode(dcmipp->dev), 0, 0,
					     FWNODE_GRAPH_ENDPOINT_NEXT);
	if (!ep) {
		dev_err(dcmipp->dev, "Failed to get next endpoint\n");
		return -EINVAL;
	}

	v4l2_async_nf_init(&dcmipp->notifier, &dcmipp->v4l2_dev);

	asd = v4l2_async_nf_add_fwnode_remote(&dcmipp->notifier, ep,
					      struct v4l2_async_connection);

	fwnode_handle_put(ep);

	if (IS_ERR(asd)) {
		dev_err(dcmipp->dev, "Failed to add fwnode remote subdev\n");
		return PTR_ERR(asd);
	}

	dcmipp->notifier.ops = &dcmipp_graph_notify_ops;

	ret = v4l2_async_nf_register(&dcmipp->notifier);
	if (ret < 0) {
		dev_err(dcmipp->dev, "Failed to register notifier\n");
		v4l2_async_nf_cleanup(&dcmipp->notifier);
		return ret;
	}

	return 0;
}

static int dcmipp_probe(struct platform_device *pdev)
{
	struct dcmipp_device *dcmipp;
	struct clk *kclk;
	const struct dcmipp_pipeline_config *pipe_cfg;
	struct reset_control *rstc;
	int irq;
	int ret;

	dcmipp = devm_kzalloc(&pdev->dev, sizeof(*dcmipp), GFP_KERNEL);
	if (!dcmipp)
		return -ENOMEM;

	dcmipp->dev = &pdev->dev;

	pipe_cfg = device_get_match_data(dcmipp->dev);
	if (!pipe_cfg) {
		dev_err(&pdev->dev, "Can't get device data\n");
		return -ENODEV;
	}
	dcmipp->pipe_cfg = pipe_cfg;

	platform_set_drvdata(pdev, dcmipp);

	/* Get hardware resources from devicetree */
	rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
	if (IS_ERR(rstc))
		return dev_err_probe(&pdev->dev, PTR_ERR(rstc),
				     "Could not get reset control\n");

	irq = platform_get_irq(pdev, 0);
	if (irq <= 0) {
		if (irq != -EPROBE_DEFER)
			dev_err(&pdev->dev, "Could not get irq\n");
		return irq ? irq : -ENXIO;
	}

	dcmipp->regs = devm_platform_get_and_ioremap_resource(pdev, 0, NULL);
	if (IS_ERR(dcmipp->regs)) {
		dev_err(&pdev->dev, "Could not map registers\n");
		return PTR_ERR(dcmipp->regs);
	}

	ret = devm_request_threaded_irq(&pdev->dev, irq, dcmipp_irq_callback,
					dcmipp_irq_thread, IRQF_ONESHOT,
					dev_name(&pdev->dev), dcmipp);
	if (ret) {
		dev_err(&pdev->dev, "Unable to request irq %d\n", irq);
		return ret;
	}

	/* Reset device */
	ret = reset_control_assert(rstc);
	if (ret) {
		dev_err(&pdev->dev, "Failed to assert the reset line\n");
		return ret;
	}

	usleep_range(3000, 5000);

	ret = reset_control_deassert(rstc);
	if (ret) {
		dev_err(&pdev->dev, "Failed to deassert the reset line\n");
		return ret;
	}

	kclk = devm_clk_get(&pdev->dev, NULL);
	if (IS_ERR(kclk))
		return dev_err_probe(&pdev->dev, PTR_ERR(kclk),
				     "Unable to get kclk\n");
	dcmipp->kclk = kclk;

	dcmipp->entity = devm_kcalloc(&pdev->dev, dcmipp->pipe_cfg->num_ents,
				      sizeof(*dcmipp->entity), GFP_KERNEL);
	if (!dcmipp->entity)
		return -ENOMEM;

	/* Register the v4l2 struct */
	ret = v4l2_device_register(&pdev->dev, &dcmipp->v4l2_dev);
	if (ret) {
		dev_err(&pdev->dev,
			"v4l2 device register failed (err=%d)\n", ret);
		return ret;
	}

	/* Link the media device within the v4l2_device */
	dcmipp->v4l2_dev.mdev = &dcmipp->mdev;

	/* Initialize media device */
	strscpy(dcmipp->mdev.model, DCMIPP_MDEV_MODEL_NAME,
		sizeof(dcmipp->mdev.model));
	dcmipp->mdev.dev = &pdev->dev;
	media_device_init(&dcmipp->mdev);

	/* Initialize subdevs */
	ret = dcmipp_create_subdevs(dcmipp);
	if (ret) {
		media_device_cleanup(&dcmipp->mdev);
		v4l2_device_unregister(&dcmipp->v4l2_dev);
		return ret;
	}

	pm_runtime_enable(dcmipp->dev);

	dev_info(&pdev->dev, "Probe done");

	return 0;
}

static void dcmipp_remove(struct platform_device *pdev)
{
	struct dcmipp_device *dcmipp = platform_get_drvdata(pdev);
	unsigned int i;

	pm_runtime_disable(&pdev->dev);

	v4l2_async_nf_unregister(&dcmipp->notifier);
	v4l2_async_nf_cleanup(&dcmipp->notifier);

	for (i = 0; i < dcmipp->pipe_cfg->num_ents; i++)
		dcmipp->pipe_cfg->ents[i].release(dcmipp->entity[i]);

	media_device_unregister(&dcmipp->mdev);
	media_device_cleanup(&dcmipp->mdev);

	v4l2_device_unregister(&dcmipp->v4l2_dev);
}

static int dcmipp_runtime_suspend(struct device *dev)
{
	struct dcmipp_device *dcmipp = dev_get_drvdata(dev);

	clk_disable_unprepare(dcmipp->kclk);

	return 0;
}

static int dcmipp_runtime_resume(struct device *dev)
{
	struct dcmipp_device *dcmipp = dev_get_drvdata(dev);
	int ret;

	ret = clk_prepare_enable(dcmipp->kclk);
	if (ret)
		dev_err(dev, "%s: Failed to prepare_enable kclk\n", __func__);

	return ret;
}

static int dcmipp_suspend(struct device *dev)
{
	/* disable clock */
	pm_runtime_force_suspend(dev);

	/* change pinctrl state */
	pinctrl_pm_select_sleep_state(dev);

	return 0;
}

static int dcmipp_resume(struct device *dev)
{
	/* restore pinctl default state */
	pinctrl_pm_select_default_state(dev);

	/* clock enable */
	pm_runtime_force_resume(dev);

	return 0;
}

static const struct dev_pm_ops dcmipp_pm_ops = {
	SYSTEM_SLEEP_PM_OPS(dcmipp_suspend, dcmipp_resume)
	RUNTIME_PM_OPS(dcmipp_runtime_suspend, dcmipp_runtime_resume, NULL)
};

static struct platform_driver dcmipp_pdrv = {
	.probe		= dcmipp_probe,
	.remove_new	= dcmipp_remove,
	.driver		= {
		.name	= DCMIPP_PDEV_NAME,
		.of_match_table = dcmipp_of_match,
		.pm = pm_ptr(&dcmipp_pm_ops),
	},
};

module_platform_driver(dcmipp_pdrv);

MODULE_AUTHOR("Hugues Fruchet <hugues.fruchet@foss.st.com>");
MODULE_AUTHOR("Alain Volmat <alain.volmat@foss.st.com>");
MODULE_DESCRIPTION("STMicroelectronics STM32 Digital Camera Memory Interface with Pixel Processor driver");
MODULE_LICENSE("GPL");
