// SPDX-License-Identifier: GPL-2.0
/*
 * Renesas RCar Gen2 PCIEC driver
 *
 * Copyright (C) 2018 Marek Vasut <marek.vasut@gmail.com>
 */

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

/* AHB-PCI Bridge PCI communication registers */
#define RCAR_AHBPCI_PCICOM_OFFSET	0x800

#define RCAR_PCIAHB_WIN1_CTR_REG	(RCAR_AHBPCI_PCICOM_OFFSET + 0x00)
#define RCAR_PCIAHB_WIN2_CTR_REG	(RCAR_AHBPCI_PCICOM_OFFSET + 0x04)
#define RCAR_PCIAHB_PREFETCH0		0x0
#define RCAR_PCIAHB_PREFETCH4		0x1
#define RCAR_PCIAHB_PREFETCH8		0x2
#define RCAR_PCIAHB_PREFETCH16		0x3

#define RCAR_AHBPCI_WIN1_CTR_REG	(RCAR_AHBPCI_PCICOM_OFFSET + 0x10)
#define RCAR_AHBPCI_WIN2_CTR_REG	(RCAR_AHBPCI_PCICOM_OFFSET + 0x14)
#define RCAR_AHBPCI_WIN_CTR_MEM		(3 << 1)
#define RCAR_AHBPCI_WIN_CTR_CFG		(5 << 1)
#define RCAR_AHBPCI_WIN1_HOST		BIT(30)
#define RCAR_AHBPCI_WIN1_DEVICE		BIT(31)

#define RCAR_PCI_INT_ENABLE_REG		(RCAR_AHBPCI_PCICOM_OFFSET + 0x20)
#define RCAR_PCI_INT_STATUS_REG		(RCAR_AHBPCI_PCICOM_OFFSET + 0x24)
#define RCAR_PCI_INT_SIGTABORT		BIT(0)
#define RCAR_PCI_INT_SIGRETABORT	BIT(1)
#define RCAR_PCI_INT_REMABORT		BIT(2)
#define RCAR_PCI_INT_PERR		BIT(3)
#define RCAR_PCI_INT_SIGSERR		BIT(4)
#define RCAR_PCI_INT_RESERR		BIT(5)
#define RCAR_PCI_INT_WIN1ERR		BIT(12)
#define RCAR_PCI_INT_WIN2ERR		BIT(13)
#define RCAR_PCI_INT_A			BIT(16)
#define RCAR_PCI_INT_B			BIT(17)
#define RCAR_PCI_INT_PME		BIT(19)
#define RCAR_PCI_INT_ALLERRORS (RCAR_PCI_INT_SIGTABORT		| \
				RCAR_PCI_INT_SIGRETABORT	| \
				RCAR_PCI_INT_SIGRETABORT	| \
				RCAR_PCI_INT_REMABORT		| \
				RCAR_PCI_INT_PERR		| \
				RCAR_PCI_INT_SIGSERR		| \
				RCAR_PCI_INT_RESERR		| \
				RCAR_PCI_INT_WIN1ERR		| \
				RCAR_PCI_INT_WIN2ERR)

#define RCAR_AHB_BUS_CTR_REG		(RCAR_AHBPCI_PCICOM_OFFSET + 0x30)
#define RCAR_AHB_BUS_MMODE_HTRANS	BIT(0)
#define RCAR_AHB_BUS_MMODE_BYTE_BURST	BIT(1)
#define RCAR_AHB_BUS_MMODE_WR_INCR	BIT(2)
#define RCAR_AHB_BUS_MMODE_HBUS_REQ	BIT(7)
#define RCAR_AHB_BUS_SMODE_READYCTR	BIT(17)
#define RCAR_AHB_BUS_MODE		(RCAR_AHB_BUS_MMODE_HTRANS |	\
					RCAR_AHB_BUS_MMODE_BYTE_BURST |	\
					RCAR_AHB_BUS_MMODE_WR_INCR |	\
					RCAR_AHB_BUS_MMODE_HBUS_REQ |	\
					RCAR_AHB_BUS_SMODE_READYCTR)

#define RCAR_USBCTR_REG			(RCAR_AHBPCI_PCICOM_OFFSET + 0x34)
#define RCAR_USBCTR_USBH_RST		BIT(0)
#define RCAR_USBCTR_PCICLK_MASK		BIT(1)
#define RCAR_USBCTR_PLL_RST		BIT(2)
#define RCAR_USBCTR_DIRPD		BIT(8)
#define RCAR_USBCTR_PCIAHB_WIN2_EN	BIT(9)
#define RCAR_USBCTR_PCIAHB_WIN1_256M	(0 << 10)
#define RCAR_USBCTR_PCIAHB_WIN1_512M	(1 << 10)
#define RCAR_USBCTR_PCIAHB_WIN1_1G	(2 << 10)
#define RCAR_USBCTR_PCIAHB_WIN1_2G	(3 << 10)
#define RCAR_USBCTR_PCIAHB_WIN1_MASK	(3 << 10)

#define RCAR_PCI_ARBITER_CTR_REG	(RCAR_AHBPCI_PCICOM_OFFSET + 0x40)
#define RCAR_PCI_ARBITER_PCIREQ0	BIT(0)
#define RCAR_PCI_ARBITER_PCIREQ1	BIT(1)
#define RCAR_PCI_ARBITER_PCIBP_MODE	BIT(12)

#define RCAR_PCI_UNIT_REV_REG		(RCAR_AHBPCI_PCICOM_OFFSET + 0x48)

struct rcar_gen2_pci_priv {
	fdt_addr_t		cfg_base;
	fdt_addr_t		mem_base;
};

static int rcar_gen2_pci_addr_valid(pci_dev_t d, uint offset)
{
	u32 slot;

	if (PCI_FUNC(d))
		return -EINVAL;

	/* Only one EHCI/OHCI device built-in */
	slot = PCI_DEV(d);
	if (slot != 1 && slot != 2)
		return -EINVAL;

	/* bridge logic only has registers to 0x40 */
	if (slot == 0x0 && offset >= 0x40)
		return -EINVAL;

	return 0;
}

static u32 get_bus_address(const struct udevice *dev, pci_dev_t bdf, u32 offset)
{
	struct rcar_gen2_pci_priv *priv = dev_get_priv(dev);

	return priv->cfg_base + (PCI_DEV(bdf) >> 1) * 0x100 + (offset & ~3);
}

static u32 setup_bus_address(struct udevice *dev, pci_dev_t bdf, u32 offset)
{
	struct rcar_gen2_pci_priv *priv = dev_get_priv(dev);
	u32 reg;

	reg = PCI_DEV(bdf) ? RCAR_AHBPCI_WIN1_DEVICE : RCAR_AHBPCI_WIN1_HOST;
	reg |= RCAR_AHBPCI_WIN_CTR_CFG;
	writel(reg, priv->cfg_base + RCAR_AHBPCI_WIN1_CTR_REG);

	return get_bus_address(dev, bdf, offset);
}

static int rcar_gen2_pci_read_config(const struct udevice *dev, pci_dev_t bdf,
				     uint offset, ulong *value,
				     enum pci_size_t size)
{
	u32 addr, reg;
	int ret;

	ret = rcar_gen2_pci_addr_valid(bdf, offset);
	if (ret) {
		*value = pci_get_ff(size);
		return 0;
	}

	addr = get_bus_address(dev, bdf, offset);
	reg = readl(addr);
	*value = pci_conv_32_to_size(reg, offset, size);

	return 0;
}

static int rcar_gen2_pci_write_config(struct udevice *dev, pci_dev_t bdf,
				      uint offset, ulong value,
				      enum pci_size_t size)
{
	u32 addr, reg, old;
	int ret;

	ret = rcar_gen2_pci_addr_valid(bdf, offset);
	if (ret)
		return ret;

	addr = get_bus_address(dev, bdf, offset);

	old = readl(addr);
	reg = pci_conv_size_to_32(old, value, offset, size);
	writel(reg, addr);

	return 0;
}

static int rcar_gen2_pci_probe(struct udevice *dev)
{
	struct rcar_gen2_pci_priv *priv = dev_get_priv(dev);
	struct clk pci_clk;
	u32 devad;
	int ret;

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

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

	/* Clock & Reset & Direct Power Down */
	clrsetbits_le32(priv->cfg_base + RCAR_USBCTR_REG,
			RCAR_USBCTR_DIRPD | RCAR_USBCTR_PCICLK_MASK |
			RCAR_USBCTR_USBH_RST,
			RCAR_USBCTR_PCIAHB_WIN1_1G);
	clrbits_le32(priv->cfg_base + RCAR_USBCTR_REG, RCAR_USBCTR_PLL_RST);

	/* AHB-PCI Bridge Communication Registers */
	writel(RCAR_AHB_BUS_MODE, priv->cfg_base + RCAR_AHB_BUS_CTR_REG);
	writel((CFG_SYS_SDRAM_BASE & 0xf0000000) | RCAR_PCIAHB_PREFETCH16,
	       priv->cfg_base + RCAR_PCIAHB_WIN1_CTR_REG);
	writel(0xf0000000 | RCAR_PCIAHB_PREFETCH16,
	       priv->cfg_base + RCAR_PCIAHB_WIN2_CTR_REG);
	writel(priv->mem_base | RCAR_AHBPCI_WIN_CTR_MEM,
	       priv->cfg_base + RCAR_AHBPCI_WIN2_CTR_REG);
	setbits_le32(priv->cfg_base + RCAR_PCI_ARBITER_CTR_REG,
		     RCAR_PCI_ARBITER_PCIREQ0 | RCAR_PCI_ARBITER_PCIREQ1 |
		     RCAR_PCI_ARBITER_PCIBP_MODE);

	/* PCI Configuration Registers for AHBPCI */
	devad = setup_bus_address(dev, PCI_BDF(0, 0, 0), 0);
	writel(priv->cfg_base + 0x800, devad + PCI_BASE_ADDRESS_0);
	writel(CFG_SYS_SDRAM_BASE & 0xf0000000, devad + PCI_BASE_ADDRESS_1);
	writel(0xf0000000, devad + PCI_BASE_ADDRESS_2);
	writel(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
	       PCI_COMMAND_PARITY | PCI_COMMAND_SERR,
	       devad + PCI_COMMAND);

	/* PCI Configuration Registers for OHCI */
	devad = setup_bus_address(dev, PCI_BDF(0, 1, 0), 0);
	writel(priv->mem_base + 0x0, devad + PCI_BASE_ADDRESS_0);
	writel(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
	       PCI_COMMAND_PARITY | PCI_COMMAND_SERR,
	       devad + PCI_COMMAND);

	/* PCI Configuration Registers for EHCI */
	devad = setup_bus_address(dev, PCI_BDF(0, 2, 0), 0);
	writel(priv->mem_base + 0x1000, devad + PCI_BASE_ADDRESS_0);
	writel(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
	       PCI_COMMAND_PARITY | PCI_COMMAND_SERR,
	       devad + PCI_COMMAND);

	/* Enable PCI interrupt */
	setbits_le32(priv->cfg_base + RCAR_PCI_INT_ENABLE_REG,
		     RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME);

	return 0;
}

static int rcar_gen2_pci_of_to_plat(struct udevice *dev)
{
	struct rcar_gen2_pci_priv *priv = dev_get_priv(dev);

	priv->cfg_base = devfdt_get_addr_index(dev, 0);
	priv->mem_base = devfdt_get_addr_index(dev, 1);
	if (!priv->cfg_base || !priv->mem_base)
		return -EINVAL;

	return 0;
}

static const struct dm_pci_ops rcar_gen2_pci_ops = {
	.read_config	= rcar_gen2_pci_read_config,
	.write_config	= rcar_gen2_pci_write_config,
};

static const struct udevice_id rcar_gen2_pci_ids[] = {
	{ .compatible = "renesas,pci-rcar-gen2" },
	{ }
};

U_BOOT_DRIVER(rcar_gen2_pci) = {
	.name			= "rcar_gen2_pci",
	.id			= UCLASS_PCI,
	.of_match		= rcar_gen2_pci_ids,
	.ops			= &rcar_gen2_pci_ops,
	.probe			= rcar_gen2_pci_probe,
	.of_to_plat	= rcar_gen2_pci_of_to_plat,
	.priv_auto	= sizeof(struct rcar_gen2_pci_priv),
};
