/*
 * Copyright (C) 2015 Marvell International Ltd.
 *
 * Copyright (C) 2016 Stefan Roese <sr@denx.de>
 *
 * Based on:
 *   - drivers/pci/pcie_imx.c
 *   - drivers/pci/pci_mvebu.c
 *   - drivers/pci/pcie_xilinx.c
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

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

DECLARE_GLOBAL_DATA_PTR;

/* PCI Config space registers */
#define PCIE_CONFIG_BAR0		0x10
#define PCIE_LINK_STATUS_REG		0x80
#define PCIE_LINK_STATUS_SPEED_OFF	16
#define PCIE_LINK_STATUS_SPEED_MASK	(0xf << PCIE_LINK_STATUS_SPEED_OFF)
#define PCIE_LINK_STATUS_WIDTH_OFF	20
#define PCIE_LINK_STATUS_WIDTH_MASK	(0xf << PCIE_LINK_STATUS_WIDTH_OFF)

/* Resizable bar capability registers */
#define RESIZABLE_BAR_CAP		0x250
#define RESIZABLE_BAR_CTL0		0x254
#define RESIZABLE_BAR_CTL1		0x258

/* iATU registers */
#define PCIE_ATU_VIEWPORT		0x900
#define PCIE_ATU_REGION_INBOUND		(0x1 << 31)
#define PCIE_ATU_REGION_OUTBOUND	(0x0 << 31)
#define PCIE_ATU_REGION_INDEX1		(0x1 << 0)
#define PCIE_ATU_REGION_INDEX0		(0x0 << 0)
#define PCIE_ATU_CR1			0x904
#define PCIE_ATU_TYPE_MEM		(0x0 << 0)
#define PCIE_ATU_TYPE_IO		(0x2 << 0)
#define PCIE_ATU_TYPE_CFG0		(0x4 << 0)
#define PCIE_ATU_TYPE_CFG1		(0x5 << 0)
#define PCIE_ATU_CR2			0x908
#define PCIE_ATU_ENABLE			(0x1 << 31)
#define PCIE_ATU_BAR_MODE_ENABLE	(0x1 << 30)
#define PCIE_ATU_LOWER_BASE		0x90C
#define PCIE_ATU_UPPER_BASE		0x910
#define PCIE_ATU_LIMIT			0x914
#define PCIE_ATU_LOWER_TARGET		0x918
#define PCIE_ATU_BUS(x)			(((x) & 0xff) << 24)
#define PCIE_ATU_DEV(x)			(((x) & 0x1f) << 19)
#define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
#define PCIE_ATU_UPPER_TARGET		0x91C

#define PCIE_LINK_CAPABILITY		0x7C
#define PCIE_LINK_CTL_2			0xA0
#define TARGET_LINK_SPEED_MASK		0xF
#define LINK_SPEED_GEN_1		0x1
#define LINK_SPEED_GEN_2		0x2
#define LINK_SPEED_GEN_3		0x3

#define PCIE_GEN3_RELATED		0x890
#define GEN3_EQU_DISABLE		(1 << 16)
#define GEN3_ZRXDC_NON_COMP		(1 << 0)

#define PCIE_GEN3_EQU_CTRL		0x8A8
#define GEN3_EQU_EVAL_2MS_DISABLE	(1 << 5)

#define PCIE_ROOT_COMPLEX_MODE_MASK	(0xF << 4)

#define PCIE_LINK_UP_TIMEOUT_MS		100

#define PCIE_GLOBAL_CONTROL		0x8000
#define PCIE_APP_LTSSM_EN		(1 << 2)
#define PCIE_DEVICE_TYPE_OFFSET		(4)
#define PCIE_DEVICE_TYPE_MASK		(0xF)
#define PCIE_DEVICE_TYPE_EP		(0x0) /* Endpoint */
#define PCIE_DEVICE_TYPE_LEP		(0x1) /* Legacy endpoint */
#define PCIE_DEVICE_TYPE_RC		(0x4) /* Root complex */

#define PCIE_GLOBAL_STATUS		0x8008
#define PCIE_GLB_STS_RDLH_LINK_UP	(1 << 1)
#define PCIE_GLB_STS_PHY_LINK_UP	(1 << 9)

#define PCIE_ARCACHE_TRC		0x8050
#define PCIE_AWCACHE_TRC		0x8054
#define ARCACHE_SHAREABLE_CACHEABLE	0x3511
#define AWCACHE_SHAREABLE_CACHEABLE	0x5311

#define LINK_SPEED_GEN_1                0x1
#define LINK_SPEED_GEN_2                0x2
#define LINK_SPEED_GEN_3                0x3

/**
 * struct pcie_dw_mvebu - MVEBU DW PCIe controller state
 *
 * @ctrl_base: The base address of the register space
 * @cfg_base: The base address of the configuration space
 * @cfg_size: The size of the configuration space which is needed
 *            as it gets written into the PCIE_ATU_LIMIT register
 * @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
 *               (PEX switches etc).
 */
struct pcie_dw_mvebu {
	void *ctrl_base;
	void *cfg_base;
	fdt_size_t cfg_size;
	int first_busno;
};

static int pcie_dw_get_link_speed(const void *regs_base)
{
	return (readl(regs_base + PCIE_LINK_STATUS_REG) &
		PCIE_LINK_STATUS_SPEED_MASK) >> PCIE_LINK_STATUS_SPEED_OFF;
}

static int pcie_dw_get_link_width(const void *regs_base)
{
	return (readl(regs_base + PCIE_LINK_STATUS_REG) &
		PCIE_LINK_STATUS_WIDTH_MASK) >> PCIE_LINK_STATUS_WIDTH_OFF;
}

/**
 * set_cfg_address() - Configure the PCIe controller config space access
 *
 * @pcie: Pointer to the PCI controller state
 * @d: PCI device to access
 * @where: Offset in the configuration space
 *
 * Configures the PCIe controller to access the configuration space of
 * a specific PCIe device and returns the address to use for this
 * access.
 *
 * Return: Address that can be used to access the configation space
 *         of the requested device / offset
 */
static uintptr_t set_cfg_address(struct pcie_dw_mvebu *pcie,
				 pci_dev_t d, uint where)
{
	uintptr_t va_address;

	/*
	 * Region #0 is used for Outbound CFG space access.
	 * Direction = Outbound
	 * Region Index = 0
	 */
	writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT);

	if (PCI_BUS(d) == (pcie->first_busno + 1))
		/* For local bus, change TLP Type field to 4. */
		writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1);
	else
		/* Otherwise, change TLP Type field to 5. */
		writel(PCIE_ATU_TYPE_CFG1, pcie->ctrl_base + PCIE_ATU_CR1);

	if (PCI_BUS(d) == pcie->first_busno) {
		/* Accessing root port configuration space. */
		va_address = (uintptr_t)pcie->ctrl_base;
	} else {
		writel(d << 8, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET);
		va_address = (uintptr_t)pcie->cfg_base;
	}

	va_address += where & ~0x3;

	return va_address;
}

/**
 * pcie_dw_addr_valid() - Check for valid bus address
 *
 * @d: The PCI device to access
 * @first_busno: Bus number of the PCIe controller root complex
 *
 * Return 1 (true) if the PCI device can be accessed by this controller.
 *
 * Return: 1 on valid, 0 on invalid
 */
static int pcie_dw_addr_valid(pci_dev_t d, int first_busno)
{
	if ((PCI_BUS(d) == first_busno) && (PCI_DEV(d) > 0))
		return 0;
	if ((PCI_BUS(d) == first_busno + 1) && (PCI_DEV(d) > 0))
		return 0;

	return 1;
}

/**
 * pcie_dw_mvebu_read_config() - Read from configuration space
 *
 * @bus: Pointer to the PCI bus
 * @bdf: Identifies the PCIe device to access
 * @offset: The offset into the device's configuration space
 * @valuep: A pointer at which to store the read value
 * @size: Indicates the size of access to perform
 *
 * Read a value of size @size from offset @offset within the configuration
 * space of the device identified by the bus, device & function numbers in @bdf
 * on the PCI bus @bus.
 *
 * Return: 0 on success
 */
static int pcie_dw_mvebu_read_config(struct udevice *bus, pci_dev_t bdf,
				     uint offset, ulong *valuep,
				     enum pci_size_t size)
{
	struct pcie_dw_mvebu *pcie = dev_get_priv(bus);
	uintptr_t va_address;
	ulong value;

	debug("PCIE CFG read:  (b,d,f)=(%2d,%2d,%2d) ",
	      PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));

	if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) {
		debug("- out of range\n");
		*valuep = pci_get_ff(size);
		return 0;
	}

	va_address = set_cfg_address(pcie, bdf, offset);

	value = readl(va_address);

	debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);
	*valuep = pci_conv_32_to_size(value, offset, size);

	return 0;
}

/**
 * pcie_dw_mvebu_write_config() - Write to configuration space
 *
 * @bus: Pointer to the PCI bus
 * @bdf: Identifies the PCIe device to access
 * @offset: The offset into the device's configuration space
 * @value: The value to write
 * @size: Indicates the size of access to perform
 *
 * Write the value @value of size @size from offset @offset within the
 * configuration space of the device identified by the bus, device & function
 * numbers in @bdf on the PCI bus @bus.
 *
 * Return: 0 on success
 */
static int pcie_dw_mvebu_write_config(struct udevice *bus, pci_dev_t bdf,
				      uint offset, ulong value,
				      enum pci_size_t size)
{
	struct pcie_dw_mvebu *pcie = dev_get_priv(bus);
	uintptr_t va_address;
	ulong old;

	debug("PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
	      PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
	debug("(addr,val)=(0x%04x, 0x%08lx)\n", offset, value);

	if (!pcie_dw_addr_valid(bdf, pcie->first_busno)) {
		debug("- out of range\n");
		return 0;
	}

	va_address = set_cfg_address(pcie, bdf, offset);

	old = readl(va_address);
	value = pci_conv_size_to_32(old, value, offset, size);
	writel(value, va_address);

	return 0;
}

/**
 * pcie_dw_configure() - Configure link capabilities and speed
 *
 * @regs_base: A pointer to the PCIe controller registers
 * @cap_speed: The capabilities and speed to configure
 *
 * Configure the link capabilities and speed in the PCIe root complex.
 */
static void pcie_dw_configure(const void *regs_base, u32 cap_speed)
{
	/*
	 * TODO (shadi@marvell.com, sr@denx.de):
	 * Need to read the serdes speed from the dts and according to it
	 * configure the PCIe gen
	 */

	/* Set link to GEN 3 */
	clrsetbits_le32(regs_base + PCIE_LINK_CTL_2,
			TARGET_LINK_SPEED_MASK, cap_speed);
	clrsetbits_le32(regs_base + PCIE_LINK_CAPABILITY,
			TARGET_LINK_SPEED_MASK, cap_speed);
	setbits_le32(regs_base + PCIE_GEN3_EQU_CTRL, GEN3_EQU_EVAL_2MS_DISABLE);
}

/**
 * is_link_up() - Return the link state
 *
 * @regs_base: A pointer to the PCIe controller registers
 *
 * Return: 1 (true) for active line and 0 (false) for no link
 */
static int is_link_up(const void *regs_base)
{
	u32 mask = PCIE_GLB_STS_RDLH_LINK_UP | PCIE_GLB_STS_PHY_LINK_UP;
	u32 reg;

	reg = readl(regs_base + PCIE_GLOBAL_STATUS);
	if ((reg & mask) == mask)
		return 1;

	return 0;
}

/**
 * wait_link_up() - Wait for the link to come up
 *
 * @regs_base: A pointer to the PCIe controller registers
 *
 * Return: 1 (true) for active line and 0 (false) for no link (timeout)
 */
static int wait_link_up(const void *regs_base)
{
	unsigned long timeout;

	timeout = get_timer(0) + PCIE_LINK_UP_TIMEOUT_MS;
	while (!is_link_up(regs_base)) {
		if (get_timer(0) > timeout)
			return 0;
	};

	return 1;
}

/**
 * pcie_dw_mvebu_pcie_link_up() - Configure the PCIe root port
 *
 * @regs_base: A pointer to the PCIe controller registers
 * @cap_speed: The capabilities and speed to configure
 *
 * Configure the PCIe controller root complex depending on the
 * requested link capabilities and speed.
 *
 * Return: 1 (true) for active line and 0 (false) for no link
 */
static int pcie_dw_mvebu_pcie_link_up(const void *regs_base, u32 cap_speed)
{
	if (!is_link_up(regs_base)) {
		/* Disable LTSSM state machine to enable configuration */
		clrbits_le32(regs_base + PCIE_GLOBAL_CONTROL,
			     PCIE_APP_LTSSM_EN);
	}

	clrsetbits_le32(regs_base + PCIE_GLOBAL_CONTROL,
			PCIE_DEVICE_TYPE_MASK << PCIE_DEVICE_TYPE_OFFSET,
			PCIE_DEVICE_TYPE_RC << PCIE_DEVICE_TYPE_OFFSET);

	/* Set the PCIe master AXI attributes */
	writel(ARCACHE_SHAREABLE_CACHEABLE, regs_base + PCIE_ARCACHE_TRC);
	writel(AWCACHE_SHAREABLE_CACHEABLE, regs_base + PCIE_AWCACHE_TRC);

	/* DW pre link configurations */
	pcie_dw_configure(regs_base, cap_speed);

	if (!is_link_up(regs_base)) {
		/* Configuration done. Start LTSSM */
		setbits_le32(regs_base + PCIE_GLOBAL_CONTROL,
			     PCIE_APP_LTSSM_EN);
	}

	/* Check that link was established */
	if (!wait_link_up(regs_base))
		return 0;

	/*
	 * Link can be established in Gen 1. still need to wait
	 * till MAC nagaotiation is completed
	 */
	udelay(100);

	return 1;
}

/**
 * pcie_dw_regions_setup() - iATU region setup
 *
 * @pcie: Pointer to the PCI controller state
 *
 * Configure the iATU regions in the PCIe controller for outbound access.
 */
static void pcie_dw_regions_setup(struct pcie_dw_mvebu *pcie)
{
	/*
	 * Region #0 is used for Outbound CFG space access.
	 * Direction = Outbound
	 * Region Index = 0
	 */
	writel(0, pcie->ctrl_base + PCIE_ATU_VIEWPORT);

	writel((u32)(uintptr_t)pcie->cfg_base, pcie->ctrl_base
	       + PCIE_ATU_LOWER_BASE);
	writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_BASE);
	writel((u32)(uintptr_t)pcie->cfg_base + pcie->cfg_size,
	       pcie->ctrl_base + PCIE_ATU_LIMIT);

	writel(0, pcie->ctrl_base + PCIE_ATU_LOWER_TARGET);
	writel(0, pcie->ctrl_base + PCIE_ATU_UPPER_TARGET);
	writel(PCIE_ATU_TYPE_CFG0, pcie->ctrl_base + PCIE_ATU_CR1);
	writel(PCIE_ATU_ENABLE, pcie->ctrl_base + PCIE_ATU_CR2);
}

/**
 * pcie_dw_set_host_bars() - Configure the host BARs
 *
 * @regs_base: A pointer to the PCIe controller registers
 *
 * Configure the host BARs of the PCIe controller root port so that
 * PCI(e) devices may access the system memory.
 */
static void pcie_dw_set_host_bars(const void *regs_base)
{
	u32 size = gd->ram_size;
	u64 max_size;
	u32 reg;
	u32 bar0;

	/* Verify the maximal BAR size */
	reg = readl(regs_base + RESIZABLE_BAR_CAP);
	max_size = 1ULL << (5 + (reg + (1 << 4)));

	if (size > max_size) {
		size = max_size;
		printf("Warning: PCIe BARs can't map all DRAM space\n");
	}

	/* Set the BAR base and size towards DDR */
	bar0 = CONFIG_SYS_SDRAM_BASE & ~0xf;
	bar0 |= PCI_BASE_ADDRESS_MEM_TYPE_32;
	writel(CONFIG_SYS_SDRAM_BASE, regs_base + PCIE_CONFIG_BAR0);

	reg = ((size >> 20) - 1) << 12;
	writel(size, regs_base + RESIZABLE_BAR_CTL0);
}

/**
 * pcie_dw_mvebu_probe() - Probe the PCIe bus for active link
 *
 * @dev: A pointer to the device being operated on
 *
 * Probe for an active link on the PCIe bus and configure the controller
 * to enable this port.
 *
 * Return: 0 on success, else -ENODEV
 */
static int pcie_dw_mvebu_probe(struct udevice *dev)
{
	struct pcie_dw_mvebu *pcie = dev_get_priv(dev);
	struct udevice *ctlr = pci_get_controller(dev);
	struct pci_controller *hose = dev_get_uclass_priv(ctlr);

	pcie->first_busno = dev->seq;

	/* Don't register host if link is down */
	if (!pcie_dw_mvebu_pcie_link_up(pcie->ctrl_base, LINK_SPEED_GEN_3)) {
		printf("PCIE-%d: Link down\n", dev->seq);
		return -ENODEV;
	}

	printf("PCIE-%d: Link up (Gen%d-x%d, Bus%d)\n", dev->seq,
	       pcie_dw_get_link_speed(pcie->ctrl_base),
	       pcie_dw_get_link_width(pcie->ctrl_base), hose->first_busno);

	pcie_dw_regions_setup(pcie);

	/* Set the CLASS_REV of RC CFG header to PCI_CLASS_BRIDGE_PCI */
	clrsetbits_le32(pcie->ctrl_base + PCI_CLASS_REVISION,
			0xffff << 16, PCI_CLASS_BRIDGE_PCI << 16);

	pcie_dw_set_host_bars(pcie->ctrl_base);

	return 0;
}

/**
 * pcie_dw_mvebu_ofdata_to_platdata() - Translate from DT to device state
 *
 * @dev: A pointer to the device being operated on
 *
 * Translate relevant data from the device tree pertaining to device @dev into
 * state that the driver will later make use of. This state is stored in the
 * device's private data structure.
 *
 * Return: 0 on success, else -EINVAL
 */
static int pcie_dw_mvebu_ofdata_to_platdata(struct udevice *dev)
{
	struct pcie_dw_mvebu *pcie = dev_get_priv(dev);

	/* Get the controller base address */
	pcie->ctrl_base = (void *)dev_get_addr_index(dev, 0);
	if ((fdt_addr_t)pcie->ctrl_base == FDT_ADDR_T_NONE)
		return -EINVAL;

	/* Get the config space base address and size */
	pcie->cfg_base = (void *)dev_get_addr_size_index(dev, 1,
							 &pcie->cfg_size);
	if ((fdt_addr_t)pcie->cfg_base == FDT_ADDR_T_NONE)
		return -EINVAL;

	return 0;
}

static const struct dm_pci_ops pcie_dw_mvebu_ops = {
	.read_config	= pcie_dw_mvebu_read_config,
	.write_config	= pcie_dw_mvebu_write_config,
};

static const struct udevice_id pcie_dw_mvebu_ids[] = {
	{ .compatible = "marvell,armada8k-pcie" },
	{ }
};

U_BOOT_DRIVER(pcie_dw_mvebu) = {
	.name			= "pcie_dw_mvebu",
	.id			= UCLASS_PCI,
	.of_match		= pcie_dw_mvebu_ids,
	.ops			= &pcie_dw_mvebu_ops,
	.ofdata_to_platdata	= pcie_dw_mvebu_ofdata_to_platdata,
	.probe			= pcie_dw_mvebu_probe,
	.priv_auto_alloc_size	= sizeof(struct pcie_dw_mvebu),
};
