// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright (C) 2020-21 Intel Corporation.
 */

#include <linux/acpi.h>
#include <linux/bitfield.h>
#include <linux/module.h>
#include <net/rtnetlink.h>

#include "iosm_ipc_imem.h"
#include "iosm_ipc_pcie.h"
#include "iosm_ipc_protocol.h"

MODULE_DESCRIPTION("IOSM Driver");
MODULE_LICENSE("GPL v2");

/* WWAN GUID */
static guid_t wwan_acpi_guid = GUID_INIT(0xbad01b75, 0x22a8, 0x4f48, 0x87, 0x92,
				       0xbd, 0xde, 0x94, 0x67, 0x74, 0x7d);

static void ipc_pcie_resources_release(struct iosm_pcie *ipc_pcie)
{
	/* Free the MSI resources. */
	ipc_release_irq(ipc_pcie);

	/* Free mapped doorbell scratchpad bus memory into CPU space. */
	iounmap(ipc_pcie->scratchpad);

	/* Free mapped IPC_REGS bus memory into CPU space. */
	iounmap(ipc_pcie->ipc_regs);

	/* Releases all PCI I/O and memory resources previously reserved by a
	 * successful call to pci_request_regions.  Call this function only
	 * after all use of the PCI regions has ceased.
	 */
	pci_release_regions(ipc_pcie->pci);
}

static void ipc_pcie_cleanup(struct iosm_pcie *ipc_pcie)
{
	/* Free the shared memory resources. */
	ipc_imem_cleanup(ipc_pcie->imem);

	ipc_pcie_resources_release(ipc_pcie);

	/* Signal to the system that the PCI device is not in use. */
	pci_disable_device(ipc_pcie->pci);
}

static void ipc_pcie_deinit(struct iosm_pcie *ipc_pcie)
{
	kfree(ipc_pcie->imem);
	kfree(ipc_pcie);
}

static void ipc_pcie_remove(struct pci_dev *pci)
{
	struct iosm_pcie *ipc_pcie = pci_get_drvdata(pci);

	ipc_pcie_cleanup(ipc_pcie);

	ipc_pcie_deinit(ipc_pcie);
}

static int ipc_pcie_resources_request(struct iosm_pcie *ipc_pcie)
{
	struct pci_dev *pci = ipc_pcie->pci;
	u32 cap = 0;
	u32 ret;

	/* Reserved PCI I/O and memory resources.
	 * Mark all PCI regions associated with PCI device pci as
	 * being reserved by owner IOSM_IPC.
	 */
	ret = pci_request_regions(pci, "IOSM_IPC");
	if (ret) {
		dev_err(ipc_pcie->dev, "failed pci request regions");
		goto pci_request_region_fail;
	}

	/* Reserve the doorbell IPC REGS memory resources.
	 * Remap the memory into CPU space. Arrange for the physical address
	 * (BAR) to be visible from this driver.
	 * pci_ioremap_bar() ensures that the memory is marked uncachable.
	 */
	ipc_pcie->ipc_regs = pci_ioremap_bar(pci, ipc_pcie->ipc_regs_bar_nr);

	if (!ipc_pcie->ipc_regs) {
		dev_err(ipc_pcie->dev, "IPC REGS ioremap error");
		ret = -EBUSY;
		goto ipc_regs_remap_fail;
	}

	/* Reserve the MMIO scratchpad memory resources.
	 * Remap the memory into CPU space. Arrange for the physical address
	 * (BAR) to be visible from this driver.
	 * pci_ioremap_bar() ensures that the memory is marked uncachable.
	 */
	ipc_pcie->scratchpad =
		pci_ioremap_bar(pci, ipc_pcie->scratchpad_bar_nr);

	if (!ipc_pcie->scratchpad) {
		dev_err(ipc_pcie->dev, "doorbell scratchpad ioremap error");
		ret = -EBUSY;
		goto scratch_remap_fail;
	}

	/* Install the irq handler triggered by CP. */
	ret = ipc_acquire_irq(ipc_pcie);
	if (ret) {
		dev_err(ipc_pcie->dev, "acquiring MSI irq failed!");
		goto irq_acquire_fail;
	}

	/* Enable bus-mastering for the IOSM IPC device. */
	pci_set_master(pci);

	/* Enable LTR if possible
	 * This is needed for L1.2!
	 */
	pcie_capability_read_dword(ipc_pcie->pci, PCI_EXP_DEVCAP2, &cap);
	if (cap & PCI_EXP_DEVCAP2_LTR)
		pcie_capability_set_word(ipc_pcie->pci, PCI_EXP_DEVCTL2,
					 PCI_EXP_DEVCTL2_LTR_EN);

	dev_dbg(ipc_pcie->dev, "link between AP and CP is fully on");

	return ret;

irq_acquire_fail:
	iounmap(ipc_pcie->scratchpad);
scratch_remap_fail:
	iounmap(ipc_pcie->ipc_regs);
ipc_regs_remap_fail:
	pci_release_regions(pci);
pci_request_region_fail:
	return ret;
}

bool ipc_pcie_check_aspm_enabled(struct iosm_pcie *ipc_pcie,
				 bool parent)
{
	struct pci_dev *pdev;
	u16 value = 0;
	u32 enabled;

	if (parent)
		pdev = ipc_pcie->pci->bus->self;
	else
		pdev = ipc_pcie->pci;

	pcie_capability_read_word(pdev, PCI_EXP_LNKCTL, &value);
	enabled = value & PCI_EXP_LNKCTL_ASPMC;
	dev_dbg(ipc_pcie->dev, "ASPM L1: 0x%04X 0x%03X", pdev->device, value);

	return (enabled == PCI_EXP_LNKCTL_ASPM_L1 ||
		enabled == PCI_EXP_LNKCTL_ASPMC);
}

bool ipc_pcie_check_data_link_active(struct iosm_pcie *ipc_pcie)
{
	struct pci_dev *parent;
	u16 link_status = 0;

	if (!ipc_pcie->pci->bus || !ipc_pcie->pci->bus->self) {
		dev_err(ipc_pcie->dev, "root port not found");
		return false;
	}

	parent = ipc_pcie->pci->bus->self;

	pcie_capability_read_word(parent, PCI_EXP_LNKSTA, &link_status);
	dev_dbg(ipc_pcie->dev, "Link status: 0x%04X", link_status);

	return link_status & PCI_EXP_LNKSTA_DLLLA;
}

static bool ipc_pcie_check_aspm_supported(struct iosm_pcie *ipc_pcie,
					  bool parent)
{
	struct pci_dev *pdev;
	u32 support;
	u32 cap = 0;

	if (parent)
		pdev = ipc_pcie->pci->bus->self;
	else
		pdev = ipc_pcie->pci;
	pcie_capability_read_dword(pdev, PCI_EXP_LNKCAP, &cap);
	support = u32_get_bits(cap, PCI_EXP_LNKCAP_ASPMS);
	if (support < PCI_EXP_LNKCTL_ASPM_L1) {
		dev_dbg(ipc_pcie->dev, "ASPM L1 not supported: 0x%04X",
			pdev->device);
		return false;
	}
	return true;
}

void ipc_pcie_config_aspm(struct iosm_pcie *ipc_pcie)
{
	bool parent_aspm_enabled, dev_aspm_enabled;

	/* check if both root port and child supports ASPM L1 */
	if (!ipc_pcie_check_aspm_supported(ipc_pcie, true) ||
	    !ipc_pcie_check_aspm_supported(ipc_pcie, false))
		return;

	parent_aspm_enabled = ipc_pcie_check_aspm_enabled(ipc_pcie, true);
	dev_aspm_enabled = ipc_pcie_check_aspm_enabled(ipc_pcie, false);

	dev_dbg(ipc_pcie->dev, "ASPM parent: %s device: %s",
		parent_aspm_enabled ? "Enabled" : "Disabled",
		dev_aspm_enabled ? "Enabled" : "Disabled");
}

/* Initializes PCIe endpoint configuration */
static void ipc_pcie_config_init(struct iosm_pcie *ipc_pcie)
{
	/* BAR0 is used for doorbell */
	ipc_pcie->ipc_regs_bar_nr = IPC_DOORBELL_BAR0;

	/* update HW configuration */
	ipc_pcie->scratchpad_bar_nr = IPC_SCRATCHPAD_BAR2;
	ipc_pcie->doorbell_reg_offset = IPC_DOORBELL_CH_OFFSET;
	ipc_pcie->doorbell_write = IPC_WRITE_PTR_REG_0;
	ipc_pcie->doorbell_capture = IPC_CAPTURE_PTR_REG_0;
}

/* This will read the BIOS WWAN RTD3 settings:
 * D0L1.2/D3L2/Disabled
 */
static enum ipc_pcie_sleep_state ipc_pcie_read_bios_cfg(struct device *dev)
{
	enum ipc_pcie_sleep_state sleep_state = IPC_PCIE_D0L12;
	union acpi_object *object;
	acpi_handle handle_acpi;

	handle_acpi = ACPI_HANDLE(dev);
	if (!handle_acpi) {
		pr_debug("pci device is NOT ACPI supporting device\n");
		goto default_ret;
	}

	object = acpi_evaluate_dsm(handle_acpi, &wwan_acpi_guid, 0, 3, NULL);
	if (!object)
		goto default_ret;

	if (object->integer.value == 3)
		sleep_state = IPC_PCIE_D3L2;

	ACPI_FREE(object);

default_ret:
	return sleep_state;
}

static int ipc_pcie_probe(struct pci_dev *pci,
			  const struct pci_device_id *pci_id)
{
	struct iosm_pcie *ipc_pcie = kzalloc(sizeof(*ipc_pcie), GFP_KERNEL);
	int ret;

	pr_debug("Probing device 0x%X from the vendor 0x%X", pci_id->device,
		 pci_id->vendor);

	if (!ipc_pcie)
		goto ret_fail;

	/* Initialize ipc dbg component for the PCIe device */
	ipc_pcie->dev = &pci->dev;

	/* Set the driver specific data. */
	pci_set_drvdata(pci, ipc_pcie);

	/* Save the address of the PCI device configuration. */
	ipc_pcie->pci = pci;

	/* Update platform configuration */
	ipc_pcie_config_init(ipc_pcie);

	/* Initialize the device before it is used. Ask low-level code
	 * to enable I/O and memory. Wake up the device if it was suspended.
	 */
	if (pci_enable_device(pci)) {
		dev_err(ipc_pcie->dev, "failed to enable the AP PCIe device");
		/* If enable of PCIe device has failed then calling
		 * ipc_pcie_cleanup will panic the system. More over
		 * ipc_pcie_cleanup() is required to be called after
		 * ipc_imem_mount()
		 */
		goto pci_enable_fail;
	}

	ret = dma_set_mask(ipc_pcie->dev, DMA_BIT_MASK(64));
	if (ret) {
		dev_err(ipc_pcie->dev, "Could not set PCI DMA mask: %d", ret);
		goto set_mask_fail;
	}

	ipc_pcie_config_aspm(ipc_pcie);
	dev_dbg(ipc_pcie->dev, "PCIe device enabled.");

	/* Read WWAN RTD3 BIOS Setting
	 */
	ipc_pcie->d3l2_support = ipc_pcie_read_bios_cfg(&pci->dev);

	ipc_pcie->suspend = 0;

	if (ipc_pcie_resources_request(ipc_pcie))
		goto resources_req_fail;

	/* Establish the link to the imem layer. */
	ipc_pcie->imem = ipc_imem_init(ipc_pcie, pci->device,
				       ipc_pcie->scratchpad, ipc_pcie->dev);
	if (!ipc_pcie->imem) {
		dev_err(ipc_pcie->dev, "failed to init imem");
		goto imem_init_fail;
	}

	return 0;

imem_init_fail:
	ipc_pcie_resources_release(ipc_pcie);
resources_req_fail:
set_mask_fail:
	pci_disable_device(pci);
pci_enable_fail:
	kfree(ipc_pcie);
ret_fail:
	return -EIO;
}

static const struct pci_device_id iosm_ipc_ids[] = {
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_CP_DEVICE_7560_ID) },
	{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, INTEL_CP_DEVICE_7360_ID) },
	{}
};
MODULE_DEVICE_TABLE(pci, iosm_ipc_ids);

/* Enter sleep in s2idle case
 */
static int __maybe_unused ipc_pcie_suspend_s2idle(struct iosm_pcie *ipc_pcie)
{
	ipc_cp_irq_sleep_control(ipc_pcie, IPC_MEM_DEV_PM_FORCE_SLEEP);

	/* Complete all memory stores before setting bit */
	smp_mb__before_atomic();

	set_bit(0, &ipc_pcie->suspend);

	/* Complete all memory stores after setting bit */
	smp_mb__after_atomic();

	ipc_imem_pm_s2idle_sleep(ipc_pcie->imem, true);

	return 0;
}

/* Resume from sleep in s2idle case
 */
static int __maybe_unused ipc_pcie_resume_s2idle(struct iosm_pcie *ipc_pcie)
{
	ipc_cp_irq_sleep_control(ipc_pcie, IPC_MEM_DEV_PM_FORCE_ACTIVE);

	ipc_imem_pm_s2idle_sleep(ipc_pcie->imem, false);

	/* Complete all memory stores before clearing bit. */
	smp_mb__before_atomic();

	clear_bit(0, &ipc_pcie->suspend);

	/* Complete all memory stores after clearing bit. */
	smp_mb__after_atomic();
	return 0;
}

int __maybe_unused ipc_pcie_suspend(struct iosm_pcie *ipc_pcie)
{
	/* The HAL shall ask the shared memory layer whether D3 is allowed. */
	ipc_imem_pm_suspend(ipc_pcie->imem);

	dev_dbg(ipc_pcie->dev, "SUSPEND done");
	return 0;
}

int __maybe_unused ipc_pcie_resume(struct iosm_pcie *ipc_pcie)
{
	/* The HAL shall inform the shared memory layer that the device is
	 * active.
	 */
	ipc_imem_pm_resume(ipc_pcie->imem);

	dev_dbg(ipc_pcie->dev, "RESUME done");
	return 0;
}

static int __maybe_unused ipc_pcie_suspend_cb(struct device *dev)
{
	struct iosm_pcie *ipc_pcie;
	struct pci_dev *pdev;

	pdev = to_pci_dev(dev);

	ipc_pcie = pci_get_drvdata(pdev);

	switch (ipc_pcie->d3l2_support) {
	case IPC_PCIE_D0L12:
		ipc_pcie_suspend_s2idle(ipc_pcie);
		break;
	case IPC_PCIE_D3L2:
		ipc_pcie_suspend(ipc_pcie);
		break;
	}

	return 0;
}

static int __maybe_unused ipc_pcie_resume_cb(struct device *dev)
{
	struct iosm_pcie *ipc_pcie;
	struct pci_dev *pdev;

	pdev = to_pci_dev(dev);

	ipc_pcie = pci_get_drvdata(pdev);

	switch (ipc_pcie->d3l2_support) {
	case IPC_PCIE_D0L12:
		ipc_pcie_resume_s2idle(ipc_pcie);
		break;
	case IPC_PCIE_D3L2:
		ipc_pcie_resume(ipc_pcie);
		break;
	}

	return 0;
}

static SIMPLE_DEV_PM_OPS(iosm_ipc_pm, ipc_pcie_suspend_cb, ipc_pcie_resume_cb);

static struct pci_driver iosm_ipc_driver = {
	.name = KBUILD_MODNAME,
	.probe = ipc_pcie_probe,
	.remove = ipc_pcie_remove,
	.driver = {
		.pm = &iosm_ipc_pm,
	},
	.id_table = iosm_ipc_ids,
};
module_pci_driver(iosm_ipc_driver);

int ipc_pcie_addr_map(struct iosm_pcie *ipc_pcie, unsigned char *data,
		      size_t size, dma_addr_t *mapping, int direction)
{
	if (ipc_pcie->pci) {
		*mapping = dma_map_single(&ipc_pcie->pci->dev, data, size,
					  direction);
		if (dma_mapping_error(&ipc_pcie->pci->dev, *mapping)) {
			dev_err(ipc_pcie->dev, "dma mapping failed");
			return -EINVAL;
		}
	}
	return 0;
}

void ipc_pcie_addr_unmap(struct iosm_pcie *ipc_pcie, size_t size,
			 dma_addr_t mapping, int direction)
{
	if (!mapping)
		return;
	if (ipc_pcie->pci)
		dma_unmap_single(&ipc_pcie->pci->dev, mapping, size, direction);
}

struct sk_buff *ipc_pcie_alloc_local_skb(struct iosm_pcie *ipc_pcie,
					 gfp_t flags, size_t size)
{
	struct sk_buff *skb;

	if (!ipc_pcie || !size) {
		pr_err("invalid pcie object or size");
		return NULL;
	}

	skb = __netdev_alloc_skb(NULL, size, flags);
	if (!skb)
		return NULL;

	IPC_CB(skb)->op_type = (u8)UL_DEFAULT;
	IPC_CB(skb)->mapping = 0;

	return skb;
}

struct sk_buff *ipc_pcie_alloc_skb(struct iosm_pcie *ipc_pcie, size_t size,
				   gfp_t flags, dma_addr_t *mapping,
				   int direction, size_t headroom)
{
	struct sk_buff *skb = ipc_pcie_alloc_local_skb(ipc_pcie, flags,
						       size + headroom);
	if (!skb)
		return NULL;

	if (headroom)
		skb_reserve(skb, headroom);

	if (ipc_pcie_addr_map(ipc_pcie, skb->data, size, mapping, direction)) {
		dev_kfree_skb(skb);
		return NULL;
	}

	BUILD_BUG_ON(sizeof(*IPC_CB(skb)) > sizeof(skb->cb));

	/* Store the mapping address in skb scratch pad for later usage */
	IPC_CB(skb)->mapping = *mapping;
	IPC_CB(skb)->direction = direction;
	IPC_CB(skb)->len = size;

	return skb;
}

void ipc_pcie_kfree_skb(struct iosm_pcie *ipc_pcie, struct sk_buff *skb)
{
	if (!skb)
		return;

	ipc_pcie_addr_unmap(ipc_pcie, IPC_CB(skb)->len, IPC_CB(skb)->mapping,
			    IPC_CB(skb)->direction);
	IPC_CB(skb)->mapping = 0;
	dev_kfree_skb(skb);
}
