// SPDX-License-Identifier: GPL-2.0
/*
 * Renesas RCar Gen3 PCIEC driver
 *
 * Copyright (C) 2018-2019 Marek Vasut <marek.vasut@gmail.com>
 *
 * Based on Linux PCIe driver for Renesas R-Car SoCs
 *  Copyright (C) 2014 Renesas Electronics Europe Ltd
 *
 * Based on:
 *  arch/sh/drivers/pci/pcie-sh7786.c
 *  arch/sh/drivers/pci/ops-sh7786.c
 *  Copyright (C) 2009 - 2011  Paul Mundt
 *
 * Author: Phil Edworthy <phil.edworthy@renesas.com>
 */

#include <common.h>
#include <asm/io.h>
#include <clk.h>
#include <dm.h>
#include <errno.h>
#include <pci.h>
#include <wait_bit.h>
#include <linux/bitops.h>
#include <linux/log2.h>

#define PCIECAR			0x000010
#define PCIECCTLR		0x000018
#define  CONFIG_SEND_ENABLE	BIT(31)
#define  TYPE0			(0 << 8)
#define  TYPE1			BIT(8)
#define PCIECDR			0x000020
#define PCIEMSR			0x000028
#define PCIEINTXR		0x000400
#define PCIEPHYSR		0x0007f0
#define  PHYRDY			BIT(0)
#define PCIEMSITXR		0x000840

/* Transfer control */
#define PCIETCTLR		0x02000
#define  CFINIT			1
#define PCIETSTR		0x02004
#define  DATA_LINK_ACTIVE	1
#define PCIEERRFR		0x02020
#define  UNSUPPORTED_REQUEST	BIT(4)
#define PCIEMSIFR		0x02044
#define PCIEMSIALR		0x02048
#define  MSIFE			1
#define PCIEMSIAUR		0x0204c
#define PCIEMSIIER		0x02050

/* root port address */
#define PCIEPRAR(x)		(0x02080 + ((x) * 0x4))

/* local address reg & mask */
#define PCIELAR(x)		(0x02200 + ((x) * 0x20))
#define PCIELAMR(x)		(0x02208 + ((x) * 0x20))
#define  LAM_PREFETCH		BIT(3)
#define  LAM_64BIT		BIT(2)
#define  LAR_ENABLE		BIT(1)

/* PCIe address reg & mask */
#define PCIEPALR(x)		(0x03400 + ((x) * 0x20))
#define PCIEPAUR(x)		(0x03404 + ((x) * 0x20))
#define PCIEPAMR(x)		(0x03408 + ((x) * 0x20))
#define PCIEPTCTLR(x)		(0x0340c + ((x) * 0x20))
#define  PAR_ENABLE		BIT(31)
#define  IO_SPACE		BIT(8)

/* Configuration */
#define PCICONF(x)		(0x010000 + ((x) * 0x4))
#define PMCAP(x)		(0x010040 + ((x) * 0x4))
#define EXPCAP(x)		(0x010070 + ((x) * 0x4))
#define VCCAP(x)		(0x010100 + ((x) * 0x4))

/* link layer */
#define IDSETR1			0x011004
#define TLCTLR			0x011048
#define MACSR			0x011054
#define  SPCHGFIN		BIT(4)
#define  SPCHGFAIL		BIT(6)
#define  SPCHGSUC		BIT(7)
#define  LINK_SPEED		(0xf << 16)
#define  LINK_SPEED_2_5GTS	(1 << 16)
#define  LINK_SPEED_5_0GTS	(2 << 16)
#define MACCTLR			0x011058
#define  SPEED_CHANGE		BIT(24)
#define  SCRAMBLE_DISABLE	BIT(27)
#define MACS2R			0x011078
#define MACCGSPSETR		0x011084
#define  SPCNGRSN		BIT(31)

/* R-Car H1 PHY */
#define H1_PCIEPHYADRR		0x04000c
#define  WRITE_CMD		BIT(16)
#define  PHY_ACK		BIT(24)
#define  RATE_POS		12
#define  LANE_POS		8
#define  ADR_POS		0
#define H1_PCIEPHYDOUTR		0x040014

/* R-Car Gen2 PHY */
#define GEN2_PCIEPHYADDR	0x780
#define GEN2_PCIEPHYDATA	0x784
#define GEN2_PCIEPHYCTRL	0x78c

#define INT_PCI_MSI_NR		32

#define RCONF(x)		(PCICONF(0) + (x))
#define RPMCAP(x)		(PMCAP(0) + (x))
#define REXPCAP(x)		(EXPCAP(0) + (x))
#define RVCCAP(x)		(VCCAP(0) + (x))

#define PCIE_CONF_BUS(b)	(((b) & 0xff) << 24)
#define PCIE_CONF_DEV(d)	(((d) & 0x1f) << 19)
#define PCIE_CONF_FUNC(f)	(((f) & 0x7) << 16)

#define RCAR_PCI_MAX_RESOURCES	4
#define MAX_NR_INBOUND_MAPS	6

enum {
	RCAR_PCI_ACCESS_READ,
	RCAR_PCI_ACCESS_WRITE,
};

struct rcar_gen3_pcie_priv {
	fdt_addr_t		regs;
};

static void rcar_rmw32(struct udevice *dev, int where, u32 mask, u32 data)
{
	struct rcar_gen3_pcie_priv *priv = dev_get_plat(dev);
	int shift = 8 * (where & 3);

	clrsetbits_le32(priv->regs + (where & ~3),
			mask << shift, data << shift);
}

static u32 rcar_read_conf(const struct udevice *dev, int where)
{
	struct rcar_gen3_pcie_priv *priv = dev_get_plat(dev);
	int shift = 8 * (where & 3);

	return readl(priv->regs + (where & ~3)) >> shift;
}

static int rcar_pcie_config_access(const struct udevice *udev,
				   unsigned char access_type,
				   pci_dev_t bdf, int where, ulong *data)
{
	struct rcar_gen3_pcie_priv *priv = dev_get_plat(udev);
	u32 reg = where & ~3;

	/* Root bus */
	if (PCI_DEV(bdf) == 0) {
		if (access_type == RCAR_PCI_ACCESS_READ)
			*data = readl(priv->regs + PCICONF(where / 4));
		else
			writel(*data, priv->regs + PCICONF(where / 4));

		return 0;
	}

	/* Clear errors */
	clrbits_le32(priv->regs + PCIEERRFR, 0);

	/* Set the PIO address */
	writel((bdf << 8) | reg, priv->regs + PCIECAR);

	/* Enable the configuration access */
	if (!PCI_BUS(bdf))
		writel(CONFIG_SEND_ENABLE | TYPE0, priv->regs + PCIECCTLR);
	else
		writel(CONFIG_SEND_ENABLE | TYPE1, priv->regs + PCIECCTLR);

	/* Check for errors */
	if (readl(priv->regs + PCIEERRFR) & UNSUPPORTED_REQUEST)
		return -ENODEV;

	/* Check for master and target aborts */
	if (rcar_read_conf(udev, RCONF(PCI_STATUS)) &
		(PCI_STATUS_REC_MASTER_ABORT | PCI_STATUS_REC_TARGET_ABORT))
		return -ENODEV;

	if (access_type == RCAR_PCI_ACCESS_READ)
		*data = readl(priv->regs + PCIECDR);
	else
		writel(*data, priv->regs + PCIECDR);

	/* Disable the configuration access */
	writel(0, priv->regs + PCIECCTLR);

	return 0;
}

static int rcar_gen3_pcie_addr_valid(pci_dev_t d, uint where)
{
	u32 slot;

	if (PCI_BUS(d))
		return -EINVAL;

	if (PCI_FUNC(d))
		return -EINVAL;

	slot = PCI_DEV(d);
	if (slot > 1)
		return -EINVAL;

	return 0;
}

static int rcar_gen3_pcie_read_config(const struct udevice *dev, pci_dev_t bdf,
				      uint where, ulong *val,
				      enum pci_size_t size)
{
	ulong reg;
	int ret;

	ret = rcar_gen3_pcie_addr_valid(bdf, where);
	if (ret) {
		*val = pci_get_ff(size);
		return 0;
	}

	ret = rcar_pcie_config_access(dev, RCAR_PCI_ACCESS_READ,
				      bdf, where, &reg);
	if (ret != 0)
		reg = 0xffffffffUL;

	*val = pci_conv_32_to_size(reg, where, size);

	return ret;
}

static int rcar_gen3_pcie_write_config(struct udevice *dev, pci_dev_t bdf,
				       uint where, ulong val,
				       enum pci_size_t size)
{
	ulong data;
	int ret;

	ret = rcar_gen3_pcie_addr_valid(bdf, where);
	if (ret)
		return ret;

	data = pci_conv_32_to_size(val, where, size);

	ret = rcar_pcie_config_access(dev, RCAR_PCI_ACCESS_WRITE,
				      bdf, where, &data);

	return ret;
}

static int rcar_gen3_pcie_wait_for_phyrdy(struct udevice *dev)
{
	struct rcar_gen3_pcie_priv *priv = dev_get_plat(dev);

	return wait_for_bit_le32((void *)priv->regs + PCIEPHYSR, PHYRDY,
				 true, 50, false);
}

static int rcar_gen3_pcie_wait_for_dl(struct udevice *dev)
{
	struct rcar_gen3_pcie_priv *priv = dev_get_plat(dev);

	return wait_for_bit_le32((void *)priv->regs + PCIETSTR,
				 DATA_LINK_ACTIVE, true, 50, false);
}

static int rcar_gen3_pcie_hw_init(struct udevice *dev)
{
	struct rcar_gen3_pcie_priv *priv = dev_get_plat(dev);
	int ret;

	/* Begin initialization */
	writel(0, priv->regs + PCIETCTLR);

	/* Set mode */
	writel(1, priv->regs + PCIEMSR);

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

	/*
	 * Initial header for port config space is type 1, set the device
	 * class to match. Hardware takes care of propagating the IDSETR
	 * settings, so there is no need to bother with a quirk.
	 */
	writel(PCI_CLASS_BRIDGE_PCI << 16, priv->regs + IDSETR1);

	/*
	 * Setup Secondary Bus Number & Subordinate Bus Number, even though
	 * they aren't used, to avoid bridge being detected as broken.
	 */
	rcar_rmw32(dev, RCONF(PCI_SECONDARY_BUS), 0xff, 1);
	rcar_rmw32(dev, RCONF(PCI_SUBORDINATE_BUS), 0xff, 1);

	/* Initialize default capabilities. */
	rcar_rmw32(dev, REXPCAP(0), 0xff, PCI_CAP_ID_EXP);
	rcar_rmw32(dev, REXPCAP(PCI_EXP_FLAGS),
		   PCI_EXP_FLAGS_TYPE, PCI_EXP_TYPE_ROOT_PORT << 4);
	rcar_rmw32(dev, RCONF(PCI_HEADER_TYPE), 0x7f,
		   PCI_HEADER_TYPE_BRIDGE);

	/* Enable data link layer active state reporting */
	rcar_rmw32(dev, REXPCAP(PCI_EXP_LNKCAP),
		   PCI_EXP_LNKCAP_DLLLARC, PCI_EXP_LNKCAP_DLLLARC);

	/* Write out the physical slot number = 0 */
	rcar_rmw32(dev, REXPCAP(PCI_EXP_SLTCAP),
		   PCI_EXP_SLTCAP_PSN, 0);

	/* Set the completion timer timeout to the maximum 50ms. */
	rcar_rmw32(dev, TLCTLR + 1, 0x3f, 50);

	/* Terminate list of capabilities (Next Capability Offset=0) */
	rcar_rmw32(dev, RVCCAP(0), 0xfff00000, 0);

	/* Finish initialization - establish a PCI Express link */
	writel(CFINIT, priv->regs + PCIETCTLR);

	return rcar_gen3_pcie_wait_for_dl(dev);
}

static int rcar_gen3_pcie_probe(struct udevice *dev)
{
	struct rcar_gen3_pcie_priv *priv = dev_get_plat(dev);
	struct pci_controller *hose = dev_get_uclass_priv(dev);
	struct clk pci_clk;
	u32 mask;
	int i, cnt, ret;

	ret = clk_get_by_index(dev, 0, &pci_clk);
	if (ret)
		return ret;

	ret = clk_enable(&pci_clk);
	if (ret)
		return ret;

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

		if (hose->regions[i].phys_start == 0)
			continue;

		mask = (roundup_pow_of_two(hose->regions[i].size) - 1) & ~0xf;
		mask |= LAR_ENABLE;
		writel(rounddown_pow_of_two(hose->regions[i].phys_start),
			priv->regs + PCIEPRAR(0));
		writel(rounddown_pow_of_two(hose->regions[i].phys_start),
			priv->regs + PCIELAR(0));
		writel(mask, priv->regs + PCIELAMR(0));
		break;
	}

	writel(0, priv->regs + PCIEPRAR(1));
	writel(0, priv->regs + PCIELAR(1));
	writel(0, priv->regs + PCIELAMR(1));

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

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

		writel(0, priv->regs + PCIEPTCTLR(cnt));
		writel((hose->regions[i].size - 1) & ~0x7f,
		       priv->regs + PCIEPAMR(cnt));
		writel(upper_32_bits(hose->regions[i].phys_start),
		       priv->regs + PCIEPAUR(cnt));
		writel(lower_32_bits(hose->regions[i].phys_start),
		       priv->regs + PCIEPALR(cnt));
		mask = PAR_ENABLE;
		if (hose->regions[i].flags == PCI_REGION_IO)
			mask |= IO_SPACE;
		writel(mask, priv->regs + PCIEPTCTLR(cnt));

		cnt++;
	}

	return 0;
}

static int rcar_gen3_pcie_of_to_plat(struct udevice *dev)
{
	struct rcar_gen3_pcie_priv *priv = dev_get_plat(dev);

	priv->regs = devfdt_get_addr_index(dev, 0);
	if (!priv->regs)
		return -EINVAL;

	return 0;
}

static const struct dm_pci_ops rcar_gen3_pcie_ops = {
	.read_config	= rcar_gen3_pcie_read_config,
	.write_config	= rcar_gen3_pcie_write_config,
};

static const struct udevice_id rcar_gen3_pcie_ids[] = {
	{ .compatible = "renesas,pcie-rcar-gen3" },
	{ }
};

U_BOOT_DRIVER(rcar_gen3_pcie) = {
	.name			= "rcar_gen3_pcie",
	.id			= UCLASS_PCI,
	.of_match		= rcar_gen3_pcie_ids,
	.ops			= &rcar_gen3_pcie_ops,
	.probe			= rcar_gen3_pcie_probe,
	.of_to_plat	= rcar_gen3_pcie_of_to_plat,
	.plat_auto	= sizeof(struct rcar_gen3_pcie_priv),
};
