/*
 * PCIe driver for Marvell MVEBU SoCs
 *
 * Based on Barebox drivers/pci/pci-mvebu.c
 *
 * Ported to U-Boot by:
 * Anton Schubert <anton.schubert@gmx.de>
 * Stefan Roese <sr@denx.de>
 *
 * SPDX-License-Identifier:	GPL-2.0
 */

#include <common.h>
#include <pci.h>
#include <linux/errno.h>
#include <asm/io.h>
#include <asm/arch/cpu.h>
#include <asm/arch/soc.h>
#include <linux/mbus.h>

DECLARE_GLOBAL_DATA_PTR;

/* PCIe unit register offsets */
#define SELECT(x, n)			((x >> n) & 1UL)

#define PCIE_DEV_ID_OFF			0x0000
#define PCIE_CMD_OFF			0x0004
#define PCIE_DEV_REV_OFF		0x0008
#define  PCIE_BAR_LO_OFF(n)		(0x0010 + ((n) << 3))
#define  PCIE_BAR_HI_OFF(n)		(0x0014 + ((n) << 3))
#define PCIE_CAPAB_OFF			0x0060
#define PCIE_CTRL_STAT_OFF		0x0068
#define PCIE_HEADER_LOG_4_OFF		0x0128
#define  PCIE_BAR_CTRL_OFF(n)		(0x1804 + (((n) - 1) * 4))
#define  PCIE_WIN04_CTRL_OFF(n)		(0x1820 + ((n) << 4))
#define  PCIE_WIN04_BASE_OFF(n)		(0x1824 + ((n) << 4))
#define  PCIE_WIN04_REMAP_OFF(n)	(0x182c + ((n) << 4))
#define PCIE_WIN5_CTRL_OFF		0x1880
#define PCIE_WIN5_BASE_OFF		0x1884
#define PCIE_WIN5_REMAP_OFF		0x188c
#define PCIE_CONF_ADDR_OFF		0x18f8
#define  PCIE_CONF_ADDR_EN		BIT(31)
#define  PCIE_CONF_REG(r)		((((r) & 0xf00) << 16) | ((r) & 0xfc))
#define  PCIE_CONF_BUS(b)		(((b) & 0xff) << 16)
#define  PCIE_CONF_DEV(d)		(((d) & 0x1f) << 11)
#define  PCIE_CONF_FUNC(f)		(((f) & 0x7) << 8)
#define  PCIE_CONF_ADDR(dev, reg) \
	(PCIE_CONF_BUS(PCI_BUS(dev)) | PCIE_CONF_DEV(PCI_DEV(dev))    | \
	 PCIE_CONF_FUNC(PCI_FUNC(dev)) | PCIE_CONF_REG(reg) | \
	 PCIE_CONF_ADDR_EN)
#define PCIE_CONF_DATA_OFF		0x18fc
#define PCIE_MASK_OFF			0x1910
#define  PCIE_MASK_ENABLE_INTS          (0xf << 24)
#define PCIE_CTRL_OFF			0x1a00
#define  PCIE_CTRL_X1_MODE		BIT(0)
#define PCIE_STAT_OFF			0x1a04
#define  PCIE_STAT_BUS                  (0xff << 8)
#define  PCIE_STAT_DEV                  (0x1f << 16)
#define  PCIE_STAT_LINK_DOWN		BIT(0)
#define PCIE_DEBUG_CTRL			0x1a60
#define  PCIE_DEBUG_SOFT_RESET		BIT(20)

struct resource {
	u32 start;
	u32 end;
};

struct mvebu_pcie {
	struct pci_controller hose;
	char *name;
	void __iomem *base;
	void __iomem *membase;
	struct resource mem;
	void __iomem *iobase;
	u32 port;
	u32 lane;
	u32 lane_mask;
	pci_dev_t dev;
};

#define to_pcie(_hc)	container_of(_hc, struct mvebu_pcie, pci)

/*
 * MVEBU PCIe controller needs MEMORY and I/O BARs to be mapped
 * into SoCs address space. Each controller will map 32M of MEM
 * and 64K of I/O space when registered.
 */
static void __iomem *mvebu_pcie_membase = (void __iomem *)MBUS_PCI_MEM_BASE;
#define PCIE_MEM_SIZE	(32 << 20)

#if defined(CONFIG_ARMADA_38X)
#define PCIE_BASE(if)					\
	((if) == 0 ?					\
	 MVEBU_REG_PCIE_BASE + 0x40000 :		\
	 MVEBU_REG_PCIE_BASE + 0x4000 * (if))

/*
 * On A38x MV6820 these PEX ports are supported:
 *  0 - Port 0.0
 *  1 - Port 0.1
 *  2 - Port 0.2
 */
#define MAX_PEX 3
static struct mvebu_pcie pcie_bus[MAX_PEX];

static void mvebu_get_port_lane(struct mvebu_pcie *pcie, int pex_idx,
				int *mem_target, int *mem_attr)
{
	u8 port[] = { 0, 1, 2 };
	u8 lane[] = { 0, 0, 0 };
	u8 target[] = { 8, 4, 4 };
	u8 attr[] = { 0xe8, 0xe8, 0xd8 };

	pcie->port = port[pex_idx];
	pcie->lane = lane[pex_idx];
	*mem_target = target[pex_idx];
	*mem_attr = attr[pex_idx];
}
#else
#define PCIE_BASE(if)							\
	((if) < 8 ?							\
	 (MVEBU_REG_PCIE_BASE + ((if) / 4) * 0x40000 + ((if) % 4) * 0x4000) : \
	 (MVEBU_REG_PCIE_BASE + 0x2000 + ((if) % 8) * 0x40000))

/*
 * On AXP MV78460 these PEX ports are supported:
 *  0 - Port 0.0
 *  1 - Port 0.1
 *  2 - Port 0.2
 *  3 - Port 0.3
 *  4 - Port 1.0
 *  5 - Port 1.1
 *  6 - Port 1.2
 *  7 - Port 1.3
 *  8 - Port 2.0
 *  9 - Port 3.0
 */
#define MAX_PEX 10
static struct mvebu_pcie pcie_bus[MAX_PEX];

static void mvebu_get_port_lane(struct mvebu_pcie *pcie, int pex_idx,
				int *mem_target, int *mem_attr)
{
	u8 port[] = { 0, 0, 0, 0, 1, 1, 1, 1, 2, 3 };
	u8 lane[] = { 0, 1, 2, 3, 0, 1, 2, 3, 0, 0 };
	u8 target[] = { 4, 4, 4, 4, 8, 8, 8, 8, 4, 8 };
	u8 attr[] = { 0xe8, 0xd8, 0xb8, 0x78,
		      0xe8, 0xd8, 0xb8, 0x78,
		      0xf8, 0xf8 };

	pcie->port = port[pex_idx];
	pcie->lane = lane[pex_idx];
	*mem_target = target[pex_idx];
	*mem_attr = attr[pex_idx];
}
#endif

static int mvebu_pex_unit_is_x4(int pex_idx)
{
	int pex_unit = pex_idx < 9 ? pex_idx >> 2 : 3;
	u32 mask = (0x0f << (pex_unit * 8));

	return (readl(COMPHY_REFCLK_ALIGNMENT) & mask) == mask;
}

static inline bool mvebu_pcie_link_up(struct mvebu_pcie *pcie)
{
	u32 val;
	val = readl(pcie->base + PCIE_STAT_OFF);
	return !(val & PCIE_STAT_LINK_DOWN);
}

static void mvebu_pcie_set_local_bus_nr(struct mvebu_pcie *pcie, int busno)
{
	u32 stat;

	stat = readl(pcie->base + PCIE_STAT_OFF);
	stat &= ~PCIE_STAT_BUS;
	stat |= busno << 8;
	writel(stat, pcie->base + PCIE_STAT_OFF);
}

static void mvebu_pcie_set_local_dev_nr(struct mvebu_pcie *pcie, int devno)
{
	u32 stat;

	stat = readl(pcie->base + PCIE_STAT_OFF);
	stat &= ~PCIE_STAT_DEV;
	stat |= devno << 16;
	writel(stat, pcie->base + PCIE_STAT_OFF);
}

static int mvebu_pcie_get_local_bus_nr(struct mvebu_pcie *pcie)
{
	u32 stat;

	stat = readl(pcie->base + PCIE_STAT_OFF);
	return (stat & PCIE_STAT_BUS) >> 8;
}

static int mvebu_pcie_get_local_dev_nr(struct mvebu_pcie *pcie)
{
	u32 stat;

	stat = readl(pcie->base + PCIE_STAT_OFF);
	return (stat & PCIE_STAT_DEV) >> 16;
}

static inline struct mvebu_pcie *hose_to_pcie(struct pci_controller *hose)
{
	return container_of(hose, struct mvebu_pcie, hose);
}

static int mvebu_pcie_read_config_dword(struct pci_controller *hose,
		pci_dev_t dev, int offset, u32 *val)
{
	struct mvebu_pcie *pcie = hose_to_pcie(hose);
	int local_bus = PCI_BUS(pcie->dev);
	int local_dev = PCI_DEV(pcie->dev);
	u32 reg;

	/* Only allow one other device besides the local one on the local bus */
	if (PCI_BUS(dev) == local_bus && PCI_DEV(dev) != local_dev) {
		if (local_dev == 0 && PCI_DEV(dev) != 1) {
			/*
			 * If local dev is 0, the first other dev can
			 * only be 1
			 */
			*val = 0xffffffff;
			return 1;
		} else if (local_dev != 0 && PCI_DEV(dev) != 0) {
			/*
			 * If local dev is not 0, the first other dev can
			 * only be 0
			 */
			*val = 0xffffffff;
			return 1;
		}
	}

	/* write address */
	reg = PCIE_CONF_ADDR(dev, offset);
	writel(reg, pcie->base + PCIE_CONF_ADDR_OFF);
	*val = readl(pcie->base + PCIE_CONF_DATA_OFF);

	return 0;
}

static int mvebu_pcie_write_config_dword(struct pci_controller *hose,
		pci_dev_t dev, int offset, u32 val)
{
	struct mvebu_pcie *pcie = hose_to_pcie(hose);
	int local_bus = PCI_BUS(pcie->dev);
	int local_dev = PCI_DEV(pcie->dev);

	/* Only allow one other device besides the local one on the local bus */
	if (PCI_BUS(dev) == local_bus && PCI_DEV(dev) != local_dev) {
		if (local_dev == 0 && PCI_DEV(dev) != 1) {
			/*
			 * If local dev is 0, the first other dev can
			 * only be 1
			 */
			return 1;
		} else if (local_dev != 0 && PCI_DEV(dev) != 0) {
			/*
			 * If local dev is not 0, the first other dev can
			 * only be 0
			 */
			return 1;
		}
	}

	writel(PCIE_CONF_ADDR(dev, offset), pcie->base + PCIE_CONF_ADDR_OFF);
	writel(val, pcie->base + PCIE_CONF_DATA_OFF);

	return 0;
}

/*
 * Setup PCIE BARs and Address Decode Wins:
 * BAR[0,2] -> disabled, BAR[1] -> covers all DRAM banks
 * WIN[0-3] -> DRAM bank[0-3]
 */
static void mvebu_pcie_setup_wins(struct mvebu_pcie *pcie)
{
	const struct mbus_dram_target_info *dram = mvebu_mbus_dram_info();
	u32 size;
	int i;

	/* First, disable and clear BARs and windows. */
	for (i = 1; i < 3; i++) {
		writel(0, pcie->base + PCIE_BAR_CTRL_OFF(i));
		writel(0, pcie->base + PCIE_BAR_LO_OFF(i));
		writel(0, pcie->base + PCIE_BAR_HI_OFF(i));
	}

	for (i = 0; i < 5; i++) {
		writel(0, pcie->base + PCIE_WIN04_CTRL_OFF(i));
		writel(0, pcie->base + PCIE_WIN04_BASE_OFF(i));
		writel(0, pcie->base + PCIE_WIN04_REMAP_OFF(i));
	}

	writel(0, pcie->base + PCIE_WIN5_CTRL_OFF);
	writel(0, pcie->base + PCIE_WIN5_BASE_OFF);
	writel(0, pcie->base + PCIE_WIN5_REMAP_OFF);

	/* Setup windows for DDR banks. Count total DDR size on the fly. */
	size = 0;
	for (i = 0; i < dram->num_cs; i++) {
		const struct mbus_dram_window *cs = dram->cs + i;

		writel(cs->base & 0xffff0000,
		       pcie->base + PCIE_WIN04_BASE_OFF(i));
		writel(0, pcie->base + PCIE_WIN04_REMAP_OFF(i));
		writel(((cs->size - 1) & 0xffff0000) |
		       (cs->mbus_attr << 8) |
		       (dram->mbus_dram_target_id << 4) | 1,
		       pcie->base + PCIE_WIN04_CTRL_OFF(i));

		size += cs->size;
	}

	/* Round up 'size' to the nearest power of two. */
	if ((size & (size - 1)) != 0)
		size = 1 << fls(size);

	/* Setup BAR[1] to all DRAM banks. */
	writel(dram->cs[0].base | 0xc, pcie->base + PCIE_BAR_LO_OFF(1));
	writel(0, pcie->base + PCIE_BAR_HI_OFF(1));
	writel(((size - 1) & 0xffff0000) | 0x1,
	       pcie->base + PCIE_BAR_CTRL_OFF(1));
}

void pci_init_board(void)
{
	int mem_target, mem_attr, i;
	int bus = 0;
	u32 reg;
	u32 soc_ctrl = readl(MVEBU_SYSTEM_REG_BASE + 0x4);

	/* Check SoC Control Power State */
	debug("%s: SoC Control %08x, 0en %01lx, 1en %01lx, 2en %01lx\n",
	      __func__, soc_ctrl, SELECT(soc_ctrl, 0), SELECT(soc_ctrl, 1),
	      SELECT(soc_ctrl, 2));

	for (i = 0; i < MAX_PEX; i++) {
		struct mvebu_pcie *pcie = &pcie_bus[i];
		struct pci_controller *hose = &pcie->hose;

		/* Get port number, lane number and memory target / attr */
		mvebu_get_port_lane(pcie, i, &mem_target, &mem_attr);

		/* Don't read at all from pci registers if port power is down */
		if (pcie->lane == 0 && SELECT(soc_ctrl, pcie->port) == 0) {
			i += 3;
			debug("%s: skipping port %d\n", __func__, pcie->port);
			continue;
		}

		pcie->base = (void __iomem *)PCIE_BASE(i);

		/* Check link and skip ports that have no link */
		if (!mvebu_pcie_link_up(pcie)) {
			debug("%s: PCIe %d.%d - down\n", __func__,
			      pcie->port, pcie->lane);
			continue;
		}
		debug("%s: PCIe %d.%d - up, base %08x\n", __func__,
		      pcie->port, pcie->lane, (u32)pcie->base);

		/* Read Id info and local bus/dev */
		debug("direct conf read %08x, local bus %d, local dev %d\n",
		      readl(pcie->base), mvebu_pcie_get_local_bus_nr(pcie),
		      mvebu_pcie_get_local_dev_nr(pcie));

		mvebu_pcie_set_local_bus_nr(pcie, bus);
		mvebu_pcie_set_local_dev_nr(pcie, 0);
		pcie->dev = PCI_BDF(bus, 0, 0);

		pcie->mem.start = (u32)mvebu_pcie_membase;
		pcie->mem.end = pcie->mem.start + PCIE_MEM_SIZE - 1;
		mvebu_pcie_membase += PCIE_MEM_SIZE;

		if (mvebu_mbus_add_window_by_id(mem_target, mem_attr,
						(phys_addr_t)pcie->mem.start,
						PCIE_MEM_SIZE)) {
			printf("PCIe unable to add mbus window for mem at %08x+%08x\n",
			       (u32)pcie->mem.start, PCIE_MEM_SIZE);
		}

		/* Setup windows and configure host bridge */
		mvebu_pcie_setup_wins(pcie);

		/* Master + slave enable. */
		reg = readl(pcie->base + PCIE_CMD_OFF);
		reg |= PCI_COMMAND_MEMORY;
		reg |= PCI_COMMAND_MASTER;
		reg |= BIT(10);		/* disable interrupts */
		writel(reg, pcie->base + PCIE_CMD_OFF);

		/* Setup U-Boot PCI Controller */
		hose->first_busno = 0;
		hose->current_busno = bus;

		/* PCI memory space */
		pci_set_region(hose->regions + 0, pcie->mem.start,
			       pcie->mem.start, PCIE_MEM_SIZE, PCI_REGION_MEM);
		pci_set_region(hose->regions + 1,
			       0, 0,
			       gd->ram_size,
			       PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
		hose->region_count = 2;

		pci_set_ops(hose,
			    pci_hose_read_config_byte_via_dword,
			    pci_hose_read_config_word_via_dword,
			    mvebu_pcie_read_config_dword,
			    pci_hose_write_config_byte_via_dword,
			    pci_hose_write_config_word_via_dword,
			    mvebu_pcie_write_config_dword);
		pci_register_hose(hose);

		hose->last_busno = pci_hose_scan(hose);

		/* Set BAR0 to internal registers */
		writel(SOC_REGS_PHY_BASE, pcie->base + PCIE_BAR_LO_OFF(0));
		writel(0, pcie->base + PCIE_BAR_HI_OFF(0));

		bus = hose->last_busno + 1;

		/* need to skip more for X4 links, otherwise scan will hang */
		if (mvebu_soc_family() == MVEBU_SOC_AXP) {
			if (mvebu_pex_unit_is_x4(i))
				i += 3;
		}
	}
}
