// SPDX-License-Identifier: GPL-2.0+
/*
 * Rockchip AXI PCIe host controller driver
 *
 * Copyright (c) 2016 Rockchip, Inc.
 * Copyright (c) 2020 Amarula Solutions(India)
 * Copyright (c) 2020 Jagan Teki <jagan@amarulasolutions.com>
 * Copyright (c) 2019 Patrick Wildt <patrick@blueri.se>
 * Copyright (c) 2018 Mark Kettenis <kettenis@openbsd.org>
 *
 * Bits taken from Linux Rockchip PCIe host controller.
 */

#include <common.h>
#include <clk.h>
#include <dm.h>
#include <asm/global_data.h>
#include <dm/device_compat.h>
#include <generic-phy.h>
#include <pci.h>
#include <power-domain.h>
#include <power/regulator.h>
#include <reset.h>
#include <syscon.h>
#include <asm/io.h>
#include <asm-generic/gpio.h>
#include <asm/arch-rockchip/clock.h>
#include <linux/iopoll.h>

DECLARE_GLOBAL_DATA_PTR;

#define HIWORD_UPDATE(mask, val)        (((mask) << 16) | (val))
#define HIWORD_UPDATE_BIT(val)          HIWORD_UPDATE(val, val)

#define ENCODE_LANES(x)                 ((((x) >> 1) & 3) << 4)
#define PCIE_CLIENT_BASE                0x0
#define PCIE_CLIENT_CONFIG              (PCIE_CLIENT_BASE + 0x00)
#define PCIE_CLIENT_CONF_ENABLE         HIWORD_UPDATE_BIT(0x0001)
#define PCIE_CLIENT_LINK_TRAIN_ENABLE   HIWORD_UPDATE_BIT(0x0002)
#define PCIE_CLIENT_MODE_RC             HIWORD_UPDATE_BIT(0x0040)
#define PCIE_CLIENT_GEN_SEL_1           HIWORD_UPDATE(0x0080, 0)
#define PCIE_CLIENT_BASIC_STATUS1	0x0048
#define PCIE_CLIENT_LINK_STATUS_UP	GENMASK(21, 20)
#define PCIE_CLIENT_LINK_STATUS_MASK	GENMASK(21, 20)
#define PCIE_LINK_UP(x) \
	(((x) & PCIE_CLIENT_LINK_STATUS_MASK) == PCIE_CLIENT_LINK_STATUS_UP)
#define PCIE_RC_NORMAL_BASE		0x800000
#define PCIE_LM_BASE			0x900000
#define PCIE_LM_VENDOR_ID              (PCIE_LM_BASE + 0x44)
#define PCIE_LM_VENDOR_ROCKCHIP		0x1d87
#define PCIE_LM_RCBAR			(PCIE_LM_BASE + 0x300)
#define PCIE_LM_RCBARPIE		BIT(19)
#define PCIE_LM_RCBARPIS		BIT(20)
#define PCIE_RC_BASE			0xa00000
#define PCIE_RC_CONFIG_DCR		(PCIE_RC_BASE + 0x0c4)
#define PCIE_RC_CONFIG_DCR_CSPL_SHIFT	18
#define PCIE_RC_CONFIG_DCR_CPLS_SHIFT	26
#define PCIE_RC_PCIE_LCAP		(PCIE_RC_BASE + 0x0cc)
#define PCIE_RC_PCIE_LCAP_APMS_L0S	BIT(10)
#define PCIE_ATR_BASE			0xc00000
#define PCIE_ATR_OB_ADDR0(i)		(PCIE_ATR_BASE + 0x000 + (i) * 0x20)
#define PCIE_ATR_OB_ADDR1(i)		(PCIE_ATR_BASE + 0x004 + (i) * 0x20)
#define PCIE_ATR_OB_DESC0(i)		(PCIE_ATR_BASE + 0x008 + (i) * 0x20)
#define PCIE_ATR_OB_DESC1(i)		(PCIE_ATR_BASE + 0x00c + (i) * 0x20)
#define PCIE_ATR_IB_ADDR0(i)		(PCIE_ATR_BASE + 0x800 + (i) * 0x8)
#define PCIE_ATR_IB_ADDR1(i)		(PCIE_ATR_BASE + 0x804 + (i) * 0x8)
#define PCIE_ATR_HDR_MEM		0x2
#define PCIE_ATR_HDR_IO			0x6
#define PCIE_ATR_HDR_CFG_TYPE0		0xa
#define PCIE_ATR_HDR_CFG_TYPE1		0xb
#define PCIE_ATR_HDR_RID		BIT(23)

#define PCIE_ATR_OB_REGION0_SIZE	(32 * 1024 * 1024)
#define PCIE_ATR_OB_REGION_SIZE		(1 * 1024 * 1024)

struct rockchip_pcie {
	fdt_addr_t axi_base;
	fdt_addr_t apb_base;
	int first_busno;
	struct udevice *dev;

	/* resets */
	struct reset_ctl core_rst;
	struct reset_ctl mgmt_rst;
	struct reset_ctl mgmt_sticky_rst;
	struct reset_ctl pipe_rst;
	struct reset_ctl pm_rst;
	struct reset_ctl pclk_rst;
	struct reset_ctl aclk_rst;

	/* gpio */
	struct gpio_desc ep_gpio;

	/* vpcie regulators */
	struct udevice *vpcie12v;
	struct udevice *vpcie3v3;
	struct udevice *vpcie1v8;
	struct udevice *vpcie0v9;

	/* phy */
	struct phy pcie_phy;
};

static int rockchip_pcie_rd_conf(const struct udevice *udev, pci_dev_t bdf,
				 uint offset, ulong *valuep,
				 enum pci_size_t size)
{
	struct rockchip_pcie *priv = dev_get_priv(udev);
	unsigned int bus = PCI_BUS(bdf);
	unsigned int dev = PCI_DEV(bdf);
	int where = PCIE_ECAM_OFFSET(PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), offset & ~0x3);
	ulong value;

	if (bus == priv->first_busno && dev == 0) {
		value = readl(priv->apb_base + PCIE_RC_NORMAL_BASE + where);
		*valuep = pci_conv_32_to_size(value, offset, size);
		return 0;
	}

	if ((bus == priv->first_busno + 1) && dev == 0) {
		value = readl(priv->axi_base + where);
		*valuep = pci_conv_32_to_size(value, offset, size);
		return 0;
	}

	*valuep = pci_get_ff(size);

	return 0;
}

static int rockchip_pcie_wr_conf(struct udevice *udev, pci_dev_t bdf,
				 uint offset, ulong value,
				 enum pci_size_t size)
{
	struct rockchip_pcie *priv = dev_get_priv(udev);
	unsigned int bus = PCI_BUS(bdf);
	unsigned int dev = PCI_DEV(bdf);
	int where = PCIE_ECAM_OFFSET(PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf), offset & ~0x3);
	ulong old;

	if (bus == priv->first_busno && dev == 0) {
		old = readl(priv->apb_base + PCIE_RC_NORMAL_BASE + where);
		value = pci_conv_size_to_32(old, value, offset, size);
		writel(value, priv->apb_base + PCIE_RC_NORMAL_BASE + where);
		return 0;
	}

	if ((bus == priv->first_busno + 1) && dev == 0) {
		old = readl(priv->axi_base + where);
		value = pci_conv_size_to_32(old, value, offset, size);
		writel(value, priv->axi_base + where);
		return 0;
	}

	return 0;
}

static int rockchip_pcie_atr_init(struct rockchip_pcie *priv)
{
	struct udevice *ctlr = pci_get_controller(priv->dev);
	struct pci_controller *hose = dev_get_uclass_priv(ctlr);
	u64 addr, size, offset;
	u32 type;
	int i, region;

	/* Use region 0 to map PCI configuration space. */
	writel(25 - 1, priv->apb_base + PCIE_ATR_OB_ADDR0(0));
	writel(0, priv->apb_base + PCIE_ATR_OB_ADDR1(0));
	writel(PCIE_ATR_HDR_CFG_TYPE0 | PCIE_ATR_HDR_RID,
	       priv->apb_base + PCIE_ATR_OB_DESC0(0));
	writel(0, priv->apb_base + PCIE_ATR_OB_DESC1(0));

	for (i = 0; i < hose->region_count; i++) {
		if (hose->regions[i].flags == PCI_REGION_SYS_MEMORY)
			continue;

		if (hose->regions[i].flags == PCI_REGION_IO)
			type = PCIE_ATR_HDR_IO;
		else
			type = PCIE_ATR_HDR_MEM;

		/* Only support identity mappings. */
		if (hose->regions[i].bus_start !=
		    hose->regions[i].phys_start)
			return -EINVAL;

		/* Only support mappings aligned on a region boundary. */
		addr = hose->regions[i].bus_start;
		if (addr & (PCIE_ATR_OB_REGION_SIZE - 1))
			return -EINVAL;

		/* Mappings should lie between AXI and APB regions. */
		size = hose->regions[i].size;
		if (addr < (u64)priv->axi_base + PCIE_ATR_OB_REGION0_SIZE)
			return -EINVAL;
		if (addr + size > (u64)priv->apb_base)
			return -EINVAL;

		offset = addr - (u64)priv->axi_base - PCIE_ATR_OB_REGION0_SIZE;
		region = 1 + (offset / PCIE_ATR_OB_REGION_SIZE);
		while (size > 0) {
			writel(32 - 1,
			       priv->apb_base + PCIE_ATR_OB_ADDR0(region));
			writel(0, priv->apb_base + PCIE_ATR_OB_ADDR1(region));
			writel(type | PCIE_ATR_HDR_RID,
			       priv->apb_base + PCIE_ATR_OB_DESC0(region));
			writel(0, priv->apb_base + PCIE_ATR_OB_DESC1(region));

			addr += PCIE_ATR_OB_REGION_SIZE;
			size -= PCIE_ATR_OB_REGION_SIZE;
			region++;
		}
	}

	/* Passthrough inbound translations unmodified. */
	writel(32 - 1, priv->apb_base + PCIE_ATR_IB_ADDR0(2));
	writel(0, priv->apb_base + PCIE_ATR_IB_ADDR1(2));

	return 0;
}

static int rockchip_pcie_init_port(struct udevice *dev)
{
	struct rockchip_pcie *priv = dev_get_priv(dev);
	u32 cr, val, status;
	int ret;

	if (dm_gpio_is_valid(&priv->ep_gpio))
		dm_gpio_set_value(&priv->ep_gpio, 0);

	ret = reset_assert(&priv->aclk_rst);
	if (ret) {
		dev_err(dev, "failed to assert aclk reset (ret=%d)\n", ret);
		return ret;
	}

	ret = reset_assert(&priv->pclk_rst);
	if (ret) {
		dev_err(dev, "failed to assert pclk reset (ret=%d)\n", ret);
		return ret;
	}

	ret = reset_assert(&priv->pm_rst);
	if (ret) {
		dev_err(dev, "failed to assert pm reset (ret=%d)\n", ret);
		return ret;
	}

	ret = generic_phy_init(&priv->pcie_phy);
	if (ret) {
		dev_err(dev, "failed to init phy (ret=%d)\n", ret);
		goto err_exit_phy;
	}

	ret = reset_assert(&priv->core_rst);
	if (ret) {
		dev_err(dev, "failed to assert core reset (ret=%d)\n", ret);
		goto err_exit_phy;
	}

	ret = reset_assert(&priv->mgmt_rst);
	if (ret) {
		dev_err(dev, "failed to assert mgmt reset (ret=%d)\n", ret);
		goto err_exit_phy;
	}

	ret = reset_assert(&priv->mgmt_sticky_rst);
	if (ret) {
		dev_err(dev, "failed to assert mgmt-sticky reset (ret=%d)\n",
			ret);
		goto err_exit_phy;
	}

	ret = reset_assert(&priv->pipe_rst);
	if (ret) {
		dev_err(dev, "failed to assert pipe reset (ret=%d)\n", ret);
		goto err_exit_phy;
	}

	udelay(10);

	ret = reset_deassert(&priv->pm_rst);
	if (ret) {
		dev_err(dev, "failed to deassert pm reset (ret=%d)\n", ret);
		goto err_exit_phy;
	}

	ret = reset_deassert(&priv->aclk_rst);
	if (ret) {
		dev_err(dev, "failed to deassert aclk reset (ret=%d)\n", ret);
		goto err_exit_phy;
	}

	ret = reset_deassert(&priv->pclk_rst);
	if (ret) {
		dev_err(dev, "failed to deassert pclk reset (ret=%d)\n", ret);
		goto err_exit_phy;
	}

	/* Select GEN1 for now */
	cr = PCIE_CLIENT_GEN_SEL_1;
	/* Set Root complex mode */
	cr |= PCIE_CLIENT_CONF_ENABLE | PCIE_CLIENT_MODE_RC;
	writel(cr, priv->apb_base + PCIE_CLIENT_CONFIG);

	ret = generic_phy_power_on(&priv->pcie_phy);
	if (ret) {
		dev_err(dev, "failed to power on phy (ret=%d)\n", ret);
		goto err_power_off_phy;
	}

	ret = reset_deassert(&priv->mgmt_sticky_rst);
	if (ret) {
		dev_err(dev, "failed to deassert mgmt-sticky reset (ret=%d)\n",
			ret);
		goto err_power_off_phy;
	}

	ret = reset_deassert(&priv->core_rst);
	if (ret) {
		dev_err(dev, "failed to deassert core reset (ret=%d)\n", ret);
		goto err_power_off_phy;
	}

	ret = reset_deassert(&priv->mgmt_rst);
	if (ret) {
		dev_err(dev, "failed to deassert mgmt reset (ret=%d)\n", ret);
		goto err_power_off_phy;
	}

	ret = reset_deassert(&priv->pipe_rst);
	if (ret) {
		dev_err(dev, "failed to deassert pipe reset (ret=%d)\n", ret);
		goto err_power_off_phy;
	}

	/* Enable Gen1 training */
	writel(PCIE_CLIENT_LINK_TRAIN_ENABLE,
	       priv->apb_base + PCIE_CLIENT_CONFIG);

	if (dm_gpio_is_valid(&priv->ep_gpio))
		dm_gpio_set_value(&priv->ep_gpio, 1);

	ret = readl_poll_sleep_timeout
			(priv->apb_base + PCIE_CLIENT_BASIC_STATUS1,
			status, PCIE_LINK_UP(status), 20, 500 * 1000);
	if (ret) {
		dev_err(dev, "PCIe link training gen1 timeout!\n");
		goto err_power_off_phy;
	}

	/* Initialize Root Complex registers. */
	writel(PCIE_LM_VENDOR_ROCKCHIP, priv->apb_base + PCIE_LM_VENDOR_ID);
	writel(PCI_CLASS_BRIDGE_PCI_NORMAL << 8,
	       priv->apb_base + PCIE_RC_BASE + PCI_CLASS_REVISION);
	writel(PCIE_LM_RCBARPIE | PCIE_LM_RCBARPIS,
	       priv->apb_base + PCIE_LM_RCBAR);

	if (dev_read_bool(dev, "aspm-no-l0s")) {
		val = readl(priv->apb_base + PCIE_RC_PCIE_LCAP);
		val &= ~PCIE_RC_PCIE_LCAP_APMS_L0S;
		writel(val, priv->apb_base + PCIE_RC_PCIE_LCAP);
	}

	/* Configure Address Translation. */
	ret = rockchip_pcie_atr_init(priv);
	if (ret) {
		dev_err(dev, "PCIE-%d: ATR init failed\n", dev_seq(dev));
		goto err_power_off_phy;
	}

	return 0;

err_power_off_phy:
	generic_phy_power_off(&priv->pcie_phy);
err_exit_phy:
	generic_phy_exit(&priv->pcie_phy);
	return ret;
}

static int rockchip_pcie_set_vpcie(struct udevice *dev)
{
	struct rockchip_pcie *priv = dev_get_priv(dev);
	int ret;

	if (priv->vpcie3v3) {
		ret = regulator_set_enable(priv->vpcie3v3, true);
		if (ret) {
			dev_err(dev, "failed to enable vpcie3v3 (ret=%d)\n",
				ret);
			return ret;
		}
	}

	if (priv->vpcie1v8) {
		ret = regulator_set_enable(priv->vpcie1v8, true);
		if (ret) {
			dev_err(dev, "failed to enable vpcie1v8 (ret=%d)\n",
				ret);
			goto err_disable_3v3;
		}
	}

	if (priv->vpcie0v9) {
		ret = regulator_set_enable(priv->vpcie0v9, true);
		if (ret) {
			dev_err(dev, "failed to enable vpcie0v9 (ret=%d)\n",
				ret);
			goto err_disable_1v8;
		}
	}

	return 0;

err_disable_1v8:
	if (priv->vpcie1v8)
		regulator_set_enable(priv->vpcie1v8, false);
err_disable_3v3:
	if (priv->vpcie3v3)
		regulator_set_enable(priv->vpcie3v3, false);
	return ret;
}

static int rockchip_pcie_parse_dt(struct udevice *dev)
{
	struct rockchip_pcie *priv = dev_get_priv(dev);
	int ret;

	priv->axi_base = dev_read_addr_name(dev, "axi-base");
	if (!priv->axi_base)
		return -ENODEV;

	priv->apb_base = dev_read_addr_name(dev, "apb-base");
	if (!priv->axi_base)
		return -ENODEV;

	ret = gpio_request_by_name(dev, "ep-gpios", 0,
				   &priv->ep_gpio, GPIOD_IS_OUT);
	if (ret) {
		dev_err(dev, "failed to find ep-gpios property\n");
		return ret;
	}

	ret = reset_get_by_name(dev, "core", &priv->core_rst);
	if (ret) {
		dev_err(dev, "failed to get core reset (ret=%d)\n", ret);
		return ret;
	}

	ret = reset_get_by_name(dev, "mgmt", &priv->mgmt_rst);
	if (ret) {
		dev_err(dev, "failed to get mgmt reset (ret=%d)\n", ret);
		return ret;
	}

	ret = reset_get_by_name(dev, "mgmt-sticky", &priv->mgmt_sticky_rst);
	if (ret) {
		dev_err(dev, "failed to get mgmt-sticky reset (ret=%d)\n", ret);
		return ret;
	}

	ret = reset_get_by_name(dev, "pipe", &priv->pipe_rst);
	if (ret) {
		dev_err(dev, "failed to get pipe reset (ret=%d)\n", ret);
		return ret;
	}

	ret = reset_get_by_name(dev, "pm", &priv->pm_rst);
	if (ret) {
		dev_err(dev, "failed to get pm reset (ret=%d)\n", ret);
		return ret;
	}

	ret = reset_get_by_name(dev, "pclk", &priv->pclk_rst);
	if (ret) {
		dev_err(dev, "failed to get pclk reset (ret=%d)\n", ret);
		return ret;
	}

	ret = reset_get_by_name(dev, "aclk", &priv->aclk_rst);
	if (ret) {
		dev_err(dev, "failed to get aclk reset (ret=%d)\n", ret);
		return ret;
	}

	ret = device_get_supply_regulator(dev, "vpcie3v3-supply",
					  &priv->vpcie3v3);
	if (ret && ret != -ENOENT) {
		dev_err(dev, "failed to get vpcie3v3 supply (ret=%d)\n", ret);
		return ret;
	}

	ret = device_get_supply_regulator(dev, "vpcie1v8-supply",
					  &priv->vpcie1v8);
	if (ret && ret != -ENOENT) {
		dev_err(dev, "failed to get vpcie1v8 supply (ret=%d)\n", ret);
		return ret;
	}

	ret = device_get_supply_regulator(dev, "vpcie0v9-supply",
					  &priv->vpcie0v9);
	if (ret && ret != -ENOENT) {
		dev_err(dev, "failed to get vpcie0v9 supply (ret=%d)\n", ret);
		return ret;
	}

	ret = generic_phy_get_by_index(dev, 0, &priv->pcie_phy);
	if (ret) {
		dev_err(dev, "failed to get pcie-phy (ret=%d)\n", ret);
		return ret;
	}

	return 0;
}

static int rockchip_pcie_probe(struct udevice *dev)
{
	struct rockchip_pcie *priv = dev_get_priv(dev);
	struct udevice *ctlr = pci_get_controller(dev);
	struct pci_controller *hose = dev_get_uclass_priv(ctlr);
	int ret;

	priv->first_busno = dev_seq(dev);
	priv->dev = dev;

	ret = rockchip_pcie_parse_dt(dev);
	if (ret)
		return ret;

	ret = rockchip_pcie_set_vpcie(dev);
	if (ret)
		return ret;

	ret = rockchip_pcie_init_port(dev);
	if (ret)
		return ret;

	dev_info(dev, "PCIE-%d: Link up (Bus%d)\n",
		 dev_seq(dev), hose->first_busno);

	return 0;
}

static const struct dm_pci_ops rockchip_pcie_ops = {
	.read_config	= rockchip_pcie_rd_conf,
	.write_config	= rockchip_pcie_wr_conf,
};

static const struct udevice_id rockchip_pcie_ids[] = {
	{ .compatible = "rockchip,rk3399-pcie" },
	{ }
};

U_BOOT_DRIVER(rockchip_pcie) = {
	.name			= "rockchip_pcie",
	.id			= UCLASS_PCI,
	.of_match		= rockchip_pcie_ids,
	.ops			= &rockchip_pcie_ops,
	.probe			= rockchip_pcie_probe,
	.priv_auto	= sizeof(struct rockchip_pcie),
};
