// 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;
};

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

struct isst_if_device {
	void __iomem *punit_mmio;
	u32 range_0[5];
	u32 range_1[45];
	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 < 0x04 || io_reg->reg > 0xD0)
		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;

	/*
	 * 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(PCI_VENDOR_ID_INTEL, INTEL_RAPL_PRIO_DEVID_0)},
	{ 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);

	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_MBOX);
	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 +
						mmio_range[0].beg + 4 * i);
	for (i = 0; i < ARRAY_SIZE(punit_dev->range_1); ++i)
		punit_dev->range_1[i] = readl(punit_dev->punit_mmio +
						mmio_range[1].beg + 4 * i);

	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 +
						mmio_range[0].beg + 4 * i);
	for (i = 0; i < ARRAY_SIZE(punit_dev->range_1); ++i)
		writel(punit_dev->range_1[i], punit_dev->punit_mmio +
						mmio_range[1].beg + 4 * i);

	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");
