// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2022-2023 Intel Corporation
 */

/**
 * DOC: MEI_GSC_PROXY Client Driver
 *
 * The mei_gsc_proxy driver acts as a translation layer between
 * proxy user (I915) and ME FW by proxying messages to ME FW
 */

#include <linux/component.h>
#include <linux/mei_cl_bus.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/slab.h>
#include <linux/uuid.h>
#include <drm/drm_connector.h>
#include <drm/i915_component.h>
#include <drm/i915_gsc_proxy_mei_interface.h>

/**
 * mei_gsc_proxy_send - Sends a proxy message to ME FW.
 * @dev: device corresponding to the mei_cl_device
 * @buf: a message buffer to send
 * @size: size of the message
 * Return: bytes sent on Success, <0 on Failure
 */
static int mei_gsc_proxy_send(struct device *dev, const void *buf, size_t size)
{
	ssize_t ret;

	if (!dev || !buf)
		return -EINVAL;

	ret = mei_cldev_send(to_mei_cl_device(dev), buf, size);
	if (ret < 0)
		dev_dbg(dev, "mei_cldev_send failed. %zd\n", ret);

	return ret;
}

/**
 * mei_gsc_proxy_recv - Receives a proxy message from ME FW.
 * @dev: device corresponding to the mei_cl_device
 * @buf: a message buffer to contain the received message
 * @size: size of the buffer
 * Return: bytes received on Success, <0 on Failure
 */
static int mei_gsc_proxy_recv(struct device *dev, void *buf, size_t size)
{
	ssize_t ret;

	if (!dev || !buf)
		return -EINVAL;

	ret = mei_cldev_recv(to_mei_cl_device(dev), buf, size);
	if (ret < 0)
		dev_dbg(dev, "mei_cldev_recv failed. %zd\n", ret);

	return ret;
}

static const struct i915_gsc_proxy_component_ops mei_gsc_proxy_ops = {
	.owner = THIS_MODULE,
	.send = mei_gsc_proxy_send,
	.recv = mei_gsc_proxy_recv,
};

static int mei_component_master_bind(struct device *dev)
{
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	struct i915_gsc_proxy_component *comp_master = mei_cldev_get_drvdata(cldev);

	comp_master->ops = &mei_gsc_proxy_ops;
	comp_master->mei_dev = dev;
	return component_bind_all(dev, comp_master);
}

static void mei_component_master_unbind(struct device *dev)
{
	struct mei_cl_device *cldev = to_mei_cl_device(dev);
	struct i915_gsc_proxy_component *comp_master = mei_cldev_get_drvdata(cldev);

	component_unbind_all(dev, comp_master);
}

static const struct component_master_ops mei_component_master_ops = {
	.bind = mei_component_master_bind,
	.unbind = mei_component_master_unbind,
};

/**
 * mei_gsc_proxy_component_match - compare function for matching mei.
 *
 *    The function checks if the device is pci device and
 *    Intel VGA adapter, the subcomponent is SW Proxy
 *    and the VGA is on the bus 0 reserved for built-in devices
 *    to reject discrete GFX.
 *
 * @dev: master device
 * @subcomponent: subcomponent to match (I915_COMPONENT_SWPROXY)
 * @data: compare data (mei pci parent)
 *
 * Return:
 * * 1 - if components match
 * * 0 - otherwise
 */
static int mei_gsc_proxy_component_match(struct device *dev, int subcomponent,
					 void *data)
{
	struct pci_dev *pdev;

	if (!dev_is_pci(dev))
		return 0;

	pdev = to_pci_dev(dev);

	if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8) ||
	    pdev->vendor != PCI_VENDOR_ID_INTEL)
		return 0;

	if (subcomponent != I915_COMPONENT_GSC_PROXY)
		return 0;

	/* Only built-in GFX */
	return (pdev->bus->number == 0);
}

static int mei_gsc_proxy_probe(struct mei_cl_device *cldev,
			       const struct mei_cl_device_id *id)
{
	struct i915_gsc_proxy_component *comp_master;
	struct component_match *master_match = NULL;
	int ret;

	ret = mei_cldev_enable(cldev);
	if (ret < 0) {
		dev_err(&cldev->dev, "mei_cldev_enable Failed. %d\n", ret);
		goto enable_err_exit;
	}

	comp_master = kzalloc(sizeof(*comp_master), GFP_KERNEL);
	if (!comp_master) {
		ret = -ENOMEM;
		goto err_exit;
	}

	component_match_add_typed(&cldev->dev, &master_match,
				  mei_gsc_proxy_component_match, NULL);
	if (IS_ERR_OR_NULL(master_match)) {
		ret = -ENOMEM;
		goto err_exit;
	}

	mei_cldev_set_drvdata(cldev, comp_master);
	ret = component_master_add_with_match(&cldev->dev,
					      &mei_component_master_ops,
					      master_match);
	if (ret < 0) {
		dev_err(&cldev->dev, "Master comp add failed %d\n", ret);
		goto err_exit;
	}

	return 0;

err_exit:
	mei_cldev_set_drvdata(cldev, NULL);
	kfree(comp_master);
	mei_cldev_disable(cldev);
enable_err_exit:
	return ret;
}

static void mei_gsc_proxy_remove(struct mei_cl_device *cldev)
{
	struct i915_gsc_proxy_component *comp_master = mei_cldev_get_drvdata(cldev);
	int ret;

	component_master_del(&cldev->dev, &mei_component_master_ops);
	kfree(comp_master);
	mei_cldev_set_drvdata(cldev, NULL);

	ret = mei_cldev_disable(cldev);
	if (ret)
		dev_warn(&cldev->dev, "mei_cldev_disable() failed %d\n", ret);
}

#define MEI_UUID_GSC_PROXY UUID_LE(0xf73db04, 0x97ab, 0x4125, \
				   0xb8, 0x93, 0xe9, 0x4, 0xad, 0xd, 0x54, 0x64)

static struct mei_cl_device_id mei_gsc_proxy_tbl[] = {
	{ .uuid = MEI_UUID_GSC_PROXY, .version = MEI_CL_VERSION_ANY },
	{ }
};
MODULE_DEVICE_TABLE(mei, mei_gsc_proxy_tbl);

static struct mei_cl_driver mei_gsc_proxy_driver = {
	.id_table = mei_gsc_proxy_tbl,
	.name = KBUILD_MODNAME,
	.probe = mei_gsc_proxy_probe,
	.remove	= mei_gsc_proxy_remove,
};

module_mei_cl_driver(mei_gsc_proxy_driver);

MODULE_AUTHOR("Intel Corporation");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("MEI GSC PROXY");
