// SPDX-License-Identifier: GPL-2.0-or-later
/*******************************************************************************
 *
 * CTU CAN FD IP Core
 *
 * Copyright (C) 2015-2018 Ondrej Ille <ondrej.ille@gmail.com> FEE CTU
 * Copyright (C) 2018-2021 Ondrej Ille <ondrej.ille@gmail.com> self-funded
 * Copyright (C) 2018-2019 Martin Jerabek <martin.jerabek01@gmail.com> FEE CTU
 * Copyright (C) 2018-2022 Pavel Pisa <pisa@cmp.felk.cvut.cz> FEE CTU/self-funded
 *
 * Project advisors:
 *     Jiri Novak <jnovak@fel.cvut.cz>
 *     Pavel Pisa <pisa@cmp.felk.cvut.cz>
 *
 * Department of Measurement         (http://meas.fel.cvut.cz/)
 * Faculty of Electrical Engineering (http://www.fel.cvut.cz)
 * Czech Technical University        (http://www.cvut.cz/)
 ******************************************************************************/

#include <linux/module.h>
#include <linux/pci.h>

#include "ctucanfd.h"

#ifndef PCI_DEVICE_DATA
#define PCI_DEVICE_DATA(vend, dev, data) \
.vendor = PCI_VENDOR_ID_##vend, \
.device = PCI_DEVICE_ID_##vend##_##dev, \
.subvendor = PCI_ANY_ID, .subdevice = PCI_ANY_ID, 0, 0, \
.driver_data = (kernel_ulong_t)(data)
#endif

#ifndef PCI_VENDOR_ID_TEDIA
#define PCI_VENDOR_ID_TEDIA 0x1760
#endif

#ifndef PCI_DEVICE_ID_TEDIA_CTUCAN_VER21
#define PCI_DEVICE_ID_TEDIA_CTUCAN_VER21 0xff00
#endif

#define CTUCAN_BAR0_CTUCAN_ID 0x0000
#define CTUCAN_BAR0_CRA_BASE  0x4000
#define CYCLONE_IV_CRA_A2P_IE (0x0050)

#define CTUCAN_WITHOUT_CTUCAN_ID  0
#define CTUCAN_WITH_CTUCAN_ID     1

struct ctucan_pci_board_data {
	void __iomem *bar0_base;
	void __iomem *cra_base;
	void __iomem *bar1_base;
	struct list_head ndev_list_head;
	int use_msi;
};

static struct ctucan_pci_board_data *ctucan_pci_get_bdata(struct pci_dev *pdev)
{
	return (struct ctucan_pci_board_data *)pci_get_drvdata(pdev);
}

static void ctucan_pci_set_drvdata(struct device *dev,
				   struct net_device *ndev)
{
	struct pci_dev *pdev = container_of(dev, struct pci_dev, dev);
	struct ctucan_priv *priv = netdev_priv(ndev);
	struct ctucan_pci_board_data *bdata = ctucan_pci_get_bdata(pdev);

	list_add(&priv->peers_on_pdev, &bdata->ndev_list_head);
	priv->irq_flags = IRQF_SHARED;
}

/**
 * ctucan_pci_probe - PCI registration call
 * @pdev:	Handle to the pci device structure
 * @ent:	Pointer to the entry from ctucan_pci_tbl
 *
 * This function does all the memory allocation and registration for the CAN
 * device.
 *
 * Return: 0 on success and failure value on error
 */
static int ctucan_pci_probe(struct pci_dev *pdev,
			    const struct pci_device_id *ent)
{
	struct device	*dev = &pdev->dev;
	unsigned long driver_data = ent->driver_data;
	struct ctucan_pci_board_data *bdata;
	void __iomem *addr;
	void __iomem *cra_addr;
	void __iomem *bar0_base;
	u32 cra_a2p_ie;
	u32 ctucan_id = 0;
	int ret;
	unsigned int ntxbufs;
	unsigned int num_cores = 1;
	unsigned int core_i = 0;
	int irq;
	int msi_ok = 0;

	ret = pci_enable_device(pdev);
	if (ret) {
		dev_err(dev, "pci_enable_device FAILED\n");
		goto err;
	}

	ret = pci_request_regions(pdev, KBUILD_MODNAME);
	if (ret) {
		dev_err(dev, "pci_request_regions FAILED\n");
		goto err_disable_device;
	}

	ret = pci_enable_msi(pdev);
	if (!ret) {
		dev_info(dev, "MSI enabled\n");
		pci_set_master(pdev);
		msi_ok = 1;
	}

	dev_info(dev, "ctucan BAR0 0x%08llx 0x%08llx\n",
		 (long long)pci_resource_start(pdev, 0),
		 (long long)pci_resource_len(pdev, 0));

	dev_info(dev, "ctucan BAR1 0x%08llx 0x%08llx\n",
		 (long long)pci_resource_start(pdev, 1),
		 (long long)pci_resource_len(pdev, 1));

	addr = pci_iomap(pdev, 1, pci_resource_len(pdev, 1));
	if (!addr) {
		dev_err(dev, "PCI BAR 1 cannot be mapped\n");
		ret = -ENOMEM;
		goto err_release_regions;
	}

	/* Cyclone IV PCI Express Control Registers Area */
	bar0_base = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
	if (!bar0_base) {
		dev_err(dev, "PCI BAR 0 cannot be mapped\n");
		ret = -EIO;
		goto err_pci_iounmap_bar1;
	}

	if (driver_data == CTUCAN_WITHOUT_CTUCAN_ID) {
		cra_addr = bar0_base;
		num_cores = 2;
	} else {
		cra_addr = bar0_base + CTUCAN_BAR0_CRA_BASE;
		ctucan_id = ioread32(bar0_base + CTUCAN_BAR0_CTUCAN_ID);
		dev_info(dev, "ctucan_id 0x%08lx\n", (unsigned long)ctucan_id);
		num_cores = ctucan_id & 0xf;
	}

	irq = pdev->irq;

	ntxbufs = 4;

	bdata = kzalloc(sizeof(*bdata), GFP_KERNEL);
	if (!bdata) {
		ret = -ENOMEM;
		goto err_pci_iounmap_bar0;
	}

	INIT_LIST_HEAD(&bdata->ndev_list_head);
	bdata->bar0_base = bar0_base;
	bdata->cra_base = cra_addr;
	bdata->bar1_base = addr;
	bdata->use_msi = msi_ok;

	pci_set_drvdata(pdev, bdata);

	ret = ctucan_probe_common(dev, addr, irq, ntxbufs, 100000000,
				  0, ctucan_pci_set_drvdata);
	if (ret < 0)
		goto err_free_board;

	core_i++;

	while (core_i < num_cores) {
		addr += 0x4000;
		ret = ctucan_probe_common(dev, addr, irq, ntxbufs, 100000000,
					  0, ctucan_pci_set_drvdata);
		if (ret < 0) {
			dev_info(dev, "CTU CAN FD core %d initialization failed\n",
				 core_i);
			break;
		}
		core_i++;
	}

	/* enable interrupt in
	 * Avalon-MM to PCI Express Interrupt Enable Register
	 */
	cra_a2p_ie = ioread32(cra_addr + CYCLONE_IV_CRA_A2P_IE);
	dev_info(dev, "cra_a2p_ie 0x%08x\n", cra_a2p_ie);
	cra_a2p_ie |= 1;
	iowrite32(cra_a2p_ie, cra_addr + CYCLONE_IV_CRA_A2P_IE);
	cra_a2p_ie = ioread32(cra_addr + CYCLONE_IV_CRA_A2P_IE);
	dev_info(dev, "cra_a2p_ie 0x%08x\n", cra_a2p_ie);

	return 0;

err_free_board:
	pci_set_drvdata(pdev, NULL);
	kfree(bdata);
err_pci_iounmap_bar0:
	pci_iounmap(pdev, cra_addr);
err_pci_iounmap_bar1:
	pci_iounmap(pdev, addr);
err_release_regions:
	if (msi_ok)
		pci_disable_msi(pdev);
	pci_release_regions(pdev);
err_disable_device:
	pci_disable_device(pdev);
err:
	return ret;
}

/**
 * ctucan_pci_remove - Unregister the device after releasing the resources
 * @pdev:	Handle to the pci device structure
 *
 * This function frees all the resources allocated to the device.
 * Return: 0 always
 */
static void ctucan_pci_remove(struct pci_dev *pdev)
{
	struct net_device *ndev;
	struct ctucan_priv *priv = NULL;
	struct ctucan_pci_board_data *bdata = ctucan_pci_get_bdata(pdev);

	dev_dbg(&pdev->dev, "ctucan_remove");

	if (!bdata) {
		dev_err(&pdev->dev, "%s: no list of devices\n", __func__);
		return;
	}

	/* disable interrupt in
	 * Avalon-MM to PCI Express Interrupt Enable Register
	 */
	if (bdata->cra_base)
		iowrite32(0, bdata->cra_base + CYCLONE_IV_CRA_A2P_IE);

	while ((priv = list_first_entry_or_null(&bdata->ndev_list_head, struct ctucan_priv,
						peers_on_pdev)) != NULL) {
		ndev = priv->can.dev;

		unregister_candev(ndev);

		netif_napi_del(&priv->napi);

		list_del_init(&priv->peers_on_pdev);
		free_candev(ndev);
	}

	pci_iounmap(pdev, bdata->bar1_base);

	if (bdata->use_msi)
		pci_disable_msi(pdev);

	pci_release_regions(pdev);
	pci_disable_device(pdev);

	pci_iounmap(pdev, bdata->bar0_base);

	pci_set_drvdata(pdev, NULL);
	kfree(bdata);
}

static SIMPLE_DEV_PM_OPS(ctucan_pci_pm_ops, ctucan_suspend, ctucan_resume);

static const struct pci_device_id ctucan_pci_tbl[] = {
	{PCI_DEVICE_DATA(TEDIA, CTUCAN_VER21,
		CTUCAN_WITH_CTUCAN_ID)},
	{},
};

static struct pci_driver ctucan_pci_driver = {
	.name = KBUILD_MODNAME,
	.id_table = ctucan_pci_tbl,
	.probe = ctucan_pci_probe,
	.remove = ctucan_pci_remove,
	.driver.pm = &ctucan_pci_pm_ops,
};

module_pci_driver(ctucan_pci_driver);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Pavel Pisa <pisa@cmp.felk.cvut.cz>");
MODULE_DESCRIPTION("CTU CAN FD for PCI bus");
