// SPDX-License-Identifier: GPL-2.0
/*
 * CDX host controller driver for AMD versal-net platform.
 *
 * Copyright (C) 2022-2023, Advanced Micro Devices, Inc.
 */

#include <linux/mod_devicetable.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/cdx/cdx_bus.h>
#include <linux/irqdomain.h>

#include "cdx_controller.h"
#include "../cdx.h"
#include "mcdi_functions.h"
#include "mcdid.h"

static unsigned int cdx_mcdi_rpc_timeout(struct cdx_mcdi *cdx, unsigned int cmd)
{
	return MCDI_RPC_TIMEOUT;
}

static void cdx_mcdi_request(struct cdx_mcdi *cdx,
			     const struct cdx_dword *hdr, size_t hdr_len,
			     const struct cdx_dword *sdu, size_t sdu_len)
{
	if (cdx_rpmsg_send(cdx, hdr, hdr_len, sdu, sdu_len))
		dev_err(&cdx->rpdev->dev, "Failed to send rpmsg data\n");
}

static const struct cdx_mcdi_ops mcdi_ops = {
	.mcdi_rpc_timeout = cdx_mcdi_rpc_timeout,
	.mcdi_request = cdx_mcdi_request,
};

static int cdx_bus_enable(struct cdx_controller *cdx, u8 bus_num)
{
	return cdx_mcdi_bus_enable(cdx->priv, bus_num);
}

static int cdx_bus_disable(struct cdx_controller *cdx, u8 bus_num)
{
	return cdx_mcdi_bus_disable(cdx->priv, bus_num);
}

void cdx_rpmsg_post_probe(struct cdx_controller *cdx)
{
	/* Register CDX controller with CDX bus driver */
	if (cdx_register_controller(cdx))
		dev_err(cdx->dev, "Failed to register CDX controller\n");
}

void cdx_rpmsg_pre_remove(struct cdx_controller *cdx)
{
	cdx_unregister_controller(cdx);
	cdx_mcdi_wait_for_quiescence(cdx->priv, MCDI_RPC_TIMEOUT);
}

static int cdx_configure_device(struct cdx_controller *cdx,
				u8 bus_num, u8 dev_num,
				struct cdx_device_config *dev_config)
{
	u16 msi_index;
	int ret = 0;
	u32 data;
	u64 addr;

	switch (dev_config->type) {
	case CDX_DEV_MSI_CONF:
		msi_index = dev_config->msi.msi_index;
		data = dev_config->msi.data;
		addr = dev_config->msi.addr;

		ret = cdx_mcdi_write_msi(cdx->priv, bus_num, dev_num, msi_index, addr, data);
		break;
	case CDX_DEV_RESET_CONF:
		ret = cdx_mcdi_reset_device(cdx->priv, bus_num, dev_num);
		break;
	case CDX_DEV_BUS_MASTER_CONF:
		ret = cdx_mcdi_bus_master_enable(cdx->priv, bus_num, dev_num,
						 dev_config->bus_master_enable);
		break;
	case CDX_DEV_MSI_ENABLE:
		ret = cdx_mcdi_msi_enable(cdx->priv, bus_num, dev_num, dev_config->msi_enable);
		break;
	default:
		ret = -EINVAL;
	}

	return ret;
}

static int cdx_scan_devices(struct cdx_controller *cdx)
{
	struct cdx_mcdi *cdx_mcdi = cdx->priv;
	u8 bus_num, dev_num, num_cdx_bus;
	int ret;

	/* MCDI FW Read: Fetch the number of CDX buses on this controller */
	ret = cdx_mcdi_get_num_buses(cdx_mcdi);
	if (ret < 0) {
		dev_err(cdx->dev,
			"Get number of CDX buses failed: %d\n", ret);
		return ret;
	}
	num_cdx_bus = (u8)ret;

	for (bus_num = 0; bus_num < num_cdx_bus; bus_num++) {
		struct device *bus_dev;
		u8 num_cdx_dev;

		/* Add the bus on cdx subsystem */
		bus_dev = cdx_bus_add(cdx, bus_num);
		if (!bus_dev)
			continue;

		/* MCDI FW Read: Fetch the number of devices present */
		ret = cdx_mcdi_get_num_devs(cdx_mcdi, bus_num);
		if (ret < 0) {
			dev_err(cdx->dev,
				"Get devices on CDX bus %d failed: %d\n", bus_num, ret);
			continue;
		}
		num_cdx_dev = (u8)ret;

		for (dev_num = 0; dev_num < num_cdx_dev; dev_num++) {
			struct cdx_dev_params dev_params;

			/* MCDI FW: Get the device config */
			ret = cdx_mcdi_get_dev_config(cdx_mcdi, bus_num,
						      dev_num, &dev_params);
			if (ret) {
				dev_err(cdx->dev,
					"CDX device config get failed for %d(bus):%d(dev), %d\n",
					bus_num, dev_num, ret);
				continue;
			}
			dev_params.cdx = cdx;
			dev_params.parent = bus_dev;

			/* Add the device to the cdx bus */
			ret = cdx_device_add(&dev_params);
			if (ret) {
				dev_err(cdx->dev, "registering cdx dev: %d failed: %d\n",
					dev_num, ret);
				continue;
			}

			dev_dbg(cdx->dev, "CDX dev: %d on cdx bus: %d created\n",
				dev_num, bus_num);
		}
	}

	return 0;
}

static struct cdx_ops cdx_ops = {
	.bus_enable		= cdx_bus_enable,
	.bus_disable	= cdx_bus_disable,
	.scan		= cdx_scan_devices,
	.dev_configure	= cdx_configure_device,
};

static int xlnx_cdx_probe(struct platform_device *pdev)
{
	struct cdx_controller *cdx;
	struct cdx_mcdi *cdx_mcdi;
	int ret;

	cdx_mcdi = kzalloc(sizeof(*cdx_mcdi), GFP_KERNEL);
	if (!cdx_mcdi)
		return -ENOMEM;

	/* Store the MCDI ops */
	cdx_mcdi->mcdi_ops = &mcdi_ops;
	/* MCDI FW: Initialize the FW path */
	ret = cdx_mcdi_init(cdx_mcdi);
	if (ret) {
		dev_err_probe(&pdev->dev, ret, "MCDI Initialization failed\n");
		goto mcdi_init_fail;
	}

	cdx = kzalloc(sizeof(*cdx), GFP_KERNEL);
	if (!cdx) {
		ret = -ENOMEM;
		goto cdx_alloc_fail;
	}
	platform_set_drvdata(pdev, cdx);

	cdx->dev = &pdev->dev;
	cdx->priv = cdx_mcdi;
	cdx->ops = &cdx_ops;

	/* Create MSI domain */
	if (IS_ENABLED(CONFIG_GENERIC_MSI_IRQ))
		cdx->msi_domain = cdx_msi_domain_init(&pdev->dev);
	if (!cdx->msi_domain) {
		ret = dev_err_probe(&pdev->dev, -ENODEV, "cdx_msi_domain_init() failed");
		goto cdx_msi_fail;
	}

	ret = cdx_setup_rpmsg(pdev);
	if (ret) {
		dev_err_probe(&pdev->dev, ret, "Failed to register CDX RPMsg transport\n");
		goto cdx_rpmsg_fail;
	}

	return 0;

cdx_rpmsg_fail:
	irq_domain_remove(cdx->msi_domain);
cdx_msi_fail:
	kfree(cdx);
cdx_alloc_fail:
	cdx_mcdi_finish(cdx_mcdi);
mcdi_init_fail:
	kfree(cdx_mcdi);

	return ret;
}

static void xlnx_cdx_remove(struct platform_device *pdev)
{
	struct cdx_controller *cdx = platform_get_drvdata(pdev);
	struct cdx_mcdi *cdx_mcdi = cdx->priv;

	cdx_destroy_rpmsg(pdev);

	irq_domain_remove(cdx->msi_domain);
	kfree(cdx);

	cdx_mcdi_finish(cdx_mcdi);
	kfree(cdx_mcdi);
}

static const struct of_device_id cdx_match_table[] = {
	{.compatible = "xlnx,versal-net-cdx",},
	{ },
};

MODULE_DEVICE_TABLE(of, cdx_match_table);

static struct platform_driver cdx_pdriver = {
	.driver = {
		   .name = "cdx-controller",
		   .of_match_table = cdx_match_table,
		   },
	.probe = xlnx_cdx_probe,
	.remove = xlnx_cdx_remove,
};

module_platform_driver(cdx_pdriver);

MODULE_AUTHOR("AMD Inc.");
MODULE_DESCRIPTION("CDX controller for AMD devices");
MODULE_LICENSE("GPL");
MODULE_IMPORT_NS("CDX_BUS_CONTROLLER");
