/*
 * ***************************************************************************
 * Copyright (C) 2015 Marvell International Ltd.
 * ***************************************************************************
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation, either version 2 of the License, or any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * ***************************************************************************
 */
/* pcie_advk.c
 *
 * Ported from Linux driver - driver/pci/host/pci-aardvark.c
 *
 * Author: Victor Gu <xigu@marvell.com>
 *         Hezi Shahmoon <hezi.shahmoon@marvell.com>
 *
 */

#include <common.h>
#include <dm.h>
#include <pci.h>
#include <asm/io.h>
#include <asm-generic/gpio.h>
#include <dm/device_compat.h>
#include <linux/bitops.h>
#include <linux/delay.h>
#include <linux/ioport.h>

/* PCIe core registers */
#define PCIE_CORE_CMD_STATUS_REG				0x4
#define     PCIE_CORE_CMD_IO_ACCESS_EN				BIT(0)
#define     PCIE_CORE_CMD_MEM_ACCESS_EN				BIT(1)
#define     PCIE_CORE_CMD_MEM_IO_REQ_EN				BIT(2)
#define PCIE_CORE_DEV_CTRL_STATS_REG				0xc8
#define     PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE	(0 << 4)
#define     PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE		(0 << 11)
#define PCIE_CORE_LINK_CTRL_STAT_REG				0xd0
#define     PCIE_CORE_LINK_TRAINING				BIT(5)
#define PCIE_CORE_ERR_CAPCTL_REG				0x118
#define     PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX			BIT(5)
#define     PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN			BIT(6)
#define     PCIE_CORE_ERR_CAPCTL_ECRC_CHECK			BIT(7)
#define     PCIE_CORE_ERR_CAPCTL_ECRC_CHECK_RCV			BIT(8)

/* PIO registers base address and register offsets */
#define PIO_BASE_ADDR				0x4000
#define PIO_CTRL				(PIO_BASE_ADDR + 0x0)
#define   PIO_CTRL_TYPE_MASK			GENMASK(3, 0)
#define   PIO_CTRL_ADDR_WIN_DISABLE		BIT(24)
#define PIO_STAT				(PIO_BASE_ADDR + 0x4)
#define   PIO_COMPLETION_STATUS_SHIFT		7
#define   PIO_COMPLETION_STATUS_MASK		GENMASK(9, 7)
#define   PIO_COMPLETION_STATUS_OK		0
#define   PIO_COMPLETION_STATUS_UR		1
#define   PIO_COMPLETION_STATUS_CRS		2
#define   PIO_COMPLETION_STATUS_CA		4
#define   PIO_NON_POSTED_REQ			BIT(10)
#define   PIO_ERR_STATUS			BIT(11)
#define PIO_ADDR_LS				(PIO_BASE_ADDR + 0x8)
#define PIO_ADDR_MS				(PIO_BASE_ADDR + 0xc)
#define PIO_WR_DATA				(PIO_BASE_ADDR + 0x10)
#define PIO_WR_DATA_STRB			(PIO_BASE_ADDR + 0x14)
#define PIO_RD_DATA				(PIO_BASE_ADDR + 0x18)
#define PIO_START				(PIO_BASE_ADDR + 0x1c)
#define PIO_ISR					(PIO_BASE_ADDR + 0x20)

/* Aardvark Control registers */
#define CONTROL_BASE_ADDR			0x4800
#define PCIE_CORE_CTRL0_REG			(CONTROL_BASE_ADDR + 0x0)
#define     PCIE_GEN_SEL_MSK			0x3
#define     PCIE_GEN_SEL_SHIFT			0x0
#define     SPEED_GEN_1				0
#define     SPEED_GEN_2				1
#define     SPEED_GEN_3				2
#define     IS_RC_MSK				1
#define     IS_RC_SHIFT				2
#define     LANE_CNT_MSK			0x18
#define     LANE_CNT_SHIFT			0x3
#define     LANE_COUNT_1			(0 << LANE_CNT_SHIFT)
#define     LANE_COUNT_2			(1 << LANE_CNT_SHIFT)
#define     LANE_COUNT_4			(2 << LANE_CNT_SHIFT)
#define     LANE_COUNT_8			(3 << LANE_CNT_SHIFT)
#define     LINK_TRAINING_EN			BIT(6)
#define PCIE_CORE_CTRL2_REG			(CONTROL_BASE_ADDR + 0x8)
#define     PCIE_CORE_CTRL2_RESERVED		0x7
#define     PCIE_CORE_CTRL2_TD_ENABLE		BIT(4)
#define     PCIE_CORE_CTRL2_STRICT_ORDER_ENABLE	BIT(5)
#define     PCIE_CORE_CTRL2_ADDRWIN_MAP_ENABLE	BIT(6)

/* LMI registers base address and register offsets */
#define LMI_BASE_ADDR				0x6000
#define CFG_REG					(LMI_BASE_ADDR + 0x0)
#define     LTSSM_SHIFT				24
#define     LTSSM_MASK				0x3f
#define     LTSSM_L0				0x10

/* PCIe core controller registers */
#define CTRL_CORE_BASE_ADDR			0x18000
#define CTRL_CONFIG_REG				(CTRL_CORE_BASE_ADDR + 0x0)
#define     CTRL_MODE_SHIFT			0x0
#define     CTRL_MODE_MASK			0x1
#define     PCIE_CORE_MODE_DIRECT		0x0
#define     PCIE_CORE_MODE_COMMAND		0x1

/* Transaction types */
#define PCIE_CONFIG_RD_TYPE0			0x8
#define PCIE_CONFIG_RD_TYPE1			0x9
#define PCIE_CONFIG_WR_TYPE0			0xa
#define PCIE_CONFIG_WR_TYPE1			0xb

/* PCI_BDF shifts 8bit, so we need extra 4bit shift */
#define PCIE_BDF(dev)				(dev << 4)
#define PCIE_CONF_BUS(bus)			(((bus) & 0xff) << 20)
#define PCIE_CONF_DEV(dev)			(((dev) & 0x1f) << 15)
#define PCIE_CONF_FUNC(fun)			(((fun) & 0x7)	<< 12)
#define PCIE_CONF_REG(reg)			((reg) & 0xffc)
#define PCIE_CONF_ADDR(bus, devfn, where)	\
	(PCIE_CONF_BUS(bus) | PCIE_CONF_DEV(PCI_SLOT(devfn))	| \
	 PCIE_CONF_FUNC(PCI_FUNC(devfn)) | PCIE_CONF_REG(where))

/* PCIe Retries & Timeout definitions */
#define MAX_RETRIES				10
#define PIO_WAIT_TIMEOUT			100
#define LINK_WAIT_TIMEOUT			100000

#define CFG_RD_UR_VAL			0xFFFFFFFF
#define CFG_RD_CRS_VAL			0xFFFF0001

/**
 * struct pcie_advk - Advk PCIe controller state
 *
 * @reg_base:    The base address of the register 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
 *               (PEX switches etc).
 * @device:      The pointer to PCI uclass device.
 */
struct pcie_advk {
	void           *base;
	int            first_busno;
	struct udevice *dev;
	struct gpio_desc reset_gpio;
};

static inline void advk_writel(struct pcie_advk *pcie, uint val, uint reg)
{
	writel(val, pcie->base + reg);
}

static inline uint advk_readl(struct pcie_advk *pcie, uint reg)
{
	return readl(pcie->base + reg);
}

/**
 * pcie_advk_addr_valid() - Check for valid bus address
 *
 * @bdf: The PCI device to access
 * @first_busno: Bus number of the PCIe controller root complex
 *
 * Return: 1 on valid, 0 on invalid
 */
static int pcie_advk_addr_valid(pci_dev_t bdf, int first_busno)
{
	/*
	 * In PCIE-E only a single device (0) can exist
	 * on the local bus. Beyound the local bus, there might be
	 * a Switch and everything is possible.
	 */
	if ((PCI_BUS(bdf) == first_busno) && (PCI_DEV(bdf) > 0))
		return 0;

	return 1;
}

/**
 * pcie_advk_wait_pio() - Wait for PIO access to be accomplished
 *
 * @pcie: The PCI device to access
 *
 * Wait up to 1 micro second for PIO access to be accomplished.
 *
 * Return 1 (true) if PIO access is accomplished.
 * Return 0 (false) if PIO access is timed out.
 */
static int pcie_advk_wait_pio(struct pcie_advk *pcie)
{
	uint start, isr;
	uint count;

	for (count = 0; count < MAX_RETRIES; count++) {
		start = advk_readl(pcie, PIO_START);
		isr = advk_readl(pcie, PIO_ISR);
		if (!start && isr)
			return 1;
		/*
		 * Do not check the PIO state too frequently,
		 * 100us delay is appropriate.
		 */
		udelay(PIO_WAIT_TIMEOUT);
	}

	dev_err(pcie->dev, "config read/write timed out\n");
	return 0;
}

/**
 * pcie_advk_check_pio_status() - Validate PIO status and get the read result
 *
 * @pcie: Pointer to the PCI bus
 * @read: Read from or write to configuration space - true(read) false(write)
 * @read_val: Pointer to the read result, only valid when read is true
 *
 */
static int pcie_advk_check_pio_status(struct pcie_advk *pcie,
				      bool read,
				      uint *read_val)
{
	uint reg;
	unsigned int status;
	char *strcomp_status, *str_posted;

	reg = advk_readl(pcie, PIO_STAT);
	status = (reg & PIO_COMPLETION_STATUS_MASK) >>
		PIO_COMPLETION_STATUS_SHIFT;

	switch (status) {
	case PIO_COMPLETION_STATUS_OK:
		if (reg & PIO_ERR_STATUS) {
			strcomp_status = "COMP_ERR";
			break;
		}
		/* Get the read result */
		if (read)
			*read_val = advk_readl(pcie, PIO_RD_DATA);
		/* No error */
		strcomp_status = NULL;
		break;
	case PIO_COMPLETION_STATUS_UR:
		if (read) {
			/* For reading, UR is not an error status. */
			*read_val = CFG_RD_UR_VAL;
			strcomp_status = NULL;
		} else {
			strcomp_status = "UR";
		}
		break;
	case PIO_COMPLETION_STATUS_CRS:
		if (read) {
			/* For reading, CRS is not an error status. */
			*read_val = CFG_RD_CRS_VAL;
			strcomp_status = NULL;
		} else {
			strcomp_status = "CRS";
		}
		break;
	case PIO_COMPLETION_STATUS_CA:
		strcomp_status = "CA";
		break;
	default:
		strcomp_status = "Unknown";
		break;
	}

	if (!strcomp_status)
		return 0;

	if (reg & PIO_NON_POSTED_REQ)
		str_posted = "Non-posted";
	else
		str_posted = "Posted";

	dev_err(pcie->dev, "%s PIO Response Status: %s, %#x @ %#x\n",
		str_posted, strcomp_status, reg,
		advk_readl(pcie, PIO_ADDR_LS));

	return -EFAULT;
}

/**
 * pcie_advk_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_advk_read_config(const struct udevice *bus, pci_dev_t bdf,
				 uint offset, ulong *valuep,
				 enum pci_size_t size)
{
	struct pcie_advk *pcie = dev_get_priv(bus);
	uint reg;
	int ret;

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

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

	/* Start PIO */
	advk_writel(pcie, 0, PIO_START);
	advk_writel(pcie, 1, PIO_ISR);

	/* Program the control register */
	reg = advk_readl(pcie, PIO_CTRL);
	reg &= ~PIO_CTRL_TYPE_MASK;
	if (PCI_BUS(bdf) == pcie->first_busno)
		reg |= PCIE_CONFIG_RD_TYPE0;
	else
		reg |= PCIE_CONFIG_RD_TYPE1;
	advk_writel(pcie, reg, PIO_CTRL);

	/* Program the address registers */
	reg = PCIE_BDF(bdf) | PCIE_CONF_REG(offset);
	advk_writel(pcie, reg, PIO_ADDR_LS);
	advk_writel(pcie, 0, PIO_ADDR_MS);

	/* Start the transfer */
	advk_writel(pcie, 1, PIO_START);

	if (!pcie_advk_wait_pio(pcie))
		return -EINVAL;

	/* Check PIO status and get the read result */
	ret = pcie_advk_check_pio_status(pcie, true, &reg);
	if (ret)
		return ret;

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

	return 0;
}

/**
 * pcie_calc_datastrobe() - Calculate data strobe
 *
 * @offset: The offset into the device's configuration space
 * @size: Indicates the size of access to perform
 *
 * Calculate data strobe according to offset and size
 *
 */
static uint pcie_calc_datastrobe(uint offset, enum pci_size_t size)
{
	uint bytes, data_strobe;

	switch (size) {
	case PCI_SIZE_8:
		bytes = 1;
		break;
	case PCI_SIZE_16:
		bytes = 2;
		break;
	default:
		bytes = 4;
	}

	data_strobe = GENMASK(bytes - 1, 0) << (offset & 0x3);

	return data_strobe;
}

/**
 * pcie_advk_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_advk_write_config(struct udevice *bus, pci_dev_t bdf,
				  uint offset, ulong value,
				  enum pci_size_t size)
{
	struct pcie_advk *pcie = dev_get_priv(bus);
	uint reg;

	dev_dbg(pcie->dev, "PCIE CFG write: (b,d,f)=(%2d,%2d,%2d) ",
		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);

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

	/* Start PIO */
	advk_writel(pcie, 0, PIO_START);
	advk_writel(pcie, 1, PIO_ISR);

	/* Program the control register */
	reg = advk_readl(pcie, PIO_CTRL);
	reg &= ~PIO_CTRL_TYPE_MASK;
	if (PCI_BUS(bdf) == pcie->first_busno)
		reg |= PCIE_CONFIG_WR_TYPE0;
	else
		reg |= PCIE_CONFIG_WR_TYPE1;
	advk_writel(pcie, reg, PIO_CTRL);

	/* Program the address registers */
	reg = PCIE_BDF(bdf) | PCIE_CONF_REG(offset);
	advk_writel(pcie, reg, PIO_ADDR_LS);
	advk_writel(pcie, 0, PIO_ADDR_MS);
	dev_dbg(pcie->dev, "\tPIO req. - addr = 0x%08x\n", reg);

	/* Program the data register */
	reg = pci_conv_size_to_32(0, value, offset, size);
	advk_writel(pcie, reg, PIO_WR_DATA);
	dev_dbg(pcie->dev, "\tPIO req. - val  = 0x%08x\n", reg);

	/* Program the data strobe */
	reg = pcie_calc_datastrobe(offset, size);
	advk_writel(pcie, reg, PIO_WR_DATA_STRB);
	dev_dbg(pcie->dev, "\tPIO req. - strb = 0x%02x\n", reg);

	/* Start the transfer */
	advk_writel(pcie, 1, PIO_START);

	if (!pcie_advk_wait_pio(pcie)) {
		return -EINVAL;
	}

	/* Check PIO status */
	pcie_advk_check_pio_status(pcie, false, &reg);

	return 0;
}

/**
 * pcie_advk_link_up() - Check if PCIe link is up or not
 *
 * @pcie: The PCI device to access
 *
 * Return 1 (true) on link up.
 * Return 0 (false) on link down.
 */
static int pcie_advk_link_up(struct pcie_advk *pcie)
{
	u32 val, ltssm_state;

	val = advk_readl(pcie, CFG_REG);
	ltssm_state = (val >> LTSSM_SHIFT) & LTSSM_MASK;
	return ltssm_state >= LTSSM_L0;
}

/**
 * pcie_advk_wait_for_link() - Wait for link training to be accomplished
 *
 * @pcie: The PCI device to access
 *
 * Wait up to 1 second for link training to be accomplished.
 *
 * Return 1 (true) if link training ends up with link up success.
 * Return 0 (false) if link training ends up with link up failure.
 */
static int pcie_advk_wait_for_link(struct pcie_advk *pcie)
{
	int retries;

	/* check if the link is up or not */
	for (retries = 0; retries < MAX_RETRIES; retries++) {
		if (pcie_advk_link_up(pcie)) {
			printf("PCIE-%d: Link up\n", pcie->first_busno);
			return 0;
		}

		udelay(LINK_WAIT_TIMEOUT);
	}

	printf("PCIE-%d: Link down\n", pcie->first_busno);

	return -ETIMEDOUT;
}

/**
 * pcie_advk_setup_hw() - PCIe initailzation
 *
 * @pcie: The PCI device to access
 *
 * Return: 0 on success
 */
static int pcie_advk_setup_hw(struct pcie_advk *pcie)
{
	u32 reg;

	/* Set to Direct mode */
	reg = advk_readl(pcie, CTRL_CONFIG_REG);
	reg &= ~(CTRL_MODE_MASK << CTRL_MODE_SHIFT);
	reg |= ((PCIE_CORE_MODE_DIRECT & CTRL_MODE_MASK) << CTRL_MODE_SHIFT);
	advk_writel(pcie, reg, CTRL_CONFIG_REG);

	/* Set PCI global control register to RC mode */
	reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
	reg |= (IS_RC_MSK << IS_RC_SHIFT);
	advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);

	/* Set Advanced Error Capabilities and Control PF0 register */
	reg = PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX |
		PCIE_CORE_ERR_CAPCTL_ECRC_CHK_TX_EN |
		PCIE_CORE_ERR_CAPCTL_ECRC_CHECK |
		PCIE_CORE_ERR_CAPCTL_ECRC_CHECK_RCV;
	advk_writel(pcie, reg, PCIE_CORE_ERR_CAPCTL_REG);

	/* Set PCIe Device Control and Status 1 PF0 register */
	reg = PCIE_CORE_DEV_CTRL_STATS_RELAX_ORDER_DISABLE |
		PCIE_CORE_DEV_CTRL_STATS_SNOOP_DISABLE;
	advk_writel(pcie, reg, PCIE_CORE_DEV_CTRL_STATS_REG);

	/* Program PCIe Control 2 to disable strict ordering */
	reg = PCIE_CORE_CTRL2_RESERVED |
		PCIE_CORE_CTRL2_TD_ENABLE;
	advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);

	/* Set GEN2 */
	reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
	reg &= ~PCIE_GEN_SEL_MSK;
	reg |= SPEED_GEN_2;
	advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);

	/* Set lane X1 */
	reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
	reg &= ~LANE_CNT_MSK;
	reg |= LANE_COUNT_1;
	advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);

	/* Enable link training */
	reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
	reg |= LINK_TRAINING_EN;
	advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);

	/*
	 * Enable AXI address window location generation:
	 * When it is enabled, the default outbound window
	 * configurations (Default User Field: 0xD0074CFC)
	 * are used to transparent address translation for
	 * the outbound transactions. Thus, PCIe address
	 * windows are not required.
	 */
	reg = advk_readl(pcie, PCIE_CORE_CTRL2_REG);
	reg |= PCIE_CORE_CTRL2_ADDRWIN_MAP_ENABLE;
	advk_writel(pcie, reg, PCIE_CORE_CTRL2_REG);

	/*
	 * Bypass the address window mapping for PIO:
	 * Since PIO access already contains all required
	 * info over AXI interface by PIO registers, the
	 * address window is not required.
	 */
	reg = advk_readl(pcie, PIO_CTRL);
	reg |= PIO_CTRL_ADDR_WIN_DISABLE;
	advk_writel(pcie, reg, PIO_CTRL);

	/* Start link training */
	reg = advk_readl(pcie, PCIE_CORE_LINK_CTRL_STAT_REG);
	reg |= PCIE_CORE_LINK_TRAINING;
	advk_writel(pcie, reg, PCIE_CORE_LINK_CTRL_STAT_REG);

	/* Wait for PCIe link up */
	if (pcie_advk_wait_for_link(pcie))
		return -ENXIO;

	reg = advk_readl(pcie, PCIE_CORE_CMD_STATUS_REG);
	reg |= PCIE_CORE_CMD_MEM_ACCESS_EN |
		PCIE_CORE_CMD_IO_ACCESS_EN |
		PCIE_CORE_CMD_MEM_IO_REQ_EN;
	advk_writel(pcie, reg, PCIE_CORE_CMD_STATUS_REG);

	return 0;
}

/**
 * pcie_advk_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_advk_probe(struct udevice *dev)
{
	struct pcie_advk *pcie = dev_get_priv(dev);

	gpio_request_by_name(dev, "reset-gpios", 0, &pcie->reset_gpio,
			     GPIOD_IS_OUT);
	/*
	 * Issue reset to add-in card through the dedicated GPIO.
	 * Some boards are connecting the card reset pin to common system
	 * reset wire and others are using separate GPIO port.
	 * In the last case we have to release a reset of the addon card
	 * using this GPIO.
	 *
	 * FIX-ME:
	 *     The PCIe RESET signal is not supposed to be released along
	 *     with the SOC RESET signal. It should be lowered as early as
	 *     possible before PCIe PHY initialization. Moreover, the PCIe
	 *     clock should be gated as well.
	 */
	if (dm_gpio_is_valid(&pcie->reset_gpio)) {
		dev_dbg(dev, "Toggle PCIE Reset GPIO ...\n");
		dm_gpio_set_value(&pcie->reset_gpio, 1);
		mdelay(200);
		dm_gpio_set_value(&pcie->reset_gpio, 0);
	} else {
		dev_warn(dev, "PCIE Reset on GPIO support is missing\n");
	}

	pcie->first_busno = dev_seq(dev);
	pcie->dev = pci_get_controller(dev);

	return pcie_advk_setup_hw(pcie);
}

static int pcie_advk_remove(struct udevice *dev)
{
	struct pcie_advk *pcie = dev_get_priv(dev);
	u32 reg;

	reg = advk_readl(pcie, PCIE_CORE_CTRL0_REG);
	reg &= ~LINK_TRAINING_EN;
	advk_writel(pcie, reg, PCIE_CORE_CTRL0_REG);

	return 0;
}

/**
 * pcie_advk_of_to_plat() - 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_advk_of_to_plat(struct udevice *dev)
{
	struct pcie_advk *pcie = dev_get_priv(dev);

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

	return 0;
}

static const struct dm_pci_ops pcie_advk_ops = {
	.read_config	= pcie_advk_read_config,
	.write_config	= pcie_advk_write_config,
};

static const struct udevice_id pcie_advk_ids[] = {
	{ .compatible = "marvell,armada-37xx-pcie" },
	{ }
};

U_BOOT_DRIVER(pcie_advk) = {
	.name			= "pcie_advk",
	.id			= UCLASS_PCI,
	.of_match		= pcie_advk_ids,
	.ops			= &pcie_advk_ops,
	.of_to_plat	= pcie_advk_of_to_plat,
	.probe			= pcie_advk_probe,
	.remove			= pcie_advk_remove,
	.flags			= DM_FLAG_OS_PREPARE,
	.priv_auto	= sizeof(struct pcie_advk),
};
