// SPDX-License-Identifier: GPL-2.0-only
/*
 * This is the driver for the MGB4 video grabber card by Digiteq Automotive.
 *
 * Copyright (C) 2021-2023 Digiteq Automotive
 *     author: Martin Tuma <martin.tuma@digiteqautomotive.com>
 *
 * This is the main driver module. The DMA, I2C and SPI sub-drivers are
 * initialized here and the input/output v4l2 devices are created.
 *
 * The mgb4 card uses different expansion modules for different video sources
 * (GMSL and FPDL3 for now) so in probe() we detect the module type based on
 * what we see on the I2C bus and check if it matches the FPGA bitstream (there
 * are different bitstreams for different expansion modules). When no expansion
 * module is present, we still let the driver initialize to allow flashing of
 * the FPGA firmware using the SPI FLASH device. No v4l2 video devices are
 * created in this case.
 */

#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/dma/amd_xdma.h>
#include <linux/platform_data/amd_xdma.h>
#include <linux/spi/xilinx_spi.h>
#include <linux/mtd/mtd.h>
#include <linux/hwmon.h>
#include <linux/debugfs.h>
#include "mgb4_dma.h"
#include "mgb4_i2c.h"
#include "mgb4_sysfs.h"
#include "mgb4_vout.h"
#include "mgb4_vin.h"
#include "mgb4_trigger.h"
#include "mgb4_core.h"

#define MGB4_USER_IRQS 16

#define DIGITEQ_VID 0x1ed8
#define T100_DID    0x0101
#define T200_DID    0x0201

ATTRIBUTE_GROUPS(mgb4_pci);

static int flashid;

static struct xdma_chan_info h2c_chan_info = {
	.dir = DMA_MEM_TO_DEV,
};

static struct xdma_chan_info c2h_chan_info = {
	.dir = DMA_DEV_TO_MEM,
};

static struct xspi_platform_data spi_platform_data = {
	.num_chipselect = 1,
	.bits_per_word = 8
};

static const struct i2c_board_info extender_info = {
	I2C_BOARD_INFO("extender", 0x21)
};

#if IS_REACHABLE(CONFIG_HWMON)
static umode_t temp_is_visible(const void *data, enum hwmon_sensor_types type,
			       u32 attr, int channel)
{
	if (type == hwmon_temp &&
	    (attr == hwmon_temp_input || attr == hwmon_temp_label))
		return 0444;
	else
		return 0;
}

static int temp_read(struct device *dev, enum hwmon_sensor_types type, u32 attr,
		     int channel, long *val)
{
	struct mgb4_dev *mgbdev = dev_get_drvdata(dev);
	u32 val10, raw;

	if (type != hwmon_temp || attr != hwmon_temp_input)
		return -EOPNOTSUPP;

	raw = mgb4_read_reg(&mgbdev->video, 0xD0);
	/* register value -> Celsius degrees formula given by Xilinx */
	val10 = ((((raw >> 20) & 0xFFF) * 503975) - 1118822400) / 409600;
	*val = val10 * 100;

	return 0;
}

static int temp_read_string(struct device *dev, enum hwmon_sensor_types type,
			    u32 attr, int channel, const char **str)
{
	if (type != hwmon_temp || attr != hwmon_temp_label)
		return -EOPNOTSUPP;

	*str = "FPGA Temperature";

	return 0;
}

static const struct hwmon_ops temp_ops = {
	.is_visible = temp_is_visible,
	.read = temp_read,
	.read_string = temp_read_string
};

static const struct hwmon_channel_info *temp_channel_info[] = {
	HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT | HWMON_T_LABEL),
	NULL
};

static const struct hwmon_chip_info temp_chip_info = {
	.ops = &temp_ops,
	.info = temp_channel_info,
};
#endif

static int match_i2c_adap(struct device *dev, void *data)
{
	return i2c_verify_adapter(dev) ? 1 : 0;
}

static struct i2c_adapter *get_i2c_adap(struct platform_device *pdev)
{
	struct device *dev;

	mutex_lock(&pdev->dev.mutex);
	dev = device_find_child(&pdev->dev, NULL, match_i2c_adap);
	mutex_unlock(&pdev->dev.mutex);

	return dev ? to_i2c_adapter(dev) : NULL;
}

static int match_spi_adap(struct device *dev, void *data)
{
	return to_spi_device(dev) ? 1 : 0;
}

static struct spi_controller *get_spi_adap(struct platform_device *pdev)
{
	struct device *dev;

	mutex_lock(&pdev->dev.mutex);
	dev = device_find_child(&pdev->dev, NULL, match_spi_adap);
	mutex_unlock(&pdev->dev.mutex);

	return dev ? container_of(dev, struct spi_controller, dev) : NULL;
}

static int init_spi(struct mgb4_dev *mgbdev, u32 devid)
{
	struct resource spi_resources[] = {
		{
			.start	= 0x400,
			.end	= 0x47f,
			.flags	= IORESOURCE_MEM,
			.name	= "io-memory",
		},
		{
			.start	= 14,
			.end	= 14,
			.flags	= IORESOURCE_IRQ,
			.name	= "irq",
		},
	};
	struct spi_board_info spi_info = {
		.max_speed_hz = 10000000,
		.modalias = "m25p80",
		.chip_select = 0,
		.mode = SPI_MODE_3,
	};
	struct pci_dev *pdev = mgbdev->pdev;
	struct device *dev = &pdev->dev;
	struct spi_controller *ctlr;
	struct spi_device *spi_dev;
	u32 irq;
	int rv, id;
	resource_size_t mapbase = pci_resource_start(pdev, MGB4_MGB4_BAR_ID);

	request_module("platform:xilinx_spi");

	irq = xdma_get_user_irq(mgbdev->xdev, 14);
	xdma_enable_user_irq(mgbdev->xdev, irq);

	spi_resources[0].parent = &pdev->resource[MGB4_MGB4_BAR_ID];
	spi_resources[0].start += mapbase;
	spi_resources[0].end += mapbase;
	spi_resources[1].start = irq;
	spi_resources[1].end = irq;

	id = pci_dev_id(pdev);
	mgbdev->spi_pdev = platform_device_register_resndata(dev, "xilinx_spi",
							     id, spi_resources,
							     ARRAY_SIZE(spi_resources),
							     &spi_platform_data,
							     sizeof(spi_platform_data));
	if (IS_ERR(mgbdev->spi_pdev)) {
		dev_err(dev, "failed to register SPI device\n");
		return PTR_ERR(mgbdev->spi_pdev);
	}

	ctlr = get_spi_adap(mgbdev->spi_pdev);
	if (!ctlr) {
		dev_err(dev, "failed to get SPI adapter\n");
		rv = -EINVAL;
		goto err_pdev;
	}

	snprintf(mgbdev->fw_part_name, sizeof(mgbdev->fw_part_name),
		 "mgb4-fw.%d", flashid);
	mgbdev->partitions[0].name = mgbdev->fw_part_name;
	if (devid == T200_DID) {
		mgbdev->partitions[0].size = 0x950000;
		mgbdev->partitions[0].offset = 0x1000000;
	} else {
		mgbdev->partitions[0].size = 0x400000;
		mgbdev->partitions[0].offset = 0x400000;
	}
	mgbdev->partitions[0].mask_flags = 0;

	snprintf(mgbdev->data_part_name, sizeof(mgbdev->data_part_name),
		 "mgb4-data.%d", flashid);
	mgbdev->partitions[1].name = mgbdev->data_part_name;
	mgbdev->partitions[1].size = 0x10000;
	mgbdev->partitions[1].offset = 0xFF0000;
	mgbdev->partitions[1].mask_flags = MTD_CAP_NORFLASH;

	snprintf(mgbdev->flash_name, sizeof(mgbdev->flash_name),
		 "mgb4-flash.%d", flashid);
	mgbdev->flash_data.name = mgbdev->flash_name;
	mgbdev->flash_data.parts = mgbdev->partitions;
	mgbdev->flash_data.nr_parts = ARRAY_SIZE(mgbdev->partitions);
	mgbdev->flash_data.type = "spi-nor";

	spi_info.platform_data = &mgbdev->flash_data;

	spi_dev = spi_new_device(ctlr, &spi_info);
	put_device(&ctlr->dev);
	if (!spi_dev) {
		dev_err(dev, "failed to create MTD device\n");
		rv = -EINVAL;
		goto err_pdev;
	}

	return 0;

err_pdev:
	platform_device_unregister(mgbdev->spi_pdev);

	return rv;
}

static void free_spi(struct mgb4_dev *mgbdev)
{
	platform_device_unregister(mgbdev->spi_pdev);
}

static int init_i2c(struct mgb4_dev *mgbdev)
{
	struct resource i2c_resources[] = {
		{
			.start	= 0x200,
			.end	= 0x3ff,
			.flags	= IORESOURCE_MEM,
			.name	= "io-memory",
		},
		{
			.start	= 15,
			.end	= 15,
			.flags	= IORESOURCE_IRQ,
			.name	= "irq",
		},
	};
	struct pci_dev *pdev = mgbdev->pdev;
	struct device *dev = &pdev->dev;
	char clk_name[16];
	u32 irq;
	int rv, id;
	resource_size_t mapbase = pci_resource_start(pdev, MGB4_MGB4_BAR_ID);

	request_module("platform:xiic-i2c");

	irq = xdma_get_user_irq(mgbdev->xdev, 15);
	xdma_enable_user_irq(mgbdev->xdev, irq);

	i2c_resources[0].parent = &pdev->resource[MGB4_MGB4_BAR_ID];
	i2c_resources[0].start += mapbase;
	i2c_resources[0].end += mapbase;
	i2c_resources[1].start = irq;
	i2c_resources[1].end = irq;

	id = pci_dev_id(pdev);

	/* create dummy clock required by the xiic-i2c adapter */
	snprintf(clk_name, sizeof(clk_name), "xiic-i2c.%d", id);
	mgbdev->i2c_clk = clk_hw_register_fixed_rate(NULL, clk_name, NULL,
						     0, 125000000);
	if (IS_ERR(mgbdev->i2c_clk)) {
		dev_err(dev, "failed to register I2C clock\n");
		return PTR_ERR(mgbdev->i2c_clk);
	}
	mgbdev->i2c_cl = clkdev_hw_create(mgbdev->i2c_clk, NULL, "xiic-i2c.%d",
					  id);
	if (!mgbdev->i2c_cl) {
		dev_err(dev, "failed to register I2C clockdev\n");
		rv = -ENOMEM;
		goto err_clk;
	}

	mgbdev->i2c_pdev = platform_device_register_resndata(dev, "xiic-i2c",
							     id, i2c_resources,
							     ARRAY_SIZE(i2c_resources),
							     NULL, 0);
	if (IS_ERR(mgbdev->i2c_pdev)) {
		dev_err(dev, "failed to register I2C device\n");
		rv = PTR_ERR(mgbdev->i2c_pdev);
		goto err_clkdev;
	}

	mgbdev->i2c_adap = get_i2c_adap(mgbdev->i2c_pdev);
	if (!mgbdev->i2c_adap) {
		dev_err(dev, "failed to get I2C adapter\n");
		rv = -EINVAL;
		goto err_pdev;
	}

	mutex_init(&mgbdev->i2c_lock);

	return 0;

err_pdev:
	platform_device_unregister(mgbdev->i2c_pdev);
err_clkdev:
	clkdev_drop(mgbdev->i2c_cl);
err_clk:
	clk_hw_unregister(mgbdev->i2c_clk);

	return rv;
}

static void free_i2c(struct mgb4_dev *mgbdev)
{
	put_device(&mgbdev->i2c_adap->dev);
	platform_device_unregister(mgbdev->i2c_pdev);
	clkdev_drop(mgbdev->i2c_cl);
	clk_hw_unregister(mgbdev->i2c_clk);
}

static int get_serial_number(struct mgb4_dev *mgbdev)
{
	struct device *dev = &mgbdev->pdev->dev;
	struct mtd_info *mtd;
	size_t rs;
	int rv;

	mgbdev->serial_number = 0;

	mtd = get_mtd_device_nm(mgbdev->data_part_name);
	if (IS_ERR(mtd)) {
		dev_warn(dev, "failed to get data MTD device\n");
		return -ENOENT;
	}
	rv = mtd_read(mtd, 0, sizeof(mgbdev->serial_number), &rs,
		      (u_char *)&mgbdev->serial_number);
	put_mtd_device(mtd);
	if (rv < 0 || rs != sizeof(mgbdev->serial_number)) {
		dev_warn(dev, "error reading MTD device\n");
		return -EIO;
	}

	return 0;
}

static int get_module_version(struct mgb4_dev *mgbdev)
{
	struct device *dev = &mgbdev->pdev->dev;
	struct mgb4_i2c_client extender;
	s32 version;
	u32 fw_version;
	int rv;

	rv = mgb4_i2c_init(&extender, mgbdev->i2c_adap, &extender_info, 8);
	if (rv < 0) {
		dev_err(dev, "failed to create extender I2C device\n");
		return rv;
	}
	version = mgb4_i2c_read_byte(&extender, 0x00);
	mgb4_i2c_free(&extender);
	if (version < 0) {
		dev_err(dev, "error reading module version\n");
		return -EIO;
	}

	mgbdev->module_version = ~((u32)version) & 0xff;
	if (!(MGB4_IS_FPDL3(mgbdev) || MGB4_IS_GMSL(mgbdev))) {
		dev_err(dev, "unknown module type\n");
		return -EINVAL;
	}
	fw_version = mgb4_read_reg(&mgbdev->video, 0xC4);
	if (fw_version >> 24 != mgbdev->module_version >> 4) {
		dev_err(dev, "module/firmware type mismatch\n");
		return -EINVAL;
	}

	dev_info(dev, "%s module detected\n",
		 MGB4_IS_FPDL3(mgbdev) ? "FPDL3" : "GMSL");

	return 0;
}

static int map_regs(struct pci_dev *pdev, struct resource *res,
		    struct mgb4_regs *regs)
{
	int rv;
	resource_size_t mapbase = pci_resource_start(pdev, MGB4_MGB4_BAR_ID);

	res->start += mapbase;
	res->end += mapbase;

	rv = mgb4_regs_map(res, regs);
	if (rv < 0) {
		dev_err(&pdev->dev, "failed to map %s registers\n", res->name);
		return rv;
	}

	return 0;
}

static int init_xdma(struct mgb4_dev *mgbdev)
{
	struct xdma_platdata data;
	struct resource res[2] = { 0 };
	struct dma_slave_map *map;
	struct pci_dev *pdev = mgbdev->pdev;
	struct device *dev = &pdev->dev;
	int i;

	res[0].start = pci_resource_start(pdev, MGB4_XDMA_BAR_ID);
	res[0].end = pci_resource_end(pdev, MGB4_XDMA_BAR_ID);
	res[0].flags = IORESOURCE_MEM;
	res[0].parent = &pdev->resource[MGB4_XDMA_BAR_ID];
	res[1].start = pci_irq_vector(pdev, 0);
	res[1].end = res[1].start + MGB4_VIN_DEVICES + MGB4_VOUT_DEVICES
		     + MGB4_USER_IRQS - 1;
	res[1].flags = IORESOURCE_IRQ;

	data.max_dma_channels = MGB4_VIN_DEVICES + MGB4_VOUT_DEVICES;
	data.device_map = mgbdev->slave_map;
	data.device_map_cnt = MGB4_VIN_DEVICES + MGB4_VOUT_DEVICES;

	for (i = 0; i < MGB4_VIN_DEVICES; i++) {
		sprintf(mgbdev->channel_names[i], "c2h%d", i);
		map = &data.device_map[i];
		map->slave = mgbdev->channel_names[i];
		map->devname = dev_name(dev);
		map->param = XDMA_FILTER_PARAM(&c2h_chan_info);
	}
	for (i = 0; i < MGB4_VOUT_DEVICES; i++) {
		sprintf(mgbdev->channel_names[i + MGB4_VIN_DEVICES], "h2c%d", i);
		map = &data.device_map[i + MGB4_VIN_DEVICES];
		map->slave = mgbdev->channel_names[i + MGB4_VIN_DEVICES];
		map->devname = dev_name(dev);
		map->param = XDMA_FILTER_PARAM(&h2c_chan_info);
	}

	mgbdev->xdev = platform_device_register_resndata(dev, "xdma",
							 PLATFORM_DEVID_AUTO, res,
							 2, &data, sizeof(data));
	if (IS_ERR(mgbdev->xdev)) {
		dev_err(dev, "failed to register XDMA device\n");
		return PTR_ERR(mgbdev->xdev);
	}

	return 0;
}

static void free_xdma(struct mgb4_dev *mgbdev)
{
	platform_device_unregister(mgbdev->xdev);
}

static int mgb4_probe(struct pci_dev *pdev, const struct pci_device_id *id)
{
	int i, rv;
	struct mgb4_dev *mgbdev;
	struct resource video = {
		.start	= 0x0,
		.end	= 0x100,
		.flags	= IORESOURCE_MEM,
		.name	= "mgb4-video",
	};
	struct resource cmt = {
		.start	= 0x1000,
		.end	= 0x1800,
		.flags	= IORESOURCE_MEM,
		.name	= "mgb4-cmt",
	};
	int irqs = pci_msix_vec_count(pdev);

	mgbdev = kzalloc(sizeof(*mgbdev), GFP_KERNEL);
	if (!mgbdev)
		return -ENOMEM;

	mgbdev->pdev = pdev;
	pci_set_drvdata(pdev, mgbdev);

	/* PCIe related stuff */
	rv = pci_enable_device(pdev);
	if (rv) {
		dev_err(&pdev->dev, "error enabling PCI device\n");
		goto err_mgbdev;
	}

	rv = pcie_capability_set_word(pdev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_RELAX_EN);
	if (rv)
		dev_warn(&pdev->dev, "error enabling PCIe relaxed ordering\n");
	rv = pcie_capability_set_word(pdev, PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_EXT_TAG);
	if (rv)
		dev_warn(&pdev->dev, "error enabling PCIe extended tag field\n");
	rv = pcie_set_readrq(pdev, 512);
	if (rv)
		dev_warn(&pdev->dev, "error setting PCIe max. memory read size\n");
	pci_set_master(pdev);

	rv = pci_alloc_irq_vectors(pdev, irqs, irqs, PCI_IRQ_MSIX);
	if (rv < 0) {
		dev_err(&pdev->dev, "error allocating MSI-X IRQs\n");
		goto err_enable_pci;
	}

	rv = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64));
	if (rv) {
		dev_err(&pdev->dev, "error setting DMA mask\n");
		goto err_enable_pci;
	}

	/* DMA + IRQ engine */
	rv = init_xdma(mgbdev);
	if (rv)
		goto err_alloc_irq;
	rv = mgb4_dma_channel_init(mgbdev);
	if (rv)
		goto err_dma_chan;

	/* mgb4 video registers */
	rv = map_regs(pdev, &video, &mgbdev->video);
	if (rv < 0)
		goto err_dma_chan;
	/* mgb4 cmt registers */
	rv = map_regs(pdev, &cmt, &mgbdev->cmt);
	if (rv < 0)
		goto err_video_regs;

	/* SPI FLASH */
	rv = init_spi(mgbdev, id->device);
	if (rv < 0)
		goto err_cmt_regs;

	/* I2C controller */
	rv = init_i2c(mgbdev);
	if (rv < 0)
		goto err_spi;

	/* PCI card related sysfs attributes */
	rv = device_add_groups(&pdev->dev, mgb4_pci_groups);
	if (rv < 0)
		goto err_i2c;

#if IS_REACHABLE(CONFIG_HWMON)
	/* HWmon (card temperature) */
	mgbdev->hwmon_dev = hwmon_device_register_with_info(&pdev->dev, "mgb4",
							    mgbdev,
							    &temp_chip_info,
							    NULL);
#endif

#ifdef CONFIG_DEBUG_FS
	mgbdev->debugfs = debugfs_create_dir(dev_name(&pdev->dev), NULL);
#endif

	/* Get card serial number. On systems without MTD flash support we may
	 * get an error thus ignore the return value. An invalid serial number
	 * should not break anything...
	 */
	if (get_serial_number(mgbdev) < 0)
		dev_warn(&pdev->dev, "error reading card serial number\n");

	/* Get module type. If no valid module is found, skip the video device
	 * creation part but do not exit with error to allow flashing the card.
	 */
	rv = get_module_version(mgbdev);
	if (rv < 0)
		goto exit;

	/* Video input v4l2 devices */
	for (i = 0; i < MGB4_VIN_DEVICES; i++)
		mgbdev->vin[i] = mgb4_vin_create(mgbdev, i);

	/* Video output v4l2 devices */
	for (i = 0; i < MGB4_VOUT_DEVICES; i++)
		mgbdev->vout[i] = mgb4_vout_create(mgbdev, i);

	/* Triggers */
	mgbdev->indio_dev = mgb4_trigger_create(mgbdev);

exit:
	flashid++;

	return 0;

err_i2c:
	free_i2c(mgbdev);
err_spi:
	free_spi(mgbdev);
err_cmt_regs:
	mgb4_regs_free(&mgbdev->cmt);
err_video_regs:
	mgb4_regs_free(&mgbdev->video);
err_dma_chan:
	mgb4_dma_channel_free(mgbdev);
	free_xdma(mgbdev);
err_alloc_irq:
	pci_disable_msix(pdev);
err_enable_pci:
	pci_disable_device(pdev);
err_mgbdev:
	kfree(mgbdev);

	return rv;
}

static void mgb4_remove(struct pci_dev *pdev)
{
	struct mgb4_dev *mgbdev = pci_get_drvdata(pdev);
	int i;

#ifdef CONFIG_DEBUG_FS
	debugfs_remove_recursive(mgbdev->debugfs);
#endif
#if IS_REACHABLE(CONFIG_HWMON)
	hwmon_device_unregister(mgbdev->hwmon_dev);
#endif

	if (mgbdev->indio_dev)
		mgb4_trigger_free(mgbdev->indio_dev);

	for (i = 0; i < MGB4_VOUT_DEVICES; i++)
		if (mgbdev->vout[i])
			mgb4_vout_free(mgbdev->vout[i]);
	for (i = 0; i < MGB4_VIN_DEVICES; i++)
		if (mgbdev->vin[i])
			mgb4_vin_free(mgbdev->vin[i]);

	device_remove_groups(&mgbdev->pdev->dev, mgb4_pci_groups);
	free_spi(mgbdev);
	free_i2c(mgbdev);
	mgb4_regs_free(&mgbdev->video);
	mgb4_regs_free(&mgbdev->cmt);

	mgb4_dma_channel_free(mgbdev);
	free_xdma(mgbdev);

	pci_disable_msix(mgbdev->pdev);
	pci_disable_device(mgbdev->pdev);

	kfree(mgbdev);
}

static const struct pci_device_id mgb4_pci_ids[] = {
	{ PCI_DEVICE(DIGITEQ_VID, T100_DID), },
	{ PCI_DEVICE(DIGITEQ_VID, T200_DID), },
	{ 0, }
};
MODULE_DEVICE_TABLE(pci, mgb4_pci_ids);

static struct pci_driver mgb4_pci_driver = {
	.name = KBUILD_MODNAME,
	.id_table = mgb4_pci_ids,
	.probe = mgb4_probe,
	.remove = mgb4_remove,
};

module_pci_driver(mgb4_pci_driver);

MODULE_AUTHOR("Digiteq Automotive s.r.o.");
MODULE_DESCRIPTION("Digiteq Automotive MGB4 Driver");
MODULE_LICENSE("GPL");
MODULE_SOFTDEP("pre: platform:xiic-i2c platform:xilinx_spi spi-nor");
