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

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

	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:
	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) },
	{}
};
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)
{
	struct pci_dev *pdev;
	int ret;

	pdev = ipc_pcie->pci;

	/* Execute D3 one time. */
	if (pdev->current_state != PCI_D0) {
		dev_dbg(ipc_pcie->dev, "done for PM=%d", pdev->current_state);
		return 0;
	}

	/* The HAL shall ask the shared memory layer whether D3 is allowed. */
	ipc_imem_pm_suspend(ipc_pcie->imem);

	/* Save the PCI configuration space of a device before suspending. */
	ret = pci_save_state(pdev);

	if (ret) {
		dev_err(ipc_pcie->dev, "pci_save_state error=%d", ret);
		return ret;
	}

	/* Set the power state of a PCI device.
	 * Transition a device to a new power state, using the device's PCI PM
	 * registers.
	 */
	ret = pci_set_power_state(pdev, PCI_D3cold);

	if (ret) {
		dev_err(ipc_pcie->dev, "pci_set_power_state error=%d", ret);
		return ret;
	}

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

int __maybe_unused ipc_pcie_resume(struct iosm_pcie *ipc_pcie)
{
	int ret;

	/* Set the power state of a PCI device.
	 * Transition a device to a new power state, using the device's PCI PM
	 * registers.
	 */
	ret = pci_set_power_state(ipc_pcie->pci, PCI_D0);

	if (ret) {
		dev_err(ipc_pcie->dev, "pci_set_power_state error=%d", ret);
		return ret;
	}

	pci_restore_state(ipc_pcie->pci);

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

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