// SPDX-License-Identifier: GPL-2.0
/*
 * MediaTek External Memory Interface (EMI) Interconnect driver
 *
 * Copyright (c) 2021 MediaTek Inc.
 * Copyright (c) 2024 Collabora Ltd.
 *                    AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
 */

#include <linux/interconnect.h>
#include <linux/interconnect-provider.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/overflow.h>
#include <linux/platform_device.h>
#include <linux/soc/mediatek/dvfsrc.h>

#include "icc-emi.h"

static int mtk_emi_icc_aggregate(struct icc_node *node, u32 tag, u32 avg_bw,
				 u32 peak_bw, u32 *agg_avg, u32 *agg_peak)
{
	struct mtk_icc_node *in = node->data;

	if (check_add_overflow(*agg_avg, avg_bw, agg_avg))
		*agg_avg = U32_MAX;

	*agg_peak = max_t(u32, *agg_peak, peak_bw);

	in->sum_avg = *agg_avg;
	in->max_peak = *agg_peak;

	return 0;
}

static int mtk_emi_icc_set(struct icc_node *src, struct icc_node *dst)
{
	struct mtk_icc_node *node = dst->data;
	struct device *dev;
	int ret;

	if (unlikely(!src->provider))
		return -EINVAL;

	dev = src->provider->dev->parent;

	switch (node->ep) {
	case 0:
		break;
	case 1:
		ret = mtk_dvfsrc_send_request(dev, MTK_DVFSRC_CMD_PEAK_BW, node->max_peak);
		if (ret) {
			dev_err(dev, "Cannot send peak bw request: %d\n", ret);
			return ret;
		}

		ret = mtk_dvfsrc_send_request(dev, MTK_DVFSRC_CMD_BW, node->sum_avg);
		if (ret) {
			dev_err(dev, "Cannot send bw request: %d\n", ret);
			return ret;
		}
		break;
	case 2:
		ret = mtk_dvfsrc_send_request(dev, MTK_DVFSRC_CMD_HRT_BW, node->sum_avg);
		if (ret) {
			dev_err(dev, "Cannot send HRT bw request: %d\n", ret);
			return ret;
		}
		break;
	default:
		dev_err(src->provider->dev, "Unknown endpoint %u\n", node->ep);
		return -EINVAL;
	}

	return 0;
}

int mtk_emi_icc_probe(struct platform_device *pdev)
{
	const struct mtk_icc_desc *desc;
	struct device *dev = &pdev->dev;
	struct icc_node *node;
	struct icc_onecell_data *data;
	struct icc_provider *provider;
	struct mtk_icc_node **mnodes;
	int i, j, ret;

	desc = of_device_get_match_data(dev);
	if (!desc)
		return -EINVAL;

	mnodes = desc->nodes;

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

	data = devm_kzalloc(dev, struct_size(data, nodes, desc->num_nodes), GFP_KERNEL);
	if (!data)
		return -ENOMEM;

	provider->dev = dev;
	provider->set = mtk_emi_icc_set;
	provider->aggregate = mtk_emi_icc_aggregate;
	provider->xlate = of_icc_xlate_onecell;
	INIT_LIST_HEAD(&provider->nodes);
	provider->data = data;

	for (i = 0; i < desc->num_nodes; i++) {
		if (!mnodes[i])
			continue;

		node = icc_node_create(mnodes[i]->id);
		if (IS_ERR(node)) {
			ret = PTR_ERR(node);
			goto err;
		}

		node->name = mnodes[i]->name;
		node->data = mnodes[i];
		icc_node_add(node, provider);

		for (j = 0; j < mnodes[i]->num_links; j++)
			icc_link_create(node, mnodes[i]->links[j]);

		data->nodes[i] = node;
	}
	data->num_nodes = desc->num_nodes;

	ret = icc_provider_register(provider);
	if (ret)
		goto err;

	platform_set_drvdata(pdev, provider);

	return 0;
err:
	icc_nodes_remove(provider);
	return ret;
}
EXPORT_SYMBOL_GPL(mtk_emi_icc_probe);

void mtk_emi_icc_remove(struct platform_device *pdev)
{
	struct icc_provider *provider = platform_get_drvdata(pdev);

	icc_provider_deregister(provider);
	icc_nodes_remove(provider);
}
EXPORT_SYMBOL_GPL(mtk_emi_icc_remove);

MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>");
MODULE_AUTHOR("Henry Chen <henryc.chen@mediatek.com>");
MODULE_DESCRIPTION("MediaTek External Memory Interface interconnect driver");
MODULE_LICENSE("GPL");
