// SPDX-License-Identifier: GPL-2.0
/*
 * Intel FPGA PCIe host controller driver
 *
 * Copyright (C) 2013-2018 Intel Corporation. All rights reserved
 *
 */

#include <common.h>
#include <dm.h>
#include <pci.h>
#include <asm/io.h>

#define RP_TX_REG0			0x2000
#define RP_TX_CNTRL			0x2004
#define RP_TX_SOP			BIT(0)
#define RP_TX_EOP			BIT(1)
#define RP_RXCPL_STATUS			0x200C
#define RP_RXCPL_SOP			BIT(0)
#define RP_RXCPL_EOP			BIT(1)
#define RP_RXCPL_REG			0x2008
#define P2A_INT_STATUS			0x3060
#define P2A_INT_STS_ALL			0xf
#define P2A_INT_ENABLE			0x3070
#define RP_CAP_OFFSET			0x70

/* TLP configuration type 0 and 1 */
#define TLP_FMTTYPE_CFGRD0		0x04	/* Configuration Read Type 0 */
#define TLP_FMTTYPE_CFGWR0		0x44	/* Configuration Write Type 0 */
#define TLP_FMTTYPE_CFGRD1		0x05	/* Configuration Read Type 1 */
#define TLP_FMTTYPE_CFGWR1		0x45	/* Configuration Write Type 1 */
#define TLP_PAYLOAD_SIZE		0x01
#define TLP_READ_TAG			0x1d
#define TLP_WRITE_TAG			0x10
#define RP_DEVFN			0

#define RP_CFG_ADDR(pcie, reg)						\
		((pcie->hip_base) + (reg) + (1 << 20))
#define TLP_REQ_ID(bus, devfn)		(((bus) << 8) | (devfn))

#define TLP_CFGRD_DW0(pcie, bus)					\
	((((bus != pcie->first_busno) ? TLP_FMTTYPE_CFGRD0		\
				      : TLP_FMTTYPE_CFGRD1) << 24) |	\
					TLP_PAYLOAD_SIZE)

#define TLP_CFGWR_DW0(pcie, bus)					\
	((((bus != pcie->first_busno) ? TLP_FMTTYPE_CFGWR0		\
				      : TLP_FMTTYPE_CFGWR1) << 24) |	\
					TLP_PAYLOAD_SIZE)

#define TLP_CFG_DW1(pcie, tag, be)					\
	(((TLP_REQ_ID(pcie->first_busno,  RP_DEVFN)) << 16) | (tag << 8) | (be))
#define TLP_CFG_DW2(bus, dev, fn, offset)				\
	(((bus) << 24) | ((dev) << 19) | ((fn) << 16) | (offset))

#define TLP_COMP_STATUS(s)		(((s) >> 13) & 7)
#define TLP_BYTE_COUNT(s)		(((s) >> 0) & 0xfff)
#define TLP_HDR_SIZE			3
#define TLP_LOOP			20000
#define DWORD_MASK			3

#define IS_ROOT_PORT(pcie, bdf)				\
		((PCI_BUS(bdf) == pcie->first_busno) ? true : false)

#define PCI_EXP_LNKSTA		18	/* Link Status */
#define PCI_EXP_LNKSTA_DLLLA	0x2000	/* Data Link Layer Link Active */

/**
 * struct intel_fpga_pcie - Intel FPGA PCIe controller state
 * @bus: Pointer to the PCI bus
 * @cra_base: The base address of CRA register space
 * @hip_base: The base address of Rootport configuration space
 * @first_busno: This driver supports multiple PCIe controllers.
 *               first_busno stores the bus number of the PCIe root-port
 *               number which may vary depending on the PCIe setup.
 */
struct intel_fpga_pcie {
	struct udevice *bus;
	void __iomem *cra_base;
	void __iomem *hip_base;
	int first_busno;
};

/**
 * Intel FPGA PCIe port uses BAR0 of RC's configuration space as the
 * translation from PCI bus to native BUS. Entire DDR region is mapped
 * into PCIe space using these registers, so it can be reached by DMA from
 * EP devices.
 * The BAR0 of bridge should be hidden during enumeration to avoid the
 * sizing and resource allocation by PCIe core.
 */
static bool intel_fpga_pcie_hide_rc_bar(struct intel_fpga_pcie *pcie,
					pci_dev_t bdf, int offset)
{
	if (IS_ROOT_PORT(pcie, bdf) && PCI_DEV(bdf) == 0 &&
	    PCI_FUNC(bdf) == 0 && offset == PCI_BASE_ADDRESS_0)
		return true;

	return false;
}

static inline void cra_writel(struct intel_fpga_pcie *pcie, const u32 value,
			      const u32 reg)
{
	writel(value, pcie->cra_base + reg);
}

static inline u32 cra_readl(struct intel_fpga_pcie *pcie, const u32 reg)
{
	return readl(pcie->cra_base + reg);
}

static bool intel_fpga_pcie_link_up(struct intel_fpga_pcie *pcie)
{
	return !!(readw(RP_CFG_ADDR(pcie, RP_CAP_OFFSET + PCI_EXP_LNKSTA))
			& PCI_EXP_LNKSTA_DLLLA);
}

static bool intel_fpga_pcie_addr_valid(struct intel_fpga_pcie *pcie,
				       pci_dev_t bdf)
{
	/* If there is no link, then there is no device */
	if (!IS_ROOT_PORT(pcie, bdf) && !intel_fpga_pcie_link_up(pcie))
		return false;

	/* access only one slot on each root port */
	if (IS_ROOT_PORT(pcie, bdf) && PCI_DEV(bdf) > 0)
		return false;

	if ((PCI_BUS(bdf) == pcie->first_busno + 1) && PCI_DEV(bdf) > 0)
		return false;

	return true;
}

static void tlp_write_tx(struct intel_fpga_pcie *pcie, u32 reg0, u32 ctrl)
{
	cra_writel(pcie, reg0, RP_TX_REG0);
	cra_writel(pcie, ctrl, RP_TX_CNTRL);
}

static int tlp_read_packet(struct intel_fpga_pcie *pcie, u32 *value)
{
	int i;
	u32 ctrl;
	u32 comp_status;
	u32 dw[4];
	u32 count = 0;

	for (i = 0; i < TLP_LOOP; i++) {
		ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
		if (!(ctrl & RP_RXCPL_SOP))
			continue;

		/* read first DW */
		dw[count++] = cra_readl(pcie, RP_RXCPL_REG);

		/* Poll for EOP */
		for (i = 0; i < TLP_LOOP; i++) {
			ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
			dw[count++] = cra_readl(pcie, RP_RXCPL_REG);
			if (ctrl & RP_RXCPL_EOP) {
				comp_status = TLP_COMP_STATUS(dw[1]);
				if (comp_status)
					return -EFAULT;

				if (value &&
				    TLP_BYTE_COUNT(dw[1]) == sizeof(u32) &&
				    count >= 3)
					*value = dw[3];

				return 0;
			}
		}

		udelay(5);
	}

	dev_err(pcie->dev, "read TLP packet timed out\n");
	return -ENODEV;
}

static void tlp_write_packet(struct intel_fpga_pcie *pcie, u32 *headers,
			     u32 data)
{
	tlp_write_tx(pcie, headers[0], RP_TX_SOP);

	tlp_write_tx(pcie, headers[1], 0);

	tlp_write_tx(pcie, headers[2], 0);

	tlp_write_tx(pcie, data, RP_TX_EOP);
}

static int tlp_cfg_dword_read(struct intel_fpga_pcie *pcie, pci_dev_t bdf,
			      int offset, u8 byte_en, u32 *value)
{
	u32 headers[TLP_HDR_SIZE];
	u8 busno = PCI_BUS(bdf);

	headers[0] = TLP_CFGRD_DW0(pcie, busno);
	headers[1] = TLP_CFG_DW1(pcie, TLP_READ_TAG, byte_en);
	headers[2] = TLP_CFG_DW2(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);

	tlp_write_packet(pcie, headers, 0);

	return tlp_read_packet(pcie, value);
}

static int tlp_cfg_dword_write(struct intel_fpga_pcie *pcie, pci_dev_t bdf,
			       int offset, u8 byte_en, u32 value)
{
	u32 headers[TLP_HDR_SIZE];
	u8 busno = PCI_BUS(bdf);

	headers[0] = TLP_CFGWR_DW0(pcie, busno);
	headers[1] = TLP_CFG_DW1(pcie, TLP_WRITE_TAG, byte_en);
	headers[2] = TLP_CFG_DW2(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);

	tlp_write_packet(pcie, headers, value);

	return tlp_read_packet(pcie, NULL);
}

int intel_fpga_rp_conf_addr(struct udevice *bus, pci_dev_t bdf,
			    uint offset, void **paddress)
{
	struct intel_fpga_pcie *pcie = dev_get_priv(bus);

	*paddress = RP_CFG_ADDR(pcie, offset);

	return 0;
}

static int intel_fpga_pcie_rp_rd_conf(struct udevice *bus, pci_dev_t bdf,
				      uint offset, ulong *valuep,
				      enum pci_size_t size)
{
	return pci_generic_mmap_read_config(bus, intel_fpga_rp_conf_addr,
					    bdf, offset, valuep, size);
}

static int intel_fpga_pcie_rp_wr_conf(struct udevice *bus, pci_dev_t bdf,
				      uint offset, ulong value,
				      enum pci_size_t size)
{
	int ret;
	struct intel_fpga_pcie *pcie = dev_get_priv(bus);

	ret = pci_generic_mmap_write_config(bus, intel_fpga_rp_conf_addr,
					    bdf, offset, value, size);
	if (!ret) {
		/* Monitor changes to PCI_PRIMARY_BUS register on root port
		 * and update local copy of root bus number accordingly.
		 */
		if (offset == PCI_PRIMARY_BUS)
			pcie->first_busno = (u8)(value);
	}

	return ret;
}

static u8 pcie_get_byte_en(uint offset, enum pci_size_t size)
{
	switch (size) {
	case PCI_SIZE_8:
		return 1 << (offset & 3);
	case PCI_SIZE_16:
		return 3 << (offset & 3);
	default:
		return 0xf;
	}
}

static int _pcie_intel_fpga_read_config(struct intel_fpga_pcie *pcie,
					pci_dev_t bdf, uint offset,
					ulong *valuep, enum pci_size_t size)
{
	int ret;
	u32 data;
	u8 byte_en;

	/* Uses memory mapped method to read rootport config registers */
	if (IS_ROOT_PORT(pcie, bdf))
		return intel_fpga_pcie_rp_rd_conf(pcie->bus, bdf,
				       offset, valuep, size);

	byte_en = pcie_get_byte_en(offset, size);
	ret = tlp_cfg_dword_read(pcie, bdf, offset & ~DWORD_MASK,
				 byte_en, &data);
	if (ret)
		return ret;

	dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08x)\n",
		offset, size, data);
	*valuep = pci_conv_32_to_size(data, offset, size);

	return 0;
}

static int _pcie_intel_fpga_write_config(struct intel_fpga_pcie *pcie,
					 pci_dev_t bdf, uint offset,
					 ulong value, enum pci_size_t size)
{
	u32 data;
	u8 byte_en;

	dev_dbg(pcie->dev, "PCIE CFG write: (b.d.f)=(%02d.%02d.%02d)\n",
		PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
	dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08lx)\n",
		offset, size, value);

	/* Uses memory mapped method to read rootport config registers */
	if (IS_ROOT_PORT(pcie, bdf))
		return intel_fpga_pcie_rp_wr_conf(pcie->bus, bdf, offset,
						  value, size);

	byte_en = pcie_get_byte_en(offset, size);
	data = pci_conv_size_to_32(0, value, offset, size);

	return tlp_cfg_dword_write(pcie, bdf, offset & ~DWORD_MASK,
				   byte_en, data);
}

static int pcie_intel_fpga_read_config(struct udevice *bus, pci_dev_t bdf,
				       uint offset, ulong *valuep,
				       enum pci_size_t size)
{
	struct intel_fpga_pcie *pcie = dev_get_priv(bus);

	dev_dbg(pcie->dev, "PCIE CFG read:  (b.d.f)=(%02d.%02d.%02d)\n",
		PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));

	if (intel_fpga_pcie_hide_rc_bar(pcie, bdf, offset)) {
		*valuep = (u32)pci_get_ff(size);
		return 0;
	}

	if (!intel_fpga_pcie_addr_valid(pcie, bdf)) {
		*valuep = (u32)pci_get_ff(size);
		return 0;
	}

	return _pcie_intel_fpga_read_config(pcie, bdf, offset, valuep, size);
}

static int pcie_intel_fpga_write_config(struct udevice *bus, pci_dev_t bdf,
					uint offset, ulong value,
					enum pci_size_t size)
{
	struct intel_fpga_pcie *pcie = dev_get_priv(bus);

	if (intel_fpga_pcie_hide_rc_bar(pcie, bdf, offset))
		return 0;

	if (!intel_fpga_pcie_addr_valid(pcie, bdf))
		return 0;

	return _pcie_intel_fpga_write_config(pcie, bdf, offset, value,
					  size);
}

static int pcie_intel_fpga_probe(struct udevice *dev)
{
	struct intel_fpga_pcie *pcie = dev_get_priv(dev);

	pcie->bus = pci_get_controller(dev);
	pcie->first_busno = dev->seq;

	/* clear all interrupts */
	cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
	/* disable all interrupts */
	cra_writel(pcie, 0, P2A_INT_ENABLE);

	return 0;
}

static int pcie_intel_fpga_ofdata_to_platdata(struct udevice *dev)
{
	struct intel_fpga_pcie *pcie = dev_get_priv(dev);
	struct fdt_resource reg_res;
	int node = dev_of_offset(dev);
	int ret;

	DECLARE_GLOBAL_DATA_PTR;

	ret = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names",
				     "Cra", &reg_res);
	if (ret) {
		dev_err(dev, "resource \"Cra\" not found\n");
		return ret;
	}

	pcie->cra_base = map_physmem(reg_res.start,
				     fdt_resource_size(&reg_res),
				     MAP_NOCACHE);

	ret = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names",
				     "Hip", &reg_res);
	if (ret) {
		dev_err(dev, "resource \"Hip\" not found\n");
		return ret;
	}

	pcie->hip_base = map_physmem(reg_res.start,
				     fdt_resource_size(&reg_res),
				     MAP_NOCACHE);

	return 0;
}

static const struct dm_pci_ops pcie_intel_fpga_ops = {
	.read_config	= pcie_intel_fpga_read_config,
	.write_config	= pcie_intel_fpga_write_config,
};

static const struct udevice_id pcie_intel_fpga_ids[] = {
	{ .compatible = "altr,pcie-root-port-2.0" },
	{},
};

U_BOOT_DRIVER(pcie_intel_fpga) = {
	.name			= "pcie_intel_fpga",
	.id			= UCLASS_PCI,
	.of_match		= pcie_intel_fpga_ids,
	.ops			= &pcie_intel_fpga_ops,
	.ofdata_to_platdata	= pcie_intel_fpga_ofdata_to_platdata,
	.probe			= pcie_intel_fpga_probe,
	.priv_auto_alloc_size	= sizeof(struct intel_fpga_pcie),
};
