// 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 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),
};
