// 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/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) < bus->seq)
		return -EINVAL;

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

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

	if (PCI_BUS(bdf) == (bus->seq + 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;
	}

	bdf = bdf - PCI_BDF(bus->seq, 0, 0);
	val = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000;
	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;

	bdf = bdf - PCI_BDF(bus->seq, 0, 0);
	val = bdf | (offset & 0xfc) | ((offset & 0xf00) << 16) | 0x80000000;
	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(bus->seq, 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(bus->seq, 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_ofdata_to_platdata(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,
	.ofdata_to_platdata = fsl_pcie_ofdata_to_platdata,
	.probe = fsl_pcie_probe,
	.priv_auto_alloc_size = sizeof(struct fsl_pcie),
};
