// SPDX-License-Identifier: GPL-2.0
/*
 * Intel Speed Select Interface: MMIO Interface
 * Copyright (c) 2019, Intel Corporation.
 * All rights reserved.
 *
 * Author: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>
 */

#include <linux/module.h>
#include <linux/pci.h>
#include <linux/sched/signal.h>
#include <linux/uaccess.h>
#include <uapi/linux/isst_if.h>

#include "isst_if_common.h"

struct isst_mmio_range {
	int beg;
	int end;
};

static struct isst_mmio_range mmio_range_devid_0[] = {
	{0x04, 0x14},
	{0x20, 0xD0},
};

static struct isst_mmio_range mmio_range_devid_1[] = {
	{0x04, 0x14},
	{0x20, 0x11C},
};

struct isst_if_device {
	void __iomem *punit_mmio;
	u32 range_0[5];
	u32 range_1[64];
	struct isst_mmio_range *mmio_range;
	struct mutex mutex;
};

static long isst_if_mmio_rd_wr(u8 *cmd_ptr, int *write_only, int resume)
{
	struct isst_if_device *punit_dev;
	struct isst_if_io_reg *io_reg;
	struct pci_dev *pdev;

	io_reg = (struct isst_if_io_reg *)cmd_ptr;

	if (io_reg->reg % 4)
		return -EINVAL;

	if (io_reg->read_write && !capable(CAP_SYS_ADMIN))
		return -EPERM;

	pdev = isst_if_get_pci_dev(io_reg->logical_cpu, 0, 0, 1);
	if (!pdev)
		return -EINVAL;

	punit_dev = pci_get_drvdata(pdev);
	if (!punit_dev)
		return -EINVAL;

	if (io_reg->reg < punit_dev->mmio_range[0].beg ||
	    io_reg->reg > punit_dev->mmio_range[1].end)
		return -EINVAL;

	/*
	 * Ensure that operation is complete on a PCI device to avoid read
	 * write race by using per PCI device mutex.
	 */
	mutex_lock(&punit_dev->mutex);
	if (io_reg->read_write) {
		writel(io_reg->value, punit_dev->punit_mmio+io_reg->reg);
		*write_only = 1;
	} else {
		io_reg->value = readl(punit_dev->punit_mmio+io_reg->reg);
		*write_only = 0;
	}
	mutex_unlock(&punit_dev->mutex);

	return 0;
}

static const struct pci_device_id isst_if_ids[] = {
	{ PCI_DEVICE_DATA(INTEL, RAPL_PRIO_DEVID_0, &mmio_range_devid_0)},
	{ PCI_DEVICE_DATA(INTEL, RAPL_PRIO_DEVID_1, &mmio_range_devid_1)},
	{ 0 },
};
MODULE_DEVICE_TABLE(pci, isst_if_ids);

static int isst_if_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
	struct isst_if_device *punit_dev;
	struct isst_if_cmd_cb cb;
	u32 mmio_base, pcu_base;
	u64 base_addr;
	int ret;

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

	ret = pcim_enable_device(pdev);
	if (ret)
		return ret;

	ret = pci_read_config_dword(pdev, 0xD0, &mmio_base);
	if (ret)
		return ret;

	ret = pci_read_config_dword(pdev, 0xFC, &pcu_base);
	if (ret)
		return ret;

	pcu_base &= GENMASK(10, 0);
	base_addr = (u64)mmio_base << 23 | (u64) pcu_base << 12;
	punit_dev->punit_mmio = devm_ioremap(&pdev->dev, base_addr, 256);
	if (!punit_dev->punit_mmio)
		return -ENOMEM;

	mutex_init(&punit_dev->mutex);
	pci_set_drvdata(pdev, punit_dev);
	punit_dev->mmio_range = (struct isst_mmio_range *) ent->driver_data;

	memset(&cb, 0, sizeof(cb));
	cb.cmd_size = sizeof(struct isst_if_io_reg);
	cb.offset = offsetof(struct isst_if_io_regs, io_reg);
	cb.cmd_callback = isst_if_mmio_rd_wr;
	cb.owner = THIS_MODULE;
	ret = isst_if_cdev_register(ISST_IF_DEV_MMIO, &cb);
	if (ret)
		mutex_destroy(&punit_dev->mutex);

	return ret;
}

static void isst_if_remove(struct pci_dev *pdev)
{
	struct isst_if_device *punit_dev;

	punit_dev = pci_get_drvdata(pdev);
	isst_if_cdev_unregister(ISST_IF_DEV_MMIO);
	mutex_destroy(&punit_dev->mutex);
}

static int __maybe_unused isst_if_suspend(struct device *device)
{
	struct isst_if_device *punit_dev = dev_get_drvdata(device);
	int i;

	for (i = 0; i < ARRAY_SIZE(punit_dev->range_0); ++i)
		punit_dev->range_0[i] = readl(punit_dev->punit_mmio +
						punit_dev->mmio_range[0].beg + 4 * i);
	for (i = 0; i < ARRAY_SIZE(punit_dev->range_1); ++i) {
		u32 addr;

		addr = punit_dev->mmio_range[1].beg + 4 * i;
		if (addr > punit_dev->mmio_range[1].end)
			break;
		punit_dev->range_1[i] = readl(punit_dev->punit_mmio + addr);
	}

	return 0;
}

static int __maybe_unused isst_if_resume(struct device *device)
{
	struct isst_if_device *punit_dev = dev_get_drvdata(device);
	int i;

	for (i = 0; i < ARRAY_SIZE(punit_dev->range_0); ++i)
		writel(punit_dev->range_0[i], punit_dev->punit_mmio +
						punit_dev->mmio_range[0].beg + 4 * i);
	for (i = 0; i < ARRAY_SIZE(punit_dev->range_1); ++i) {
		u32 addr;

		addr = punit_dev->mmio_range[1].beg + 4 * i;
		if (addr > punit_dev->mmio_range[1].end)
			break;

		writel(punit_dev->range_1[i], punit_dev->punit_mmio + addr);
	}

	return 0;
}

static SIMPLE_DEV_PM_OPS(isst_if_pm_ops, isst_if_suspend, isst_if_resume);

static struct pci_driver isst_if_pci_driver = {
	.name			= "isst_if_pci",
	.id_table		= isst_if_ids,
	.probe			= isst_if_probe,
	.remove			= isst_if_remove,
	.driver.pm		= &isst_if_pm_ops,
};

module_pci_driver(isst_if_pci_driver);

MODULE_LICENSE("GPL v2");
MODULE_DESCRIPTION("Intel speed select interface mmio driver");
