// SPDX-License-Identifier: GPL-2.0+ OR X11
/*
 * Copyright 2019 NXP
 *
 * PCIe DM U-Boot driver for Freescale PowerPC SoCs
 * Author: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
 */

#include <common.h>
#include <dm.h>
#include <malloc.h>
#include <mapmem.h>
#include <pci.h>
#include <asm/fsl_pci.h>
#include <asm/fsl_serdes.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <linux/delay.h>
#include "pcie_fsl.h"
#include <dm/device_compat.h>

LIST_HEAD(fsl_pcie_list);

static int fsl_pcie_link_up(struct fsl_pcie *pcie);

static int fsl_pcie_addr_valid(struct fsl_pcie *pcie, pci_dev_t bdf)
{
	struct udevice *bus = pcie->bus;

	if (!pcie->enabled)
		return -ENXIO;

	if (PCI_BUS(bdf) < dev_seq(bus))
		return -EINVAL;

	if (PCI_BUS(bdf) > dev_seq(bus) && (!fsl_pcie_link_up(pcie) || pcie->mode))
		return -EINVAL;

	if (PCI_BUS(bdf) == dev_seq(bus) && (PCI_DEV(bdf) > 0 || PCI_FUNC(bdf) > 0))
		return -EINVAL;

	if (PCI_BUS(bdf) == (dev_seq(bus) + 1) && (PCI_DEV(bdf) > 0))
		return -EINVAL;

	return 0;
}

static int fsl_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
				uint offset, ulong *valuep,
				enum pci_size_t size)
{
	struct fsl_pcie *pcie = dev_get_priv(bus);
	ccsr_fsl_pci_t *regs = pcie->regs;
	u32 val;

	if (fsl_pcie_addr_valid(pcie, bdf)) {
		*valuep = pci_get_ff(size);
		return 0;
	}

	val = PCI_CONF1_EXT_ADDRESS(PCI_BUS(bdf) - dev_seq(bus),
				    PCI_DEV(bdf), PCI_FUNC(bdf),
				    offset);
	out_be32(&regs->cfg_addr, val);

	sync();

	switch (size) {
	case PCI_SIZE_8:
		*valuep = in_8((u8 *)&regs->cfg_data + (offset & 3));
		break;
	case PCI_SIZE_16:
		*valuep = in_le16((u16 *)((u8 *)&regs->cfg_data +
			  (offset & 2)));
		break;
	case PCI_SIZE_32:
		*valuep = in_le32(&regs->cfg_data);
		break;
	}

	return 0;
}

static int fsl_pcie_write_config(struct udevice *bus, pci_dev_t bdf,
				 uint offset, ulong value,
				 enum pci_size_t size)
{
	struct fsl_pcie *pcie = dev_get_priv(bus);
	ccsr_fsl_pci_t *regs = pcie->regs;
	u32 val;
	u8 val_8;
	u16 val_16;
	u32 val_32;

	if (fsl_pcie_addr_valid(pcie, bdf))
		return 0;

	val = PCI_CONF1_EXT_ADDRESS(PCI_BUS(bdf) - dev_seq(bus),
				    PCI_DEV(bdf), PCI_FUNC(bdf),
				    offset);
	out_be32(&regs->cfg_addr, val);

	sync();

	switch (size) {
	case PCI_SIZE_8:
		val_8 = value;
		out_8((u8 *)&regs->cfg_data + (offset & 3), val_8);
		break;
	case PCI_SIZE_16:
		val_16 = value;
		out_le16((u16 *)((u8 *)&regs->cfg_data + (offset & 2)), val_16);
		break;
	case PCI_SIZE_32:
		val_32 = value;
		out_le32(&regs->cfg_data, val_32);
		break;
	}

	return 0;
}

static int fsl_pcie_hose_read_config(struct fsl_pcie *pcie, uint offset,
				     ulong *valuep, enum pci_size_t size)
{
	int ret;
	struct udevice *bus = pcie->bus;

	ret = fsl_pcie_read_config(bus, PCI_BDF(dev_seq(bus), 0, 0),
				   offset, valuep, size);

	return ret;
}

static int fsl_pcie_hose_write_config(struct fsl_pcie *pcie, uint offset,
				      ulong value, enum pci_size_t size)
{
	struct udevice *bus = pcie->bus;

	return fsl_pcie_write_config(bus, PCI_BDF(dev_seq(bus), 0, 0),
				     offset, value, size);
}

static int fsl_pcie_hose_read_config_byte(struct fsl_pcie *pcie, uint offset,
					  u8 *valuep)
{
	ulong val;
	int ret;

	ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_8);
	*valuep = val;

	return ret;
}

static int fsl_pcie_hose_read_config_word(struct fsl_pcie *pcie, uint offset,
					  u16 *valuep)
{
	ulong val;
	int ret;

	ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_16);
	*valuep = val;

	return ret;
}

static int fsl_pcie_hose_read_config_dword(struct fsl_pcie *pcie, uint offset,
					   u32 *valuep)
{
	ulong val;
	int ret;

	ret = fsl_pcie_hose_read_config(pcie, offset, &val, PCI_SIZE_32);
	*valuep = val;

	return ret;
}

static int fsl_pcie_hose_write_config_byte(struct fsl_pcie *pcie, uint offset,
					   u8 value)
{
	return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_8);
}

static int fsl_pcie_hose_write_config_word(struct fsl_pcie *pcie, uint offset,
					   u16 value)
{
	return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_16);
}

static int fsl_pcie_hose_write_config_dword(struct fsl_pcie *pcie, uint offset,
					    u32 value)
{
	return fsl_pcie_hose_write_config(pcie, offset, value, PCI_SIZE_32);
}

static int fsl_pcie_link_up(struct fsl_pcie *pcie)
{
	ccsr_fsl_pci_t *regs = pcie->regs;
	u16 ltssm;

	if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
		ltssm = (in_be32(&regs->pex_csr0)
			& PEX_CSR0_LTSSM_MASK) >> PEX_CSR0_LTSSM_SHIFT;
		return ltssm == LTSSM_L0_REV3;
	}

	fsl_pcie_hose_read_config_word(pcie, PCI_LTSSM, &ltssm);

	return ltssm == LTSSM_L0;
}

static bool fsl_pcie_is_agent(struct fsl_pcie *pcie)
{
	u8 header_type;

	fsl_pcie_hose_read_config_byte(pcie, PCI_HEADER_TYPE, &header_type);

	return (header_type & 0x7f) == PCI_HEADER_TYPE_NORMAL;
}

static int fsl_pcie_setup_law(struct fsl_pcie *pcie)
{
	struct pci_region *io, *mem, *pref;

	pci_get_regions(pcie->bus, &io, &mem, &pref);

	if (mem)
		set_next_law(mem->phys_start,
			     law_size_bits(mem->size),
			     pcie->law_trgt_if);

	if (io)
		set_next_law(io->phys_start,
			     law_size_bits(io->size),
			     pcie->law_trgt_if);

	return 0;
}

static void fsl_pcie_config_ready(struct fsl_pcie *pcie)
{
	ccsr_fsl_pci_t *regs = pcie->regs;

	if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
		setbits_be32(&regs->config, FSL_PCIE_V3_CFG_RDY);
		return;
	}

	fsl_pcie_hose_write_config_byte(pcie, FSL_PCIE_CFG_RDY, 0x1);
}

static int fsl_pcie_setup_outbound_win(struct fsl_pcie *pcie, int idx,
				       int type, u64 phys, u64 bus_addr,
				       pci_size_t size)
{
	ccsr_fsl_pci_t *regs = pcie->regs;
	pot_t *po = &regs->pot[idx];
	u32 war, sz;

	if (idx < 0)
		return -EINVAL;

	out_be32(&po->powbar, phys >> 12);
	out_be32(&po->potar, bus_addr >> 12);
#ifdef CONFIG_SYS_PCI_64BIT
	out_be32(&po->potear, bus_addr >> 44);
#else
	out_be32(&po->potear, 0);
#endif

	sz = (__ilog2_u64((u64)size) - 1);
	war = POWAR_EN | sz;

	if (type == PCI_REGION_IO)
		war |= POWAR_IO_READ | POWAR_IO_WRITE;
	else
		war |= POWAR_MEM_READ | POWAR_MEM_WRITE;

	out_be32(&po->powar, war);

	return 0;
}

static int fsl_pcie_setup_inbound_win(struct fsl_pcie *pcie, int idx,
				      bool pf, u64 phys, u64 bus_addr,
				      pci_size_t size)
{
	ccsr_fsl_pci_t *regs = pcie->regs;
	pit_t *pi = &regs->pit[idx];
	u32 sz = (__ilog2_u64(size) - 1);
	u32 flag = PIWAR_LOCAL;

	if (idx < 0)
		return -EINVAL;

	out_be32(&pi->pitar, phys >> 12);
	out_be32(&pi->piwbar, bus_addr >> 12);

#ifdef CONFIG_SYS_PCI_64BIT
	out_be32(&pi->piwbear, bus_addr >> 44);
#else
	out_be32(&pi->piwbear, 0);
#endif

#ifdef CONFIG_SYS_FSL_ERRATUM_A005434
	flag = 0;
#endif

	flag |= PIWAR_EN | PIWAR_READ_SNOOP | PIWAR_WRITE_SNOOP;
	if (pf)
		flag |= PIWAR_PF;
	out_be32(&pi->piwar, flag | sz);

	return 0;
}

static int fsl_pcie_setup_outbound_wins(struct fsl_pcie *pcie)
{
	struct pci_region *io, *mem, *pref;
	int idx = 1; /* skip 0 */

	pci_get_regions(pcie->bus, &io, &mem, &pref);

	if (io)
		/* ATU : OUTBOUND : IO */
		fsl_pcie_setup_outbound_win(pcie, idx++,
					    PCI_REGION_IO,
					    io->phys_start,
					    io->bus_start,
					    io->size);

	if (mem)
		/* ATU : OUTBOUND : MEM */
		fsl_pcie_setup_outbound_win(pcie, idx++,
					    PCI_REGION_MEM,
					    mem->phys_start,
					    mem->bus_start,
					    mem->size);
	return 0;
}

static int fsl_pcie_setup_inbound_wins(struct fsl_pcie *pcie)
{
	phys_addr_t phys_start = CONFIG_SYS_PCI_MEMORY_PHYS;
	pci_addr_t bus_start = CONFIG_SYS_PCI_MEMORY_BUS;
	u64 sz = min((u64)gd->ram_size, (1ull << 32));
	pci_size_t pci_sz;
	int idx;

	if (pcie->block_rev >= PEX_IP_BLK_REV_2_2)
		idx = 2;
	else
		idx = 3;

	pci_sz = 1ull << __ilog2_u64(sz);

	dev_dbg(pcie->bus, "R0 bus_start: %llx phys_start: %llx size: %llx\n",
		(u64)bus_start, (u64)phys_start, (u64)sz);

	/* if we aren't an exact power of two match, pci_sz is smaller
	 * round it up to the next power of two.  We report the actual
	 * size to pci region tracking.
	 */
	if (pci_sz != sz)
		sz = 2ull << __ilog2_u64(sz);

	fsl_pcie_setup_inbound_win(pcie, idx--, true,
				   CONFIG_SYS_PCI_MEMORY_PHYS,
				   CONFIG_SYS_PCI_MEMORY_BUS, sz);
#if defined(CONFIG_PHYS_64BIT) && defined(CONFIG_SYS_PCI_64BIT)
	/*
	 * On 64-bit capable systems, set up a mapping for all of DRAM
	 * in high pci address space.
	 */
	pci_sz = 1ull << __ilog2_u64(gd->ram_size);
	/* round up to the next largest power of two */
	if (gd->ram_size > pci_sz)
		pci_sz = 1ull << (__ilog2_u64(gd->ram_size) + 1);

	dev_dbg(pcie->bus, "R64 bus_start: %llx phys_start: %llx size: %llx\n",
		(u64)CONFIG_SYS_PCI64_MEMORY_BUS,
		(u64)CONFIG_SYS_PCI_MEMORY_PHYS, (u64)pci_sz);

	fsl_pcie_setup_inbound_win(pcie, idx--, true,
				   CONFIG_SYS_PCI_MEMORY_PHYS,
				   CONFIG_SYS_PCI64_MEMORY_BUS, pci_sz);
#endif

	return 0;
}

static int fsl_pcie_init_atmu(struct fsl_pcie *pcie)
{
	fsl_pcie_setup_outbound_wins(pcie);
	fsl_pcie_setup_inbound_wins(pcie);

	return 0;
}

static void fsl_pcie_dbi_read_only_reg_write_enable(struct fsl_pcie *pcie,
						    bool enable)
{
	u32 val;

	fsl_pcie_hose_read_config_dword(pcie, DBI_RO_WR_EN, &val);
	if (enable)
		val |= 1;
	else
		val &= ~1;
	fsl_pcie_hose_write_config_dword(pcie, DBI_RO_WR_EN, val);
}

static int fsl_pcie_init_port(struct fsl_pcie *pcie)
{
	ccsr_fsl_pci_t *regs = pcie->regs;
	u32 val_32;
	u16 val_16;

	fsl_pcie_init_atmu(pcie);

#ifdef CONFIG_FSL_PCIE_DISABLE_ASPM
	val_32 = 0;
	fsl_pcie_hose_read_config_dword(pcie, PCI_LCR, &val_32);
	val_32 &= ~0x03;
	fsl_pcie_hose_write_config_dword(pcie, PCI_LCR, val_32);
	udelay(1);
#endif

#ifdef CONFIG_FSL_PCIE_RESET
	u16 ltssm;
	int i;

	if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
		/* assert PCIe reset */
		setbits_be32(&regs->pdb_stat, 0x08000000);
		(void)in_be32(&regs->pdb_stat);
		udelay(1000);
		/* clear PCIe reset */
		clrbits_be32(&regs->pdb_stat, 0x08000000);
		asm("sync;isync");
		for (i = 0; i < 100 && !fsl_pcie_link_up(pcie); i++)
			udelay(1000);
	} else {
		fsl_pcie_hose_read_config_word(pcie, PCI_LTSSM, &ltssm);
		if (ltssm == 1) {
			/* assert PCIe reset */
			setbits_be32(&regs->pdb_stat, 0x08000000);
			(void)in_be32(&regs->pdb_stat);
			udelay(100);
			/* clear PCIe reset */
			clrbits_be32(&regs->pdb_stat, 0x08000000);
			asm("sync;isync");
			for (i = 0; i < 100 &&
			     !fsl_pcie_link_up(pcie); i++)
				udelay(1000);
		}
	}
#endif

#ifdef CONFIG_SYS_P4080_ERRATUM_PCIE_A003
	if (!fsl_pcie_link_up(pcie)) {
		serdes_corenet_t *srds_regs;

		srds_regs = (void *)CONFIG_SYS_FSL_CORENET_SERDES_ADDR;
		val_32 = in_be32(&srds_regs->srdspccr0);

		if ((val_32 >> 28) == 3) {
			int i;

			out_be32(&srds_regs->srdspccr0, 2 << 28);
			setbits_be32(&regs->pdb_stat, 0x08000000);
			in_be32(&regs->pdb_stat);
			udelay(100);
			clrbits_be32(&regs->pdb_stat, 0x08000000);
			asm("sync;isync");
			for (i = 0; i < 100 && !fsl_pcie_link_up(pcie); i++)
				udelay(1000);
		}
	}
#endif

	/*
	 * The Read-Only Write Enable bit defaults to 1 instead of 0.
	 * Set to 0 to protect the read-only registers.
	 */
#ifdef CONFIG_SYS_FSL_ERRATUM_A007815
	fsl_pcie_dbi_read_only_reg_write_enable(pcie, false);
#endif

	/*
	 * Enable All Error Interrupts except
	 * - Master abort (pci)
	 * - Master PERR (pci)
	 * - ICCA (PCIe)
	 */
	out_be32(&regs->peer, ~0x20140);

	/* set URR, FER, NFER (but not CER) */
	fsl_pcie_hose_read_config_dword(pcie, PCI_DCR, &val_32);
	val_32 |= 0xf000e;
	fsl_pcie_hose_write_config_dword(pcie, PCI_DCR, val_32);

	/* Clear all error indications */
	out_be32(&regs->pme_msg_det, 0xffffffff);
	out_be32(&regs->pme_msg_int_en, 0xffffffff);
	out_be32(&regs->pedr, 0xffffffff);

	fsl_pcie_hose_read_config_word(pcie, PCI_DSR, &val_16);
	if (val_16)
		fsl_pcie_hose_write_config_word(pcie, PCI_DSR, 0xffff);

	fsl_pcie_hose_read_config_word(pcie, PCI_SEC_STATUS, &val_16);
	if (val_16)
		fsl_pcie_hose_write_config_word(pcie, PCI_SEC_STATUS, 0xffff);

	return 0;
}

static int fsl_pcie_fixup_classcode(struct fsl_pcie *pcie)
{
	u32 classcode_reg;
	u32 val;

	if (pcie->block_rev >= PEX_IP_BLK_REV_3_0) {
		classcode_reg = PCI_CLASS_REVISION;
		fsl_pcie_dbi_read_only_reg_write_enable(pcie, true);
	} else {
		classcode_reg = CSR_CLASSCODE;
	}

	fsl_pcie_hose_read_config_dword(pcie, classcode_reg, &val);
	val &= 0xff;
	val |= PCI_CLASS_BRIDGE_PCI << 16;
	fsl_pcie_hose_write_config_dword(pcie, classcode_reg, val);

	if (pcie->block_rev >= PEX_IP_BLK_REV_3_0)
		fsl_pcie_dbi_read_only_reg_write_enable(pcie, false);

	return 0;
}

static int fsl_pcie_init_rc(struct fsl_pcie *pcie)
{
	return fsl_pcie_fixup_classcode(pcie);
}

static int fsl_pcie_init_ep(struct fsl_pcie *pcie)
{
	fsl_pcie_config_ready(pcie);

	return 0;
}

static int fsl_pcie_probe(struct udevice *dev)
{
	struct fsl_pcie *pcie = dev_get_priv(dev);
	ccsr_fsl_pci_t *regs = pcie->regs;
	u16 val_16;

	pcie->bus = dev;
	pcie->block_rev = in_be32(&regs->block_rev1);

	list_add(&pcie->list, &fsl_pcie_list);
	pcie->enabled = is_serdes_configured(PCIE1 + pcie->idx);
	if (!pcie->enabled) {
		printf("PCIe%d: %s disabled\n", pcie->idx, dev->name);
		return 0;
	}

	fsl_pcie_setup_law(pcie);

	pcie->mode = fsl_pcie_is_agent(pcie);

	fsl_pcie_init_port(pcie);

	printf("PCIe%d: %s ", pcie->idx, dev->name);

	if (pcie->mode) {
		printf("Endpoint");
		fsl_pcie_init_ep(pcie);
	} else {
		printf("Root Complex");
		fsl_pcie_init_rc(pcie);
	}

	if (!fsl_pcie_link_up(pcie)) {
		printf(": %s\n", pcie->mode ? "undetermined link" : "no link");
		return 0;
	}

	fsl_pcie_hose_read_config_word(pcie, PCI_LSR, &val_16);
	printf(": x%d gen%d\n", (val_16 & 0x3f0) >> 4, (val_16 & 0xf));

	return 0;
}

static int fsl_pcie_of_to_plat(struct udevice *dev)
{
	struct fsl_pcie *pcie = dev_get_priv(dev);
	struct fsl_pcie_data *info;
	int ret;

	pcie->regs = dev_remap_addr(dev);
	if (!pcie->regs) {
		pr_err("\"reg\" resource not found\n");
		return -EINVAL;
	}

	ret = dev_read_u32(dev, "law_trgt_if", &pcie->law_trgt_if);
	if (ret < 0) {
		pr_err("\"law_trgt_if\" not found\n");
		return ret;
	}

	info = (struct fsl_pcie_data *)dev_get_driver_data(dev);
	pcie->info = info;
	pcie->idx = abs((u32)(dev_read_addr(dev) & info->block_offset_mask) -
		    info->block_offset) / info->stride;

	return 0;
}

static const struct dm_pci_ops fsl_pcie_ops = {
	.read_config	= fsl_pcie_read_config,
	.write_config	= fsl_pcie_write_config,
};

static struct fsl_pcie_data p1_p2_data = {
	.block_offset = 0xa000,
	.block_offset_mask = 0xffff,
	.stride = 0x1000,
};

static struct fsl_pcie_data p2041_data = {
	.block_offset = 0x200000,
	.block_offset_mask = 0x3fffff,
	.stride = 0x1000,
};

static struct fsl_pcie_data t2080_data = {
	.block_offset = 0x240000,
	.block_offset_mask = 0x3fffff,
	.stride = 0x10000,
};

static const struct udevice_id fsl_pcie_ids[] = {
	{ .compatible = "fsl,pcie-mpc8548", .data = (ulong)&p1_p2_data },
	{ .compatible = "fsl,pcie-p1_p2", .data = (ulong)&p1_p2_data },
	{ .compatible = "fsl,pcie-p2041", .data = (ulong)&p2041_data },
	{ .compatible = "fsl,pcie-p3041", .data = (ulong)&p2041_data },
	{ .compatible = "fsl,pcie-p4080", .data = (ulong)&p2041_data },
	{ .compatible = "fsl,pcie-p5040", .data = (ulong)&p2041_data },
	{ .compatible = "fsl,pcie-t102x", .data = (ulong)&t2080_data },
	{ .compatible = "fsl,pcie-t104x", .data = (ulong)&t2080_data },
	{ .compatible = "fsl,pcie-t2080", .data = (ulong)&t2080_data },
	{ .compatible = "fsl,pcie-t4240", .data = (ulong)&t2080_data },
	{ }
};

U_BOOT_DRIVER(fsl_pcie) = {
	.name = "fsl_pcie",
	.id = UCLASS_PCI,
	.of_match = fsl_pcie_ids,
	.ops = &fsl_pcie_ops,
	.of_to_plat = fsl_pcie_of_to_plat,
	.probe = fsl_pcie_probe,
	.priv_auto	= sizeof(struct fsl_pcie),
};
