// SPDX-License-Identifier: GPL-2.0
/*
 * PCIe endpoint driver for Renesas R-Car SoCs
 *  Copyright (c) 2020 Renesas Electronics Europe GmbH
 *
 * Author: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com>
 */

#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_pci.h>
#include <linux/of_platform.h>
#include <linux/pci.h>
#include <linux/pci-epc.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>

#include "pcie-rcar.h"

#define RCAR_EPC_MAX_FUNCTIONS		1

/* Structure representing the PCIe interface */
struct rcar_pcie_endpoint {
	struct rcar_pcie	pcie;
	phys_addr_t		*ob_mapped_addr;
	struct pci_epc_mem_window *ob_window;
	u8			max_functions;
	unsigned int		bar_to_atu[MAX_NR_INBOUND_MAPS];
	unsigned long		*ib_window_map;
	u32			num_ib_windows;
	u32			num_ob_windows;
};

static void rcar_pcie_ep_hw_init(struct rcar_pcie *pcie)
{
	u32 val;

	rcar_pci_write_reg(pcie, 0, PCIETCTLR);

	/* Set endpoint mode */
	rcar_pci_write_reg(pcie, 0, PCIEMSR);

	/* Initialize default capabilities. */
	rcar_rmw32(pcie, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
	rcar_rmw32(pcie, REXPCAP(PCI_EXP_FLAGS),
		   PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ENDPOINT << 4);
	rcar_rmw32(pcie, RCONF(PCI_HEADER_TYPE), 0x7f,
		   PCI_HEADER_TYPE_NORMAL);

	/* Write out the physical slot number = 0 */
	rcar_rmw32(pcie, REXPCAP(PCI_EXP_SLTCAP), PCI_EXP_SLTCAP_PSN, 0);

	val = rcar_pci_read_reg(pcie, EXPCAP(1));
	/* device supports fixed 128 bytes MPSS */
	val &= ~GENMASK(2, 0);
	rcar_pci_write_reg(pcie, val, EXPCAP(1));

	val = rcar_pci_read_reg(pcie, EXPCAP(2));
	/* read requests size 128 bytes */
	val &= ~GENMASK(14, 12);
	/* payload size 128 bytes */
	val &= ~GENMASK(7, 5);
	rcar_pci_write_reg(pcie, val, EXPCAP(2));

	/* Set target link speed to 5.0 GT/s */
	rcar_rmw32(pcie, EXPCAP(12), PCI_EXP_LNKSTA_CLS,
		   PCI_EXP_LNKSTA_CLS_5_0GB);

	/* Set the completion timer timeout to the maximum 50ms. */
	rcar_rmw32(pcie, TLCTLR + 1, 0x3f, 50);

	/* Terminate list of capabilities (Next Capability Offset=0) */
	rcar_rmw32(pcie, RVCCAP(0), 0xfff00000, 0);

	/* flush modifications */
	wmb();
}

static int rcar_pcie_ep_get_window(struct rcar_pcie_endpoint *ep,
				   phys_addr_t addr)
{
	int i;

	for (i = 0; i < ep->num_ob_windows; i++)
		if (ep->ob_window[i].phys_base == addr)
			return i;

	return -EINVAL;
}

static int rcar_pcie_parse_outbound_ranges(struct rcar_pcie_endpoint *ep,
					   struct platform_device *pdev)
{
	struct rcar_pcie *pcie = &ep->pcie;
	char outbound_name[10];
	struct resource *res;
	unsigned int i = 0;

	ep->num_ob_windows = 0;
	for (i = 0; i < RCAR_PCI_MAX_RESOURCES; i++) {
		sprintf(outbound_name, "memory%u", i);
		res = platform_get_resource_byname(pdev,
						   IORESOURCE_MEM,
						   outbound_name);
		if (!res) {
			dev_err(pcie->dev, "missing outbound window %u\n", i);
			return -EINVAL;
		}
		if (!devm_request_mem_region(&pdev->dev, res->start,
					     resource_size(res),
					     outbound_name)) {
			dev_err(pcie->dev, "Cannot request memory region %s.\n",
				outbound_name);
			return -EIO;
		}

		ep->ob_window[i].phys_base = res->start;
		ep->ob_window[i].size = resource_size(res);
		/* controller doesn't support multiple allocation
		 * from same window, so set page_size to window size
		 */
		ep->ob_window[i].page_size = resource_size(res);
	}
	ep->num_ob_windows = i;

	return 0;
}

static int rcar_pcie_ep_get_pdata(struct rcar_pcie_endpoint *ep,
				  struct platform_device *pdev)
{
	struct rcar_pcie *pcie = &ep->pcie;
	struct pci_epc_mem_window *window;
	struct device *dev = pcie->dev;
	struct resource res;
	int err;

	err = of_address_to_resource(dev->of_node, 0, &res);
	if (err)
		return err;
	pcie->base = devm_ioremap_resource(dev, &res);
	if (IS_ERR(pcie->base))
		return PTR_ERR(pcie->base);

	ep->ob_window = devm_kcalloc(dev, RCAR_PCI_MAX_RESOURCES,
				     sizeof(*window), GFP_KERNEL);
	if (!ep->ob_window)
		return -ENOMEM;

	rcar_pcie_parse_outbound_ranges(ep, pdev);

	err = of_property_read_u8(dev->of_node, "max-functions",
				  &ep->max_functions);
	if (err < 0 || ep->max_functions > RCAR_EPC_MAX_FUNCTIONS)
		ep->max_functions = RCAR_EPC_MAX_FUNCTIONS;

	return 0;
}

static int rcar_pcie_ep_write_header(struct pci_epc *epc, u8 fn,
				     struct pci_epf_header *hdr)
{
	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
	struct rcar_pcie *pcie = &ep->pcie;
	u32 val;

	if (!fn)
		val = hdr->vendorid;
	else
		val = rcar_pci_read_reg(pcie, IDSETR0);
	val |= hdr->deviceid << 16;
	rcar_pci_write_reg(pcie, val, IDSETR0);

	val = hdr->revid;
	val |= hdr->progif_code << 8;
	val |= hdr->subclass_code << 16;
	val |= hdr->baseclass_code << 24;
	rcar_pci_write_reg(pcie, val, IDSETR1);

	if (!fn)
		val = hdr->subsys_vendor_id;
	else
		val = rcar_pci_read_reg(pcie, SUBIDSETR);
	val |= hdr->subsys_id << 16;
	rcar_pci_write_reg(pcie, val, SUBIDSETR);

	if (hdr->interrupt_pin > PCI_INTERRUPT_INTA)
		return -EINVAL;
	val = rcar_pci_read_reg(pcie, PCICONF(15));
	val |= (hdr->interrupt_pin << 8);
	rcar_pci_write_reg(pcie, val, PCICONF(15));

	return 0;
}

static int rcar_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no,
				struct pci_epf_bar *epf_bar)
{
	int flags = epf_bar->flags | LAR_ENABLE | LAM_64BIT;
	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
	u64 size = 1ULL << fls64(epf_bar->size - 1);
	dma_addr_t cpu_addr = epf_bar->phys_addr;
	enum pci_barno bar = epf_bar->barno;
	struct rcar_pcie *pcie = &ep->pcie;
	u32 mask;
	int idx;
	int err;

	idx = find_first_zero_bit(ep->ib_window_map, ep->num_ib_windows);
	if (idx >= ep->num_ib_windows) {
		dev_err(pcie->dev, "no free inbound window\n");
		return -EINVAL;
	}

	if ((flags & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
		flags |= IO_SPACE;

	ep->bar_to_atu[bar] = idx;
	/* use 64-bit BARs */
	set_bit(idx, ep->ib_window_map);
	set_bit(idx + 1, ep->ib_window_map);

	if (cpu_addr > 0) {
		unsigned long nr_zeros = __ffs64(cpu_addr);
		u64 alignment = 1ULL << nr_zeros;

		size = min(size, alignment);
	}

	size = min(size, 1ULL << 32);

	mask = roundup_pow_of_two(size) - 1;
	mask &= ~0xf;

	rcar_pcie_set_inbound(pcie, cpu_addr,
			      0x0, mask | flags, idx, false);

	err = rcar_pcie_wait_for_phyrdy(pcie);
	if (err) {
		dev_err(pcie->dev, "phy not ready\n");
		return -EINVAL;
	}

	return 0;
}

static void rcar_pcie_ep_clear_bar(struct pci_epc *epc, u8 fn,
				   struct pci_epf_bar *epf_bar)
{
	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
	enum pci_barno bar = epf_bar->barno;
	u32 atu_index = ep->bar_to_atu[bar];

	rcar_pcie_set_inbound(&ep->pcie, 0x0, 0x0, 0x0, bar, false);

	clear_bit(atu_index, ep->ib_window_map);
	clear_bit(atu_index + 1, ep->ib_window_map);
}

static int rcar_pcie_ep_set_msi(struct pci_epc *epc, u8 fn, u8 interrupts)
{
	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
	struct rcar_pcie *pcie = &ep->pcie;
	u32 flags;

	flags = rcar_pci_read_reg(pcie, MSICAP(fn));
	flags |= interrupts << MSICAP0_MMESCAP_OFFSET;
	rcar_pci_write_reg(pcie, flags, MSICAP(fn));

	return 0;
}

static int rcar_pcie_ep_get_msi(struct pci_epc *epc, u8 fn)
{
	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
	struct rcar_pcie *pcie = &ep->pcie;
	u32 flags;

	flags = rcar_pci_read_reg(pcie, MSICAP(fn));
	if (!(flags & MSICAP0_MSIE))
		return -EINVAL;

	return ((flags & MSICAP0_MMESE_MASK) >> MSICAP0_MMESE_OFFSET);
}

static int rcar_pcie_ep_map_addr(struct pci_epc *epc, u8 fn,
				 phys_addr_t addr, u64 pci_addr, size_t size)
{
	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
	struct rcar_pcie *pcie = &ep->pcie;
	struct resource_entry win;
	struct resource res;
	int window;
	int err;

	/* check if we have a link. */
	err = rcar_pcie_wait_for_dl(pcie);
	if (err) {
		dev_err(pcie->dev, "link not up\n");
		return err;
	}

	window = rcar_pcie_ep_get_window(ep, addr);
	if (window < 0) {
		dev_err(pcie->dev, "failed to get corresponding window\n");
		return -EINVAL;
	}

	memset(&win, 0x0, sizeof(win));
	memset(&res, 0x0, sizeof(res));
	res.start = pci_addr;
	res.end = pci_addr + size - 1;
	res.flags = IORESOURCE_MEM;
	win.res = &res;

	rcar_pcie_set_outbound(pcie, window, &win);

	ep->ob_mapped_addr[window] = addr;

	return 0;
}

static void rcar_pcie_ep_unmap_addr(struct pci_epc *epc, u8 fn,
				    phys_addr_t addr)
{
	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);
	struct resource_entry win;
	struct resource res;
	int idx;

	for (idx = 0; idx < ep->num_ob_windows; idx++)
		if (ep->ob_mapped_addr[idx] == addr)
			break;

	if (idx >= ep->num_ob_windows)
		return;

	memset(&win, 0x0, sizeof(win));
	memset(&res, 0x0, sizeof(res));
	win.res = &res;
	rcar_pcie_set_outbound(&ep->pcie, idx, &win);

	ep->ob_mapped_addr[idx] = 0;
}

static int rcar_pcie_ep_assert_intx(struct rcar_pcie_endpoint *ep,
				    u8 fn, u8 intx)
{
	struct rcar_pcie *pcie = &ep->pcie;
	u32 val;

	val = rcar_pci_read_reg(pcie, PCIEMSITXR);
	if ((val & PCI_MSI_FLAGS_ENABLE)) {
		dev_err(pcie->dev, "MSI is enabled, cannot assert INTx\n");
		return -EINVAL;
	}

	val = rcar_pci_read_reg(pcie, PCICONF(1));
	if ((val & INTDIS)) {
		dev_err(pcie->dev, "INTx message transmission is disabled\n");
		return -EINVAL;
	}

	val = rcar_pci_read_reg(pcie, PCIEINTXR);
	if ((val & ASTINTX)) {
		dev_err(pcie->dev, "INTx is already asserted\n");
		return -EINVAL;
	}

	val |= ASTINTX;
	rcar_pci_write_reg(pcie, val, PCIEINTXR);
	usleep_range(1000, 1001);
	val = rcar_pci_read_reg(pcie, PCIEINTXR);
	val &= ~ASTINTX;
	rcar_pci_write_reg(pcie, val, PCIEINTXR);

	return 0;
}

static int rcar_pcie_ep_assert_msi(struct rcar_pcie *pcie,
				   u8 fn, u8 interrupt_num)
{
	u16 msi_count;
	u32 val;

	/* Check MSI enable bit */
	val = rcar_pci_read_reg(pcie, MSICAP(fn));
	if (!(val & MSICAP0_MSIE))
		return -EINVAL;

	/* Get MSI numbers from MME */
	msi_count = ((val & MSICAP0_MMESE_MASK) >> MSICAP0_MMESE_OFFSET);
	msi_count = 1 << msi_count;

	if (!interrupt_num || interrupt_num > msi_count)
		return -EINVAL;

	val = rcar_pci_read_reg(pcie, PCIEMSITXR);
	rcar_pci_write_reg(pcie, val | (interrupt_num - 1), PCIEMSITXR);

	return 0;
}

static int rcar_pcie_ep_raise_irq(struct pci_epc *epc, u8 fn,
				  enum pci_epc_irq_type type,
				  u16 interrupt_num)
{
	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);

	switch (type) {
	case PCI_EPC_IRQ_LEGACY:
		return rcar_pcie_ep_assert_intx(ep, fn, 0);

	case PCI_EPC_IRQ_MSI:
		return rcar_pcie_ep_assert_msi(&ep->pcie, fn, interrupt_num);

	default:
		return -EINVAL;
	}
}

static int rcar_pcie_ep_start(struct pci_epc *epc)
{
	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);

	rcar_pci_write_reg(&ep->pcie, MACCTLR_INIT_VAL, MACCTLR);
	rcar_pci_write_reg(&ep->pcie, CFINIT, PCIETCTLR);

	return 0;
}

static void rcar_pcie_ep_stop(struct pci_epc *epc)
{
	struct rcar_pcie_endpoint *ep = epc_get_drvdata(epc);

	rcar_pci_write_reg(&ep->pcie, 0, PCIETCTLR);
}

static const struct pci_epc_features rcar_pcie_epc_features = {
	.linkup_notifier = false,
	.msi_capable = true,
	.msix_capable = false,
	/* use 64-bit BARs so mark BAR[1,3,5] as reserved */
	.reserved_bar = 1 << BAR_1 | 1 << BAR_3 | 1 << BAR_5,
	.bar_fixed_64bit = 1 << BAR_0 | 1 << BAR_2 | 1 << BAR_4,
	.bar_fixed_size[0] = 128,
	.bar_fixed_size[2] = 256,
	.bar_fixed_size[4] = 256,
};

static const struct pci_epc_features*
rcar_pcie_ep_get_features(struct pci_epc *epc, u8 func_no)
{
	return &rcar_pcie_epc_features;
}

static const struct pci_epc_ops rcar_pcie_epc_ops = {
	.write_header	= rcar_pcie_ep_write_header,
	.set_bar	= rcar_pcie_ep_set_bar,
	.clear_bar	= rcar_pcie_ep_clear_bar,
	.set_msi	= rcar_pcie_ep_set_msi,
	.get_msi	= rcar_pcie_ep_get_msi,
	.map_addr	= rcar_pcie_ep_map_addr,
	.unmap_addr	= rcar_pcie_ep_unmap_addr,
	.raise_irq	= rcar_pcie_ep_raise_irq,
	.start		= rcar_pcie_ep_start,
	.stop		= rcar_pcie_ep_stop,
	.get_features	= rcar_pcie_ep_get_features,
};

static const struct of_device_id rcar_pcie_ep_of_match[] = {
	{ .compatible = "renesas,r8a774c0-pcie-ep", },
	{ .compatible = "renesas,rcar-gen3-pcie-ep" },
	{ },
};

static int rcar_pcie_ep_probe(struct platform_device *pdev)
{
	struct device *dev = &pdev->dev;
	struct rcar_pcie_endpoint *ep;
	struct rcar_pcie *pcie;
	struct pci_epc *epc;
	int err;

	ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL);
	if (!ep)
		return -ENOMEM;

	pcie = &ep->pcie;
	pcie->dev = dev;

	pm_runtime_enable(dev);
	err = pm_runtime_get_sync(dev);
	if (err < 0) {
		dev_err(dev, "pm_runtime_get_sync failed\n");
		goto err_pm_disable;
	}

	err = rcar_pcie_ep_get_pdata(ep, pdev);
	if (err < 0) {
		dev_err(dev, "failed to request resources: %d\n", err);
		goto err_pm_put;
	}

	ep->num_ib_windows = MAX_NR_INBOUND_MAPS;
	ep->ib_window_map =
			devm_kcalloc(dev, BITS_TO_LONGS(ep->num_ib_windows),
				     sizeof(long), GFP_KERNEL);
	if (!ep->ib_window_map) {
		err = -ENOMEM;
		dev_err(dev, "failed to allocate memory for inbound map\n");
		goto err_pm_put;
	}

	ep->ob_mapped_addr = devm_kcalloc(dev, ep->num_ob_windows,
					  sizeof(*ep->ob_mapped_addr),
					  GFP_KERNEL);
	if (!ep->ob_mapped_addr) {
		err = -ENOMEM;
		dev_err(dev, "failed to allocate memory for outbound memory pointers\n");
		goto err_pm_put;
	}

	epc = devm_pci_epc_create(dev, &rcar_pcie_epc_ops);
	if (IS_ERR(epc)) {
		dev_err(dev, "failed to create epc device\n");
		err = PTR_ERR(epc);
		goto err_pm_put;
	}

	epc->max_functions = ep->max_functions;
	epc_set_drvdata(epc, ep);

	rcar_pcie_ep_hw_init(pcie);

	err = pci_epc_multi_mem_init(epc, ep->ob_window, ep->num_ob_windows);
	if (err < 0) {
		dev_err(dev, "failed to initialize the epc memory space\n");
		goto err_pm_put;
	}

	return 0;

err_pm_put:
	pm_runtime_put(dev);

err_pm_disable:
	pm_runtime_disable(dev);

	return err;
}

static struct platform_driver rcar_pcie_ep_driver = {
	.driver = {
		.name = "rcar-pcie-ep",
		.of_match_table = rcar_pcie_ep_of_match,
		.suppress_bind_attrs = true,
	},
	.probe = rcar_pcie_ep_probe,
};
builtin_platform_driver(rcar_pcie_ep_driver);
