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

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