// 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 <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 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(SEND_ENABLE | TYPE0, priv->regs + PCIECCTLR);
	else
		writel(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_NORMAL << 8, 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),
};
